From 6cb4814cf0519447f3d3572c300e32dc75dcd31e Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sat, 11 Feb 2023 15:29:51 +0800 Subject: [PATCH] almost finish migration from py to c++ --- CodeGen/src/CK_CLASSID.txt | 3 +- LibCmo/LibCmo.vcxproj | 34 ++++---- LibCmo/LibCmo.vcxproj.filters | 6 +- LibCmo/VTConstants.hpp | 11 ++- LibCmo/VTEncoding.cpp | 106 +++++++++++++++++++++++ LibCmo/VTEncoding.hpp | 88 ++----------------- LibCmo/VTReader.cpp | 155 +++++++++++++++++++++++++++++++++- LibCmo/VTReader.hpp | 12 --- LibCmo/VTStruct.cpp | 74 ++++++++++++++-- LibCmo/VTStruct.hpp | 71 ++++++++-------- LibCmo/VTUtils.hpp | 22 ++++- Unvirt/AccessibleValue.cpp | 1 - Unvirt/Unvirt.cpp | 17 +--- Unvirt/Unvirt.vcxproj | 24 +++--- 14 files changed, 434 insertions(+), 190 deletions(-) create mode 100644 LibCmo/VTEncoding.cpp delete mode 100644 LibCmo/VTReader.hpp diff --git a/CodeGen/src/CK_CLASSID.txt b/CodeGen/src/CK_CLASSID.txt index 2ebbb8b..ee3e175 100644 --- a/CodeGen/src/CK_CLASSID.txt +++ b/CodeGen/src/CK_CLASSID.txt @@ -42,7 +42,6 @@ #define CKCID_BODYPART 42 #define CKCID_PARAMETER 46 #define CKCID_PARAMETERLOCAL 45 - #define CKCID_PARAMETERVARIABLE 55 #define CKCID_PARAMETEROUT 3 #define CKCID_INTERFACEOBJECTMANAGER 48 #define CKCID_CRITICALSECTION 49 @@ -66,5 +65,5 @@ #define CKCID_TIMEMANAGER 93 #define CKCID_CUIKBEHDATA -1 -#define CKCID_MAXCLASSID 56 +#define CKCID_MAXCLASSID 55 #define CKCID_MAXMAXCLASSID 128 \ No newline at end of file diff --git a/LibCmo/LibCmo.vcxproj b/LibCmo/LibCmo.vcxproj index 35fff1b..9b39697 100644 --- a/LibCmo/LibCmo.vcxproj +++ b/LibCmo/LibCmo.vcxproj @@ -27,26 +27,26 @@ - DynamicLibrary + StaticLibrary true v142 Unicode - DynamicLibrary + StaticLibrary false v142 true Unicode - DynamicLibrary + StaticLibrary true v142 Unicode - DynamicLibrary + StaticLibrary false v142 true @@ -98,7 +98,7 @@ Level3 true - LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -106,8 +106,7 @@ Console true - $(ZLIB_PATH)\contrib\vstudio\vc14\x86\ZlibDllReleaseWithoutAsm;%(AdditionalLibraryDirectories) - zlibwapi.lib;%(AdditionalDependencies) + %(AdditionalDependencies) @@ -116,7 +115,7 @@ true true true - LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -126,15 +125,14 @@ true true true - $(ZLIB_PATH)\contrib\vstudio\vc14\x86\ZlibDllReleaseWithoutAsm;%(AdditionalLibraryDirectories) - zlibwapi.lib;%(AdditionalDependencies) + %(AdditionalDependencies) Level3 true - LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -142,8 +140,9 @@ Console true - $(ZLIB_PATH)\contrib\vstudio\vc14\x64\ZlibDllReleaseWithoutAsm - zlibwapi.lib;%(AdditionalDependencies) + + + %(AdditionalDependencies) @@ -152,7 +151,7 @@ true true true - LIBCMO_EXPORTING;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -162,18 +161,19 @@ true true true - $(ZLIB_PATH)\contrib\vstudio\vc14\x64\ZlibDllReleaseWithoutAsm - zlibwapi.lib;%(AdditionalDependencies) + + + %(AdditionalDependencies) + - diff --git a/LibCmo/LibCmo.vcxproj.filters b/LibCmo/LibCmo.vcxproj.filters index e63257d..b93dc59 100644 --- a/LibCmo/LibCmo.vcxproj.filters +++ b/LibCmo/LibCmo.vcxproj.filters @@ -21,11 +21,11 @@ Sources + + Sources + - - Headers - Headers diff --git a/LibCmo/VTConstants.hpp b/LibCmo/VTConstants.hpp index e9a3e09..7c7c462 100644 --- a/LibCmo/VTConstants.hpp +++ b/LibCmo/VTConstants.hpp @@ -26,9 +26,12 @@ namespace LibCmo { } } + using CKINT = int32_t; using CK_ID = uint32_t; using CKDWORD = uint32_t; using CKBOOL = int32_t; + using CKMUTSTRING = char*; + using CKSTRING = const char*; using XString = std::string; using XBitArray = std::vector; @@ -36,7 +39,8 @@ namespace LibCmo { using XArray = std::vector; using XIntArray = std::vector; template - using XClassArray = std::vector; + using XClassArray = std::vector; + //using CKObjectArray = std::vector; enum class CK_CLASSID : uint32_t { CKCID_OBJECT = 1, @@ -83,7 +87,6 @@ namespace LibCmo { CKCID_BODYPART = 42, CKCID_PARAMETER = 46, CKCID_PARAMETERLOCAL = 45, - CKCID_PARAMETERVARIABLE = 55, CKCID_PARAMETEROUT = 3, CKCID_INTERFACEOBJECTMANAGER = 48, CKCID_CRITICALSECTION = 49, @@ -105,9 +108,9 @@ namespace LibCmo { CKCID_GRIDMANAGER = 91, CKCID_SOUNDMANAGER = 92, CKCID_TIMEMANAGER = 93, - CKCID_CUIKBEHDATA = (uint32_t)-1, + CKCID_CUIKBEHDATA = static_cast(-1), - CKCID_MAXCLASSID = 56, + CKCID_MAXCLASSID = 55, CKCID_MAXMAXCLASSID = 128 }; diff --git a/LibCmo/VTEncoding.cpp b/LibCmo/VTEncoding.cpp new file mode 100644 index 0000000..dc4fefc --- /dev/null +++ b/LibCmo/VTEncoding.cpp @@ -0,0 +1,106 @@ +#include "VTEncoding.hpp" + +namespace LibCmo { + namespace Encoding { + +#pragma region assist functions + +#if defined(LIBCMO_OS_WIN32) + +#define LIBCMO_STR_EQUAL(a, b) strcmp(reinterpret_cast(a), reinterpret_cast(b)) == 0 + bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result) { + if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_ACP")) *result = CP_ACP; + else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_MACCP")) *result = CP_MACCP; + else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_OEMCP")) *result = CP_OEMCP; + else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_THREAD_ACPP")) *result = CP_THREAD_ACP; + else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_UTF8")) *result = CP_UTF8; + else { + char* pend = nullptr; + errno = 0; + uint64_t v = std::strtoull(u8_encoding_spec, &pend, 10); + + if (pend == u8_encoding_spec || errno == ERANGE) return false; + *result = static_cast(v); + } + return true; + } +#undef LIBCMO_STR_EQUAL + + bool WcharToChar(const wchar_t* src, std::string& dest, UINT codepage) { + int count, write_result; + + //converter to CHAR + count = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL); + if (count <= 0) return false; + + dest.resize(count); + write_result = WideCharToMultiByte(CP_UTF8, 0, src, -1, dest.data(), count, NULL, NULL); + if (write_result <= 0) return false; + + return true; + } + bool WcharToChar(std::wstring& src, std::string& dest, UINT codepage) { + return WcharToChar(src.c_str(), dest, codepage); + } + + bool CharToWchar(const char* src, std::wstring& dest, UINT codepage) { + int wcount, write_result; + + // convert to WCHAR + wcount = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0); + if (wcount <= 0) return false; + + dest.resize(wcount); + write_result = MultiByteToWideChar(CP_UTF8, 0, src, -1, dest.data(), wcount); + if (write_result <= 0) return false; + + return true; + } + bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage) { + return CharToWchar(src.c_str(), dest, codepage); + } + +#else + + //todo: linux implementation + +#endif + +#pragma endregion + +#pragma region core functions + +#if defined(LIBCMO_OS_WIN32) + + void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec) { + // switch encoding spec + UINT codepage = CP_ACP; + if (!GetWindowsCodePage(u8_encoding_spec, &codepage)) { + u8_name = native_name.c_str(); + return; + } + + // do convert + std::wstring intermediary; + if (!CharToWchar(native_name, intermediary, codepage)) { + u8_name = native_name.c_str(); + return; + } + if (!WcharToChar(intermediary, u8_name, CP_UTF8)) { + u8_name = native_name.c_str(); + return; + } + + return; + } + +#else + //todo: linux implementation + +#endif + +#pragma endregion + + } +} + diff --git a/LibCmo/VTEncoding.hpp b/LibCmo/VTEncoding.hpp index b22f372..a2eb84a 100644 --- a/LibCmo/VTEncoding.hpp +++ b/LibCmo/VTEncoding.hpp @@ -1,11 +1,8 @@ #pragma once +#include "VTUtils.hpp" #include -#if defined(_WIN32) -#define LIBCMO_OS_WIN32 -#endif - #if defined(LIBCMO_OS_WIN32) #include #else @@ -19,63 +16,16 @@ namespace LibCmo { #if defined(LIBCMO_OS_WIN32) -#define LIBCMO_STR_EQUAL(a, b) strcmp(reinterpret_cast(a), reinterpret_cast(b)) == 0 - bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result) { - if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_ACP")) *result = CP_ACP; - else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_MACCP")) *result = CP_MACCP; - else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_OEMCP")) *result = CP_OEMCP; - else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_THREAD_ACPP")) *result = CP_THREAD_ACP; - else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_UTF8")) *result = CP_UTF8; - else { - char* pend = nullptr; - errno = 0; - uint64_t v = std::strtoull(u8_encoding_spec, &pend, 10); + bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result); - if (pend == u8_encoding_spec || errno == ERANGE) return false; - *result = static_cast(v); - } - return true; - } -#undef LIBCMO_STR_EQUAL + bool WcharToChar(const wchar_t* src, std::string& dest, UINT codepage); + bool WcharToChar(std::wstring& src, std::string& dest, UINT codepage); - bool WcharToChar(const wchar_t* src, std::string& dest, UINT codepage) { - int count, write_result; - - //converter to CHAR - count = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL); - if (count <= 0) return false; - - dest.resize(count); - write_result = WideCharToMultiByte(CP_UTF8, 0, src, -1, dest.data(), count, NULL, NULL); - if (write_result <= 0) return false; - - return true; - } - bool WcharToChar(std::wstring& src, std::string& dest, UINT codepage) { - return WcharToChar(src.c_str(), dest, codepage); - } - - bool CharToWchar(const char* src, std::wstring& dest, UINT codepage) { - int wcount, write_result; - - // convert to WCHAR - wcount = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0); - if (wcount <= 0) return false; - - dest.resize(wcount); - write_result = MultiByteToWideChar(CP_UTF8, 0, src, -1, dest.data(), wcount); - if (write_result <= 0) return false; - - return true; - } - bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage) { - return CharToWchar(src.c_str(), dest, codepage); - } + bool CharToWchar(const char* src, std::wstring& dest, UINT codepage); + bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage); #else - - //todo: linux implementation - +#error NO IMPLEMENTATION FOR LINUX ENCODING! #endif #pragma endregion @@ -84,32 +34,10 @@ namespace LibCmo { #if defined(LIBCMO_OS_WIN32) - void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec) { - // switch encoding spec - UINT codepage = CP_ACP; - if (!GetWindowsCodePage(u8_encoding_spec, &codepage)) { - u8_name = native_name.c_str(); - return; - } - - // do convert - std::wstring intermediary; - if (!CharToWchar(native_name, intermediary, codepage)) { - u8_name = native_name.c_str(); - return; - } - if (!WcharToChar(intermediary, u8_name, CP_UTF8)) { - u8_name = native_name.c_str(); - return; - } - - return; - } + void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec); #else - //todo: linux implementation #error NO IMPLEMENTATION FOR LINUX ENCODING! - #endif #pragma endregion diff --git a/LibCmo/VTReader.cpp b/LibCmo/VTReader.cpp index 349cc31..cbacd50 100644 --- a/LibCmo/VTReader.cpp +++ b/LibCmo/VTReader.cpp @@ -1,13 +1,162 @@ -#include "VTReader.hpp" +#include "VTUtils.hpp" +#if defined(LIBCMO_OS_WIN32) +#define ZLIB_WINAPI +#include "zconf.h" +#endif + +#include "VTStruct.hpp" +#include namespace LibCmo { - CKERROR ReadFileHeaders(void) { + CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) { + CKERROR result = this->OpenFile(u8_filename, flags); + if (result == CKERROR::CKERR_OK || result == CKERROR::CKERR_PLUGINSMISSING) { + result = this->LoadFileData(); + } + + return result; + } + + CKERROR CKFile::OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags) { + this->ClearData(); + if (u8_filename == nullptr) return CKERROR::CKERR_INVALIDPARAMETER; + + this->m_FileName = u8_filename; + this->m_MappedFile = new VxMemoryMappedFile(this->m_FileName.c_str()); + if (!this->m_MappedFile->IsValid()) return CKERROR::CKERR_INVALIDFILE; + + return this->OpenMemory(this->m_MappedFile->GetBase(), this->m_MappedFile->GetFileSize(), flags); + } + + CKERROR CKFile::OpenMemory(void* MemoryBuffer, size_t BufferSize, CK_LOAD_FLAGS Flags) { + if (MemoryBuffer == nullptr) return CKERROR::CKERR_INVALIDPARAMETER; + // compare magic words + if (BufferSize < 0x20 || memcmp(MemoryBuffer, "Nemo", 4u)) return CKERROR::CKERR_INVALIDFILE; + + this->m_Parser = new CKBufferParser(MemoryBuffer, BufferSize, false); + + this->m_Flags = Flags; + this->m_IndexByClassId.resize(static_cast(CK_CLASSID::CKCID_MAXCLASSID)); + return this->ReadFileHeaders(&(this->m_Parser)); + } + + CKERROR CKFile::ReadFileHeaders(CKBufferParser** ParserPtr) { + CKBufferParser* parser = *ParserPtr; + this->m_IncludedFiles.clear(); + + // ========== read header1 ========== + CKDWORD fhdr1[8]; + CKDWORD fhdr2[8]; + if (parser->GetSize() < sizeof(fhdr1)) return CKERROR::CKERR_INVALIDFILE; + memcpy(fhdr1, parser->GetPtr(), sizeof(fhdr1)); + parser->MoveCursor(sizeof(fhdr1)); + + if (fhdr1[5]) { // it seems that there is a ZERO checker? + memset(fhdr1, 0, sizeof(fhdr1)); + } + // check outdated + if (fhdr1[4] > 9) return CKERROR::CKERR_OBSOLETEVIRTOOLS; + + // ========== read header2 ========== + // file ver < 5 do not have second header + if (fhdr1[4] < 5) { + memset(fhdr2, 0, sizeof(fhdr2)); + } else { + if (parser->GetSize() < sizeof(fhdr1) + sizeof(fhdr2)) return CKERROR::CKERR_INVALIDFILE; + memcpy(fhdr2, parser->GetPtr(), sizeof(fhdr2)); + parser->MoveCursor(sizeof(fhdr2)); + } + + // forcely reset too big product ver + if (fhdr2[5] >= 12) { + fhdr2[5] = 0; + fhdr2[6] = 0x1010000; + } + + // ========== assign value ========== + this->m_FileInfo.ProductVersion = fhdr2[5]; + this->m_FileInfo.ProductBuild = fhdr2[6]; + this->m_FileInfo.FileWriteMode = static_cast(fhdr1[6]); + this->m_FileInfo.CKVersion = fhdr1[3]; + this->m_FileInfo.FileVersion = fhdr1[4]; + this->m_FileInfo.FileSize = parser->GetSize(); + this->m_FileInfo.ManagerCount = fhdr2[2]; + this->m_FileInfo.ObjectCount = fhdr2[3]; + this->m_FileInfo.MaxIDSaved = fhdr2[4]; + this->m_FileInfo.Hdr1PackSize = fhdr1[7]; + this->m_FileInfo.Hdr1UnPackSize = fhdr2[7]; + this->m_FileInfo.DataPackSize = fhdr2[0]; + this->m_FileInfo.DataUnPackSize = fhdr2[1]; + this->m_FileInfo.Crc = fhdr1[3]; + + // ========== crc and body unpacker ========== + if (this->m_FileInfo.FileVersion >= 8) { + // crc checker for file ver >= 8 + // reset crc field of header + fhdr1[2] = 0; + + // compute crc + uLong gotten_crc = adler32(0u, reinterpret_cast(&fhdr1), sizeof(fhdr1)); + parser->SetCursor(sizeof(fhdr1)); + gotten_crc = adler32(gotten_crc, reinterpret_cast(parser->GetPtr()), sizeof(fhdr2)); + parser->MoveCursor(sizeof(fhdr2)); + gotten_crc = adler32(gotten_crc, reinterpret_cast(parser->GetPtr()), this->m_FileInfo.Hdr1PackSize); + parser->MoveCursor(this->m_FileInfo.Hdr1PackSize); + gotten_crc = adler32(gotten_crc, reinterpret_cast(parser->GetPtr()), this->m_FileInfo.DataPackSize); + parser->SetCursor(sizeof(fhdr1) + sizeof(fhdr2)); + + if (gotten_crc != static_cast(this->m_FileInfo.Crc)) return CKERROR::CKERR_FILECRCERROR; + + // compare size to decide wheher use compress feature + void* decomp_buffer = CKUnPackData(this->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), this->m_FileInfo.Hdr1PackSize); + if (decomp_buffer != nullptr) { + parser = new CKBufferParser(decomp_buffer, this->m_FileInfo.Hdr1UnPackSize, true); + } + } + + // ========== object list read ========== + // file ver >= 7 have this features + if (this->m_FileInfo.FileVersion >= 7) { + // apply max id saved + this->m_SaveIDMax = this->m_FileInfo.MaxIDSaved; + // resize + this->m_FileObject.resize(this->m_FileInfo.ObjectCount); + + // read data + for (auto it = this->m_FileObject.begin(); it != this->m_FileObject.end(); ++it) { + CKFileObject* fileobj = &(*it); + // setup useless fields + fileobj->ObjPtr = nullptr; + fileobj->Data = nullptr; + + // read basic fields + memcpy(&(fileobj->Object), parser->GetPtr(), sizeof(CK_ID)); + parser->MoveCursor(sizeof(CK_ID)); + memcpy(&(fileobj->ObjectCid), parser->GetPtr(), sizeof(CK_CLASSID)); + parser->MoveCursor(sizeof(CK_CLASSID)); + memcpy(&(fileobj->FileIndex), parser->GetPtr(), sizeof(CKDWORD)); + parser->MoveCursor(sizeof(CKDWORD)); + + CKDWORD namelen; + memcpy(&namelen, parser->GetPtr(), sizeof(CKDWORD)); + parser->MoveCursor(sizeof(CKDWORD)); + if (namelen != 0) { + fileobj->Name.resize(namelen); + memcpy(fileobj->Name.data(), parser->GetPtr(), namelen); + parser->MoveCursor(namelen); + } + } + } + return CKERROR::CKERR_OK; } - CKERROR Load(void) { + CKERROR CKFile::ReadFileData(CKBufferParser** ParserPtr) { return CKERROR::CKERR_OK; } + CKERROR CKFile::LoadFileData(void/*CKObjectArray list*/) { + return CKERROR::CKERR_OK; + } } diff --git a/LibCmo/VTReader.hpp b/LibCmo/VTReader.hpp deleted file mode 100644 index 4e028b2..0000000 --- a/LibCmo/VTReader.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "VTUtils.hpp" -#include "VTConstants.hpp" - -namespace LibCmo { - - LIBCMO_EXPORT CKERROR ReadFileHeaders(void); - LIBCMO_EXPORT CKERROR Load(void); - -} - diff --git a/LibCmo/VTStruct.cpp b/LibCmo/VTStruct.cpp index abf6204..603729c 100644 --- a/LibCmo/VTStruct.cpp +++ b/LibCmo/VTStruct.cpp @@ -1,7 +1,32 @@ +#include "VTUtils.hpp" +#if defined(LIBCMO_OS_WIN32) +#define ZLIB_WINAPI +#include "zconf.h" +#endif + #include "VTStruct.hpp" +#include +#include namespace LibCmo { + void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize) { + char* DestBuffer = (char*)malloc(DestSize); + if (DestBuffer == nullptr) return nullptr; + + uLongf cache = DestSize; + if (uncompress( + reinterpret_cast(DestBuffer), &cache, + reinterpret_cast(SrcBuffer), SrcSize) != Z_OK) { + free(DestBuffer); + return nullptr; + } + + return DestBuffer; + } + +#pragma region VxMemoryMappedFile + VxMemoryMappedFile::VxMemoryMappedFile(const char* u8_filepath) : m_szFilePath(), m_hFile(nullptr), m_hFileMapping(nullptr), @@ -24,7 +49,7 @@ namespace LibCmo { // open region this->m_hFileMapping = new boost::interprocess::mapped_region( - this->m_hFile, boost::interprocess::read_only, + *(this->m_hFile), boost::interprocess::read_only, 0, 0, nullptr, region_option ); @@ -42,15 +67,54 @@ namespace LibCmo { delete this->m_hFile; } - void* VxMemoryMappedFile::GetBase(void) { return this->m_hFileMapping->get_address(); } - size_t VxMemoryMappedFile::GetFileSize(void) { return this->m_hFileMapping->get_size(); } - bool VxMemoryMappedFile::IsValid(void) { return this->m_bIsValid; } +#pragma endregion +#pragma region CKBufferParser - CKFile::CKFile() { + CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) : + m_ReaderBegin(static_cast(ptr)), + m_ReaderPos(0u), m_ReaderSize(rsize), + m_NeedManualFree(need_manual_free) { + ; + } + CKBufferParser::~CKBufferParser() { + if (this->m_NeedManualFree) free(this->m_ReaderBegin); + } + +#pragma endregion + +#pragma region CKFile Misc + + CKFile::CKFile(const Utils::VirtoolsContext& cfg) : + m_Parser(nullptr), m_MappedFile(nullptr), + m_UserCfg(cfg) { + ; } CKFile::~CKFile() { } + + void CKFile::ClearData(void) { + m_SaveIDMax = 0; + m_FileObject.clear(); + m_PluginDep.clear(); + + memset(&m_FileInfo, 0, sizeof(CKFileInfo)); + + m_Flags = CK_LOAD_FLAGS::CK_LOAD_DEFAULT; + m_FileName.clear(); + if (m_Parser != nullptr) { + delete m_Parser; + m_Parser = nullptr; + } + if (m_MappedFile != nullptr) { + delete m_MappedFile; + m_MappedFile = nullptr; + } + } + +#pragma endregion + + } diff --git a/LibCmo/VTStruct.hpp b/LibCmo/VTStruct.hpp index 2fc05fe..9a2220d 100644 --- a/LibCmo/VTStruct.hpp +++ b/LibCmo/VTStruct.hpp @@ -1,17 +1,17 @@ #pragma once +#include "VTUtils.hpp" #include "VTConstants.hpp" #include "VTEncoding.hpp" #include -// only expose boost in libcom self. do not let it be seen by any program using libcmo. -#if defined(LIBCMO_EXPORTING) #include #include -#endif namespace LibCmo { + void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize); + struct CKGUID { union { struct { @@ -22,25 +22,7 @@ namespace LibCmo { CKGUID(CKDWORD gd1 = 0, CKDWORD gd2 = 0) { d[0] = gd1; d[1] = gd2; } }; - // define some mapped file to make boost is invisible for - // any program using this library -#if defined(LIBCMO_EXPORTING) - using P_FILE_MAPPING = boost::interprocess::file_mapping*; - using P_MAPPED_REGION = boost::interprocess::mapped_region*; -#else - using P_FILE_MAPPING = void*; - using P_MAPPED_REGION = void*; -#endif - class VxMemoryMappedFile { - public: - VxMemoryMappedFile(const char* u8_filepath); - ~VxMemoryMappedFile(void); - - void* GetBase(void); - size_t GetFileSize(void); - bool IsValid(void); - private: #if defined(LIBCMO_OS_WIN32) @@ -49,9 +31,18 @@ namespace LibCmo { std::string m_szFilePath; #endif - P_FILE_MAPPING m_hFile; - P_MAPPED_REGION m_hFileMapping; + boost::interprocess::file_mapping* m_hFile; + boost::interprocess::mapped_region* m_hFileMapping; bool m_bIsValid; + public: + VxMemoryMappedFile(const char* u8_filepath); + VxMemoryMappedFile(const VxMemoryMappedFile&) = delete; + VxMemoryMappedFile& operator=(const VxMemoryMappedFile&) = delete; + ~VxMemoryMappedFile(void); + + inline void* GetBase(void) { return this->m_hFileMapping->get_address(); } + inline size_t GetFileSize(void) { return this->m_hFileMapping->get_size(); } + inline bool IsValid(void) { return this->m_bIsValid; } }; class CKBufferParser { @@ -62,17 +53,12 @@ namespace LibCmo { size_t m_ReaderSize; public: - CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) : - m_ReaderBegin(static_cast(ptr)), - m_ReaderPos(0u), m_ReaderSize(rsize), - m_NeedManualFree(need_manual_free) { - ; - } - ~CKBufferParser() { - if (this->m_NeedManualFree) free(this->m_ReaderBegin); - } + CKBufferParser(void* ptr, size_t rsize, bool need_manual_free); + CKBufferParser(const CKBufferParser&) = delete; + CKBufferParser& operator=(const CKBufferParser&) = delete; + ~CKBufferParser(); - inline void* GetPtr(void) { return (this->m_ReaderBegin + m_ReaderPos); } + inline const void* GetPtr(void) { return (this->m_ReaderBegin + m_ReaderPos); } inline size_t GetSize(void) { return this->m_ReaderSize; } inline void MoveCursor(size_t off) { this->m_ReaderPos += off; } inline void SetCursor(size_t off) { this->m_ReaderPos = off; } @@ -84,7 +70,7 @@ namespace LibCmo { CK_FILE_WRITEMODE FileWriteMode; // Options used to save this file. (CK_FILE_WRITEMODE) CKDWORD FileVersion; // Version of file format when file was saved. CKDWORD CKVersion; // Version of CK when file was saved. - CKDWORD FileSize; // Size of file in bytes. + size_t FileSize; // Size of file in bytes. CKDWORD ObjectCount; // Number of objects stored in the file. CKDWORD ManagerCount; // Number of managers which saved data in the file. CKDWORD MaxIDSaved; // Maximum Object identifier saved @@ -117,16 +103,25 @@ namespace LibCmo { class CKFile { public: - CKFile(); + CKFile(const Utils::VirtoolsContext& cfg); + CKFile(const CKFile&) = delete; + CKFile& operator=(const CKFile&) = delete; ~CKFile(); + void ClearData(void); + CKERROR Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags); + CKERROR OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags); + CKERROR OpenMemory(void* MemoryBuffer, size_t BufferSize, CK_LOAD_FLAGS Flags); + CKERROR ReadFileHeaders(CKBufferParser** ParserPtr); + CKERROR ReadFileData(CKBufferParser** ParserPtr); + CKERROR LoadFileData(void/*CKObjectArray list*/); int32_t m_SaveIDMax; XArray m_FileObject; //XArray m_ManagersData; XClassArray m_PluginDep; - //XClassArray m_IndexByClassId; - //XClassArray m_IncludedFiles; + XClassArray m_IndexByClassId; + XClassArray m_IncludedFiles; CKFileInfo m_FileInfo; @@ -137,6 +132,8 @@ namespace LibCmo { bool m_ReadFileDataDone; + private: + Utils::VirtoolsContext m_UserCfg; }; } diff --git a/LibCmo/VTUtils.hpp b/LibCmo/VTUtils.hpp index d108d88..7759159 100644 --- a/LibCmo/VTUtils.hpp +++ b/LibCmo/VTUtils.hpp @@ -1,9 +1,12 @@ #pragma once +#include + +/* // https://stackoverflow.com/questions/2164827/explicitly-exporting-shared-library-functions-in-linux // generate import export macro #if defined(_MSC_VER) -// Microsoft +// Microsoft #define LIBCMO_RAW_EXPORT __declspec(dllexport) #define LIBCMO_RAW_IMPORT __declspec(dllimport) #elif defined(__GNUC__) @@ -34,3 +37,20 @@ #else #define LIBCMO_EXPORT LIBCMO_NAKED_EXPORT #endif +*/ + +#if defined(_WIN32) +#define LIBCMO_OS_WIN32 +#endif + +namespace LibCmo { + namespace Utils { + + struct VirtoolsContext { + std::string NameEncoding; + + }; + + } + +} diff --git a/Unvirt/AccessibleValue.cpp b/Unvirt/AccessibleValue.cpp index 96001ea..0f9cc5b 100644 --- a/Unvirt/AccessibleValue.cpp +++ b/Unvirt/AccessibleValue.cpp @@ -174,7 +174,6 @@ namespace Unvirt { { LibCmo::CK_CLASSID::CKCID_BODYPART, {"CKCID_OBJECT", "CKCID_SCENEOBJECT", "CKCID_BEOBJECT", "CKCID_3DENTITY", "CKCID_3DOBJECT", "CKCID_BODYPART"} }, { LibCmo::CK_CLASSID::CKCID_PARAMETER, {"CKCID_OBJECT", "CKCID_PARAMETER"} }, { LibCmo::CK_CLASSID::CKCID_PARAMETERLOCAL, {"CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL"} }, - { LibCmo::CK_CLASSID::CKCID_PARAMETERVARIABLE, {"CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETERLOCAL", "CKCID_PARAMETERVARIABLE"} }, { LibCmo::CK_CLASSID::CKCID_PARAMETEROUT, {"CKCID_OBJECT", "CKCID_PARAMETER", "CKCID_PARAMETEROUT"} }, { LibCmo::CK_CLASSID::CKCID_INTERFACEOBJECTMANAGER, {"CKCID_OBJECT", "CKCID_INTERFACEOBJECTMANAGER"} }, { LibCmo::CK_CLASSID::CKCID_CRITICALSECTION, {"CKCID_OBJECT", "CKCID_CRITICALSECTION"} }, diff --git a/Unvirt/Unvirt.cpp b/Unvirt/Unvirt.cpp index 25308c4..8b0236d 100644 --- a/Unvirt/Unvirt.cpp +++ b/Unvirt/Unvirt.cpp @@ -1,20 +1,11 @@ #include "AccessibleValue.hpp" +#include "VTStruct.hpp" #include int main(int argc, char* argv[]) { - std::string test; - Unvirt::AccessibleValue::GetClassIdHierarchy(test, LibCmo::CK_CLASSID::CKCID_TARGETCAMERA); - printf("%s\n", test.c_str()); - Unvirt::AccessibleValue::GetCkErrorDescription(test, LibCmo::CKERROR::CKERR_OBSOLETEVIRTOOLS); - printf("%s\n", test.c_str()); + LibCmo::Utils::VirtoolsContext vtctx; + LibCmo::CKFile vtfile(vtctx); + vtfile.Load("Language.old.nmo", LibCmo::CK_LOAD_FLAGS::CK_LOAD_DEFAULT); - Unvirt::AccessibleValue::GetEnumName(Unvirt::AccessibleValue::EnumDesc::CK_FO_OPTIONS, test, LibCmo::CK_FO_OPTIONS::CK_FO_RENAMEOBJECT); - printf("%s\n", test.c_str()); - - Unvirt::AccessibleValue::GetFlagEnumName(Unvirt::AccessibleValue::EnumDesc::CK_LOAD_FLAGS, test, LibCmo::CK_LOAD_FLAGS::CK_LOAD_DEFAULT); - printf("%s\n", test.c_str()); - auto v = LibCmo::EnumHelper::FlagEnumAdd(LibCmo::CK_LOAD_FLAGS::CK_LOAD_ANIMATION, LibCmo::CK_LOAD_FLAGS::CK_LOAD_ASCHARACTER); - Unvirt::AccessibleValue::GetFlagEnumName(Unvirt::AccessibleValue::EnumDesc::CK_LOAD_FLAGS, test, v); - printf("%s\n", test.c_str()); return 0; } diff --git a/Unvirt/Unvirt.vcxproj b/Unvirt/Unvirt.vcxproj index 48c7c52..233d63e 100644 --- a/Unvirt/Unvirt.vcxproj +++ b/Unvirt/Unvirt.vcxproj @@ -100,14 +100,14 @@ true _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) + $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) stdcpp20 Console true - sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) - $(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN32_LIB_PATH) + zlibwapi.lib;sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) + $(ZLIB_PATH)\contrib\vstudio\vc14\x86\ZlibDllReleaseWithoutAsm;$(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN32_LIB_PATH) @@ -118,7 +118,7 @@ true _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) + $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -126,8 +126,8 @@ true true true - sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) - $(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN32_LIB_PATH) + zlibwapi.lib;sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) + $(ZLIB_PATH)\contrib\vstudio\vc14\x86\ZlibDllReleaseWithoutAsm;$(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN32_LIB_PATH) @@ -136,14 +136,14 @@ true _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) + $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) stdcpp20 Console true - sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) - $(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN64_LIB_PATH) + zlibwapi.lib;sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) + $(ZLIB_PATH)\contrib\vstudio\vc14\x64\ZlibDllReleaseWithoutAsm;$(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN64_LIB_PATH) @@ -154,7 +154,7 @@ true _CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - ../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) + $(BOOST_INCLUDE_PATH);$(ZLIB_PATH);../LibCmo;$(SQLITE_HEADER_PATH);%(AdditionalIncludeDirectories) stdcpp20 @@ -162,8 +162,8 @@ true true true - sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) - $(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN64_LIB_PATH) + zlibwapi.lib;sqlite3.lib;LibCmo.lib;%(AdditionalDependencies) + $(ZLIB_PATH)\contrib\vstudio\vc14\x64\ZlibDllReleaseWithoutAsm;$(SolutionDir)out\$(Platform)\$(Configuration)\LibCmo;$(SQLITE_WIN64_LIB_PATH)