diff options
| author | Shauren <shauren.trinity@gmail.com> | 2017-01-18 17:18:20 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2017-01-18 17:20:16 +0100 |
| commit | 3fd51db845e9753e4320798d1f2e41688d78d852 (patch) | |
| tree | 754adaf982bb204b34ab7b7c549beb0c4d62a078 /src/tools/extractor_common | |
| parent | 9eda3d85423b4b5a84ad0c45e1bc06db37b6eb5c (diff) | |
Tools/Extractors: Intruduce safe casc handles and fix all casc related memory leaks
CID 1254545
CID 1254555
CID 1254588
CID 1343649
Diffstat (limited to 'src/tools/extractor_common')
| -rw-r--r-- | src/tools/extractor_common/CMakeLists.txt | 21 | ||||
| -rw-r--r-- | src/tools/extractor_common/CascHandles.cpp | 101 | ||||
| -rw-r--r-- | src/tools/extractor_common/CascHandles.h | 56 |
3 files changed, 178 insertions, 0 deletions
diff --git a/src/tools/extractor_common/CMakeLists.txt b/src/tools/extractor_common/CMakeLists.txt new file mode 100644 index 00000000000..50cc20c9682 --- /dev/null +++ b/src/tools/extractor_common/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +CollectSourceFiles( + ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE_SOURCES) + +add_library(extractor_common STATIC ${PRIVATE_SOURCES}) + +target_link_libraries(extractor_common boost casc) + +target_include_directories(extractor_common + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/tools/extractor_common/CascHandles.cpp b/src/tools/extractor_common/CascHandles.cpp new file mode 100644 index 00000000000..9624a1ca149 --- /dev/null +++ b/src/tools/extractor_common/CascHandles.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "CascHandles.h" +#include "CascLib.h" +#include <boost/filesystem/operations.hpp> + +namespace +{ + const char* HumanReadableCASCError(int error) + { + switch (error) + { + case ERROR_SUCCESS: return "SUCCESS"; + case ERROR_FILE_CORRUPT: return "FILE_CORRUPT"; + case ERROR_CAN_NOT_COMPLETE: return "CAN_NOT_COMPLETE"; + case ERROR_HANDLE_EOF: return "HANDLE_EOF"; + case ERROR_NO_MORE_FILES: return "NO_MORE_FILES"; + case ERROR_BAD_FORMAT: return "BAD_FORMAT"; + case ERROR_INSUFFICIENT_BUFFER: return "INSUFFICIENT_BUFFER"; + case ERROR_ALREADY_EXISTS: return "ALREADY_EXISTS"; + case ERROR_DISK_FULL: return "DISK_FULL"; + case ERROR_INVALID_PARAMETER: return "INVALID_PARAMETER"; + case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; + case ERROR_NOT_ENOUGH_MEMORY: return "NOT_ENOUGH_MEMORY"; + case ERROR_INVALID_HANDLE: return "INVALID_HANDLE"; + case ERROR_ACCESS_DENIED: return "ACCESS_DENIED"; + case ERROR_FILE_NOT_FOUND: return "FILE_NOT_FOUND"; + default: return "UNKNOWN"; + } + } +} + +void CASC::StorageDeleter::operator()(HANDLE handle) +{ + if (handle != nullptr && handle != INVALID_HANDLE_VALUE) + ::CascCloseStorage(handle); +} + +void CASC::FileDeleter::operator()(HANDLE handle) +{ + if (handle != nullptr && handle != INVALID_HANDLE_VALUE) + ::CascCloseFile(handle); +} + +CASC::StorageHandle CASC::OpenStorage(boost::filesystem::path const& path, DWORD localeMask) +{ + HANDLE handle = nullptr; + if (!::CascOpenStorage(path.string().c_str(), localeMask, &handle)) + { + DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close* + printf("Error opening casc storage '%s': %s\n", path.string().c_str(), HumanReadableCASCError(lastError)); + CascCloseStorage(handle); + SetLastError(lastError); + return StorageHandle(); + } + + printf("Opened casc storage '%s'\n", path.string().c_str()); + return StorageHandle(handle); +} + +CASC::FileHandle CASC::OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors /*= false*/) +{ + HANDLE handle = nullptr; + if (!::CascOpenFile(storage.get(), fileName, localeMask, 0, &handle)) + { + DWORD lastError = GetLastError(); // support checking error set by *Open* call, not the next *Close* + if (printErrors) + fprintf(stderr, "Failed to open '%s' in CASC storage: %s\n", fileName, HumanReadableCASCError(lastError)); + + CascCloseFile(handle); + SetLastError(lastError); + return FileHandle(); + } + + return FileHandle(handle); +} + +DWORD CASC::GetFileSize(FileHandle const& file, PDWORD fileSizeHigh) +{ + return ::CascGetFileSize(file.get(), fileSizeHigh); +} + +bool CASC::ReadFile(FileHandle const& file, void* buffer, DWORD bytes, PDWORD bytesRead) +{ + return ::CascReadFile(file.get(), buffer, bytes, bytesRead); +} diff --git a/src/tools/extractor_common/CascHandles.h b/src/tools/extractor_common/CascHandles.h new file mode 100644 index 00000000000..455306ad5e0 --- /dev/null +++ b/src/tools/extractor_common/CascHandles.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CascHandles_h__ +#define CascHandles_h__ + +#include "CascPort.h" +#include <memory> + +namespace boost +{ + namespace filesystem + { + class path; + } +} + +namespace CASC +{ + struct StorageDeleter + { + typedef HANDLE pointer; + void operator()(HANDLE handle); + }; + + struct FileDeleter + { + typedef HANDLE pointer; + void operator()(HANDLE handle); + }; + + typedef std::unique_ptr<HANDLE, StorageDeleter> StorageHandle; + typedef std::unique_ptr<HANDLE, FileDeleter> FileHandle; + + StorageHandle OpenStorage(boost::filesystem::path const& path, DWORD localeMask); + + FileHandle OpenFile(StorageHandle const& storage, char const* fileName, DWORD localeMask, bool printErrors = false); + DWORD GetFileSize(FileHandle const& file, PDWORD fileSizeHigh); + bool ReadFile(FileHandle const& file, void* buffer, DWORD bytes, PDWORD bytesRead); +} + +#endif // CascHandles_h__ |
