diff options
Diffstat (limited to 'dep/CascLib')
-rw-r--r-- | dep/CascLib/CMakeLists.txt | 8 | ||||
-rw-r--r-- | dep/CascLib/src/CascCommon.h | 40 | ||||
-rw-r--r-- | dep/CascLib/src/CascFiles.cpp | 289 | ||||
-rw-r--r-- | dep/CascLib/src/CascIndexFiles.cpp | 4 | ||||
-rw-r--r-- | dep/CascLib/src/CascLib.def | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascLib.h | 74 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenStorage.cpp | 445 | ||||
-rw-r--r-- | dep/CascLib/src/CascPort.h | 3 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_Mndx_x86.asm | 4369 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_TVFS.cpp | 160 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_WoW.cpp | 23 | ||||
-rw-r--r-- | dep/CascLib/src/DllMain.rc | 106 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 105 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 27 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.cpp | 28 |
15 files changed, 894 insertions, 4789 deletions
diff --git a/dep/CascLib/CMakeLists.txt b/dep/CascLib/CMakeLists.txt index e64c92bb735..5c3fa7c55e6 100644 --- a/dep/CascLib/CMakeLists.txt +++ b/dep/CascLib/CMakeLists.txt @@ -2,20 +2,23 @@ set(HEADER_FILES src/CascCommon.h src/CascLib.h src/CascPort.h + src/CascStructs.h src/common/Array.h src/common/Common.h src/common/Csv.h + src/common/Directory.h src/common/FileStream.h src/common/FileTree.h src/common/ListFile.h src/common/Map.h + src/common/RootHandler.h src/jenkins/lookup.h ) set(SRC_FILES src/common/Common.cpp - src/common/Directory.cpp src/common/Csv.cpp + src/common/Directory.cpp src/common/FileStream.cpp src/common/FileTree.cpp src/common/ListFile.cpp @@ -34,14 +37,15 @@ set(SRC_FILES src/CascRootFile_Diablo3.cpp src/CascRootFile_Install.cpp src/CascRootFile_MNDX.cpp + src/CascRootFile_OW.cpp src/CascRootFile_Text.cpp src/CascRootFile_TVFS.cpp - src/CascRootFile_OW.cpp src/CascRootFile_WoW.cpp ) set(MD5_FILES src/md5/md5.cpp + src/md5/md5.h ) add_library(casc STATIC ${SRC_FILES} ${HEADER_FILES} ${MD5_FILES}) diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h index f32be935352..b1248544b9f 100644 --- a/dep/CascLib/src/CascCommon.h +++ b/dep/CascLib/src/CascCommon.h @@ -206,20 +206,19 @@ struct TCascStorage static TCascStorage * IsValid(HANDLE hStorage); - PFNPROGRESSCALLBACK PfnCallback; // Callback to be called during CascOpen(Online)Storage - void * PtrCallbackParam; - - const TCHAR * szIndexFormat; // Format of the index file name - const char * szClassName; // "TCascStorage" - const char * szProductName; // String representation of the product name - TCHAR * szRootPath; // Path where the build file is - TCHAR * szDataPath; // This is the directory where data files are - TCHAR * szIndexPath; // This is the directory where index files are - TCHAR * szBuildFile; // Build file name (.build.info or .build.db) - TCHAR * szCdnServers; // Multi-SZ list of CDN servers - TCHAR * szCdnPath; // Remote CDN sub path for the product - TCHAR * szCodeName; // Product code name. Only for online storages - char * szRegion; // Product region. Only when "versions" is used as storage root file + PCASC_OPEN_STORAGE_ARGS pArgs; // Open storage arguments. Only valid during opening the storage + + LPCTSTR szIndexFormat; // Format of the index file name + LPCSTR szClassName; // "TCascStorage" + LPCSTR szProductName; // String representation of the product name + LPTSTR szCodeName; // On local storage, this select a product in a multi-product storage. For online storage, this selects a product + LPTSTR szRootPath; // Path where the build file is + LPTSTR szDataPath; // This is the directory where data files are + LPTSTR szIndexPath; // This is the directory where index files are + LPTSTR szBuildFile; // Build file name (.build.info or .build.db) + LPTSTR szCdnServers; // Multi-SZ list of CDN servers + LPTSTR szCdnPath; // Remote CDN sub path for the product + LPSTR szRegion; // Product region. Only when "versions" is used as storage root file CASC_PRODUCT Product; // Product enum value (see CASC_PRODUCT) DWORD dwBuildNumber; // Product build number DWORD dwRefCount; // Number of references @@ -414,12 +413,13 @@ void FreeCascBlob(PQUERY_KEY pQueryKey); //----------------------------------------------------------------------------- // Text file parsing (CascFiles.cpp) -int DownloadFileFromCDN(TCascStorage * hs, const TCHAR * szSubDir, LPBYTE pbEKey, const TCHAR * szExtension, TCHAR * szOutLocalPath, size_t cchOutLocalPath); -int CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory); -int LoadCdnsInfo(TCascStorage * hs); -int LoadBuildInfo(TCascStorage * hs); -int LoadCdnConfigFile(TCascStorage * hs); -int LoadCdnBuildFile(TCascStorage * hs); +bool InvokeProgressCallback(TCascStorage * hs, LPCSTR szMessage, LPCSTR szObject, DWORD CurrentValue, DWORD TotalValue); +DWORD DownloadFileFromCDN(TCascStorage * hs, const TCHAR * szSubDir, LPBYTE pbEKey, const TCHAR * szExtension, TCHAR * szOutLocalPath, size_t cchOutLocalPath); +DWORD CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory); +DWORD LoadCdnsInfo(TCascStorage * hs); +DWORD LoadBuildInfo(TCascStorage * hs); +DWORD LoadCdnConfigFile(TCascStorage * hs); +DWORD LoadCdnBuildFile(TCascStorage * hs); //----------------------------------------------------------------------------- // Internal file functions diff --git a/dep/CascLib/src/CascFiles.cpp b/dep/CascLib/src/CascFiles.cpp index 33f065b66d3..5f4080bc4f2 100644 --- a/dep/CascLib/src/CascFiles.cpp +++ b/dep/CascLib/src/CascFiles.cpp @@ -16,8 +16,8 @@ //----------------------------------------------------------------------------- // Local defines +typedef DWORD (*PARSECSVFILE)(TCascStorage * hs, CASC_CSV & Csv); typedef int (*PARSETEXTFILE)(TCascStorage * hs, void * pvListFile); -typedef int (*PARSECSVFILE)(TCascStorage * hs, CASC_CSV & Csv); typedef int (*PARSE_VARIABLE)(TCascStorage * hs, const char * szVariableName, const char * szDataBegin, const char * szDataEnd, void * pvParam); #define MAX_VAR_NAME 80 @@ -560,7 +560,18 @@ static int GetDefaultLocaleMask(TCascStorage * hs, const CASC_CSV_COLUMN & Colum return ERROR_SUCCESS; } -static int ParseFile_CDNS(TCascStorage * hs, CASC_CSV & Csv) +static void SetProductCodeName(TCascStorage * hs, LPCSTR szCodeName) +{ + TCHAR szCodeNameT[0x40]; + + if(hs->szCodeName == NULL && szCodeName != NULL) + { + CascStrCopy(szCodeNameT, _countof(szCodeNameT), szCodeName); + hs->szCodeName = CascNewStr(szCodeNameT); + } +} + +static DWORD ParseFile_CDNS(TCascStorage * hs, CASC_CSV & Csv) { const char * szWantedRegion = hs->szRegion; TCHAR szCdnServers[MAX_PATH]; @@ -596,49 +607,133 @@ static int ParseFile_CDNS(TCascStorage * hs, CASC_CSV & Csv) return ERROR_FILE_NOT_FOUND; } -static int ParseFile_BuildInfo(TCascStorage * hs, CASC_CSV & Csv) +static DWORD ParseFile_BuildInfo(TCascStorage * hs, CASC_CSV & Csv) { + PFNPRODUCTCALLBACK PfnProductCallback = hs->pArgs->PfnProductCallback; + LPCSTR szProductColumn = "Product!STRING:0"; + LPCSTR szCodeName; + void * PtrProductParam = hs->pArgs->PtrProductParam; + size_t nProductColumnIndex = Csv.GetColumnIndex(szProductColumn); size_t nLineCount = Csv.GetLineCount(); - int nError; + size_t nSelected = CASC_INVALID_INDEX; + DWORD dwErrCode; + char szWantedCodeName[0x40] = ""; - // Find the active config - for(size_t i = 0; i < nLineCount; i++) + // + // Find the configuration that we're gonna load. + // + + // If the product is not specified and there is product callback, we use the callback to specify the product + if(hs->szCodeName == NULL && nProductColumnIndex != CASC_INVALID_INDEX && PfnProductCallback != NULL) { - // Is that build config active? - if (!strcmp(Csv[i]["Active!DEC:1"].szValue, "1")) + LPCSTR ProductsList[0x40] = {NULL}; + size_t nProductCount = 0; + size_t nChoiceIndex = CASC_INVALID_INDEX; + size_t nDefault = CASC_INVALID_INDEX; + + // Load all products to the array + for(size_t i = 0; i < nLineCount; i++) { - // Extract the CDN build key - nError = LoadQueryKey(Csv[i]["Build Key!HEX:16"], hs->CdnBuildKey); - if (nError != ERROR_SUCCESS) - return nError; + // Ignore anything that is not marked "active" + if(!strcmp(Csv[i]["Active!DEC:1"].szValue, "1")) + { + ProductsList[nProductCount] = Csv[i]["Product!STRING:0"].szValue; + nProductCount++; + nDefault = i; + } + } + + // Only if there is more than one active products + if(nProductCount > 1) + { + // Ask the callback to choose the product + if(!PfnProductCallback(PtrProductParam, ProductsList, nProductCount, &nChoiceIndex) || (nChoiceIndex >= nProductCount)) + return ERROR_CANCELLED; - // Extract the CDN config key - nError = LoadQueryKey(Csv[i]["CDN Key!HEX:16"], hs->CdnConfigKey); - if (nError != ERROR_SUCCESS) - return nError; + // We now have preferred product to open + SetProductCodeName(hs, ProductsList[nChoiceIndex]); + } + else if(nProductCount == 1) + { + // We now have preferred product to open + SetProductCodeName(hs, ProductsList[nDefault]); + } + else + { + return ERROR_FILE_NOT_FOUND; + } + } - // If we found tags, we can extract language build from it - GetDefaultLocaleMask(hs, Csv[i]["Tags!STRING:0"]); + // If the product is specified by hs->szCodeName and the ".build.info" contains "Product!STRING:0", we watch for that product. + if(hs->szCodeName != NULL && nProductColumnIndex != CASC_INVALID_INDEX) + { + CascStrCopy(szWantedCodeName, _countof(szWantedCodeName), hs->szCodeName); + } - // If we found version, extract a build number - const CASC_CSV_COLUMN & VerColumn = Csv[i]["Version!STRING:0"]; - if(VerColumn.szValue && VerColumn.nLength) + // Parse all lines in the CSV file. Either take the first that is active + // or take the one that has been selected by the callback + for(size_t i = 0; i < nLineCount; i++) + { + // Ignore anything that is not marked "active" + if(!strcmp(Csv[i]["Active!DEC:1"].szValue, "1")) + { + // If we have no product code name specified, we pick the very first active build + if(hs->szCodeName == NULL) { - LoadBuildNumber(hs, NULL, VerColumn.szValue, VerColumn.szValue + VerColumn.nLength, NULL); + // Save the code name of the selected product + SetProductCodeName(hs, Csv[i]["Product!STRING:0"].szValue); + nSelected = i; + goto __ChooseThisProduct; } - // Verify all variables - return (hs->CdnBuildKey.pbData != NULL && hs->CdnConfigKey.pbData != NULL) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; + // If we have a product code name specified, pick the first matching + else if((szCodeName = Csv[i]["Product!STRING:0"].szValue) != NULL) + { + if(!strcmp(szCodeName, szWantedCodeName)) + { + nSelected = i; + goto __ChooseThisProduct; + } + } + } + } + + __ChooseThisProduct: + + // Load the selected product + if(nSelected < nLineCount) + { + // Extract the CDN build key + dwErrCode = LoadQueryKey(Csv[nSelected]["Build Key!HEX:16"], hs->CdnBuildKey); + if (dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // Extract the CDN config key + dwErrCode = LoadQueryKey(Csv[nSelected]["CDN Key!HEX:16"], hs->CdnConfigKey); + if (dwErrCode != ERROR_SUCCESS) + return dwErrCode; + + // If we found tags, we can extract language build from it + GetDefaultLocaleMask(hs, Csv[nSelected]["Tags!STRING:0"]); + + // If we found version, extract a build number + const CASC_CSV_COLUMN & VerColumn = Csv[nSelected]["Version!STRING:0"]; + if(VerColumn.szValue && VerColumn.nLength) + { + LoadBuildNumber(hs, NULL, VerColumn.szValue, VerColumn.szValue + VerColumn.nLength, NULL); } + + // Verify all variables + return (hs->CdnBuildKey.pbData != NULL && hs->CdnConfigKey.pbData != NULL) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; } return ERROR_FILE_NOT_FOUND; } -static int ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) +static DWORD ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) { size_t nLineCount = Csv.GetLineCount(); - int nError; + DWORD dwErrCode; // Find the active config for (size_t i = 0; i < nLineCount; i++) @@ -647,14 +742,14 @@ static int ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) if (hs->szRegion == NULL || !strcmp(Csv[i]["Region!STRING:0"].szValue, hs->szRegion)) { // Extract the CDN build key - nError = LoadQueryKey(Csv[i]["BuildConfig!HEX:16"], hs->CdnBuildKey); - if (nError != ERROR_SUCCESS) - return nError; + dwErrCode = LoadQueryKey(Csv[i]["BuildConfig!HEX:16"], hs->CdnBuildKey); + if (dwErrCode != ERROR_SUCCESS) + return dwErrCode; // Extract the CDN config key - nError = LoadQueryKey(Csv[i]["CDNConfig!HEX:16"], hs->CdnConfigKey); - if (nError != ERROR_SUCCESS) - return nError; + dwErrCode = LoadQueryKey(Csv[i]["CDNConfig!HEX:16"], hs->CdnConfigKey); + if (dwErrCode != ERROR_SUCCESS) + return dwErrCode; const CASC_CSV_COLUMN & VerColumn = Csv[i]["VersionsName!String:0"]; if (VerColumn.szValue && VerColumn.nLength) @@ -670,19 +765,19 @@ static int ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) return ERROR_FILE_NOT_FOUND; } -static int ParseFile_BuildDb(TCascStorage * hs, CASC_CSV & Csv) +static DWORD ParseFile_BuildDb(TCascStorage * hs, CASC_CSV & Csv) { - int nError; + DWORD dwErrCode; // Extract the CDN build key - nError = LoadQueryKey(Csv[CSV_ZERO][CSV_ZERO], hs->CdnBuildKey); - if(nError != ERROR_SUCCESS) - return nError; + dwErrCode = LoadQueryKey(Csv[CSV_ZERO][CSV_ZERO], hs->CdnBuildKey); + if(dwErrCode != ERROR_SUCCESS) + return dwErrCode; // Extract the CDN config key - nError = LoadQueryKey(Csv[CSV_ZERO][1], hs->CdnConfigKey); - if (nError != ERROR_SUCCESS) - return nError; + dwErrCode = LoadQueryKey(Csv[CSV_ZERO][1], hs->CdnConfigKey); + if (dwErrCode != ERROR_SUCCESS) + return dwErrCode; // Load the the tags GetDefaultLocaleMask(hs, Csv[CSV_ZERO][2]); @@ -840,15 +935,15 @@ static int CheckDataDirectory(TCascStorage * hs, TCHAR * szDirectory) return nError; } -static int LoadCsvFile(TCascStorage * hs, const TCHAR * szFileName, PARSECSVFILE PfnParseProc, bool bHasHeader) +static DWORD LoadCsvFile(TCascStorage * hs, const TCHAR * szFileName, PARSECSVFILE PfnParseProc, bool bHasHeader) { CASC_CSV Csv(0x40, bHasHeader); - int nError = Csv.Load(szFileName); + DWORD dwErrCode; // Load the external file to memory - if (nError == ERROR_SUCCESS) - nError = PfnParseProc(hs, Csv); - return nError; + if ((dwErrCode = Csv.Load(szFileName)) == ERROR_SUCCESS) + dwErrCode = PfnParseProc(hs, Csv); + return dwErrCode; } static const TCHAR * ExtractCdnServerName(TCHAR * szServerName, size_t cchServerName, const TCHAR * szCdnServers) @@ -1028,8 +1123,8 @@ static int DownloadFile( szLocalPath2 = szServerPath2; // Create remote path - CombineUrlPath(szRemotePath, _countof(szRemotePath), szServerName, szServerPath1, szServerPath2); - CombineFilePath(szLocalPath, _countof(szLocalPath), hs->szRootPath, NULL, szLocalPath2); + CombinePath(szRemotePath, _countof(szRemotePath), URL_SEP_CHAR, szServerName, szServerPath1, szServerPath2, NULL); + CombinePath(szLocalPath, _countof(szLocalPath), PATH_SEP_CHAR, hs->szRootPath, szLocalPath2, NULL); // Make sure that the path exists ForcePathExist(szLocalPath, true); @@ -1079,7 +1174,7 @@ static int FetchAndLoadConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PARSET else { CreateCascSubdirectoryName(szSubDir, _countof(szSubDir), szPathType, NULL, pFileKey->pbData); - CombineFilePath(szLocalPath, _countof(szLocalPath), hs->szDataPath, szSubDir); + CombinePath(szLocalPath, _countof(szLocalPath), PATH_SEP_CHAR, hs->szDataPath, szSubDir, NULL); } // Load and verify the external listfile @@ -1107,14 +1202,24 @@ static int FetchAndLoadConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PARSET //----------------------------------------------------------------------------- // Public functions -int DownloadFileFromCDN(TCascStorage * hs, const TCHAR * szSubDir, LPBYTE pbEKey, const TCHAR * szExtension, TCHAR * szOutLocalPath, size_t cchOutLocalPath) +bool InvokeProgressCallback(TCascStorage * hs, LPCSTR szMessage, LPCSTR szObject, DWORD CurrentValue, DWORD TotalValue) +{ + PCASC_OPEN_STORAGE_ARGS pArgs = hs->pArgs; + bool bResult = false; + + if(pArgs && pArgs->PfnProgressCallback) + bResult = pArgs->PfnProgressCallback(pArgs->PtrProgressParam, szMessage, szObject, CurrentValue, TotalValue); + return bResult; +} + +DWORD DownloadFileFromCDN(TCascStorage * hs, const TCHAR * szSubDir, LPBYTE pbEKey, const TCHAR * szExtension, TCHAR * szOutLocalPath, size_t cchOutLocalPath) { PCASC_ARCINDEX_ENTRY pIndexEntry; const TCHAR * szCdnServers = hs->szCdnServers; TCHAR szRemoteFolder[MAX_PATH]; TCHAR szLocalFolder[MAX_PATH]; TCHAR szServerName[MAX_PATH]; - int nError = ERROR_CAN_NOT_COMPLETE; + DWORD dwErrCode = ERROR_CAN_NOT_COMPLETE; // Try all download servers while((szCdnServers = ExtractCdnServerName(szServerName, _countof(szServerName), szCdnServers)) != NULL) @@ -1130,44 +1235,44 @@ int DownloadFileFromCDN(TCascStorage * hs, const TCHAR * szSubDir, LPBYTE pbEKey // Change the subpath to an archive CreateCascSubdirectoryName(szRemoteFolder, _countof(szRemoteFolder), szSubDir, szExtension, pIndexEntry->IndexHash); ByteOffset = pIndexEntry->ArchiveOffset; - nError = DownloadFile(hs, - szServerName, - hs->szCdnPath, - szRemoteFolder, - szLocalFolder, - &ByteOffset, - pIndexEntry->EncodedSize, - szOutLocalPath, - cchOutLocalPath, 0, false, false); + dwErrCode = DownloadFile(hs, + szServerName, + hs->szCdnPath, + szRemoteFolder, + szLocalFolder, + &ByteOffset, + pIndexEntry->EncodedSize, + szOutLocalPath, + cchOutLocalPath, 0, false, false); } else { - nError = DownloadFile(hs, - szServerName, - hs->szCdnPath, - szLocalFolder, - szLocalFolder, - NULL, - 0, - szOutLocalPath, - cchOutLocalPath, 0, false, false); + dwErrCode = DownloadFile(hs, + szServerName, + hs->szCdnPath, + szLocalFolder, + szLocalFolder, + NULL, + 0, + szOutLocalPath, + cchOutLocalPath, 0, false, false); } - if (nError == ERROR_SUCCESS) + if (dwErrCode == ERROR_SUCCESS) break; } - return nError; + return dwErrCode; } // Checks whether there is a ".build.info" or ".build.db". // If yes, the function sets "szDataPath" and "szIndexPath" // in the storage structure and returns ERROR_SUCCESS -int CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory) +DWORD CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory) { TFileStream * pStream; TCHAR * szBuildFile; - int nError = ERROR_FILE_NOT_FOUND; + DWORD dwErrCode = ERROR_FILE_NOT_FOUND; // Try to find any of the root files used in the history for (size_t i = 0; BuildTypes[i].szFileName != NULL; i++) @@ -1184,8 +1289,8 @@ int CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory) FileStream_Close(pStream); // Check for the data directory - nError = CheckDataDirectory(hs, szDirectory); - if (nError == ERROR_SUCCESS) + dwErrCode = CheckDataDirectory(hs, szDirectory); + if (dwErrCode == ERROR_SUCCESS) { hs->szBuildFile = szBuildFile; hs->BuildFileType = BuildTypes[i].BuildFileType; @@ -1197,27 +1302,27 @@ int CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory) } } - return nError; + return dwErrCode; } -int LoadBuildInfo(TCascStorage * hs) +DWORD LoadBuildInfo(TCascStorage * hs) { PARSECSVFILE PfnParseProc = NULL; + DWORD dwErrCode; bool bHasHeader = true; - int nError; // If the storage is online storage, we need to download "versions" if(hs->dwFeatures & CASC_FEATURE_ONLINE) { // Inform the user about loading the build.info/build.db/versions - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Downloading the \"versions\" file", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Downloading the \"versions\" file", NULL, 0, 0)) return ERROR_CANCELLED; // Attempt to download the "versions" file - nError = DownloadFile(hs, _T("us.patch.battle.net"), hs->szCodeName, _T("versions"), NULL, NULL, 0, NULL, 0, STREAM_FLAG_USE_PORT_1119, true, false); - if(nError != ERROR_SUCCESS) + dwErrCode = DownloadFile(hs, _T("us.patch.battle.net"), hs->szCodeName, _T("versions"), NULL, NULL, 0, NULL, 0, STREAM_FLAG_USE_PORT_1119, true, false); + if(dwErrCode != ERROR_SUCCESS) { - return nError; + return dwErrCode; } } @@ -1244,48 +1349,48 @@ int LoadBuildInfo(TCascStorage * hs) return LoadCsvFile(hs, hs->szBuildFile, PfnParseProc, bHasHeader); } -int LoadCdnsInfo(TCascStorage * hs) +DWORD LoadCdnsInfo(TCascStorage * hs) { TCHAR szLocalPath[MAX_PATH]; - int nError = ERROR_SUCCESS; + DWORD dwErrCode = ERROR_SUCCESS; // Sanity checks assert(hs->dwFeatures & CASC_FEATURE_ONLINE); // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Downloading the \"cdns\" file", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Downloading the \"cdns\" file", NULL, 0, 0)) return ERROR_CANCELLED; // Download file and parse it - nError = DownloadFile(hs, _T("us.patch.battle.net"), hs->szCodeName, _T("cdns"), NULL, NULL, 0, szLocalPath, _countof(szLocalPath), STREAM_FLAG_USE_PORT_1119, false, true); - if(nError == ERROR_SUCCESS) + dwErrCode = DownloadFile(hs, _T("us.patch.battle.net"), hs->szCodeName, _T("cdns"), NULL, NULL, 0, szLocalPath, _countof(szLocalPath), STREAM_FLAG_USE_PORT_1119, false, true); + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadCsvFile(hs, szLocalPath, ParseFile_CDNS, true); + dwErrCode = LoadCsvFile(hs, szLocalPath, ParseFile_CDNS, true); } - return nError; + return dwErrCode; } -int LoadCdnConfigFile(TCascStorage * hs) +DWORD LoadCdnConfigFile(TCascStorage * hs) { // The CKey for the CDN config should have been loaded already assert(hs->CdnConfigKey.pbData != NULL && hs->CdnConfigKey.cbData == MD5_HASH_SIZE); // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Downloading CDN config file", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Downloading CDN config file", NULL, 0, 0)) return ERROR_CANCELLED; // Load the CDN config file return FetchAndLoadConfigFile(hs, &hs->CdnConfigKey, ParseFile_CdnConfig); } -int LoadCdnBuildFile(TCascStorage * hs) +DWORD LoadCdnBuildFile(TCascStorage * hs) { // The CKey for the CDN config should have been loaded already assert(hs->CdnBuildKey.pbData != NULL && hs->CdnBuildKey.cbData == MD5_HASH_SIZE); // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Downloading CDN build file", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Downloading CDN build file", NULL, 0, 0)) return ERROR_CANCELLED; // Load the CDN config file. Note that we don't diff --git a/dep/CascLib/src/CascIndexFiles.cpp b/dep/CascLib/src/CascIndexFiles.cpp index c54c874ec8c..ed680f4c4d9 100644 --- a/dep/CascLib/src/CascIndexFiles.cpp +++ b/dep/CascLib/src/CascIndexFiles.cpp @@ -522,7 +522,7 @@ static int LoadLocalIndexFiles(TCascStorage * hs) if((szFileName = CreateIndexFileName(hs, i, IndexArray[i])) != NULL) { // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Loading index files", NULL, i, CASC_INDEX_COUNT)) + if(InvokeProgressCallback(hs, "Loading index files", NULL, i, CASC_INDEX_COUNT)) { nError = ERROR_CANCELLED; break; @@ -727,7 +727,7 @@ static int LoadArchiveIndexFiles(TCascStorage * hs) LPBYTE pbIndexHash = hs->ArchivesKey.pbData + (i * MD5_HASH_SIZE); // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Downloading archive indexes", NULL, (DWORD)(i), (DWORD)(nArchiveCount))) + if(InvokeProgressCallback(hs, "Downloading archive indexes", NULL, (DWORD)(i), (DWORD)(nArchiveCount))) { nError = ERROR_CANCELLED; break; diff --git a/dep/CascLib/src/CascLib.def b/dep/CascLib/src/CascLib.def index 12e7904cb84..fbed70bf128 100644 --- a/dep/CascLib/src/CascLib.def +++ b/dep/CascLib/src/CascLib.def @@ -9,9 +9,11 @@ LIBRARY CascLib.dll EXPORTS CascOpenStorage + CascOpenStorageEx CascOpenOnlineStorage CascGetStorageInfo CascAddEncryptionKey + CascFindEncryptionKey CascCloseStorage CascOpenFile diff --git a/dep/CascLib/src/CascLib.h b/dep/CascLib/src/CascLib.h index 52451ac8f20..1ed387aee01 100644 --- a/dep/CascLib/src/CascLib.h +++ b/dep/CascLib/src/CascLib.h @@ -133,13 +133,13 @@ extern "C" { // Flags for CASC_STORAGE_FEATURES::dwFeatures #define CASC_FEATURE_FILE_NAMES 0x00000001 // File names are supported by the storage #define CASC_FEATURE_ROOT_CKEY 0x00000002 // Present if the storage's ROOT returns CKey -#define CASC_FEATURE_TAGS 0x00000002 // Tags are supported by the storage -#define CASC_FEATURE_FNAME_HASHES 0x00000004 // The storage contains file name hashes on ALL files -#define CASC_FEATURE_FNAME_HASHES_OPTIONAL 0x00000008 // The storage contains file name hashes for SOME files -#define CASC_FEATURE_FILE_DATA_IDS 0x00000010 // The storage indexes files by FileDataId -#define CASC_FEATURE_LOCALE_FLAGS 0x00000020 // Locale flags are supported -#define CASC_FEATURE_CONTENT_FLAGS 0x00000040 // Content flags are supported -#define CASC_FEATURE_ONLINE 0x00000080 // The storage is an online storage +#define CASC_FEATURE_TAGS 0x00000004 // Tags are supported by the storage +#define CASC_FEATURE_FNAME_HASHES 0x00000008 // The storage contains file name hashes on ALL files +#define CASC_FEATURE_FNAME_HASHES_OPTIONAL 0x00000010 // The storage contains file name hashes for SOME files +#define CASC_FEATURE_FILE_DATA_IDS 0x00000020 // The storage indexes files by FileDataId +#define CASC_FEATURE_LOCALE_FLAGS 0x00000040 // Locale flags are supported +#define CASC_FEATURE_CONTENT_FLAGS 0x00000080 // Content flags are supported +#define CASC_FEATURE_ONLINE 0x00000100 // The storage is an online storage // Macro to convert FileDataId to the argument of CascOpenFile #define CASC_FILE_DATA_ID(FileDataId) ((LPCSTR)(size_t)FileDataId) @@ -158,11 +158,12 @@ typedef enum _CASC_STORAGE_INFO_CLASS // Returns the total file count, including the offline files CascStorageTotalFileCount, - // Returns the CASC_STORAGE_FEATURES structure. - CascStorageFeatures, + + CascStorageFeatures, // Returns the features flag CascStorageInstalledLocales, CascStorageProduct, // Gives CASC_STORAGE_PRODUCT CascStorageTags, // Gives CASC_STORAGE_TAGS structure + CascStoragePathProduct, // Gives Path:Product into a LPTSTR buffer CascStorageInfoClassMax } CASC_STORAGE_INFO_CLASS, *PCASC_STORAGE_INFO_CLASS; @@ -288,28 +289,63 @@ typedef struct _CASC_FILE_FULL_INFO } CASC_FILE_FULL_INFO, *PCASC_FILE_FULL_INFO; //----------------------------------------------------------------------------- -// Some operations (e.g. opening an online storage) may take long time. -// This callback allows an application to be notified about loading progress. -// This callback only works for a single CascOpen(Online)Storage call. +// Extended version of CascOpenStorage +// Some operations (e.g. opening an online storage) may take long time. +// This callback allows an application to be notified about loading progress +// and even cancel the storage loading process typedef bool (WINAPI * PFNPROGRESSCALLBACK)( // Return 'true' to cancel the loading process void * PtrUserParam, // User-specific parameter passed to the callback LPCSTR szWork, // Text for the current activity (example: "Loading "ENCODING" file") LPCSTR szObject, // (optional) name of the object tied to the activity (example: index file name) - DWORD nCurrent, // (optional) current object being processed - DWORD nTotal // (optional) If non-zero, this is the total number of objects to process + DWORD CurrentValue, // (optional) current object being processed + DWORD TotalValue // (optional) If non-zero, this is the total number of objects to process ); -void WINAPI CascSetProgressCallback( - PFNPROGRESSCALLBACK PtrUserCallback, // Pointer to the callback function that will be called during opening the storage - void * PtrUserParam // Arbitrary user parameter that will be passed to the callback +// Some storages support multi-product installation (e.g. World of Warcraft). +// With this callback, the calling application can specify which storage to open +typedef bool (WINAPI * PFNPRODUCTCALLBACK)( // Return 'true' to cancel the loading process + void * PtrUserParam, // User-specific parameter passed to the callback + LPCSTR * ProductList, // Array of product codenames found in the storage + size_t ProductCount, // Number of products in the ProductList array + size_t * PtrSelectedProduct // [out] This is the selected product to open. On input, set to 0 (aka the first product) ); +typedef struct _CASC_OPEN_STORAGE_ARGS +{ + size_t Size; // Length of this structure. Initialize to sizeof(CASC_OPEN_STORAGE_ARGS) + + LPCTSTR szLocalPath; // Local: Path to the storage directory (where ".build.info: is) or any of the sub-path + // Online: Path to the local storage cache + + LPCTSTR szCodeName; // If non-null, this will specify a product in a multi-product local storage + // Has higher priority than PfnProductCallback (if both specified) + LPCTSTR szRegion; // If non-null, this will specify a product region. + + PFNPROGRESSCALLBACK PfnProgressCallback; // Progress callback. If non-NULL, this can inform the caller about state of the opening storage + void * PtrProgressParam; // Pointer-sized parameter that will be passed to PfnProgressCallback + PFNPRODUCTCALLBACK PfnProductCallback; // Progress callback. If non-NULL, will be called on multi-product storage to select one of the products + void * PtrProductParam; // Pointer-sized parameter that will be passed to PfnProgressCallback + + DWORD dwLocaleMask; // Locale mask to open + DWORD dwFlags; // Reserved. Set to zero. + + // + // Any additional member from here on must be checked for availability using the ExtractVersionedArgument function. + // Example: + // + // DWORD dwMyExtraMember = 0; + // ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, dwMyExtraMember), &dwMyExtraMember); + // + +} CASC_OPEN_STORAGE_ARGS, *PCASC_OPEN_STORAGE_ARGS; + //----------------------------------------------------------------------------- // Functions for storage manipulation -bool WINAPI CascOpenStorage(LPCTSTR szDataPath, DWORD dwLocaleMask, HANDLE * phStorage); -bool WINAPI CascOpenOnlineStorage(LPCTSTR szLocalCache, LPCSTR szCodeName, LPCSTR szRegion, DWORD dwLocaleMask, HANDLE * phStorage); +bool WINAPI CascOpenStorageEx(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs, bool bOnlineStorage, HANDLE * phStorage); +bool WINAPI CascOpenStorage(LPCTSTR szParams, DWORD dwLocaleMask, HANDLE * phStorage); +bool WINAPI CascOpenOnlineStorage(LPCTSTR szParams, DWORD dwLocaleMask, HANDLE * phStorage); bool WINAPI CascGetStorageInfo(HANDLE hStorage, CASC_STORAGE_INFO_CLASS InfoClass, void * pvStorageInfo, size_t cbStorageInfo, size_t * pcbLengthNeeded); bool WINAPI CascAddEncryptionKey(HANDLE hStorage, ULONGLONG KeyName, LPBYTE Key); LPBYTE WINAPI CascFindEncryptionKey(HANDLE hStorage, ULONGLONG KeyName); diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp index 53031169cbb..e10db730d41 100644 --- a/dep/CascLib/src/CascOpenStorage.cpp +++ b/dep/CascLib/src/CascOpenStorage.cpp @@ -21,12 +21,6 @@ #define CASC_MAX_ORPHANED_ITEMS 0x100 //----------------------------------------------------------------------------- -// Local variables - -static PFNPROGRESSCALLBACK PfnProgressCallback = NULL; -static void * PtrProgressParam = NULL; - -//----------------------------------------------------------------------------- // TCascStorage service functions TCascStorage::TCascStorage() @@ -50,12 +44,6 @@ TCascStorage::TCascStorage() BuildFileType = CascBuildNone; LocalFiles = TotalFiles = EKeyEntries = OrphanItems = SkippedItems = EKeyLength = FileOffsetBits = 0; - - // Take the callback param and data. Zero the global pointers - PfnCallback = PfnProgressCallback; - PtrCallbackParam = PtrProgressParam; - PfnProgressCallback = NULL; - PtrProgressParam = NULL; } TCascStorage::~TCascStorage() @@ -414,7 +402,7 @@ static int LoadEncodingManifest(TCascStorage * hs) int nError = ERROR_SUCCESS; // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Loading ENCODING manifest", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Loading ENCODING manifest", NULL, 0, 0)) return ERROR_CANCELLED; // Load the entire encoding file to memory @@ -745,7 +733,7 @@ static int LoadDownloadManifest(TCascStorage * hs) int nError = ERROR_SUCCESS; // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Loading DOWNLOAD manifest", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Loading DOWNLOAD manifest", NULL, 0, 0)) return ERROR_CANCELLED; // Load the entire DOWNLOAD file to memory @@ -782,7 +770,7 @@ static int LoadInstallManifest(TCascStorage * hs) int nError = ERROR_SUCCESS; // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Loading INSTALL manifest", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Loading INSTALL manifest", NULL, 0, 0)) return ERROR_CANCELLED; // Load the entire DOWNLOAD file to memory @@ -843,7 +831,7 @@ static int LoadBuildManifest(TCascStorage * hs, DWORD dwLocaleMask) pCKeyEntry = FindCKeyEntry_CKey(hs, pCKeyEntry->CKey); // Inform the user about what we are doing - if(hs->PfnCallback && hs->PfnCallback(hs->PtrCallbackParam, "Loading ROOT manifest", NULL, 0, 0)) + if(InvokeProgressCallback(hs, "Loading ROOT manifest", NULL, 0, 0)) return ERROR_CANCELLED; // Load the entire ROOT file to memory @@ -904,83 +892,6 @@ static int LoadBuildManifest(TCascStorage * hs, DWORD dwLocaleMask) return nError; } -static int InitializeLocalDirectories(TCascStorage * hs, const TCHAR * szPath) -{ - TCHAR * szWorkPath; - int nError = ERROR_NOT_ENOUGH_MEMORY; - - // Find the root directory of the storage. The root directory - // is the one with ".build.info" or ".build.db". - szWorkPath = CascNewStr(szPath); - if(szWorkPath != NULL) - { - // Get the length and go up until we find the ".build.info" or ".build.db" - for(;;) - { - // Is this a game directory? - nError = CheckGameDirectory(hs, szWorkPath); - if(nError == ERROR_SUCCESS) - { - nError = ERROR_SUCCESS; - break; - } - - // Cut one path part - if(!CutLastPathPart(szWorkPath)) - { - nError = ERROR_FILE_NOT_FOUND; - break; - } - } - - // Find the index directory - if (nError == ERROR_SUCCESS) - { - // First, check for more common "data" subdirectory - if ((hs->szIndexPath = CheckForIndexDirectory(hs, _T("data"))) != NULL) - nError = ERROR_SUCCESS; - - // Second, try the "darch" subdirectory (older builds of HOTS - Alpha) - else if ((hs->szIndexPath = CheckForIndexDirectory(hs, _T("darch"))) != NULL) - nError = ERROR_SUCCESS; - - else - nError = ERROR_FILE_NOT_FOUND; - } - - // Free the work path buffer - CASC_FREE(szWorkPath); - } - - return nError; -} - -static int InitializeOnlineDirectories(TCascStorage * hs, LPCTSTR szLocalCache, LPCSTR szCodeName, LPCSTR szRegion) -{ - TCHAR szCodeNameT[0x40]; - - CascStrCopy(szCodeNameT, _countof(szCodeNameT), szCodeName); - hs->szRootPath = CombinePath(szLocalCache, szCodeNameT); - if (hs->szRootPath != NULL) - { - // Create the name of the build file - hs->szBuildFile = CombinePath(hs->szRootPath, _T("versions")); - if(hs->szBuildFile != NULL) - { - hs->szCodeName = CascNewStr(szCodeNameT); - hs->szRegion = CascNewStr(szRegion); - if(hs->szCodeName != NULL) - { - hs->BuildFileType = CascVersionsDb; - hs->dwFeatures |= CASC_FEATURE_ONLINE; - return ERROR_SUCCESS; - } - } - } - - return ERROR_NOT_ENOUGH_MEMORY; -} - static DWORD GetStorageTotalFileCount(TCascStorage * hs) { PCASC_CKEY_ENTRY pCKeyEntry; @@ -1076,68 +987,205 @@ static bool GetStorageTags(TCascStorage * hs, void * pvStorageInfo, size_t cbSto return (pTags != NULL); } -static int LoadCascStorage(TCascStorage * hs, DWORD dwLocaleMask) +static bool GetStoragePathProduct(TCascStorage * hs, void * pvStorageInfo, size_t cbStorageInfo, size_t * pcbLengthNeeded) { - int nError = ERROR_SUCCESS; + LPTSTR szBuffer = (LPTSTR)pvStorageInfo; + size_t nMaxChars = cbStorageInfo / sizeof(TCHAR); + size_t nLength; + + // Calculate the length needed + nLength = _tcslen(hs->szRootPath); + if(hs->szCodeName != NULL) + nLength = nLength + 1 + _tcslen(hs->szCodeName); + if(hs->szRegion != NULL) + nLength = nLength + 1 + strlen(hs->szRegion); + nLength++; + + // Verify whether we have enough space in the buffer + szBuffer = (LPTSTR)ProbeOutputBuffer(pvStorageInfo, cbStorageInfo, (nLength * sizeof(TCHAR)), pcbLengthNeeded); + if(szBuffer != NULL) + { + LPTSTR szBufferEnd = szBuffer + nMaxChars; + + // Copy the storage path + CascStrCopy(szBuffer, (szBufferEnd - szBuffer), hs->szRootPath); + szBuffer += _tcslen(hs->szRootPath); + + // Append the product code name, if any + if(hs->szCodeName != NULL) + { + *szBuffer++ = _T(':'); + CascStrCopy(szBuffer, (szBufferEnd - szBuffer), hs->szCodeName); + szBuffer += _tcslen(hs->szCodeName); + } + + // Append the product region, if any + if(hs->szRegion != NULL) + { + *szBuffer++ = _T(':'); + CascStrCopy(szBuffer, (szBufferEnd - szBuffer), hs->szRegion); + } + } + + return (szBuffer != NULL); +} + +static DWORD InitializeLocalDirectories(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs) +{ + TCHAR * szWorkPath; + DWORD dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // Find the root directory of the storage. The root directory + // is the one with ".build.info" or ".build.db". + szWorkPath = CascNewStr(pArgs->szLocalPath); + if(szWorkPath != NULL) + { + // Get the length and go up until we find the ".build.info" or ".build.db" + for(;;) + { + // Is this a game directory? + dwErrCode = CheckGameDirectory(hs, szWorkPath); + if(dwErrCode == ERROR_SUCCESS) + { + dwErrCode = ERROR_SUCCESS; + break; + } + + // Cut one path part + if(!CutLastPathPart(szWorkPath)) + { + dwErrCode = ERROR_FILE_NOT_FOUND; + break; + } + } + + // Find the index directory + if (dwErrCode == ERROR_SUCCESS) + { + // First, check for more common "data" subdirectory + if ((hs->szIndexPath = CheckForIndexDirectory(hs, _T("data"))) != NULL) + dwErrCode = ERROR_SUCCESS; + + // Second, try the "darch" subdirectory (older builds of HOTS - Alpha) + else if ((hs->szIndexPath = CheckForIndexDirectory(hs, _T("darch"))) != NULL) + dwErrCode = ERROR_SUCCESS; + + else + dwErrCode = ERROR_FILE_NOT_FOUND; + } + + // Free the work path buffer + CASC_FREE(szWorkPath); + } + + return dwErrCode; +} + +static DWORD InitializeOnlineDirectories(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs) +{ + LPCTSTR szLocalCache = pArgs->szLocalPath; + LPCTSTR szCodeName = pArgs->szCodeName; + + // Create the root path + hs->szRootPath = CombinePath(szLocalCache, szCodeName); + if (hs->szRootPath != NULL) + { + // Create the name of the build file + hs->szBuildFile = CombinePath(hs->szRootPath, _T("versions")); + if(hs->szBuildFile != NULL) + { + hs->BuildFileType = CascVersionsDb; + hs->dwFeatures |= CASC_FEATURE_ONLINE; + return ERROR_SUCCESS; + } + } + + return ERROR_NOT_ENOUGH_MEMORY; +} + +static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs) +{ + LPCTSTR szCodeName = NULL; + LPCTSTR szRegion = NULL; + char szRegionA[0x40]; + DWORD dwLocaleMask = 0; + DWORD dwErrCode = ERROR_SUCCESS; + + // Pass the argument array to the storage + hs->pArgs = pArgs; + + // Extract optional arguments + ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, dwLocaleMask), &dwLocaleMask); + + // Extract the product code name + if(ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, szCodeName), &szCodeName) && szCodeName != NULL) + hs->szCodeName = CascNewStr(szCodeName); + + // Extract the region (optional) + if(ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, szRegion), &szRegion) && szRegion != NULL) + { + CascStrCopy(szRegionA, _countof(szRegionA), szRegion); + hs->szRegion = CascNewStr(szRegionA); + } // For online storages, we need to load CDN servers - if ((nError == ERROR_SUCCESS) && (hs->dwFeatures & CASC_FEATURE_ONLINE)) + if ((dwErrCode == ERROR_SUCCESS) && (hs->dwFeatures & CASC_FEATURE_ONLINE)) { - nError = LoadCdnsInfo(hs); + dwErrCode = LoadCdnsInfo(hs); } // Now, load the main storage file ".build.info" (or ".build.db" in old storages) - if(nError == ERROR_SUCCESS) + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadBuildInfo(hs); + dwErrCode = LoadBuildInfo(hs); } // If the .build.info OR .build.db file has been loaded, // proceed with loading the CDN config file - if (nError == ERROR_SUCCESS) + if (dwErrCode == ERROR_SUCCESS) { - nError = LoadCdnConfigFile(hs); + dwErrCode = LoadCdnConfigFile(hs); } // Proceed with loading the CDN build file - if (nError == ERROR_SUCCESS) + if (dwErrCode == ERROR_SUCCESS) { - nError = LoadCdnBuildFile(hs); + dwErrCode = LoadCdnBuildFile(hs); } // Load the index files. Store information from the index files to the CKeyArray. - if(nError == ERROR_SUCCESS) + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadIndexFiles(hs); + dwErrCode = LoadIndexFiles(hs); } // Load the ENCODING manifest - if(nError == ERROR_SUCCESS) + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadEncodingManifest(hs); + dwErrCode = LoadEncodingManifest(hs); } // We need to load the DOWNLOAD manifest. This will give us the information about // how many physical files are in the storage, so we can start building file tables - if(nError == ERROR_SUCCESS) + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadDownloadManifest(hs); + dwErrCode = LoadDownloadManifest(hs); } // Load the build manifest ("ROOT" file) - if(nError == ERROR_SUCCESS) + if(dwErrCode == ERROR_SUCCESS) { // If we fail to load the ROOT file, we take the file names from the INSTALL manifest - nError = LoadBuildManifest(hs, dwLocaleMask); - if (nError != ERROR_SUCCESS) + dwErrCode = LoadBuildManifest(hs, dwLocaleMask); + if (dwErrCode != ERROR_SUCCESS) { - nError = LoadInstallManifest(hs); + dwErrCode = LoadInstallManifest(hs); } } // Insert entries for files with well-known names. Their CKeys are in the BUILD file // See https://wowdev.wiki/TACT#Encoding_table for their list - if (nError == ERROR_SUCCESS) + if (dwErrCode == ERROR_SUCCESS) { InsertWellKnownFile(hs, "ENCODING", hs->EncodingCKey); InsertWellKnownFile(hs, "DOWNLOAD", hs->DownloadCKey); @@ -1151,85 +1199,151 @@ static int LoadCascStorage(TCascStorage * hs, DWORD dwLocaleMask) } // Load the encryption keys - if (nError == ERROR_SUCCESS) + if (dwErrCode == ERROR_SUCCESS) { - nError = CascLoadEncryptionKeys(hs); + dwErrCode = CascLoadEncryptionKeys(hs); } - return nError; + // Clear the arg structure + hs->pArgs = pArgs; + return dwErrCode; } -//----------------------------------------------------------------------------- -// Public functions - -void WINAPI CascSetProgressCallback(PFNPROGRESSCALLBACK PtrUserCallback, void * PtrUserParam) +static LPTSTR ParseOpenParams(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs) { - PfnProgressCallback = PtrUserCallback; - PtrProgressParam = PtrUserParam; -} + LPTSTR szParamsCopy; -bool WINAPI CascOpenStorage(LPCTSTR szPath, DWORD dwLocaleMask, HANDLE * phStorage) -{ - TCascStorage * hs; - int nError = ERROR_NOT_ENOUGH_MEMORY; + // The 'szParams' must not be empty + if(szParams == NULL || pArgs == NULL || szParams[0] == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } - // Allocate the storage structure - if((hs = new TCascStorage()) != NULL) + // The 'pArgs' must be valid but must not contain 'szLocalPath', 'szCodeName' or 'szRegion' + if(pArgs->szLocalPath != NULL || pArgs->szCodeName != NULL || pArgs->szRegion != NULL) { - // Setup the directories - nError = InitializeLocalDirectories(hs, szPath); - if(nError == ERROR_SUCCESS) + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + // Make a copy of the parameters so we can temper with them + if((szParamsCopy = CascNewStr(szParams)) != NULL) + { + LPTSTR szPlainName = (LPTSTR)GetPlainFileName(szParamsCopy); + LPTSTR szSeparator; + + // The local path is always set + pArgs->szLocalPath = szParamsCopy; + pArgs->szCodeName = NULL; + pArgs->szRegion = NULL; + + // Find the first ":". This will indicate the end of local path and also begin of product code + if((szSeparator = _tcschr(szPlainName, _T(':'))) != NULL) { - nError = LoadCascStorage(hs, dwLocaleMask); - if(nError == ERROR_SUCCESS) + // The found string is a product code name + pArgs->szCodeName = szSeparator + 1; + szSeparator[0] = 0; + + // Try again. If found, it is a product region + if((szSeparator = _tcschr(szSeparator + 1, _T(':'))) != NULL) { - *phStorage = (HANDLE)hs; - return true; + pArgs->szRegion = szSeparator + 1; + szSeparator[0] = 0; } } - - // Delete the so-far-allocated storage - hs = hs->Release(); + } + else + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); } - // Failed - SetLastError(nError); - *phStorage = NULL; - return false; + return szParamsCopy; } -// Allows to browse an online CDN storage -// szLocalCache: Local folder, where the online file will be cached. -// szCodeName: Product code name, e.g. "agent" for Battle.net Agent. More info: https://wowdev.wiki/TACT#Products -// szRegion: The region (or subvariant) of the product. Corresponds to the first column of the "versions" file. -bool WINAPI CascOpenOnlineStorage(LPCTSTR szLocalCache, LPCSTR szCodeName, LPCSTR szRegion, DWORD dwLocaleMask, HANDLE * phStorage) +//----------------------------------------------------------------------------- +// Public functions + +bool WINAPI CascOpenStorageEx(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs, bool bOnlineStorage, HANDLE * phStorage) { + CASC_OPEN_STORAGE_ARGS LocalArgs = {sizeof(CASC_OPEN_STORAGE_ARGS)}; + DWORD (*PfnInitDirs)(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs); TCascStorage * hs; - int nError = ERROR_NOT_ENOUGH_MEMORY; + LPTSTR szParamsCopy = NULL; + DWORD dwErrCode = ERROR_NOT_ENOUGH_MEMORY; + + // The storage path[+product[+region]] must either be passed in szParams or in pArgs. Not both. + // It is allowed to pass NULL as pArgs if the szParams is not NULL + if(szParams != NULL) + { + if(pArgs == NULL) + pArgs = &LocalArgs; + + szParamsCopy = ParseOpenParams(szParams, pArgs); + if(szParamsCopy == NULL) + return false; + } + else + { + // The arguments and the local path must be entered + if(pArgs == NULL || pArgs->szLocalPath == NULL || pArgs->szLocalPath[0] == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return false; + } + } // Allocate the storage structure if((hs = new TCascStorage()) != NULL) { // Setup the directories - nError = InitializeOnlineDirectories(hs, szLocalCache, szCodeName, szRegion); - if(nError == ERROR_SUCCESS) + PfnInitDirs = (bOnlineStorage) ? InitializeOnlineDirectories : InitializeLocalDirectories; + dwErrCode = PfnInitDirs(hs, pArgs); + if(dwErrCode == ERROR_SUCCESS) { - nError = LoadCascStorage(hs, dwLocaleMask); - if(nError == ERROR_SUCCESS) - { - *phStorage = (HANDLE)hs; - return true; - } + // Perform the entire storage loading + dwErrCode = LoadCascStorage(hs, pArgs); } - // Delete the so-far-allocated storage - hs = hs->Release(); + // Free the storage structure on fail + if(dwErrCode != ERROR_SUCCESS) + { + hs = hs->Release(); + } } - // Failed - SetLastError(nError); - *phStorage = NULL; - return false; + // Give the output parameter to the caller + CASC_FREE(szParamsCopy); + *phStorage = (HANDLE)hs; + + // Return the result + if(dwErrCode != ERROR_SUCCESS) + SetLastError(dwErrCode); + return (dwErrCode == ERROR_SUCCESS); +} + +// szParams: "LocalPath:CodeName", e.g. "C:\\Games\\World of Warcraft:wowt" +// * LocalPath: Local folder, where the online file will be cached. +// * CodeName: Product code name, e.g. "agent" for Battle.net Agent. More info: https://wowdev.wiki/TACT#Products +bool WINAPI CascOpenStorage(LPCTSTR szParams, DWORD dwLocaleMask, HANDLE * phStorage) +{ + CASC_OPEN_STORAGE_ARGS OpenArgs = {sizeof(CASC_OPEN_STORAGE_ARGS)}; + + OpenArgs.dwLocaleMask = dwLocaleMask; + return CascOpenStorageEx(szParams, &OpenArgs, false, phStorage); +} + +// Allows to browse an online CDN storage +// szParams: "CachePath:CodeName:Region", e.g. "C:\\Cache:wowt:us" +// * CachePath: Local folder, where the online file will be cached. +// * CodeName: Product code name, e.g. "agent" for Battle.net Agent. More info: https://wowdev.wiki/TACT#Products +// * Region: The region (or subvariant) of the product. Corresponds to the first column of the "versions" file. +bool WINAPI CascOpenOnlineStorage(LPCTSTR szParams, DWORD dwLocaleMask, HANDLE * phStorage) +{ + CASC_OPEN_STORAGE_ARGS OpenArgs = {sizeof(CASC_OPEN_STORAGE_ARGS)}; + + OpenArgs.dwLocaleMask = dwLocaleMask; + return CascOpenStorageEx(szParams, &OpenArgs, true, phStorage); } bool WINAPI CascGetStorageInfo( @@ -1278,6 +1392,9 @@ bool WINAPI CascGetStorageInfo( case CascStorageTags: return GetStorageTags(hs, pvStorageInfo, cbStorageInfo, pcbLengthNeeded); + case CascStoragePathProduct: + return GetStoragePathProduct(hs, pvStorageInfo, cbStorageInfo, pcbLengthNeeded); + default: SetLastError(ERROR_INVALID_PARAMETER); return false; diff --git a/dep/CascLib/src/CascPort.h b/dep/CascLib/src/CascPort.h index 87a2f2fddbd..8172a5dde35 100644 --- a/dep/CascLib/src/CascPort.h +++ b/dep/CascLib/src/CascPort.h @@ -60,6 +60,7 @@ #define PLATFORM_32BIT #endif + #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '\\' #define PATH_SEP_STRING "\\" @@ -102,6 +103,7 @@ #define PLATFORM_LITTLE_ENDIAN #endif + #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '/' #define PATH_SEP_STRING "/" @@ -132,6 +134,7 @@ #include <assert.h> #include <errno.h> + #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '/' #define PATH_SEP_STRING "/" diff --git a/dep/CascLib/src/CascRootFile_Mndx_x86.asm b/dep/CascLib/src/CascRootFile_Mndx_x86.asm deleted file mode 100644 index bf6d6d0b489..00000000000 --- a/dep/CascLib/src/CascRootFile_Mndx_x86.asm +++ /dev/null @@ -1,4369 +0,0 @@ -.686P -.MODEL FLAT -ASSUME FS: NOTHING - -; --------------------------------------------------------------------------- - -TMndxFindResult struc ; (sizeof=0x1C) ; XREF: GAME_OBJECT_03F7E848::sub_E94500_r -szSearchMask dd ? ; XREF: TMndxFindResult__SetPath+2D_w - ; TMndxFindResult__Constructor+4_w -cchSearchMask dd ? ; XREF: TMndxFindResult__SetPath:loc_1956E9A_w - ; TMndxFindResult__Constructor+6_w -field_8 dd ? ; XREF: TMndxFindResult__Constructor+9_w -szFoundPath dd ? ; XREF: TMndxFindResult__Constructor+C_w - ; TFileNameDatabase__FindFileInDatabase+55_w -cchFoundPath dd ? ; XREF: TMndxFindResult__Constructor+F_w - ; TFileNameDatabase__FindFileInDatabase+5B_w -FileNameIndex dd ? ; XREF: TMndxFindResult__Constructor+12_w - ; TFileNameDatabase__FindFileInDatabase+6B_w -pStruct40 dd ? ; XREF: MAR_FILE__FindFileInDatabase+19_r - ; TMndxFindResult__SetPath:loc_1956E8C_r -TMndxFindResult ends - -; --------------------------------------------------------------------------- - -TRIPLET struc ; (sizeof=0xC) -BitIndex dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+39_r -NextKey dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+8C_r - ; TSparseArray__GetItemValue:loc_1959B8F_r -Distance dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+3E_r - ; TSparseArray__GetItemValue:loc_1959BBE_r -TRIPLET ends - -; --------------------------------------------------------------------------- - -NAME_ENTRY struc ; (sizeof=0xC) -ExpectedHashModifier dd ? -NextHashModifier dd ? ; XREF: TArchiveDatabase__sub_1958B00+D3r - ; sub_1958D70+2Cr -FragmentOffset dd ? ; XREF: TArchiveDatabase__sub_1958B00+45r - ; sub_1958D70+36r -NAME_ENTRY ends - -; --------------------------------------------------------------------------- - -TStruct14 struc ; (sizeof=0x14) ; XREF: TFileNameDatabase::sub_1959460r -HashValue dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+44r - ; TGenericArray__InsertItem_STRUCT14+46w -field_4 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+48r - ; TGenericArray__InsertItem_STRUCT14+4Bw -field_8 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+4Er - ; TGenericArray__InsertItem_STRUCT14+51w -field_C dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+54r - ; TGenericArray__InsertItem_STRUCT14+57w -field_10 dd ? ; XREF: TGenericArray__InsertItem_STRUCT14+5Ar - ; TGenericArray__InsertItem_STRUCT14+5Dw -TStruct14 ends - -; --------------------------------------------------------------------------- - -TGenericArray struc ; (sizeof=0x15) ; XREF: TGenericArray::LoadDwordsArrayWithCopyr - ; TFileNameDatabase::LoadBytesr -DataBuffer dd ? ; XREF: TMndxFindResult__CreateStruct40+24w - ; TMndxFindResult__CreateStruct40+35w -field_4 dd ? ; XREF: TMndxFindResult__CreateStruct40+26w - ; TMndxFindResult__CreateStruct40+38w -ItemArray dd ? ; XREF: TMndxFindResult__CreateStruct40+29w - ; TMndxFindResult__CreateStruct40+3Bw -ItemCount dd ? ; XREF: TMndxFindResult__CreateStruct40+2Cw - ; TMndxFindResult__CreateStruct40+3Ew -MaxItemCount dd ? ; XREF: TFileNameDatabasePtr__CreateDatabase+27o - ; TMndxFindResult__CreateStruct40+2Fw -bIsValidArray db ? ; XREF: LoadAndVerifyIndexFileHeader+31w - ; TMndxFindResult__CreateStruct40+32w -TGenericArray ends - -; --------------------------------------------------------------------------- - -TBitEntryArray struc ; (sizeof=0x24) ; XREF: TGenericArrayEx::LoadFromStream_Exchanger - ; TFileNameDatabaser -DataBuffer dd ? ; XREF: TArchiveDatabase__Destructor+64r - ; TArchiveDatabase__Constructor+1A3w -field_4 dd ? ; XREF: TArchiveDatabase__Constructor+1A9w -ItemArray dd ? ; XREF: sub_1957350+31r - ; sub_19573D0+1Fr -ItemCount dd ? ; XREF: TArchiveDatabase__Constructor+1B5w -MaxItemCount dd ? ; XREF: TArchiveDatabase__Constructor+1BBw -bIsValidArray db ? ; XREF: TArchiveDatabase__Constructor+1C1w - db ? ; undefined - db ? ; undefined - db ? ; undefined -BitsPerEntry dd ? ; XREF: sub_1957350+1Fr - ; sub_19573D0+6r -EntryBitMask dd ? ; XREF: sub_1957350:loc_19573B1r - ; sub_19573D0:loc_1957419r -TotalEntries dd ? ; XREF: TGenericArrayEx__LoadFromStream:loc_195861Bw - ; TArchiveDatabase__Constructor+1D3w -TBitEntryArray ends - ; TFileNameDatabase__Constructor+1D3_w -; --------------------------------------------------------------------------- - -TStruct40 struc ; (sizeof=0x40) -array_00 TGenericArray <> ; XREF: TMndxFindResult__CreateStruct40+24w - ; TMndxFindResult__CreateStruct40+26w - db ? ; undefined - db ? ; undefined - db ? ; undefined -array_18 TGenericArray <> ; XREF: TMndxFindResult__CreateStruct40+35w - ; TMndxFindResult__CreateStruct40+38w - db ? ; undefined - db ? ; undefined - db ? ; undefined -HashValue dd ? ; XREF: TMndxFindResult__CreateStruct40+47w - ; TFileNameDatabase__CheckNextPathFragment+1Ar -CharIndex dd ? ; XREF: TMndxFindResult__CreateStruct40+4Aw - ; TFileNameDatabase__CheckNextPathFragment+11r -ItemCount dd ? ; XREF: TMndxFindResult__CreateStruct40+4Dw - ; TStruct40__InitSearchBuffers+6Bw -SearchPhase dd ? ; XREF: TMndxFindResult__CreateStruct40+50w - ; TFileNameDatabase__FindFileInDatabase+17w -TStruct40 ends - -; --------------------------------------------------------------------------- - -TSparseArray struc ; (sizeof=0x65) ; XREF: TSparseArray::LoadFromStream_Exchange_r - ; TNameIndexStruct_r -ItemIsPresent TGenericArray <> ; XREF: LoadAndVerifyIndexFileHeader+31_w - ; TFileNameDatabase__Destructor+4C_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -TotalItemCount dd ? ; XREF: TSparseArray__ExchangeWith+4D_r - ; TSparseArray__ExchangeWith+56_w -ValidItemCount dd ? ; XREF: TFileNameDatabasePtr__GetFileNameCount:loc_1956D32_r - ; TSparseArray__ExchangeWith+59_r -ArrayTriplets_20 TGenericArray <> ; XREF: TFileNameDatabase__Destructor+40_r - ; TFileNameDatabase__Destructor+94_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -ArrayDwords_38 TGenericArray <> ; XREF: TFileNameDatabasePtr__CreateDatabase+27_o - ; TFileNameDatabase__Destructor+34_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -ArrayDwords_50 TGenericArray <> ; XREF: TFileNameDatabase__Destructor+28_r - ; TFileNameDatabase__Destructor+7C_r -TSparseArray ends - -; --------------------------------------------------------------------------- - -TNameIndexStruct struc ; (sizeof=0x7D) ; XREF: TNameIndexStruct::LoadFromStream_Exchange_r - ; TFileNameDatabaser -NameFragments TGenericArray <> ; XREF: TFileNameDatabase__Destructor+58_r - ; TFileNameDatabase__LoadFromStream+82_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -Struct68 TSparseArray <> ; XREF: LoadAndVerifyIndexFileHeader+31_w - ; TFileNameDatabase__Destructor+28_r -TNameIndexStruct ends - -; --------------------------------------------------------------------------- - -TByteStream struc ; (sizeof=0x18) ; XREF: TFileNameDatabasePtr::CreateDatabase_r - ; TFileNameDatabase_r -pbData dd ? ; XREF: TByteStream__Constructor+4_w - ; TByteStream__IsMarDataValid+2_r -pvMappedFile dd ? ; XREF: TByteStream__Constructor+6_w - ; TByteStream__Destructor+3_r -cbData dd ? ; XREF: TByteStream__Constructor+9_w - ; TByteStream__GetBytes:loc_1959A05_r -field_C dd ? ; XREF: TByteStream__Constructor+C_w -hFile dd ? ; XREF: TByteStream__Constructor+F_w - ; TByteStream__Destructor:loc_19599D2_r -hMap dd ? ; XREF: TByteStream__Constructor+12_w - ; TByteStream__Destructor:loc_19599C2_r -TByteStream ends - -; --------------------------------------------------------------------------- - -TStruct10 struc ; (sizeof=0x10) ; XREF: TStruct10::sub_1957800_r - ; TFileNameDatabase_r -field_0 dd ? ; XREF: sub_19572E0+24_w - ; TFileNameDatabase__Constructor+21A_w -field_4 dd ? ; XREF: sub_1956FD0+28_w - ; sub_1956FD0:loc_1957001_w -field_8 dd ? ; XREF: sub_19572E0+4A_w - ; sub_19572E0+5B_w -field_C dd ? ; XREF: sub_1957050:loc_1957074_w - ; sub_1957050:loc_1957081_w -TStruct10 ends - -; --------------------------------------------------------------------------- - -TFileNameDatabasePtr struc ; (sizeof=0x4) ; XREF: TFileNameDatabase_r - ; MAR_FILE_r -pDatabase dd ? ; XREF: MAR_FILE__Constructor+1D_w - ; MAR_FILE__CreateDatabase+22_w -TFileNameDatabasePtr ends - -; --------------------------------------------------------------------------- - -TFileNameDatabase struc ; (sizeof=0x240) ; XREF: TFileNameDatabase::LoadFromStream_Exchange_r -Struct68_00 TSparseArray <> ; XREF: TFileNameDatabasePtr__CreateDatabase+27_o - ; TFileNameDatabase__Destructor+D9_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -FileNameIndexes TSparseArray <> ; XREF: TFileNameDatabasePtr__GetFileNameCount:loc_1956D32_r - ; TFileNameDatabase__Destructor+AC_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -Struct68_D0 TSparseArray <> ; XREF: TFileNameDatabase__Destructor+7C_r - ; TFileNameDatabase__Destructor+88_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -FrgmDist_LoBits TGenericArray <> ; XREF: TFileNameDatabase__Destructor+70_r - ; TFileNameDatabase__CheckNextPathFragment:loc_1957AC9_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -FrgmDist_HiBits TBitEntryArray <> ; XREF: TFileNameDatabase__Destructor+64_r - ; TFileNameDatabase__CheckNextPathFragment+119_r -IndexStruct_174 TNameIndexStruct <> ; XREF: TFileNameDatabase__Destructor+28_r - ; TFileNameDatabase__Destructor+34_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -NextDB TFileNameDatabasePtr <> ; XREF: TFileNameDatabase__Destructor+1D_o - ; TFileNameDatabase__CheckNextPathFragment+52_r -NameFragTable TGenericArray <> ; XREF: TFileNameDatabase__Destructor+E_r - ; TFileNameDatabase__CheckNextPathFragment+2F_r - db ? ; undefined - db ? ; undefined - db ? ; undefined -NameFragIndexMask dd ? ; XREF: TFileNameDatabase__CheckNextPathFragment+26_r - ; sub_1957B80:loc_1957B95_r -field_214 dd ? ; XREF: TFileNameDatabase__Constructor+20E_w - ; TFileNameDatabase__LoadFromStream+110_w -Struct10 TStruct10 <> ; XREF: TFileNameDatabase__Constructor+21A_w - ; TFileNameDatabase__Constructor+224_w -MarStream TByteStream <> ; XREF: TFileNameDatabase__Destructor+3_o - ; TFileNameDatabase__Constructor+214_o -TFileNameDatabase ends - -; --------------------------------------------------------------------------- - -MAR_FILE struc ; (sizeof=0xC) -pDatabasePtr TFileNameDatabasePtr <> ; XREF: MAR_FILE__Constructor+1D_w - ; MAR_FILE__CreateDatabase+22_w -pbMarFileData dd ? ; XREF: MAR_FILE__Constructor+1A_w - ; MAR_FILE__CreateDatabase+1B_r -cbMarFileData dd ? ; XREF: MAR_FILE__Constructor+12_w - ; MAR_FILE__CreateDatabase+18_r -MAR_FILE ends - -.DATA -table_1BA1818 db 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0 - db 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0 - db 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0 - db 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0 - db 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0 - db 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0 - db 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0 - db 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 - db 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0 - db 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0 - db 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0 - db 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0 - db 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0 - db 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0 - db 2, 0, 1, 0, 3 dup(7), 1, 7, 2 dup(2), 1, 7, 2 dup(3) - db 1, 3, 2 dup(2), 1, 7, 2 dup(4), 1, 4, 2 dup(2), 1, 4 - db 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(5), 1, 5, 2 dup(2) - db 1, 5, 2 dup(3), 1, 3, 2 dup(2), 1, 5, 2 dup(4), 1, 4 - db 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(6) - db 1, 6, 2 dup(2), 1, 6, 2 dup(3), 1, 3, 2 dup(2), 1, 6 - db 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2) - db 1, 6, 2 dup(5), 1, 5, 2 dup(2), 1, 5, 2 dup(3), 1, 3 - db 2 dup(2), 1, 5, 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3) - db 1, 3, 2 dup(2), 1, 3 dup(7), 1, 7, 2 dup(2), 1, 7, 2 dup(3) - db 1, 3, 2 dup(2), 1, 7, 2 dup(4), 1, 4, 2 dup(2), 1, 4 - db 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(5), 1, 5, 2 dup(2) - db 1, 5, 2 dup(3), 1, 3, 2 dup(2), 1, 5, 2 dup(4), 1, 4 - db 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2), 1, 7, 2 dup(6) - db 1, 6, 2 dup(2), 1, 6, 2 dup(3), 1, 3, 2 dup(2), 1, 6 - db 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3), 1, 3, 2 dup(2) - db 1, 6, 2 dup(5), 1, 5, 2 dup(2), 1, 5, 2 dup(3), 1, 3 - db 2 dup(2), 1, 5, 2 dup(4), 1, 4, 2 dup(2), 1, 4, 2 dup(3) - db 1, 3, 2 dup(2), 1, 7 dup(7), 2, 3 dup(7), 3, 7, 2 dup(3) - db 2, 3 dup(7), 4, 7, 2 dup(4), 2, 7, 2 dup(4), 3, 4, 2 dup(3) - db 2, 3 dup(7), 5, 7, 2 dup(5), 2, 7, 2 dup(5), 3, 5, 2 dup(3) - db 2, 7, 2 dup(5), 4, 5, 2 dup(4), 2, 5, 2 dup(4), 3, 4 - db 2 dup(3), 2, 3 dup(7), 6, 7, 2 dup(6), 2, 7, 2 dup(6) - db 3, 6, 2 dup(3), 2, 7, 2 dup(6), 4, 6, 2 dup(4), 2, 6 - db 2 dup(4), 3, 4, 2 dup(3), 2, 7, 2 dup(6), 5, 6, 2 dup(5) - db 2, 6, 2 dup(5), 3, 5, 2 dup(3), 2, 6, 2 dup(5), 4, 5 - db 2 dup(4), 2, 5, 2 dup(4), 3, 4, 2 dup(3), 2, 7 dup(7) - db 2, 3 dup(7), 3, 7, 2 dup(3), 2, 3 dup(7), 4, 7, 2 dup(4) - db 2, 7, 2 dup(4), 3, 4, 2 dup(3), 2, 3 dup(7), 5, 7, 2 dup(5) - db 2, 7, 2 dup(5), 3, 5, 2 dup(3), 2, 7, 2 dup(5), 4, 5 - db 2 dup(4), 2, 5, 2 dup(4), 3, 4, 2 dup(3), 2, 3 dup(7) - db 6, 7, 2 dup(6), 2, 7, 2 dup(6), 3, 6, 2 dup(3), 2, 7 - db 2 dup(6), 4, 6, 2 dup(4), 2, 6, 2 dup(4), 3, 4, 2 dup(3) - db 2, 7, 2 dup(6), 5, 6, 2 dup(5), 2, 6, 2 dup(5), 3, 5 - db 2 dup(3), 2, 6, 2 dup(5), 4, 5, 2 dup(4), 2, 5, 2 dup(4) - db 3, 4, 2 dup(3), 2, 0Fh dup(7), 3, 7 dup(7), 4, 3 dup(7) - db 4, 7, 2 dup(4), 3, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5) - db 3, 3 dup(7), 5, 7, 2 dup(5), 4, 7, 2 dup(5), 4, 5, 2 dup(4) - db 3, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 3, 3 dup(7) - db 6, 7, 2 dup(6), 4, 7, 2 dup(6), 4, 6, 2 dup(4), 3, 3 dup(7) - db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 3, 7 - db 2 dup(6), 5, 6, 2 dup(5), 4, 6, 2 dup(5), 4, 5, 2 dup(4) - db 3, 0Fh dup(7), 3, 7 dup(7), 4, 3 dup(7), 4, 7, 2 dup(4) - db 3, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5), 3, 3 dup(7) - db 5, 7, 2 dup(5), 4, 7, 2 dup(5), 4, 5, 2 dup(4), 3, 7 dup(7) - db 6, 3 dup(7), 6, 7, 2 dup(6), 3, 3 dup(7), 6, 7, 2 dup(6) - db 4, 7, 2 dup(6), 4, 6, 2 dup(4), 3, 3 dup(7), 6, 7, 2 dup(6) - db 5, 7, 2 dup(6), 5, 6, 2 dup(5), 3, 7, 2 dup(6), 5, 6 - db 2 dup(5), 4, 6, 2 dup(5), 4, 5, 2 dup(4), 3, 1Fh dup(7) - db 4, 0Fh dup(7), 5, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5) - db 4, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6) - db 4, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 3 dup(7) - db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 4, 1Fh dup(7) - db 4, 0Fh dup(7), 5, 7 dup(7), 5, 3 dup(7), 5, 7, 2 dup(5) - db 4, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6) - db 4, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 3 dup(7) - db 6, 7, 2 dup(6), 5, 7, 2 dup(6), 5, 6, 2 dup(5), 4, 3Fh dup(7) - db 5, 1Fh dup(7), 6, 0Fh dup(7), 6, 7 dup(7), 6, 3 dup(7) - db 6, 7, 2 dup(6), 5, 3Fh dup(7), 5, 1Fh dup(7), 6, 0Fh dup(7) - db 6, 7 dup(7), 6, 3 dup(7), 6, 7, 2 dup(6), 5, 7Fh dup(7) - db 6, 7Fh dup(7), 6, 100h dup(7) - -unk_53ABE00 db 0 - -.CODE - -; -; void * operator_new_safe(size_t ByteCount, void * unk_53ABE00); -; - -EXTERN _allocate_zeroed_memory_x86:PROC -EXTERN _free_memory_x86:PROC - -j_operator_new_safe PROC - push ebp - mov ebp, esp - push [ebp+08] - call _allocate_zeroed_memory_x86 - add esp, 4 - mov esp, ebp - pop ebp - ret -j_operator_new_safe ENDP - -operator_delete PROC - push ebp - mov ebp, esp - push [ebp+08] - call _free_memory_x86 - add esp, 4 - mov esp, ebp - pop ebp - ret -operator_delete ENDP - - -TSparseArray__GetItemValue proc near ; CODE XREF: sub_1957350+1A_p - ; TFileNameDatabase__CheckNextPathFragment+103_p - -arg_0 = dword ptr 8 - - push ebp - mov ebp, esp - mov edx, [ecx+28h] - push ebx - push esi - push edi - mov edi, [ebp+arg_0] - mov eax, edi - shr eax, 9 - lea eax, [eax+eax*2] - mov esi, [edx+eax*4] - lea eax, [edx+eax*4] - mov edx, edi - shr edx, 6 - and edx, 7 - dec edx - cmp edx, 6 ; switch 7 cases - ja short loc_1959BE0 ; jumptable 01959B88 default case - jmp ds:off_1959C90[edx*4] ; switch jump - -loc_1959B8F: ; DATA XREF: .text:off_1959C90o - mov eax, [eax+4] ; jumptable 01959B88 case 0 - and eax, 7Fh - jmp short loc_1959BDE -; --------------------------------------------------------------------------- - -loc_1959B97: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov edx, [eax+4] ; jumptable 01959B88 case 1 - shr edx, 7 - and edx, 0FFh - add esi, edx - jmp short loc_1959BE0 ; jumptable 01959B88 default case -; --------------------------------------------------------------------------- - -loc_1959BA7: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov eax, [eax+4] ; jumptable 01959B88 case 2 - shr eax, 0Fh - and eax, 0FFh - jmp short loc_1959BDE -; --------------------------------------------------------------------------- - -loc_1959BB4: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov edx, [eax+4] ; jumptable 01959B88 case 3 - shr edx, 17h - add esi, edx - jmp short loc_1959BE0 ; jumptable 01959B88 default case -; --------------------------------------------------------------------------- - -loc_1959BBE: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov eax, [eax+8] ; jumptable 01959B88 case 4 - jmp short loc_1959BD9 -; --------------------------------------------------------------------------- - -loc_1959BC3: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov edx, [eax+8] ; jumptable 01959B88 case 5 - shr edx, 9 - and edx, 1FFh - add esi, edx - jmp short loc_1959BE0 ; jumptable 01959B88 default case -; --------------------------------------------------------------------------- - -loc_1959BD3: ; CODE XREF: TSparseArray__GetItemValue+28_j - ; DATA XREF: .text:off_1959C90o - mov eax, [eax+8] ; jumptable 01959B88 case 6 - shr eax, 12h - -loc_1959BD9: ; CODE XREF: TSparseArray__GetItemValue+61_j - and eax, 1FFh - -loc_1959BDE: ; CODE XREF: TSparseArray__GetItemValue+35_j - ; TSparseArray__GetItemValue+52_j - add esi, eax - -loc_1959BE0: ; CODE XREF: TSparseArray__GetItemValue+26_j - ; TSparseArray__GetItemValue+45_j - mov ebx, edi ; jumptable 01959B88 default case - shr ebx, 5 - test bl, 1 - jz short loc_1959C31 - mov edx, [ecx+8] - mov edx, [edx+ebx*4-4] - mov eax, edx - shr eax, 1 - and eax, 55555555h - and edx, 55555555h - add eax, edx - mov edx, eax - and eax, 33333333h - shr edx, 2 - and edx, 33333333h - add edx, eax - mov eax, edx - shr eax, 4 - and eax, 0F0F0F0Fh - and edx, 0F0F0F0Fh - add eax, edx - imul eax, 1010101h - shr eax, 18h - add esi, eax - -loc_1959C31: ; CODE XREF: TSparseArray__GetItemValue+88_j - mov edx, [ecx+8] - mov ecx, edi - and ecx, 1Fh - mov eax, 1 - shl eax, cl - mov ecx, [edx+ebx*4] - pop edi - dec eax - and ecx, eax - mov eax, ecx - shr eax, 1 - and eax, 55555555h - and ecx, 55555555h - add eax, ecx - mov ecx, eax - and eax, 33333333h - shr ecx, 2 - and ecx, 33333333h - add ecx, eax - mov eax, ecx - shr eax, 4 - and eax, 0F0F0F0Fh - and ecx, 0F0F0F0Fh - add eax, ecx - imul eax, 1010101h - shr eax, 18h - add eax, esi - pop esi - pop ebx - pop ebp - retn 4 - -off_1959C90 dd offset loc_1959B8F ; DATA XREF: TSparseArray__GetItemValue+28_r - dd offset loc_1959B97 ; jump table for switch statement - dd offset loc_1959BA7 - dd offset loc_1959BB4 - dd offset loc_1959BBE - dd offset loc_1959BC3 - dd offset loc_1959BD3 - -TSparseArray__GetItemValue endp - -;------------------------------------------------------------------------------ -; TArchiveDatabase__sub_1959CB0 - -TArchiveDatabase__sub_1959CB0 proc near - ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+A1_p - ; sub_1958B00+E8_p - -pThis = dword ptr -4 -dwKey = dword ptr 8 - - push ebp - mov ebp, esp - push ecx - mov edx, [ebp+dwKey] - mov eax, edx - shr eax, 9 - mov [ebp+pThis], ecx - test edx, 1FFh ; if(dwKey & 0x01FF) - jnz short loc_1959CD3 - mov ecx, [ecx+40h] - mov eax, [ecx+eax*4] ; EAX = pDatabase->NextKeyTable[dwKey >> 0x09] - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1959CD3: ; CODE XREF: TFileNameDatabase__FindNextMatch+15_j - push ebx - push esi - mov esi, [ecx+40h] - lea esi, [esi+eax*4] - mov eax, [esi] - mov esi, [esi+4] - shr eax, 9 - add esi, 1FFh - push edi - shr esi, 9 - lea edi, [eax+0Ah] - mov [ebp+dwKey], esi - cmp edi, esi - jb short loc_1959D2E - mov edi, [ecx+28h] - lea esi, [eax+eax*2+3] - lea esi, [edi+esi*4] - mov edi, eax - shl edi, 9 - mov ebx, edi - sub ebx, [esi] - add ebx, 200h - cmp edx, ebx - jb short loc_1959D5F - -loc_1959D14: ; CODE XREF: TFileNameDatabase__FindNextMatch+7Aj - add edi, 200h - add esi, 0Ch - mov ebx, edi - sub ebx, [esi] - inc eax - add ebx, 200h - cmp edx, ebx - jnb short loc_1959D14 - jmp short loc_1959D5F -; --------------------------------------------------------------------------- - -loc_1959D2E: ; CODE XREF: TFileNameDatabase__FindNextMatch+45_j - lea edi, [eax+1] - cmp edi, esi - jnb short loc_1959D5F - mov ecx, [ecx+28h] - -loc_1959D38: ; CODE XREF: TFileNameDatabase__FindNextMatch+AAj - add esi, eax - shr esi, 1 - mov ebx, esi - shl ebx, 9 - lea edi, [esi+esi*2] - sub ebx, [ecx+edi*4] - cmp edx, ebx - jnb short loc_1959D50 - mov [ebp+dwKey], esi - jmp short loc_1959D55 -; --------------------------------------------------------------------------- - -loc_1959D50: ; CODE XREF: TFileNameDatabase__FindNextMatch+99_j - mov eax, esi - mov esi, [ebp+dwKey] - -loc_1959D55: ; CODE XREF: TFileNameDatabase__FindNextMatch+9E_j - lea edi, [eax+1] - cmp edi, esi - jb short loc_1959D38 - mov ecx, [ebp+pThis] - -loc_1959D5F: ; CODE XREF: TFileNameDatabase__FindNextMatch+62_j - ; TFileNameDatabase__FindNextMatch+7C_j - mov ecx, [ecx+28h] - lea esi, [eax+eax*2] - mov edi, [ecx+esi*4] ; EDI = Struct68_00.ArrayTriplets_20.ItemArray[eax] - lea esi, [ecx+esi*4] ; ESI = Struct68_00.ArrayTriplets_20.ItemArray + eax - mov ecx, eax - shl ecx, 9 - sub edi, ecx - shl eax, 4 - add edx, edi - mov edi, eax - mov eax, [esi+4] - mov ecx, eax - shr ecx, 17h - mov ebx, 100h - sub ebx, ecx - cmp edx, ebx - jnb short loc_1959DE8 - mov ecx, eax - shr ecx, 7 - and ecx, 0FFh - mov esi, 80h - sub esi, ecx - cmp edx, esi - jnb short loc_1959DC0 - and eax, 7Fh - mov ecx, 40h - sub ecx, eax - cmp edx, ecx - jb loc_1959E53 - add edi, 2 - lea edx, [edx+eax-40h] - jmp loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DC0: ; CODE XREF: TFileNameDatabase__FindNextMatch+F0_j - shr eax, 0Fh - and eax, 0FFh - mov esi, 0C0h - sub esi, eax - cmp edx, esi - jnb short loc_1959DDC - add edi, 4 - lea edx, [edx+ecx-80h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DDC: ; CODE XREF: TFileNameDatabase__FindNextMatch+121_j - add edi, 6 - lea edx, [edx+eax-0C0h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DE8: ; CODE XREF: TFileNameDatabase__FindNextMatch+DA_j - mov esi, [esi+8] - mov eax, esi - shr eax, 9 - and eax, 1FFh - mov ebx, 180h - sub ebx, eax - cmp edx, ebx - jnb short loc_1959E29 - and esi, 1FFh - mov eax, 140h - sub eax, esi - cmp edx, eax - jnb short loc_1959E1D - add edi, 8 - lea edx, [edx+ecx-100h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E1D: ; CODE XREF: TFileNameDatabase__FindNextMatch+15F_j - add edi, 0Ah - lea edx, [edx+esi-140h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E29: ; CODE XREF: TFileNameDatabase__FindNextMatch+14E_j - shr esi, 12h - and esi, 1FFh - mov ecx, 1C0h - sub ecx, esi - cmp edx, ecx - jnb short loc_1959E49 - add edi, 0Ch - lea edx, [edx+eax-180h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E49: ; CODE XREF: TFileNameDatabase__FindNextMatch+18B_j - add edi, 0Eh - lea edx, [edx+esi-1C0h] - -loc_1959E53: ; CODE XREF: TFileNameDatabase__FindNextMatch+FE_j - ; TFileNameDatabase__FindNextMatch+10B_j - mov eax, [ebp+pThis] - mov ebx, [eax+8] - mov ecx, [ebx+edi*4] - not ecx - mov eax, ecx - shr eax, 1 - and eax, 55555555h - mov esi, ecx - and esi, 55555555h - add eax, esi - mov esi, eax - shr esi, 2 - and eax, 33333333h - and esi, 33333333h - add esi, eax - mov eax, esi - shr eax, 4 - and esi, 0F0F0F0Fh - and eax, 0F0F0F0Fh - add eax, esi - imul eax, 1010101h - mov esi, eax - shr esi, 18h - cmp edx, esi - jb short loc_1959EEA - mov ecx, [ebx+edi*4+4] - inc edi - sub edx, esi - not ecx - mov eax, ecx - shr eax, 1 - and eax, 55555555h - mov esi, ecx - and esi, 55555555h - add eax, esi - mov esi, eax - shr esi, 2 - and eax, 33333333h - and esi, 33333333h - add esi, eax - mov eax, esi - shr eax, 4 - and eax, 0F0F0F0Fh - and esi, 0F0F0F0Fh - add eax, esi - imul eax, 1010101h - -loc_1959EEA: ; CODE XREF: TFileNameDatabase__FindNextMatch+1F2_j - mov esi, eax - shr esi, 8 - and esi, 0FFh - shl edi, 5 - cmp edx, esi - jnb short loc_1959F0D - and eax, 0FFh - cmp edx, eax - jb short loc_1959F2B - add edi, 8 - shr ecx, 8 - jmp short loc_1959F29 -; --------------------------------------------------------------------------- - -loc_1959F0D: ; CODE XREF: TFileNameDatabase__FindNextMatch+24A_j - shr eax, 10h - and eax, 0FFh - cmp edx, eax - jnb short loc_1959F23 - add edi, 10h - shr ecx, 10h - sub edx, esi - jmp short loc_1959F2B -; --------------------------------------------------------------------------- - -loc_1959F23: ; CODE XREF: TFileNameDatabase__FindNextMatch+267_j - add edi, 18h - shr ecx, 18h - -loc_1959F29: ; CODE XREF: TFileNameDatabase__FindNextMatch+25B_j - sub edx, eax - -loc_1959F2B: ; CODE XREF: TFileNameDatabase__FindNextMatch+253_j - ; TFileNameDatabase__FindNextMatch+271_j - and ecx, 0FFh - shl edx, 8 - movzx eax, byte ptr ds:table_1BA1818[ecx+edx] - add eax, edi - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 4 -TArchiveDatabase__sub_1959CB0 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TNameIndexStruct__CheckNameFragment proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+6B_p - ; TFileNameDatabase__CheckNextPathFragment+191_p - -pThis = dword ptr -4 -pUnknownStruct1C= dword ptr 8 -dwDistance = dword ptr 0Ch - - push ebp - mov ebp, esp - push ecx - push ebx - push esi - push edi - mov edi, ecx - cmp [edi+TNameIndexStruct.Struct68.TotalItemCount], 0 - mov ecx, [ebp+pUnknownStruct1C] - mov edx, [ecx+TMndxFindResult.pStruct40] - mov [ebp+pThis], edi - jnz short loc_195A1C8 - mov edi, [edi+TNameIndexStruct.NameFragments.ItemArray] ; Pointer to name table - sub edi, [edx+TStruct40.CharIndex] - add edi, [ebp+dwDistance] ; EDI = szPathFragment - -loc_195A1A1: ; CODE XREF: TNameIndexStruct__CheckNameFragment+3Bj - mov eax, [edx+TStruct40.CharIndex] - mov esi, [ecx+TMndxFindResult.szSearchMask] - mov bl, [eax+edi] - cmp bl, [eax+esi] - jnz short loc_195A1BD - inc eax - mov [edx+TStruct40.CharIndex], eax - cmp byte ptr [eax+edi], 0 - jz short loc_195A215 - cmp eax, [ecx+TMndxFindResult.cchSearchMask] - jb short loc_195A1A1 - -loc_195A1BD: ; CODE XREF: TNameIndexStruct__CheckNameFragment+2C_j - ; TNameIndexStruct__CheckNameFragment+5Ej - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_195A1C8: ; CODE XREF: TNameIndexStruct__CheckNameFragment+16_j - mov eax, [ebp+dwDistance] - jmp short loc_195A1D0 -; --------------------------------------------------------------------------- - align 10h - -loc_195A1D0: ; CODE XREF: TNameIndexStruct__CheckNameFragment+4B_j - ; TNameIndexStruct__CheckNameFragment+93j - mov ebx, [edi+TNameIndexStruct.NameFragments.ItemArray] - mov esi, [edx+TStruct40.CharIndex] - mov ecx, [ecx+TMndxFindResult.szSearchMask] - mov bl, [eax+ebx] ; pNameList[dwNameOffset] == szPathName[nCharIndex] - cmp bl, [esi+ecx] - jnz short loc_195A1BD - lea ecx, [esi+1] - mov [edx+TStruct40.CharIndex], ecx - mov edi, [edi+TNameIndexStruct.Struct68.ItemIsPresent.ItemArray] - mov [ebp+dwDistance], ecx - mov ecx, eax - and ecx, 1Fh ; ecx = (dwNameOffset & 0x1F) - mov esi, eax - mov ebx, 1 - shl ebx, cl ; ebx = 1 << (dwNameOffset & 0x1F); - shr esi, 5 ; esi = (dwNameOffset >> 0x05) - mov ecx, [edi+esi*4] - inc eax - and ecx, ebx - jnz short loc_195A215 - mov esi, [ebp+dwDistance] - mov ecx, [ebp+pUnknownStruct1C] - cmp esi, [ecx+4] - jnb short loc_195A1BD - mov edi, [ebp+pThis] - jmp short loc_195A1D0 -; --------------------------------------------------------------------------- - -loc_195A215: ; CODE XREF: TNameIndexStruct__CheckNameFragment+36_j - ; TNameIndexStruct__CheckNameFragment+83_j - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 8 -TNameIndexStruct__CheckNameFragment endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1957350 proc near ; CODE XREF: sub_1957B80+D8p - ; sub_1957B80:loc_1957C73p - -arg_0 = dword ptr 8 - - push ebp - mov ebp, esp - mov eax, [ebp+arg_0] - push ebx - push esi - mov esi, ecx - mov ebx, [esi+140h] - push edi - push eax - lea ecx, [esi+0D0h] - add ebx, eax - call TSparseArray__GetItemValue - mov edi, [esi+168h] - mov ecx, edi - imul ecx, eax - mov eax, ecx - and ecx, 1Fh - mov edx, ecx - mov ecx, [esi+158h] - add edi, edx - shr eax, 5 - cmp edi, 20h - ja short loc_195739A - mov eax, [ecx+eax*4] - mov ecx, edx - shr eax, cl - jmp short loc_19573B1 -; --------------------------------------------------------------------------- - -loc_195739A: ; CODE XREF: sub_1957350+3F_j - lea edi, [ecx+eax*4] - mov eax, [edi+4] - mov edi, [edi] - mov ecx, 20h - sub ecx, edx - shl eax, cl - mov ecx, edx - shr edi, cl - or eax, edi - -loc_19573B1: ; CODE XREF: sub_1957350+48_j - and eax, [esi+16Ch] - movzx edx, byte ptr [ebx] - pop edi - shl eax, 8 - pop esi - or eax, edx - pop ebx - pop ebp - retn 4 -sub_1957350 endp - -; --------------------------------------------------------------------------- - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1959F50 proc near ; CODE XREF: sub_1957B80+14C_p - ; sub_1958980+62_p - -var_4 = dword ptr -4 -arg_0 = dword ptr 8 - - push ebp - mov ebp, esp - push ecx - mov edx, [ebp+arg_0] - mov eax, edx - shr eax, 9 - mov [ebp+var_4], ecx - test edx, 1FFh - jnz short loc_1959F73 - mov ecx, [ecx+58h] - mov eax, [ecx+eax*4] - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1959F73: ; CODE XREF: sub_1959F50+15_j - push ebx - push esi - mov esi, [ecx+58h] - lea esi, [esi+eax*4] - mov eax, [esi] - push edi - mov edi, [esi+4] - shr eax, 9 - add edi, 1FFh - shr edi, 9 - lea esi, [eax+0Ah] - cmp esi, edi - jb short loc_1959FAD - mov edi, [ecx+28h] - lea esi, [eax+eax*2+3] - cmp edx, [edi+esi*4] - lea esi, [edi+esi*4] - jb short loc_1959FD4 - -loc_1959FA3: ; CODE XREF: sub_1959F50+59j - add esi, 0Ch - inc eax - cmp edx, [esi] - jnb short loc_1959FA3 - jmp short loc_1959FD4 -; --------------------------------------------------------------------------- - -loc_1959FAD: ; CODE XREF: sub_1959F50+42_j - lea esi, [eax+1] - cmp esi, edi - jnb short loc_1959FD4 - mov ecx, [ecx+28h] - -loc_1959FB7: ; CODE XREF: sub_1959F50+7Fj - lea esi, [edi+eax] - shr esi, 1 - lea ebx, [esi+esi*2] - cmp edx, [ecx+ebx*4] - jnb short loc_1959FC8 - mov edi, esi - jmp short loc_1959FCA -; --------------------------------------------------------------------------- - -loc_1959FC8: ; CODE XREF: sub_1959F50+72_j - mov eax, esi - -loc_1959FCA: ; CODE XREF: sub_1959F50+76_j - lea esi, [eax+1] - cmp esi, edi - jb short loc_1959FB7 - mov ecx, [ebp+var_4] - -loc_1959FD4: ; CODE XREF: sub_1959F50+51_j - ; sub_1959F50+5B_j - mov edi, [ecx+28h] - lea esi, [eax+eax*2] - sub edx, [edi+esi*4] - shl eax, 4 - lea esi, [edi+esi*4] - mov edi, eax - mov eax, [esi+4] - mov ebx, eax - shr ebx, 17h - cmp edx, ebx - jnb short loc_195A026 - mov esi, eax - shr esi, 7 - and esi, 0FFh - cmp edx, esi - jnb short loc_195A00E - and eax, 7Fh - cmp edx, eax - jb short loc_195A066 - add edi, 2 - sub edx, eax - jmp short loc_195A066 -; --------------------------------------------------------------------------- - -loc_195A00E: ; CODE XREF: sub_1959F50+AE_j - shr eax, 0Fh - and eax, 0FFh - cmp edx, eax - jnb short loc_195A01F - add edi, 4 - jmp short loc_195A064 -; --------------------------------------------------------------------------- - -loc_195A01F: ; CODE XREF: sub_1959F50+C8_j - add edi, 6 - sub edx, eax - jmp short loc_195A066 -; --------------------------------------------------------------------------- - -loc_195A026: ; CODE XREF: sub_1959F50+9F_j - mov esi, [esi+8] - mov eax, esi - shr eax, 9 - and eax, 1FFh - cmp edx, eax - jnb short loc_195A04D - and esi, 1FFh - cmp edx, esi - jnb short loc_195A048 - add edi, 8 - sub edx, ebx - jmp short loc_195A066 -; --------------------------------------------------------------------------- - -loc_195A048: ; CODE XREF: sub_1959F50+EF_j - add edi, 0Ah - jmp short loc_195A064 -; --------------------------------------------------------------------------- - -loc_195A04D: ; CODE XREF: sub_1959F50+E5_j - shr esi, 12h - and esi, 1FFh - cmp edx, esi - jnb short loc_195A061 - add edi, 0Ch - sub edx, eax - jmp short loc_195A066 -; --------------------------------------------------------------------------- - -loc_195A061: ; CODE XREF: sub_1959F50+108_j - add edi, 0Eh - -loc_195A064: ; CODE XREF: sub_1959F50+CD_j - ; sub_1959F50+FB_j - sub edx, esi - -loc_195A066: ; CODE XREF: sub_1959F50+B5_j - ; sub_1959F50+BC_j - mov ebx, [ecx+8] - mov esi, [ebx+edi*4] - mov eax, esi - shr eax, 1 - and eax, 55555555h - mov ecx, esi - and ecx, 55555555h - add eax, ecx - mov ecx, eax - shr ecx, 2 - and eax, 33333333h - and ecx, 33333333h - add ecx, eax - mov eax, ecx - shr eax, 4 - and ecx, 0F0F0F0Fh - and eax, 0F0F0F0Fh - add eax, ecx - imul eax, 1010101h - mov ecx, eax - shr ecx, 18h - cmp edx, ecx - jb short loc_195A0F6 - mov esi, [ebx+edi*4+4] - sub edx, ecx - inc edi - mov eax, esi - shr eax, 1 - and eax, 55555555h - mov ecx, esi - and ecx, 55555555h - add eax, ecx - mov ecx, eax - shr ecx, 2 - and eax, 33333333h - and ecx, 33333333h - add ecx, eax - mov eax, ecx - shr eax, 4 - and eax, 0F0F0F0Fh - and ecx, 0F0F0F0Fh - add eax, ecx - imul eax, 1010101h - -loc_195A0F6: ; CODE XREF: sub_1959F50+160_j - mov ecx, eax - shr ecx, 8 - and ecx, 0FFh - shl edi, 5 - cmp edx, ecx - jnb short loc_195A119 - and eax, 0FFh - cmp edx, eax - jb short loc_195A137 - add edi, 8 - shr esi, 8 - jmp short loc_195A135 -; --------------------------------------------------------------------------- - -loc_195A119: ; CODE XREF: sub_1959F50+1B6_j - shr eax, 10h - and eax, 0FFh - cmp edx, eax - jnb short loc_195A12F - add edi, 10h - shr esi, 10h - sub edx, ecx - jmp short loc_195A137 -; --------------------------------------------------------------------------- - -loc_195A12F: ; CODE XREF: sub_1959F50+1D3_j - add edi, 18h - shr esi, 18h - -loc_195A135: ; CODE XREF: sub_1959F50+1C7_j - sub edx, eax - -loc_195A137: ; CODE XREF: sub_1959F50+1BF_j - ; sub_1959F50+1DD_j - and esi, 0FFh - shl edx, 8 - movzx eax, ds:table_1BA1818[esi+edx] - add eax, edi - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 4 -sub_1959F50 endp - -; --------------------------------------------------------------------------- - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1957B80 proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+5E_p - ; TFileNameDatabase__CheckNextPathFragment+180_p - -pStruct40 = dword ptr -4 -arg_0 = dword ptr 8 -arg_4 = dword ptr 0Ch - - push ebp - mov ebp, esp - push ecx - push ebx - mov ebx, [ebp+arg_0] - mov eax, [ebx+18h] - push esi - push edi - mov edi, [ebp+arg_4] - mov esi, ecx - mov [ebp+pStruct40], eax - -loc_1957B95: ; CODE XREF: sub_1957B80+9Fj - ; sub_1957B80+156j - mov eax, [esi+TFileNameDatabase.NameFragIndexMask] - and eax, edi - lea ecx, [eax+eax*2] - mov eax, [esi+TFileNameDatabase.NameFragTable.ItemArray] - add ecx, ecx - add ecx, ecx - add eax, ecx - mov [ebp+arg_4], ecx - cmp edi, [eax+4] - jnz short loc_1957C30 - mov edx, [eax+8] - mov edi, edx - and edi, 0FFFFFF00h - cmp edi, 0FFFFFF00h - jz short loc_1957BEE - mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase] - push edx - push ebx - test ecx, ecx - jz short loc_1957BDA - call sub_1957B80 - jmp short loc_1957BE5 -; --------------------------------------------------------------------------- - -loc_1957BDA: ; CODE XREF: sub_1957B80+51_j - lea ecx, [esi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckNameFragment - -loc_1957BE5: ; CODE XREF: sub_1957B80+58_j - test al, al - jz short loc_1957C25 - mov ecx, [ebp+arg_4] - jmp short loc_1957C05 -; --------------------------------------------------------------------------- - -loc_1957BEE: ; CODE XREF: sub_1957B80+45_j - mov edx, [ebp+pStruct40] - mov edi, [edx+34h] - mov edx, [ebx] - mov al, [eax+8] - cmp al, [edi+edx] - jnz short loc_1957C25 - mov edx, [ebp+pStruct40] - inc edi - mov [edx+34h], edi - -loc_1957C05: ; CODE XREF: sub_1957B80+6C_j - mov eax, [esi+200h] - mov edi, [ecx+eax] - test edi, edi - jz loc_1957CDB - mov ecx, [ebp+pStruct40] - mov edx, [ecx+34h] - cmp edx, [ebx+4] - jb loc_1957B95 - -loc_1957C25: ; CODE XREF: sub_1957B80+67_j - ; sub_1957B80+7C_j - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_1957C30: ; CODE XREF: sub_1957B80+32_j - mov edx, [esi+0D8h] - mov ecx, edi - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - mov eax, edi - shr eax, 5 - test [edx+eax*4], ebx - jz short loc_1957C8E - cmp dword ptr [esi+1F4h], 0 - push edi - mov ecx, esi - jz short loc_1957C73 - call sub_1957350 - mov ecx, [esi+1F4h] - mov ebx, [ebp+arg_0] - push eax - push ebx - test ecx, ecx - jz short loc_1957C7D - call sub_1957B80 - jmp short loc_1957C88 -; --------------------------------------------------------------------------- - -loc_1957C73: ; CODE XREF: sub_1957B80+D6_j - call sub_1957350 - mov ebx, [ebp+arg_0] - push eax - push ebx - -loc_1957C7D: ; CODE XREF: sub_1957B80+EA_j - lea ecx, [esi+174h] - call TNameIndexStruct__CheckNameFragment - -loc_1957C88: ; CODE XREF: sub_1957B80+F1_j - test al, al - jz short loc_1957C25 - jmp short loc_1957CB2 -; --------------------------------------------------------------------------- - -loc_1957C8E: ; CODE XREF: sub_1957B80+CA_j - mov eax, [ebp+pStruct40] - mov ecx, [esi+140h] - mov ebx, [ebp+arg_0] - mov eax, [eax+34h] - mov edx, [ebx] - mov cl, [edi+ecx] - cmp cl, [eax+edx] - jnz loc_1957C25 - mov edx, [ebp+pStruct40] - inc eax - mov [edx+34h], eax - -loc_1957CB2: ; CODE XREF: sub_1957B80+10C_j - cmp edi, [esi+214h] - jbe short loc_1957CDB - mov eax, [ebp+pStruct40] - mov ecx, [eax+34h] - cmp ecx, [ebx+4] - jnb loc_1957C25 - push edi - mov ecx, esi - call sub_1959F50 - sub eax, edi - lea edi, [eax-1] - jmp loc_1957B95 -; --------------------------------------------------------------------------- - -loc_1957CDB: ; CODE XREF: sub_1957B80+90_j - ; sub_1957B80+138_j - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 8 -sub_1957B80 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_19573D0 proc near ; CODE XREF: TFileNameDatabase__sub_1959460+1D9p - -arg_0 = dword ptr 8 -arg_4 = dword ptr 0Ch - - push ebp - mov ebp, esp - push esi - mov esi, ecx - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - mov eax, edx - imul eax, [ebp+arg_4] - mov ecx, eax - and eax, 1Fh - add edx, eax - shr ecx, 5 - cmp edx, 20h - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray] - ja short loc_1957400 - mov edx, [edx+ecx*4] - mov ecx, eax - shr edx, cl - jmp short loc_1957419 -; --------------------------------------------------------------------------- - -loc_1957400: ; CODE XREF: sub_19573D0+25j - push edi - lea edi, [edx+ecx*4] - mov edx, [edi+4] - mov edi, [edi] - mov ecx, 20h - sub ecx, eax - shl edx, cl - mov ecx, eax - shr edi, cl - or edx, edi - pop edi - -loc_1957419: ; CODE XREF: sub_19573D0+2Ej - and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask] - mov eax, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov ecx, [ebp+arg_0] - movzx eax, byte ptr [eax+ecx] - shl edx, 8 - or eax, edx - pop esi - pop ebp - retn 8 -sub_19573D0 endp - -; --------------------------------------------------------------------------- - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TFileNameDatabase__CheckNextPathFragment proc near ; CODE XREF: TFileNameDatabase__FindFileInDatabase+25p - -var_C = dword ptr -0Ch -CollisionIndex = dword ptr -8 -var_4 = dword ptr -4 -pStruct1C = dword ptr 8 - - push ebp - mov ebp, esp - mov edx, [ebp+pStruct1C] - sub esp, 0Ch - push ebx - mov ebx, [edx+TMndxFindResult.szSearchMask] - push esi - push edi - mov edi, [edx+TMndxFindResult.pStruct40] - mov eax, [edi+TStruct40.CharIndex] - movzx eax, byte ptr [eax+ebx] ; EAX = szPathName[nCharIndex] - mov esi, ecx - mov ecx, [edi+TStruct40.HashValue] - mov ebx, ecx - shl ebx, 5 - xor eax, ebx - xor eax, ecx - and eax, [esi+TFileNameDatabase.NameFragIndexMask] ; (000000ff) - Mask value - lea ebx, [eax+eax*2] - mov eax, [esi+TFileNameDatabase.NameFragTable.ItemArray] ; (7f3ae128) - Array of 256 triplets - add ebx, ebx - add ebx, ebx ; EBX = Offset of the triplet we want to know - cmp ecx, [eax+ebx+TRIPLET.BitIndex] - jnz short loc_1957A0E - mov eax, [eax+ebx+TRIPLET.Distance] - mov ecx, eax - and ecx, 0FFFFFF00h - cmp ecx, 0FFFFFF00h - jz short loc_19579EF - mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase] - push eax - push edx - test ecx, ecx - jz short loc_19579D5 - call sub_1957B80 - jmp short loc_19579E0 -; --------------------------------------------------------------------------- - -loc_19579D5: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+5C_j - lea ecx, [esi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckNameFragment - -loc_19579E0: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+63_j - test al, al - jnz short loc_19579F6 - -loc_19579E4: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+C1j - ; TFileNameDatabase__CheckNextPathFragment+1A4j - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_19579EF: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+50_j - mov eax, [edi+TStruct40.CharIndex] ; nCharIndex = nCharIndex + 1 - inc eax - mov [edi+TStruct40.CharIndex], eax - -loc_19579F6: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+72_j - mov edx, [esi+TFileNameDatabase.NameFragTable.ItemArray] ; EDX = pTripletArray - mov eax, [edx+ebx+TRIPLET.NextKey] - mov [edi+TStruct40.HashValue], eax - -loc_1957A03: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+198j - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1957A0E: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+3C_j - push ecx ; dwKey - mov ecx, esi ; pDatabase - call TArchiveDatabase__sub_1959CB0 - mov ebx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - inc eax - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, eax - shr ecx, 5 - mov [ebp+CollisionIndex], eax - test [ebx+ecx*4], edx - jz short loc_19579E4 - sub eax, [edi+TStruct40.HashValue] - mov [ebp+var_4], 0FFFFFFFFh - dec eax - mov [edi+TStruct40.HashValue], eax - -loc_1957A41: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1E1j - mov eax, [edi+TStruct40.HashValue] - mov ebx, [esi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray] - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, eax - shr ecx, 5 - test [ebx+ecx*4], edx - jz loc_1957B1C - mov ecx, [ebp+var_4] - cmp ecx, 0FFFFFFFFh - jnz short loc_1957A7F - push eax - lea ecx, [esi+TFileNameDatabase.Struct68_D0] - call TSparseArray__GetItemValue - mov ecx, eax - mov [ebp+var_4], eax - jmp short loc_1957A83 -; --------------------------------------------------------------------------- - -loc_1957A7F: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+FA_j - inc ecx - mov [ebp+var_4], ecx - -loc_1957A83: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+10D_j - mov edx, [edi+TStruct40.CharIndex] - mov [ebp+var_C], edx - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - mov eax, edx - imul eax, ecx - mov ecx, eax - and eax, 1Fh - add edx, eax - shr ecx, 5 - cmp edx, 20h - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray] - ja short loc_1957AB2 - mov edx, [edx+ecx*4] - mov ecx, eax - shr edx, cl - jmp short loc_1957AC9 -; --------------------------------------------------------------------------- - -loc_1957AB2: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+137_j - lea ebx, [edx+ecx*4] - mov edx, [ebx+4] - mov ebx, [ebx] - mov ecx, 20h - sub ecx, eax - shl edx, cl - mov ecx, eax - shr ebx, cl - or edx, ebx - -loc_1957AC9: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+140_j - mov ecx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask] - mov eax, [edi+TStruct40.HashValue] - movzx eax, byte ptr [ecx+eax] - mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase] - shl edx, 8 - or eax, edx - push eax - test ecx, ecx - jz short loc_1957AF7 - mov edx, [ebp+pStruct1C] - push edx - call sub_1957B80 - jmp short loc_1957B06 -; --------------------------------------------------------------------------- - -loc_1957AF7: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+17A_j - mov eax, [ebp+pStruct1C] - push eax - lea ecx, [esi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckNameFragment - -loc_1957B06: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+185_j - test al, al - jnz loc_1957A03 - mov ecx, [ebp+var_C] - cmp [edi+TStruct40.CharIndex], ecx - jnz loc_19579E4 - jmp short loc_1957B32 -; --------------------------------------------------------------------------- - -loc_1957B1C: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+EE_j - mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov ebx, [ebp+pStruct1C] - mov ecx, [edi+TStruct40.CharIndex] - mov ebx, [ebx+TMndxFindResult.szSearchMask] - mov dl, [eax+edx] - cmp dl, [ecx+ebx] - jz short loc_1957B62 - -loc_1957B32: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1AA_j - mov eax, [ebp+CollisionIndex] - inc [edi+TStruct40.HashValue] - inc eax - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - mov [ebp+CollisionIndex], eax - shr eax, 5 - test [ecx+eax*4], edx - jnz loc_1957A41 - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1957B62: ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+1C0_j - mov eax, 1 - add [edi+TStruct40.CharIndex], eax - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 4 -TFileNameDatabase__CheckNextPathFragment endp - - -TFileNameDatabase__FindFileInDatabase proc near - ; CODE XREF: MAR_FILE__FindFileInDatabase+2D_p - -pThis = dword ptr -4 -pStruct1C = dword ptr 8 - - push ebp ; ecx = Pointer to ARCHIVE_DATABASE - mov ebp, esp - push ecx - push ebx - push esi - mov esi, [ebp+pStruct1C] - xor eax, eax - push edi - mov edi, [esi+TMndxFindResult.pStruct40] - mov ebx, ecx - mov [edi+TStruct40.HashValue], eax - mov [edi+TStruct40.CharIndex], eax - mov [edi+TStruct40.SearchPhase], eax - mov [ebp+pThis], ebx - cmp [esi+TMndxFindResult.cchSearchMask], eax - jbe short loc_1957F26 - -label_process_all_characters: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+34j - push esi - mov ecx, ebx - call TFileNameDatabase__CheckNextPathFragment - test al, al - jz short label_return_false - mov eax, [edi+TStruct40.CharIndex] - cmp eax, [esi+TMndxFindResult.cchSearchMask] - jb short label_process_all_characters - -loc_1957F26: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+20_j - mov ecx, [edi+TStruct40.HashValue] - mov eax, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray] - mov edx, ecx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr edx, 5 - test [eax+edx*4], ebx - jz short label_return_false - mov ecx, [esi+TMndxFindResult.szSearchMask] - mov eax, [esi+TMndxFindResult.cchSearchMask] - mov [esi+TMndxFindResult.szFoundPath], ecx - mov ecx, [ebp+pThis] - mov [esi+TMndxFindResult.cchFoundPath], eax - mov edi, [edi+TStruct40.HashValue] - push edi - add ecx, TFileNameDatabase.FileNameIndexes - call TSparseArray__GetItemValue - pop edi - mov [esi+TMndxFindResult.FileNameIndex], eax - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -label_return_false: ; CODE XREF: TFileNameDatabase__FindFileInDatabase+2C_j - ; TFileNameDatabase__FindFileInDatabase+4E_j - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -TFileNameDatabase__FindFileInDatabase endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TGenericArray__SetMaxItems_BYTE proc near ; CODE XREF: sub_19582E0+2Cp - ; TStruct40__InitSearchBuffers+2Cp - -ByteCount = dword ptr 8 - - push ebp - mov ebp, esp - push ebx - mov ebx, [ebp+ByteCount] - push esi - push edi - push offset unk_53ABE00 - push ebx - mov esi, ecx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - mov edi, eax - cmp [esi+TGenericArray.ItemCount], ecx - jbe short loc_19575D7 - -loc_19575C2: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+35j - lea edx, [ecx+edi] - test edx, edx - jz short loc_19575D1 - mov eax, [esi+TGenericArray.field_4] - mov al, [ecx+eax] - mov [edx], al - -loc_19575D1: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+27j - inc ecx - cmp ecx, [esi+TGenericArray.ItemCount] - jb short loc_19575C2 - -loc_19575D7: ; CODE XREF: TGenericArray__SetMaxItems_BYTE+20j - mov eax, [esi+TGenericArray.DataBuffer] - push eax - mov [esi+TGenericArray.DataBuffer], edi - mov [esi+TGenericArray.field_4], edi - mov [esi+TGenericArray.ItemArray], edi - mov [esi+TGenericArray.MaxItemCount], ebx - call operator_delete - add esp, 4 - pop edi - pop esi - pop ebx - pop ebp - retn 4 -TGenericArray__SetMaxItems_BYTE endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TGenericArray__SetMaxItems_STRUCT14 proc near - ; CODE XREF: TGenericArray__InsertItem_STRUCT14+2Cp - ; TGenericArray__sub_19583A0+2Dp - -var_4 = dword ptr -4 -ItemCount = dword ptr 8 - - push ebp - mov ebp, esp - push ecx - push esi - push edi - mov edi, [ebp+ItemCount] - lea eax, [edi+edi*4] ; EAX = (ItemCount * 5) - add eax, eax ; EAX = (ItemCount * 10) - add eax, eax ; EAX = (ItemCount * 20) - push offset unk_53ABE00 - push eax - mov esi, ecx - call j_operator_new_safe - mov ecx, eax - xor eax, eax - add esp, 8 - mov [ebp+var_4], ecx - cmp [esi+0Ch], eax - jbe short loc_195766A - xor edi, edi - mov edx, ecx - push ebx - -loc_1957631: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+64j - test edx, edx - jz short loc_195765A - mov ecx, [esi+4] - mov ebx, [ecx+edi] - add ecx, edi - mov [edx], ebx - mov ebx, [ecx+4] - mov [edx+4], ebx - mov ebx, [ecx+8] - mov [edx+8], ebx - mov ebx, [ecx+0Ch] - mov [edx+0Ch], ebx - mov ecx, [ecx+10h] - mov [edx+10h], ecx - mov ecx, [ebp+var_4] - -loc_195765A: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+33j - inc eax - add edi, 14h - add edx, 14h - cmp eax, [esi+0Ch] - jb short loc_1957631 - mov edi, [ebp+ItemCount] - pop ebx - -loc_195766A: ; CODE XREF: TGenericArray__SetMaxItems_STRUCT14+2Aj - mov eax, [esi+TGenericArray.DataBuffer] - push eax - mov [esi+TGenericArray.DataBuffer], ecx - mov [esi+TGenericArray.field_4], ecx - mov [esi+TGenericArray.ItemArray], ecx - mov [esi+TGenericArray.MaxItemCount], edi - call operator_delete - add esp, 4 - pop edi - pop esi - mov esp, ebp - pop ebp - retn 4 -TGenericArray__SetMaxItems_STRUCT14 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TGenericArray__sub_19583A0 proc near ; CODE XREF: TStruct40__InitSearchBuffers+35p - -NewItemCount = dword ptr 8 - - push ebp - mov ebp, esp - push esi - mov esi, ecx - mov eax, [esi+TGenericArray.MaxItemCount] - push edi - mov edi, [ebp+NewItemCount] - cmp edi, eax - jbe short loc_19583D2 - mov edx, edi - shr edx, 1 - mov ecx, edi - cmp eax, edx - jbe short loc_19583CA - mov ecx, 0CCCCCCCh - cmp eax, 6666666h - ja short loc_19583CA - lea ecx, [eax+eax] - -loc_19583CA: ; CODE XREF: TGenericArray__sub_19583A0+19j - ; TGenericArray__sub_19583A0+25j - push ecx - mov ecx, esi - call TGenericArray__SetMaxItems_STRUCT14 - -loc_19583D2: ; CODE XREF: TGenericArray__sub_19583A0+Fj - mov eax, [esi+TGenericArray.ItemCount] - cmp eax, edi - jnb short loc_1958410 - lea ecx, [eax+eax*4] - add ecx, ecx - mov edx, edi - push ebx - add ecx, ecx - sub edx, eax - or ebx, 0FFFFFFFFh - -loc_19583E8: ; CODE XREF: TGenericArray__sub_19583A0+6Dj - mov eax, [esi+TGenericArray.field_4] - add eax, ecx - jz short loc_1958409 - mov dword ptr [eax], 0 - mov dword ptr [eax+4], 0 - mov dword ptr [eax+8], 0 - mov [eax+0Ch], ebx - mov [eax+10h], ebx - -loc_1958409: ; CODE XREF: TGenericArray__sub_19583A0+4Dj - add ecx, 14h - dec edx - jnz short loc_19583E8 - pop ebx - -loc_1958410: ; CODE XREF: TGenericArray__sub_19583A0+37j - mov [esi+TGenericArray.ItemCount], edi - pop edi - pop esi - pop ebp - retn 4 -TGenericArray__sub_19583A0 endp - -; =============== S U B R O U T I N E ======================================= - - -TStruct40__InitSearchBuffers proc near ; CODE XREF: TFileNameDatabase__sub_1959460+2Bp - push ebx - push esi - mov esi, ecx - mov eax, [esi+TStruct40.array_00.MaxItemCount] - xor ebx, ebx - push edi - mov [esi+TStruct40.array_00.ItemCount], ebx - cmp eax, 40h - jnb short loc_19586E1 - lea ecx, [ebx+40h] ; ECX = 0x40 - cmp eax, 20h - jbe short loc_19586D9 - cmp eax, 7FFFFFFFh - jbe short loc_19586D6 - or ecx, 0FFFFFFFFh - jmp short loc_19586D9 -; --------------------------------------------------------------------------- - -loc_19586D6: ; CODE XREF: TStruct40__InitSearchBuffers+1Fj - lea ecx, [eax+eax] - -loc_19586D9: ; CODE XREF: TStruct40__InitSearchBuffers+18j - ; TStruct40__InitSearchBuffers+24j - push ecx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_19586E1: ; CODE XREF: TStruct40__InitSearchBuffers+10j - push ebx - lea ecx, [esi+TStruct40.array_18] - call TGenericArray__sub_19583A0 - mov eax, [esi+TStruct40.array_18.MaxItemCount] - cmp eax, 4 - jnb short loc_1958714 - mov ecx, 4 - cmp eax, 2 - jbe short loc_195870B - mov ecx, 0CCCCCCCh - cmp eax, 6666666h - ja short loc_195870B - lea ecx, [eax+eax] - -loc_195870B: ; CODE XREF: TStruct40__InitSearchBuffers+4Aj - ; TStruct40__InitSearchBuffers+56j - push ecx - lea ecx, [esi+TStruct40.array_18] - call TGenericArray__SetMaxItems_STRUCT14 - -loc_1958714: ; CODE XREF: TStruct40__InitSearchBuffers+40j - pop edi - mov [esi+TStruct40.HashValue], ebx - mov [esi+TStruct40.CharIndex], ebx - mov [esi+TStruct40.ItemCount], ebx - mov [esi+TStruct40.SearchPhase], 2 - pop esi - pop ebx - retn -TStruct40__InitSearchBuffers endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TGenericArray__InsertItem_STRUCT14 proc near - ; CODE XREF: TFileNameDatabase__sub_1959460+73p - -pStruct14 = dword ptr 8 - - push ebp - mov ebp, esp - push esi - mov esi, ecx - mov eax, [esi+TGenericArray.ItemCount] - mov ecx, [esi+TGenericArray.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_1958361 - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_1958359 - mov edx, 0CCCCCCCh - cmp ecx, 6666666h - ja short loc_1958359 - lea edx, [ecx+ecx] - -loc_1958359: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+17j - ; TGenericArray__InsertItem_STRUCT14+24j - push edx - mov ecx, esi - call TGenericArray__SetMaxItems_STRUCT14 - -loc_1958361: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+Fj - mov eax, [esi+TGenericArray.ItemCount] - mov ecx, [esi+TGenericArray.field_4] - lea eax, [eax+eax*4] - lea eax, [ecx+eax*4] - test eax, eax - jz short loc_1958390 - mov ecx, [ebp+pStruct14] - mov edx, [ecx+TStruct14.HashValue] - mov [eax+TStruct14.HashValue], edx - mov edx, [ecx+TStruct14.field_4] - mov [eax+TStruct14.field_4], edx - mov edx, [ecx+TStruct14.field_8] - mov [eax+TStruct14.field_8], edx - mov edx, [ecx+TStruct14.field_C] - mov [eax+TStruct14.field_C], edx - mov ecx, [ecx+TStruct14.field_10] - mov [eax+TStruct14.field_10], ecx - -loc_1958390: ; CODE XREF: TGenericArray__InsertItem_STRUCT14+3Fj - inc [esi+TGenericArray.ItemCount] - pop esi - pop ebp - retn 4 -TGenericArray__InsertItem_STRUCT14 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -CopyNameFragment proc near ; CODE XREF: sub_1958980+DAp - ; sub_1958D70+6Dp - -pThis = dword ptr -4 -pStruct1C = dword ptr 8 -dwDistance = dword ptr 0Ch - - push ebp - mov ebp, esp - push ecx - mov eax, [ebp+pStruct1C] - push ebx - mov ebx, ecx - cmp [ebx+TNameIndexStruct.Struct68.TotalItemCount], 0 - push esi - mov esi, [eax+TMndxFindResult.pStruct40] - push edi - mov [ebp+pThis], ebx - jnz loc_195A4B3 - mov ebx, [ebx+TNameIndexStruct.NameFragments.ItemArray] - add ebx, [ebp+dwDistance] - cmp byte ptr [ebx], 0 - mov [ebp+dwDistance], ebx - jz loc_195A55E - mov edi, edi - -loc_195A420: ; CODE XREF: CopyNameFragment+B4j - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_195A48E - mov ebx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A443 - cmp ecx, 7FFFFFFFh - jbe short loc_195A440 - or ebx, 0FFFFFFFFh - jmp short loc_195A443 -; --------------------------------------------------------------------------- - -loc_195A440: ; CODE XREF: CopyNameFragment+49j - lea ebx, [ecx+ecx] - -loc_195A443: ; CODE XREF: CopyNameFragment+41j - ; CopyNameFragment+4Ej - push offset unk_53ABE00 - push ebx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - mov edi, eax - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_195A475 - lea ebx, [ebx+0] - -loc_195A460: ; CODE XREF: CopyNameFragment+83j - lea edx, [ecx+edi] - test edx, edx - jz short loc_195A46F - mov eax, [esi+TStruct40.array_00.field_4] - mov al, [ecx+eax] - mov [edx], al - -loc_195A46F: ; CODE XREF: CopyNameFragment+75j - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_195A460 - -loc_195A475: ; CODE XREF: CopyNameFragment+68j - mov eax, [esi+TStruct40.array_00.DataBuffer] - push eax - mov [esi+TStruct40.array_00.DataBuffer], edi - mov [esi+TStruct40.array_00.field_4], edi - mov [esi+TStruct40.array_00.ItemArray], edi - mov [esi+TStruct40.array_00.MaxItemCount], ebx - call operator_delete - mov ebx, [ebp+dwDistance] - add esp, 4 - -loc_195A48E: ; CODE XREF: CopyNameFragment+39j - mov eax, [esi+TStruct40.array_00.ItemCount] - add eax, [esi+TStruct40.array_00.field_4] - jz short loc_195A49A - mov cl, [ebx] - mov [eax], cl - -loc_195A49A: ; CODE XREF: CopyNameFragment+A4j - inc [esi+TStruct40.array_00.ItemCount] - inc ebx - cmp byte ptr [ebx], 0 - mov [ebp+dwDistance], ebx - jnz loc_195A420 - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_195A4B3: ; CODE XREF: CopyNameFragment+16j - ; CopyNameFragment+168j - mov eax, [esi+TStruct40.array_00.ItemCount] - mov edx, [ebx+TNameIndexStruct.NameFragments.ItemArray] - mov edi, [ebp+dwDistance] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - add edx, edi - inc eax - mov [ebp+pStruct1C], edx - cmp eax, ecx - jbe short loc_195A52C - mov ebx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A4E1 - cmp ecx, 7FFFFFFFh - jbe short loc_195A4DE - or ebx, 0FFFFFFFFh - jmp short loc_195A4E1 -; --------------------------------------------------------------------------- - -loc_195A4DE: ; CODE XREF: CopyNameFragment+E7j - lea ebx, [ecx+ecx] - -loc_195A4E1: ; CODE XREF: CopyNameFragment+DFj - ; CopyNameFragment+ECj - push offset unk_53ABE00 - push ebx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - mov edi, eax - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_195A50D - -loc_195A4F8: ; CODE XREF: CopyNameFragment+11Bj - lea edx, [ecx+edi] - test edx, edx - jz short loc_195A507 - mov eax, [esi+TStruct40.array_00.field_4] - mov al, [ecx+eax] - mov [edx], al - -loc_195A507: ; CODE XREF: CopyNameFragment+10Dj - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_195A4F8 - -loc_195A50D: ; CODE XREF: CopyNameFragment+106j - mov eax, [esi+TStruct40.array_00.DataBuffer] - push eax - mov [esi+TStruct40.array_00.DataBuffer], edi - mov [esi+TStruct40.array_00.field_4], edi - mov [esi+TStruct40.array_00.ItemArray], edi - mov [esi+TStruct40.array_00.MaxItemCount], ebx - call operator_delete - mov edx, [ebp+pStruct1C] - mov edi, [ebp+dwDistance] - mov ebx, [ebp+pThis] - add esp, 4 - -loc_195A52C: ; CODE XREF: CopyNameFragment+D7j - mov eax, [esi+TStruct40.array_00.ItemCount] - add eax, [esi+TStruct40.array_00.field_4] - jz short loc_195A538 - mov cl, [edx] - mov [eax], cl - -loc_195A538: ; CODE XREF: CopyNameFragment+142j - inc [esi+TStruct40.array_00.ItemCount] - mov ecx, edi - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, [ebx+TNameIndexStruct.Struct68.ItemIsPresent.ItemArray] - mov eax, edi - shr eax, 5 - and edx, [ecx+eax*4] - inc edi - mov [ebp+dwDistance], edi - test edx, edx - jz loc_195A4B3 - -loc_195A55E: ; CODE XREF: CopyNameFragment+28j - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 8 -CopyNameFragment endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1958D70 proc near ; CODE XREF: sub_1958980+C9p - ; sub_1958D70+59p - -var_C = dword ptr -0Ch -var_8 = dword ptr -8 -var_1 = byte ptr -1 -pStruct1C = dword ptr 8 -arg_4 = dword ptr 0Ch - - push ebp - mov ebp, esp - mov eax, [ebp+pStruct1C] - sub esp, 0Ch - push ebx - push esi - mov esi, [eax+TMndxFindResult.pStruct40] - push edi - mov edi, ecx - mov ecx, [ebp+arg_4] - -loc_1958D84: ; CODE XREF: sub_1958D70+10Fj - ; sub_1958D70+28Fj - mov eax, [edi+TFileNameDatabase.NameFragIndexMask] - and eax, ecx - lea ebx, [eax+eax*2] - mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray] - add ebx, ebx - add ebx, ebx - mov [ebp+var_C], ebx - cmp ecx, [eax+ebx+4] - jnz loc_1958E8E - mov edx, [eax+ebx+8] - mov ecx, edx - and ecx, 0FFFFFF00h - cmp ecx, 0FFFFFF00h - jz short loc_1958DE7 - mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase] - push edx - test ecx, ecx - jz short loc_1958DD3 - mov edx, [ebp+pStruct1C] - push edx - call sub_1958D70 - jmp loc_1958E71 -; --------------------------------------------------------------------------- - -loc_1958DD3: ; CODE XREF: sub_1958D70+53j - mov eax, [ebp+pStruct1C] - push eax - lea ecx, [edi+TFileNameDatabase.IndexStruct_174] - call CopyNameFragment - jmp loc_1958E71 -; --------------------------------------------------------------------------- - -loc_1958DE7: ; CODE XREF: sub_1958D70+48j - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - mov byte ptr [ebp+arg_4+3], dl - cmp eax, ecx - jbe short loc_1958E61 - mov [ebp+var_8], eax - shr eax, 1 - cmp ecx, eax - jbe short loc_1958E15 - cmp ecx, 7FFFFFFFh - jbe short loc_1958E0F - mov [ebp+var_8], 0FFFFFFFFh - jmp short loc_1958E15 -; --------------------------------------------------------------------------- - -loc_1958E0F: ; CODE XREF: sub_1958D70+94j - lea edx, [ecx+ecx] - mov [ebp+var_8], edx - -loc_1958E15: ; CODE XREF: sub_1958D70+8Cj - ; sub_1958D70+9Dj - mov eax, [ebp+var_8] - push offset unk_53ABE00 - push eax - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_1958E48 - lea ecx, [ecx+0] - -loc_1958E30: ; CODE XREF: sub_1958D70+D6j - lea edx, [ecx+eax] - test edx, edx - jz short loc_1958E42 - mov ebx, [esi+4] - mov bl, [ecx+ebx] - mov [edx], bl - mov ebx, [ebp+var_C] - -loc_1958E42: ; CODE XREF: sub_1958D70+C5j - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_1958E30 - -loc_1958E48: ; CODE XREF: sub_1958D70+BBj - mov ecx, [esi] - mov edx, [ebp+var_8] - push ecx - mov [esi+TStruct40.array_00.DataBuffer], eax - mov [esi+TStruct40.array_00.field_4], eax - mov [esi+TStruct40.array_00.ItemArray], eax - mov [esi+TStruct40.array_00.MaxItemCount], edx - call operator_delete - add esp, 4 - -loc_1958E61: ; CODE XREF: sub_1958D70+83j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_1958E6E - mov cl, byte ptr [ebp+arg_4+3] - mov [eax], cl - -loc_1958E6E: ; CODE XREF: sub_1958D70+F7j - inc [esi+TStruct40.array_00.ItemCount] - -loc_1958E71: ; CODE XREF: sub_1958D70+5Ej - ; sub_1958D70+72j - mov edx, [edi+TFileNameDatabase.NameFragTable.ItemArray] - mov ecx, [ebx+edx] - mov [ebp+arg_4], ecx - test ecx, ecx - jnz loc_1958D84 - -loc_1958E85: ; CODE XREF: sub_1958D70+277j - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_1958E8E: ; CODE XREF: sub_1958D70+30j - mov edx, [edi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray] - mov eax, ecx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr eax, 5 - test [edx+eax*4], ebx - mov eax, [ebp+arg_4] - jz loc_1958F50 - mov ebx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - push eax - lea ecx, [edi+TFileNameDatabase.Struct68_D0] - add ebx, eax - call TSparseArray__GetItemValue - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - imul ecx, eax - mov eax, ecx - and ecx, 1Fh - mov edx, ecx - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - add ecx, edx - shr eax, 5 - cmp ecx, 20h - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.ItemArray] - ja short loc_1958EF2 - mov eax, [ecx+eax*4] - mov ecx, edx - shr eax, cl - jmp short loc_1958F15 -; --------------------------------------------------------------------------- - -loc_1958EF2: ; CODE XREF: sub_1958D70+177j - lea eax, [ecx+eax*4] - mov [ebp+var_C], eax - mov eax, [eax+4] - mov ecx, 20h - sub ecx, edx - shl eax, cl - mov ecx, [ebp+var_C] - mov ecx, [ecx] - mov [ebp+var_C], ecx - mov ecx, edx - mov edx, [ebp+var_C] - shr edx, cl - or eax, edx - -loc_1958F15: ; CODE XREF: sub_1958D70+180j - and eax, [edi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask] - movzx edx, byte ptr [ebx] - mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase] - shl eax, 8 - or eax, edx - push eax - test ecx, ecx - jz short loc_1958F3C - mov eax, [ebp+pStruct1C] - push eax - call sub_1958D70 - jmp loc_1958FDE -; --------------------------------------------------------------------------- - -loc_1958F3C: ; CODE XREF: sub_1958D70+1BCj - mov ecx, [ebp+pStruct1C] - push ecx - lea ecx, [edi+TFileNameDatabase.IndexStruct_174] - call CopyNameFragment - jmp loc_1958FDE -; --------------------------------------------------------------------------- - -loc_1958F50: ; CODE XREF: sub_1958D70+139j - mov edx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov cl, [eax+edx] - mov eax, [esi+TStruct40.array_00.ItemCount] - mov [ebp+var_1], cl - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_1958FCE - mov ebx, eax - shr eax, 1 - mov [ebp+var_8], ebx - cmp ecx, eax - jbe short loc_1958F85 - cmp ecx, 7FFFFFFFh - jbe short loc_1958F7F - or ebx, 0FFFFFFFFh - jmp short loc_1958F82 -; --------------------------------------------------------------------------- - -loc_1958F7F: ; CODE XREF: sub_1958D70+208j - lea ebx, [ecx+ecx] - -loc_1958F82: ; CODE XREF: sub_1958D70+20Dj - mov [ebp+var_8], ebx - -loc_1958F85: ; CODE XREF: sub_1958D70+200j - push offset unk_53ABE00 - push ebx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_1958FB8 - lea ebx, [ebx+0] - -loc_1958FA0: ; CODE XREF: sub_1958D70+243j - lea edx, [ecx+eax] - test edx, edx - jz short loc_1958FAF - mov ebx, [esi+TStruct40.array_00.field_4] - mov bl, [ecx+ebx] - mov [edx], bl - -loc_1958FAF: ; CODE XREF: sub_1958D70+235j - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_1958FA0 - mov ebx, [ebp+var_8] - -loc_1958FB8: ; CODE XREF: sub_1958D70+228j - mov ecx, [esi+TStruct40.array_00.DataBuffer] - push ecx - mov [esi+TStruct40.array_00.DataBuffer], eax - mov [esi+TStruct40.array_00.field_4], eax - mov [esi+TStruct40.array_00.ItemArray], eax - mov [esi+TStruct40.array_00.MaxItemCount], ebx - call operator_delete - add esp, 4 - -loc_1958FCE: ; CODE XREF: sub_1958D70+1F5j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_1958FDB - mov dl, [ebp+var_1] - mov [eax], dl - -loc_1958FDB: ; CODE XREF: sub_1958D70+264j - inc [esi+TStruct40.array_00.ItemCount] - -loc_1958FDE: ; CODE XREF: sub_1958D70+1C7j - ; sub_1958D70+1DBj - mov ebx, [ebp+arg_4] - cmp ebx, [edi+TFileNameDatabase.field_214] - jbe loc_1958E85 - push ebx - mov ecx, edi - call sub_1959F50 - or ecx, 0FFFFFFFFh - sub ecx, ebx - add ecx, eax - mov [ebp+arg_4], ecx - jmp loc_1958D84 -sub_1958D70 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TFileNameDatabase__sub_1959CB0 proc near ; CODE XREF: TFileNameDatabase__CheckNextPathFragment+A1p - ; TFileNameDatabase__sub_1958B00+E8p - -pThis = dword ptr -4 -dwKey = dword ptr 8 - - push ebp - mov ebp, esp - push ecx - mov edx, [ebp+dwKey] - mov eax, edx - shr eax, 9 - mov [ebp+pThis], ecx - test edx, 1FFh ; if(dwKey & 0x01FF) - jnz short loc_1959CD3 - mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayDwords_38.ItemArray] - mov eax, [ecx+eax*4] ; EAX = pDatabase->NextKeyTable[dwKey >> 0x09] - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1959CD3: ; CODE XREF: TFileNameDatabase__sub_1959CB0+15j - push ebx - push esi - mov esi, [ecx+TFileNameDatabase.Struct68_00.ArrayDwords_38.ItemArray] - lea esi, [esi+eax*4] - mov eax, [esi] - mov esi, [esi+4] - shr eax, 9 - add esi, 1FFh - push edi - shr esi, 9 - lea edi, [eax+0Ah] - mov [ebp+dwKey], esi - cmp edi, esi - jb short loc_1959D2E - mov edi, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray] - lea esi, [eax+eax*2+3] - lea esi, [edi+esi*4] - mov edi, eax - shl edi, 9 - mov ebx, edi - sub ebx, [esi] - add ebx, 200h - cmp edx, ebx - jb short loc_1959D5F - -loc_1959D14: ; CODE XREF: TFileNameDatabase__sub_1959CB0+7Aj - add edi, 200h - add esi, 0Ch - mov ebx, edi - sub ebx, [esi] - inc eax - add ebx, 200h - cmp edx, ebx - jnb short loc_1959D14 - jmp short loc_1959D5F -; --------------------------------------------------------------------------- - -loc_1959D2E: ; CODE XREF: TFileNameDatabase__sub_1959CB0+45j - lea edi, [eax+1] - cmp edi, esi - jnb short loc_1959D5F - mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray] - -loc_1959D38: ; CODE XREF: TFileNameDatabase__sub_1959CB0+AAj - add esi, eax - shr esi, 1 - mov ebx, esi - shl ebx, 9 - lea edi, [esi+esi*2] - sub ebx, [ecx+edi*4] - cmp edx, ebx - jnb short loc_1959D50 - mov [ebp+dwKey], esi - jmp short loc_1959D55 -; --------------------------------------------------------------------------- - -loc_1959D50: ; CODE XREF: TFileNameDatabase__sub_1959CB0+99j - mov eax, esi - mov esi, [ebp+dwKey] - -loc_1959D55: ; CODE XREF: TFileNameDatabase__sub_1959CB0+9Ej - lea edi, [eax+1] - cmp edi, esi - jb short loc_1959D38 - mov ecx, [ebp+pThis] - -loc_1959D5F: ; CODE XREF: TFileNameDatabase__sub_1959CB0+62j - ; TFileNameDatabase__sub_1959CB0+7Cj - mov ecx, [ecx+TFileNameDatabase.Struct68_00.ArrayTriplets_20.ItemArray] - lea esi, [eax+eax*2] - mov edi, [ecx+esi*4] ; EDI = Struct68_00.ArrayTriplets_20.ItemArray[eax] - lea esi, [ecx+esi*4] ; ESI = Struct68_00.ArrayTriplets_20.ItemArray + eax - mov ecx, eax - shl ecx, 9 - sub edi, ecx - shl eax, 4 - add edx, edi - mov edi, eax - mov eax, [esi+TRIPLET.NextKey] - mov ecx, eax - shr ecx, 17h - mov ebx, 100h - sub ebx, ecx - cmp edx, ebx - jnb short loc_1959DE8 - mov ecx, eax - shr ecx, 7 - and ecx, 0FFh - mov esi, 80h - sub esi, ecx - cmp edx, esi - jnb short loc_1959DC0 - and eax, 7Fh - mov ecx, 40h - sub ecx, eax - cmp edx, ecx - jb loc_1959E53 - add edi, 2 - lea edx, [edx+eax-40h] - jmp loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DC0: ; CODE XREF: TFileNameDatabase__sub_1959CB0+F0j - shr eax, 0Fh - and eax, 0FFh - mov esi, 0C0h - sub esi, eax - cmp edx, esi - jnb short loc_1959DDC - add edi, 4 - lea edx, [edx+ecx-80h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DDC: ; CODE XREF: TFileNameDatabase__sub_1959CB0+121j - add edi, 6 - lea edx, [edx+eax-0C0h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959DE8: ; CODE XREF: TFileNameDatabase__sub_1959CB0+DAj - mov esi, [esi+TRIPLET.Distance] - mov eax, esi - shr eax, 9 - and eax, 1FFh - mov ebx, 180h - sub ebx, eax - cmp edx, ebx - jnb short loc_1959E29 - and esi, 1FFh - mov eax, 140h - sub eax, esi - cmp edx, eax - jnb short loc_1959E1D - add edi, 8 - lea edx, [edx+ecx-100h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E1D: ; CODE XREF: TFileNameDatabase__sub_1959CB0+15Fj - add edi, 0Ah - lea edx, [edx+esi-140h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E29: ; CODE XREF: TFileNameDatabase__sub_1959CB0+14Ej - shr esi, 12h - and esi, 1FFh - mov ecx, 1C0h - sub ecx, esi - cmp edx, ecx - jnb short loc_1959E49 - add edi, 0Ch - lea edx, [edx+eax-180h] - jmp short loc_1959E53 -; --------------------------------------------------------------------------- - -loc_1959E49: ; CODE XREF: TFileNameDatabase__sub_1959CB0+18Bj - add edi, 0Eh - lea edx, [edx+esi-1C0h] - -loc_1959E53: ; CODE XREF: TFileNameDatabase__sub_1959CB0+FEj - ; TFileNameDatabase__sub_1959CB0+10Bj - mov eax, [ebp+pThis] - mov ebx, [eax+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - mov ecx, [ebx+edi*4] - not ecx - mov eax, ecx - shr eax, 1 - and eax, 55555555h - mov esi, ecx - and esi, 55555555h - add eax, esi - mov esi, eax - shr esi, 2 - and eax, 33333333h - and esi, 33333333h - add esi, eax - mov eax, esi - shr eax, 4 - and esi, 0F0F0F0Fh - and eax, 0F0F0F0Fh - add eax, esi - imul eax, 1010101h - mov esi, eax - shr esi, 18h - cmp edx, esi - jb short loc_1959EEA - mov ecx, [ebx+edi*4+4] - inc edi - sub edx, esi - not ecx - mov eax, ecx - shr eax, 1 - and eax, 55555555h - mov esi, ecx - and esi, 55555555h - add eax, esi - mov esi, eax - shr esi, 2 - and eax, 33333333h - and esi, 33333333h - add esi, eax - mov eax, esi - shr eax, 4 - and eax, 0F0F0F0Fh - and esi, 0F0F0F0Fh - add eax, esi - imul eax, 1010101h - -loc_1959EEA: ; CODE XREF: TFileNameDatabase__sub_1959CB0+1F2j - mov esi, eax - shr esi, 8 - and esi, 0FFh - shl edi, 5 - cmp edx, esi - jnb short loc_1959F0D - and eax, 0FFh - cmp edx, eax - jb short loc_1959F2B - add edi, 8 - shr ecx, 8 - jmp short loc_1959F29 -; --------------------------------------------------------------------------- - -loc_1959F0D: ; CODE XREF: TFileNameDatabase__sub_1959CB0+24Aj - shr eax, 10h - and eax, 0FFh - cmp edx, eax - jnb short loc_1959F23 - add edi, 10h - shr ecx, 10h - sub edx, esi - jmp short loc_1959F2B -; --------------------------------------------------------------------------- - -loc_1959F23: ; CODE XREF: TFileNameDatabase__sub_1959CB0+267j - add edi, 18h - shr ecx, 18h - -loc_1959F29: ; CODE XREF: TFileNameDatabase__sub_1959CB0+25Bj - sub edx, eax - -loc_1959F2B: ; CODE XREF: TFileNameDatabase__sub_1959CB0+253j - ; TFileNameDatabase__sub_1959CB0+271j - and ecx, 0FFh - shl edx, 8 - movzx eax, ds:table_1BA1818[ecx+edx] - add eax, edi - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 4 -TFileNameDatabase__sub_1959CB0 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TNameIndexStruct__CheckAndCopyNameFragment proc near ; CODE XREF: TArchiveDatabase__sub_1958B00+74p - ; TArchiveDatabase__sub_1958B00+1E0p - -var_C = dword ptr -0Ch -pThis = dword ptr -8 -var_4 = dword ptr -4 -pStruct1C = dword ptr 8 -dwDistance = dword ptr 0Ch - - push ebp - mov ebp, esp - sub esp, 0Ch - mov eax, [ebp+pStruct1C] - push ebx - mov edx, ecx - cmp [edx+TNameIndexStruct.Struct68.TotalItemCount], 0 - push esi - mov esi, [eax+TMndxFindResult.pStruct40] - push edi - mov [ebp+pThis], edx - jnz loc_195A6B7 - mov edi, [edx+TNameIndexStruct.NameFragments.ItemArray] - sub edi, [esi+TStruct40.CharIndex] - add edi, [ebp+dwDistance] - mov [ebp+pThis], edi - lea ebx, [ebx+0] - -loc_195A5A0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+E6j - mov edx, [esi+TStruct40.CharIndex] - mov ecx, [ebp+pStruct1C] - mov eax, [ecx+TMndxFindResult.szSearchMask] - mov cl, [edx+edi] - mov [ebp+dwDistance], edx - cmp cl, [edx+eax] - jnz loc_195A67D - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - mov ebx, 1 - add eax, ebx - cmp eax, ecx - jbe short loc_195A62D - mov ebx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A5E0 - cmp ecx, 7FFFFFFFh - jbe short loc_195A5DD - or ebx, 0FFFFFFFFh - jmp short loc_195A5E0 -; --------------------------------------------------------------------------- - -loc_195A5DD: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+66j - lea ebx, [ecx+ecx] - -loc_195A5E0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+5Ej - ; TNameIndexStruct__CheckAndCopyNameFragment+6Bj - push offset unk_53ABE00 - push ebx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - mov edi, eax - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_195A60C - -loc_195A5F7: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+9Aj - lea edx, [ecx+edi] - test edx, edx - jz short loc_195A606 - mov eax, [esi+TStruct40.array_00.field_4] - mov al, [ecx+eax] - mov [edx], al - -loc_195A606: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+8Cj - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_195A5F7 - -loc_195A60C: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+85j - mov eax, [esi+TStruct40.array_00.DataBuffer] - push eax - mov [esi+TStruct40.array_00.DataBuffer], edi - mov [esi+TStruct40.array_00.field_4], edi - mov [esi+TStruct40.array_00.ItemArray], edi - mov [esi+TStruct40.array_00.MaxItemCount], ebx - call operator_delete - mov edx, [ebp+dwDistance] - mov edi, [ebp+pThis] - add esp, 4 - mov ebx, 1 - -loc_195A62D: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+56j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_195A63A - mov cl, [edx+edi] - mov [eax], cl - -loc_195A63A: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+C3j - add [esi+TStruct40.CharIndex], ebx - add [esi+TStruct40.array_00.ItemCount], ebx - mov ecx, [esi+TStruct40.CharIndex] - cmp byte ptr [ecx+edi], 0 - mov eax, [esi+TStruct40.array_00.ItemCount] - jz loc_195A806 - mov edx, [ebp+pStruct1C] - cmp ecx, [edx+TMndxFindResult.cchSearchMask] - jb loc_195A5A0 - add edi, ecx - mov edi, edi - -loc_195A660: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+13Aj - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_195A693 - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A68B - cmp ecx, 7FFFFFFFh - jbe short loc_195A688 - or edx, 0FFFFFFFFh - jmp short loc_195A68B -; --------------------------------------------------------------------------- - -loc_195A67D: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+41j - ; TNameIndexStruct__CheckAndCopyNameFragment+16Bj - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_195A688: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+106j - lea edx, [ecx+ecx] - -loc_195A68B: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+FEj - ; TNameIndexStruct__CheckAndCopyNameFragment+10Bj - push edx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_195A693: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+F6j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_195A69F - mov cl, [edi] - mov [eax], cl - -loc_195A69F: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+129j - add [esi+TStruct40.array_00.ItemCount], ebx - mov eax, [esi+TStruct40.array_00.ItemCount] - add edi, ebx - cmp byte ptr [edi], 0 - jnz short loc_195A660 - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_195A6B7: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+18j - mov ebx, [ebp+dwDistance] - lea ebx, [ebx+0] - -loc_195A6C0: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+231j - mov edi, [edx+TNameIndexStruct.NameFragments.ItemArray] - mov eax, [ebp+pStruct1C] - mov ecx, [esi+TStruct40.CharIndex] - mov eax, [eax] - add edi, ebx - mov [ebp+var_4], edx - mov dl, [edi] - cmp dl, [ecx+eax] - mov edx, [ebp+var_4] - mov [ebp+var_C], edi - jnz short loc_195A67D - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_195A752 - mov [ebp+var_4], eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A707 - cmp ecx, 7FFFFFFFh - jbe short loc_195A702 - mov [ebp+var_4], 0FFFFFFFFh - jmp short loc_195A707 -; --------------------------------------------------------------------------- - -loc_195A702: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+187j - add ecx, ecx - mov [ebp+var_4], ecx - -loc_195A707: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+17Fj - ; TNameIndexStruct__CheckAndCopyNameFragment+190j - mov edx, [ebp+var_4] - push offset unk_53ABE00 - push edx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - mov edi, eax - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_195A736 - -loc_195A721: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1C4j - lea edx, [ecx+edi] - test edx, edx - jz short loc_195A730 - mov eax, [esi+TStruct40.array_00.field_4] - mov al, [ecx+eax] - mov [edx], al - -loc_195A730: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1B6j - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_195A721 - -loc_195A736: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1AFj - mov eax, [esi+TStruct40.array_00.DataBuffer] - mov ecx, [ebp+var_4] - push eax - mov [esi+TStruct40.array_00.DataBuffer], edi - mov [esi+TStruct40.array_00.field_4], edi - mov [esi+TStruct40.array_00.ItemArray], edi - mov [esi+TStruct40.array_00.MaxItemCount], ecx - call operator_delete - mov edx, [ebp+pThis] - add esp, 4 - -loc_195A752: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+176j - mov edi, [esi+TStruct40.array_00.field_4] - add edi, [esi+TStruct40.array_00.ItemCount] - jz short loc_195A761 - mov eax, [ebp+var_C] - mov cl, [eax] - mov [edi], cl - -loc_195A761: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+1E8j - mov ecx, 1 - add [esi+TStruct40.array_00.ItemCount], ecx - add [esi+TStruct40.CharIndex], ecx - mov edx, [edx+20h] - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, ebx - mov edi, ebx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr edi, 5 - mov ecx, [edx+edi*4] - and ecx, ebx - mov ebx, [ebp+dwDistance] - inc ebx - mov [ebp+dwDistance], ebx - test ecx, ecx - jnz short loc_195A806 - mov ecx, [esi+TStruct40.CharIndex] - mov edx, [ebp+pStruct1C] - cmp ecx, [edx+4] - jnb short loc_195A7A6 - mov edx, [ebp+pThis] - jmp loc_195A6C0 -; --------------------------------------------------------------------------- - -loc_195A7A6: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+22Cj - ; TNameIndexStruct__CheckAndCopyNameFragment+294j - mov ecx, [ebp+pThis] - mov edi, [ecx+8] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_195A7D4 - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_195A7CC - cmp ecx, 7FFFFFFFh - jbe short loc_195A7C9 - or edx, 0FFFFFFFFh - jmp short loc_195A7CC -; --------------------------------------------------------------------------- - -loc_195A7C9: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+252j - lea edx, [ecx+ecx] - -loc_195A7CC: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+24Aj - ; TNameIndexStruct__CheckAndCopyNameFragment+257j - push edx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_195A7D4: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+242j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_195A7E1 - mov dl, [edi+ebx] - mov [eax], dl - -loc_195A7E1: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+26Aj - inc [esi+TStruct40.array_00.ItemCount] - mov edi, [ebp+pThis] - mov edi, [edi+20h] - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, ebx - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, ebx - shr ecx, 5 - inc ebx - and edx, [edi+ecx*4] - test edx, edx - jz short loc_195A7A6 - -loc_195A806: ; CODE XREF: TNameIndexStruct__CheckAndCopyNameFragment+DAj - ; TNameIndexStruct__CheckAndCopyNameFragment+221j - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 8 -TNameIndexStruct__CheckAndCopyNameFragment endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1959010 proc near ; CODE XREF: TArchiveDatabase__sub_1958B00+67p - ; TArchiveDatabase__sub_1958B00+1CFp - -pFragmentInfo = dword ptr -0Ch -var_8 = dword ptr -8 -var_1 = byte ptr -1 -pStruct1C = dword ptr 8 -arg_4 = dword ptr 0Ch - - push ebp - mov ebp, esp - mov eax, [ebp+pStruct1C] - sub esp, 0Ch - push ebx - push esi - mov esi, [eax+TMndxFindResult.pStruct40] - push edi - mov edi, ecx - mov ecx, [ebp+arg_4] - -loc_1959024: ; CODE XREF: sub_1959010+2CEj - mov eax, [edi+TFileNameDatabase.NameFragIndexMask] - and eax, ecx - lea ebx, [eax+eax*2] - mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray] - add ebx, ebx - add ebx, ebx - add eax, ebx - mov [ebp+pFragmentInfo], ebx - cmp ecx, [eax+NAME_ENTRY.NextHashModifier] - jnz loc_1959147 - mov edx, [eax+NAME_ENTRY.FragmentOffset] - mov ecx, edx - and ecx, 0FFFFFF00h - cmp ecx, 0FFFFFF00h - jz short loc_1959092 - mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase] - push edx - test ecx, ecx - jz short loc_1959070 - mov edx, [ebp+pStruct1C] - push edx - call sub_1959010 - jmp short loc_195907F -; --------------------------------------------------------------------------- - -loc_1959070: ; CODE XREF: sub_1959010+53j - mov eax, [ebp+pStruct1C] - push eax - lea ecx, [edi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckAndCopyNameFragment - -loc_195907F: ; CODE XREF: sub_1959010+5Ej - test al, al - jnz loc_195912E - -loc_1959087: ; CODE XREF: sub_1959010+90j - ; sub_1959010+1F3j - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 8 -; --------------------------------------------------------------------------- - -loc_1959092: ; CODE XREF: sub_1959010+48j - mov ecx, [ebp+pStruct1C] - mov eax, [ecx+TMndxFindResult.szSearchMask] - mov ecx, [esi+TStruct40.CharIndex] - mov byte ptr [ebp+arg_4+3], dl - cmp dl, [eax+ecx] - jnz short loc_1959087 - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_1959119 - mov [ebp+var_8], eax - shr eax, 1 - cmp ecx, eax - jbe short loc_19590CD - cmp ecx, 7FFFFFFFh - jbe short loc_19590C7 - mov [ebp+var_8], 0FFFFFFFFh - jmp short loc_19590CD -; --------------------------------------------------------------------------- - -loc_19590C7: ; CODE XREF: sub_1959010+ACj - lea edx, [ecx+ecx] - mov [ebp+var_8], edx - -loc_19590CD: ; CODE XREF: sub_1959010+A4j - ; sub_1959010+B5j - mov eax, [ebp+var_8] - push offset unk_53ABE00 - push eax - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_19590FD - -loc_19590E5: ; CODE XREF: sub_1959010+EBj - lea edx, [ecx+eax] - test edx, edx - jz short loc_19590F7 - mov ebx, [esi+TStruct40.array_00.field_4] - mov bl, [ecx+ebx] - mov [edx], bl - mov ebx, [ebp+pFragmentInfo] - -loc_19590F7: ; CODE XREF: sub_1959010+DAj - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_19590E5 - -loc_19590FD: ; CODE XREF: sub_1959010+D3j - mov ecx, [esi+TStruct40.array_00.DataBuffer] - mov edx, [ebp+var_8] - push ecx - mov [esi+TStruct40.array_00.DataBuffer], eax - mov [esi+TStruct40.array_00.field_4], eax - mov [esi+TStruct40.array_00.ItemArray], eax - mov [esi+TStruct40.array_00.MaxItemCount], edx - call operator_delete - mov dl, byte ptr [ebp+arg_4+3] - add esp, 4 - -loc_1959119: ; CODE XREF: sub_1959010+9Bj - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_1959123 - mov [eax], dl - -loc_1959123: ; CODE XREF: sub_1959010+10Fj - mov eax, 1 - add [esi+TStruct40.array_00.ItemCount], eax - add [esi+TStruct40.CharIndex], eax - -loc_195912E: ; CODE XREF: sub_1959010+71j - mov eax, [edi+TFileNameDatabase.NameFragTable.ItemArray] - mov ecx, [ebx+eax] - mov [ebp+arg_4], ecx - test ecx, ecx - jz loc_19592ED - jmp loc_19592D5 -; --------------------------------------------------------------------------- - -loc_1959147: ; CODE XREF: sub_1959010+31j - mov eax, [edi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray] - mov edx, ecx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr edx, 5 - test [eax+edx*4], ebx - mov eax, [ebp+arg_4] - jz loc_195920E - mov ebx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - push eax - lea ecx, [edi+TFileNameDatabase.Struct68_D0] - add ebx, eax - call TSparseArray__GetItemValue - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - imul ecx, eax - mov eax, ecx - and ecx, 1Fh - mov edx, ecx - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - add ecx, edx - shr eax, 5 - cmp ecx, 20h - mov ecx, [edi+TFileNameDatabase.FrgmDist_HiBits.ItemArray] - ja short loc_19591AB - mov eax, [ecx+eax*4] - mov ecx, edx - shr eax, cl - jmp short loc_19591CE -; --------------------------------------------------------------------------- - -loc_19591AB: ; CODE XREF: sub_1959010+190j - lea eax, [ecx+eax*4] - mov [ebp+pFragmentInfo], eax - mov eax, [eax+4] - mov ecx, 20h - sub ecx, edx - shl eax, cl - mov ecx, [ebp+pFragmentInfo] - mov ecx, [ecx] - mov [ebp+pFragmentInfo], ecx - mov ecx, edx - mov edx, [ebp+pFragmentInfo] - shr edx, cl - or eax, edx - -loc_19591CE: ; CODE XREF: sub_1959010+199j - and eax, [edi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask] - movzx edx, byte ptr [ebx] - mov ecx, [edi+TFileNameDatabase.NextDB.pDatabase] - shl eax, 8 - or eax, edx - push eax - test ecx, ecx - jz short loc_19591F2 - mov eax, [ebp+pStruct1C] - push eax - call sub_1959010 - jmp short loc_1959201 -; --------------------------------------------------------------------------- - -loc_19591F2: ; CODE XREF: sub_1959010+1D5j - mov ecx, [ebp+pStruct1C] - push ecx - lea ecx, [edi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckAndCopyNameFragment - -loc_1959201: ; CODE XREF: sub_1959010+1E0j - test al, al - jz loc_1959087 - jmp loc_19592B6 -; --------------------------------------------------------------------------- - -loc_195920E: ; CODE XREF: sub_1959010+152j - mov edx, [edi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov dl, [eax+edx] - mov ecx, [ebp+pStruct1C] - mov eax, [ecx+TMndxFindResult.szSearchMask] - mov ecx, [esi+TStruct40.CharIndex] - mov [ebp+var_1], dl - cmp dl, [eax+ecx] - jnz loc_1959087 - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_19592A1 - mov ebx, eax - shr eax, 1 - mov [ebp+var_8], ebx - cmp ecx, eax - jbe short loc_1959254 - cmp ecx, 7FFFFFFFh - jbe short loc_195924E - or ebx, 0FFFFFFFFh - jmp short loc_1959251 -; --------------------------------------------------------------------------- - -loc_195924E: ; CODE XREF: sub_1959010+237j - lea ebx, [ecx+ecx] - -loc_1959251: ; CODE XREF: sub_1959010+23Cj - mov [ebp+var_8], ebx - -loc_1959254: ; CODE XREF: sub_1959010+22Fj - push offset unk_53ABE00 - push ebx - call j_operator_new_safe - xor ecx, ecx - add esp, 8 - cmp [esi+TStruct40.array_00.ItemCount], ecx - jbe short loc_1959288 - lea esp, [esp+0] - -loc_1959270: ; CODE XREF: sub_1959010+273j - lea edx, [ecx+eax] - test edx, edx - jz short loc_195927F - mov ebx, [esi+TStruct40.array_00.field_4] - mov bl, [ecx+ebx] - mov [edx], bl - -loc_195927F: ; CODE XREF: sub_1959010+265j - inc ecx - cmp ecx, [esi+TStruct40.array_00.ItemCount] - jb short loc_1959270 - mov ebx, [ebp+var_8] - -loc_1959288: ; CODE XREF: sub_1959010+257j - mov ecx, [esi+TStruct40.array_00.DataBuffer] - push ecx - mov [esi+TStruct40.array_00.DataBuffer], eax - mov [esi+TStruct40.array_00.field_4], eax - mov [esi+TStruct40.array_00.ItemArray], eax - mov [esi+TStruct40.array_00.MaxItemCount], ebx - call operator_delete - mov dl, [ebp+var_1] - add esp, 4 - -loc_19592A1: ; CODE XREF: sub_1959010+224j - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_19592AB - mov [eax], dl - -loc_19592AB: ; CODE XREF: sub_1959010+297j - mov eax, 1 - add [esi+TStruct40.array_00.ItemCount], eax - add [esi+TStruct40.CharIndex], eax - -loc_19592B6: ; CODE XREF: sub_1959010+1F9j - mov ebx, [ebp+arg_4] - cmp ebx, [edi+TFileNameDatabase.field_214] - jbe short loc_19592ED - push ebx - mov ecx, edi - call sub_1959F50 - or edx, 0FFFFFFFFh - sub edx, ebx - add eax, edx - mov ecx, eax - mov [ebp+arg_4], eax - -loc_19592D5: ; CODE XREF: sub_1959010+132j - mov edx, [esi+TStruct40.CharIndex] - mov eax, [ebp+pStruct1C] - cmp edx, [eax+TMndxFindResult.cchSearchMask] - jb loc_1959024 - push ecx - push eax - mov ecx, edi - call sub_1958D70 - -loc_19592ED: ; CODE XREF: sub_1959010+12Cj - ; sub_1959010+2AFj - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 8 -sub_1959010 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_19582E0 proc near ; CODE XREF: TFileNameDatabase__sub_1958B00+253p - -arg_0 = dword ptr 8 - - push ebp - mov ebp, esp - push esi - mov esi, ecx - mov eax, [esi+0Ch] - mov ecx, [esi+10h] - inc eax - cmp eax, ecx - jbe short loc_1958311 - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_1958309 - cmp ecx, 7FFFFFFFh - jbe short loc_1958306 - or edx, 0FFFFFFFFh - jmp short loc_1958309 -; --------------------------------------------------------------------------- - -loc_1958306: ; CODE XREF: sub_19582E0+1Fj - lea edx, [ecx+ecx] - -loc_1958309: ; CODE XREF: sub_19582E0+17j - ; sub_19582E0+24j - push edx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_1958311: ; CODE XREF: sub_19582E0+Fj - mov eax, [esi+4] - add eax, [esi+0Ch] - jz short loc_1958320 - mov ecx, [ebp+arg_0] - mov dl, [ecx] - mov [eax], dl - -loc_1958320: ; CODE XREF: sub_19582E0+37j - inc dword ptr [esi+0Ch] - pop esi - pop ebp - retn 4 -sub_19582E0 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TFileNameDatabase__sub_1958B00 proc near ; CODE XREF: TFileNameDatabase__sub_1959460+3Bp - -var_C = dword ptr -0Ch -ItemArrayOffset = dword ptr -8 -var_4 = dword ptr -4 -arg_0 = dword ptr 8 - - push ebp - mov ebp, esp - sub esp, 0Ch - mov edx, [ebp+pStruct1C] - push ebx - mov ebx, [edx+TMndxFindResult.szSearchMask] - push esi - push edi - mov edi, [edx+TMndxFindResult.pStruct40] - mov eax, [edi+TStruct40.CharIndex] - movzx eax, byte ptr [eax+ebx] - mov esi, ecx - mov ecx, [edi+TStruct40.HashValue] - mov ebx, ecx - shl ebx, 5 - xor eax, ebx - mov ebx, [esi+TFileNameDatabase.NameFragTable.ItemArray] - xor eax, ecx - and eax, [esi+TFileNameDatabase.NameFragIndexMask] - lea eax, [eax+eax*2] - add eax, eax - add eax, eax - mov [ebp+ItemArrayOffset], eax - cmp ecx, [eax+ebx] - jnz loc_1958BE5 - mov ecx, [eax+ebx+NAME_ENTRY.FragmentOffset] - mov ebx, ecx - and ebx, 0FFFFFF00h - cmp ebx, 0FFFFFF00h - jz short loc_1958B88 - mov eax, [esi+TFileNameDatabase.NextDB.pDatabase] - push ecx - push edx - test eax, eax - jz short loc_1958B6E - mov ecx, eax - call sub_1959010 - jmp short loc_1958B79 -; --------------------------------------------------------------------------- - -loc_1958B6E: ; CODE XREF: TArchiveDatabase__sub_1958B00+63j - lea ecx, [esi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckAndCopyNameFragment - -loc_1958B79: ; CODE XREF: TArchiveDatabase__sub_1958B00+6Cj - test al, al - jnz short loc_1958BCA - -loc_1958B7D: ; CODE XREF: TArchiveDatabase__sub_1958B00+108j - ; TArchiveDatabase__sub_1958B00+1F3j - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1958B88: ; CODE XREF: TArchiveDatabase__sub_1958B00+57j - mov eax, [edi+TStruct40.array_00.ItemCount] - mov bl, cl - mov ecx, [edi+TStruct40.array_00.MaxItemCount] - inc eax - cmp eax, ecx - jbe short loc_1958BB5 - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_1958BAD - cmp ecx, 7FFFFFFFh - jbe short loc_1958BAA - or edx, 0FFFFFFFFh - jmp short loc_1958BAD -; --------------------------------------------------------------------------- - -loc_1958BAA: ; CODE XREF: TArchiveDatabase__sub_1958B00+A3j - lea edx, [ecx+ecx] - -loc_1958BAD: ; CODE XREF: TArchiveDatabase__sub_1958B00+9Bj - ; TArchiveDatabase__sub_1958B00+A8j - push edx - mov ecx, edi - call TGenericArray__SetMaxItems_BYTE - -loc_1958BB5: ; CODE XREF: TArchiveDatabase__sub_1958B00+93j - mov eax, [edi+TStruct40.array_00.field_4] - add eax, [edi+TStruct40.array_00.ItemCount] - jz short loc_1958BBF - mov [eax], bl - -loc_1958BBF: ; CODE XREF: TArchiveDatabase__sub_1958B00+BBj - mov eax, 1 - add [edi+TStruct40.array_00.ItemCount], eax - add [edi+TStruct40.CharIndex], eax - -loc_1958BCA: ; CODE XREF: TArchiveDatabase__sub_1958B00+7Bj - mov ecx, [esi+TFileNameDatabase.NameFragTable.ItemArray] - mov edx, [ebp+ItemArrayOffset] - mov eax, [ecx+edx+NAME_ENTRY.NextHashModifier] - mov [edi+TStruct40.HashValue], eax - -loc_1958BDA: ; CODE XREF: TArchiveDatabase__sub_1958B00+1E7j - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1958BE5: ; CODE XREF: TArchiveDatabase__sub_1958B00+3Fj - push ecx - mov ecx, esi - call TArchiveDatabase__sub_1959CB0 - mov ebx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - inc eax - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, eax - shr ecx, 5 - mov [ebp+ItemArrayOffset], eax - test [ebx+ecx*4], edx - jz loc_1958B7D - sub eax, [edi+TStruct40.HashValue] - mov [ebp+var_4], 0FFFFFFFFh - dec eax - mov [edi+TStruct40.HashValue], eax - lea esp, [esp+0] - -loc_1958C20: ; CODE XREF: TArchiveDatabase__sub_1958B00+230j - mov eax, [edi+TStruct40.HashValue] - mov ebx, [esi+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray] - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, eax - shr ecx, 5 - test [ebx+ecx*4], edx - jz loc_1958CFB - mov ecx, [ebp+var_4] - cmp ecx, 0FFFFFFFFh - jnz short loc_1958C5E - push eax - lea ecx, [esi+TFileNameDatabase.Struct68_D0] - call TSparseArray__GetItemValue - mov ecx, eax - mov [ebp+var_4], eax - jmp short loc_1958C62 -; --------------------------------------------------------------------------- - -loc_1958C5E: ; CODE XREF: TArchiveDatabase__sub_1958B00+149j - inc ecx - mov [ebp+var_4], ecx - -loc_1958C62: ; CODE XREF: TArchiveDatabase__sub_1958B00+15Cj - mov edx, [edi+TStruct40.CharIndex] - mov [ebp+var_C], edx - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.BitsPerEntry] - mov eax, edx - imul eax, ecx - mov ecx, eax - and eax, 1Fh - add edx, eax - shr ecx, 5 - cmp edx, 20h - mov edx, [esi+TFileNameDatabase.FrgmDist_HiBits.ItemArray] - ja short loc_1958C91 - mov edx, [edx+ecx*4] - mov ecx, eax - shr edx, cl - jmp short loc_1958CA8 -; --------------------------------------------------------------------------- - -loc_1958C91: ; CODE XREF: TArchiveDatabase__sub_1958B00+186j - lea ebx, [edx+ecx*4] - mov edx, [ebx+4] - mov ebx, [ebx] - mov ecx, 20h - sub ecx, eax - shl edx, cl - mov ecx, eax - shr ebx, cl - or edx, ebx - -loc_1958CA8: ; CODE XREF: TArchiveDatabase__sub_1958B00+18Fj - mov ecx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - and edx, [esi+TFileNameDatabase.FrgmDist_HiBits.EntryBitMask] - mov eax, [edi+TStruct40.HashValue] - movzx eax, byte ptr [ecx+eax] - mov ecx, [esi+TFileNameDatabase.NextDB.pDatabase] - shl edx, 8 - or eax, edx - push eax - test ecx, ecx - jz short loc_1958CD6 - mov edx, [ebp+pStruct1C] - push edx - call sub_1959010 - jmp short loc_1958CE5 -; --------------------------------------------------------------------------- - -loc_1958CD6: ; CODE XREF: TArchiveDatabase__sub_1958B00+1C9j - mov eax, [ebp+pStruct1C] - push eax - lea ecx, [esi+TFileNameDatabase.IndexStruct_174] - call TNameIndexStruct__CheckAndCopyNameFragment - -loc_1958CE5: ; CODE XREF: TArchiveDatabase__sub_1958B00+1D4j - test al, al - jnz loc_1958BDA - mov ecx, [ebp+var_C] - cmp [edi+TStruct40.CharIndex], ecx - jnz loc_1958B7D - jmp short loc_1958D11 -; --------------------------------------------------------------------------- - -loc_1958CFB: ; CODE XREF: TArchiveDatabase__sub_1958B00+13Dj - mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov ebx, [ebp+pStruct1C] - mov ecx, [edi+TStruct40.CharIndex] - mov ebx, [ebx+TMndxFindResult.szSearchMask] - mov dl, [eax+edx] - cmp dl, [ecx+ebx] - jz short loc_1958D41 - -loc_1958D11: ; CODE XREF: TArchiveDatabase__sub_1958B00+1F9j - mov eax, [ebp+ItemArrayOffset] - inc [edi+TStruct40.HashValue] - inc eax - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, [esi+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - mov [ebp+ItemArrayOffset], eax - shr eax, 5 - test [ecx+eax*4], edx - jnz loc_1958C20 - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1958D41: ; CODE XREF: TArchiveDatabase__sub_1958B00+20Fj - mov edx, [esi+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov cl, [edx+eax] - lea edx, [ebp+pStruct1C+3] - mov byte ptr [ebp+pStruct1C+3], cl - push edx - mov ecx, edi - call sub_19582E0 - mov eax, 1 - add [edi+TStruct40.CharIndex], eax - pop edi - pop esi - pop ebx - mov esp, ebp - pop ebp - retn 4 -TFileNameDatabase__sub_1958B00 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -TFileNameDatabase__sub_1959460 proc near ; CODE XREF: TFileNameDatabasePtr__sub_1956CE0+2Dp - -Struct14 = dword ptr -20h -var_1C = dword ptr -1Ch -var_18 = dword ptr -18h -var_14 = dword ptr -14h -var_10 = dword ptr -10h -pStruct14 = dword ptr -0Ch -pThis = dword ptr -8 -OneChar = byte ptr -1 -pStruct1C = dword ptr 8 - - push ebp - mov ebp, esp - sub esp, 20h - push ebx - push esi - push edi - mov edi, [ebp+pStruct1C] - mov esi, [edi+TMndxFindResult.pStruct40] - mov eax, [esi+TStruct40.SearchPhase] - mov ebx, ecx - mov [ebp+pThis], ebx - cmp eax, 4 - jz return_false - cmp eax, 2 - jz loc_1959530 - mov ecx, esi - call TStruct40__InitSearchBuffers - mov eax, [esi+TStruct40.CharIndex] - cmp eax, [edi+TMndxFindResult.cchSearchMask] - jnb short loc_19594B0 - -loc_1959498: ; CODE XREF: TFileNameDatabase__sub_1959460+4Ej - push edi - mov ecx, ebx - call TFileNameDatabase__sub_1958B00 - test al, al - jz loc_1959778 - mov ecx, [esi+TStruct40.CharIndex] - cmp ecx, [edi+TMndxFindResult.cchSearchMask] - jb short loc_1959498 - -loc_19594B0: ; CODE XREF: TFileNameDatabase__sub_1959460+36j - mov edx, [esi+TStruct40.HashValue] - or eax, 0FFFFFFFFh - mov [ebp+Struct14], edx - mov [ebp+var_14], eax - mov [ebp+var_10], eax - mov eax, [esi+TStruct40.array_00.ItemCount] - lea edx, [ebp+Struct14] - lea ecx, [esi+TStruct40.array_18] - push edx - mov [ebp+var_1C], 0 - mov [ebp+var_18], eax - call TGenericArray__InsertItem_STRUCT14 - mov ecx, [esi+TStruct40.HashValue] - mov eax, ecx - and ecx, 1Fh - mov edi, 1 - shl edi, cl - mov [esi+TStruct40.ItemCount], 1 - mov edx, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray] - shr eax, 5 - test [edx+eax*4], edi - jz short loc_1959530 - mov ecx, [esi+TStruct40.array_00.field_4] - mov eax, [esi+TStruct40.array_00.ItemCount] - mov edi, [ebp+pStruct1C] - mov [edi+TMndxFindResult.szFoundPath], ecx - mov [edi+TMndxFindResult.cchFoundPath], eax - mov esi, [esi+TStruct40.HashValue] - push esi - lea ecx, [ebx+TFileNameDatabase.FileNameIndexes] - call TSparseArray__GetItemValue - mov [edi+TMndxFindResult.FileNameIndex], eax - pop edi - pop esi - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1959522: ; CODE XREF: TFileNameDatabase__sub_1959460+26Bj - ; TFileNameDatabase__sub_1959460+2D9j - mov ebx, [ebp+pThis] - jmp short loc_1959530 -; --------------------------------------------------------------------------- - align 10h - -loc_1959530: ; CODE XREF: TFileNameDatabase__sub_1959460+23j - ; TFileNameDatabase__sub_1959460+97j - mov edx, [esi+TStruct40.ItemCount] - cmp edx, [esi+TStruct40.array_18.ItemCount] - jnz loc_19595BD - mov eax, [esi+TStruct40.array_18.ItemCount] - mov ecx, [esi+TStruct40.array_18.field_4] - lea eax, [eax+eax*4] - lea eax, [ecx+eax*4-14h] - mov [ebp+pStruct14], eax - mov eax, [eax+TStruct14.HashValue] - push eax - mov ecx, ebx - call TFileNameDatabase__sub_1959CB0 - mov edx, [ebp+pStruct14] - mov ecx, [esi+TStruct40.array_18.ItemCount] - inc eax - mov ebx, eax - sub ebx, [edx+TStruct14.HashValue] - mov edx, [esi+TStruct40.array_18.MaxItemCount] - inc ecx - dec ebx - mov [ebp+var_1C], eax - cmp ecx, edx - jbe short loc_1959591 - mov eax, ecx - shr ecx, 1 - cmp edx, ecx - jbe short loc_1959585 - mov eax, 0CCCCCCCh - cmp edx, 6666666h - ja short loc_1959585 - lea eax, [edx+edx] - -loc_1959585: ; CODE XREF: TFileNameDatabase__sub_1959460+113j - ; TFileNameDatabase__sub_1959460+120j - push eax - lea ecx, [esi+TStruct40.array_18] - call TGenericArray__SetMaxItems_STRUCT14 - mov eax, [ebp+var_1C] - -loc_1959591: ; CODE XREF: TFileNameDatabase__sub_1959460+10Bj - mov ecx, [esi+TStruct40.array_18.ItemCount] - mov edx, [esi+TStruct40.array_18.field_4] - lea ecx, [ecx+ecx*4] - lea ecx, [edx+ecx*4] - test ecx, ecx - jz short loc_19595B7 - mov [ecx+TStruct14.HashValue], ebx - mov [ecx+TStruct14.field_4], eax - xor eax, eax - mov [ecx+TStruct14.field_8], eax - or eax, 0FFFFFFFFh - mov [ecx+TStruct14.field_C], eax - or eax, 0FFFFFFFFh - mov [ecx+TStruct14.field_10], eax - -loc_19595B7: ; CODE XREF: TFileNameDatabase__sub_1959460+13Fj - inc [esi+TStruct40.array_18.ItemCount] - mov ebx, [ebp+pThis] - -loc_19595BD: ; CODE XREF: TFileNameDatabase__sub_1959460+D6j - mov eax, [esi+TStruct40.ItemCount] - mov ecx, [esi+TStruct40.array_18.field_4] - mov ebx, [ebx+TFileNameDatabase.Struct68_00.ItemIsPresent.ItemArray] - lea eax, [eax+eax*4] - lea edi, [ecx+eax*4] - mov eax, [edi+TStruct14.field_4] - mov ecx, eax - and ecx, 1Fh - mov edx, 1 - shl edx, cl - mov ecx, eax - shr ecx, 5 - test [ebx+ecx*4], edx - setnz cl - inc eax - mov [edi+TStruct14.field_4], eax - test cl, cl - jz loc_19596E9 - inc [esi+TStruct40.ItemCount] - mov ecx, [edi+TStruct14.HashValue] - mov eax, [ebp+pThis] - mov eax, [eax+TFileNameDatabase.Struct68_D0.ItemIsPresent.ItemArray] - mov edx, ecx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr edx, 5 - test [eax+edx*4], ebx - mov ebx, [ebp+pThis] - jz short loc_1959665 - mov eax, [edi+TStruct14.field_C] - cmp eax, 0FFFFFFFFh - jnz short loc_195962F - mov eax, [edi+TStruct14.HashValue] - push eax - lea ecx, [ebx+TFileNameDatabase.Struct68_D0] - call TSparseArray__GetItemValue - jmp short loc_1959630 -; --------------------------------------------------------------------------- - -loc_195962F: ; CODE XREF: TFileNameDatabase__sub_1959460+1BDj - inc eax - -loc_1959630: ; CODE XREF: TFileNameDatabase__sub_1959460+1CDj - mov ecx, [edi+TStruct14.HashValue] - push eax - push ecx - mov ecx, ebx - mov [edi+TStruct14.field_C], eax - call sub_19573D0 - mov ecx, [ebx+TFileNameDatabase.NextDB.pDatabase] - push eax - test ecx, ecx - jz short loc_1959654 - mov edx, [ebp+pStruct1C] - push edx - call sub_1958D70 - jmp short loc_19596AE -; --------------------------------------------------------------------------- - -loc_1959654: ; CODE XREF: TFileNameDatabase__sub_1959460+1E7j - mov eax, [ebp+pStruct1C] - push eax - lea ecx, [ebx+TFileNameDatabase.IndexStruct_174] - call CopyNameFragment - jmp short loc_19596AE -; --------------------------------------------------------------------------- - -loc_1959665: ; CODE XREF: TFileNameDatabase__sub_1959460+1B5j - mov ecx, [ebx+TFileNameDatabase.FrgmDist_LoBits.ItemArray] - mov eax, [edi+TStruct14.HashValue] - mov dl, [eax+ecx] - mov eax, [esi+TStruct40.array_00.ItemCount] - mov ecx, [esi+TStruct40.array_00.MaxItemCount] - inc eax - mov [ebp+OneChar], dl - cmp eax, ecx - jbe short loc_195969E - mov edx, eax - shr eax, 1 - cmp ecx, eax - jbe short loc_1959696 - cmp ecx, 7FFFFFFFh - jbe short loc_1959693 - or edx, 0FFFFFFFFh - jmp short loc_1959696 -; --------------------------------------------------------------------------- - -loc_1959693: ; CODE XREF: TFileNameDatabase__sub_1959460+22Cj - lea edx, [ecx+ecx] - -loc_1959696: ; CODE XREF: TFileNameDatabase__sub_1959460+224j - ; TFileNameDatabase__sub_1959460+231j - push edx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_195969E: ; CODE XREF: TFileNameDatabase__sub_1959460+21Cj - mov eax, [esi+TStruct40.array_00.field_4] - add eax, [esi+TStruct40.array_00.ItemCount] - jz short loc_19596AB - mov cl, [ebp+OneChar] - mov [eax], cl - -loc_19596AB: ; CODE XREF: TFileNameDatabase__sub_1959460+244j - inc [esi+TStruct40.array_00.ItemCount] - -loc_19596AE: ; CODE XREF: TFileNameDatabase__sub_1959460+1F2j - ; TFileNameDatabase__sub_1959460+203j - mov edx, [esi+TStruct40.array_00.ItemCount] - mov ecx, [edi+TStruct14.HashValue] - mov [edi+TStruct14.field_8], edx - mov edx, [ebx+TFileNameDatabase.FileNameIndexes.ItemIsPresent.ItemArray] - mov eax, ecx - and ecx, 1Fh - mov ebx, 1 - shl ebx, cl - shr eax, 5 - test [edx+eax*4], ebx - jz loc_1959522 - mov eax, [edi+TStruct14.field_10] - cmp eax, 0FFFFFFFFh - jnz short loc_1959754 - mov eax, [edi+TStruct14.HashValue] - mov ecx, [ebp+pThis] - push eax - add ecx, TFileNameDatabase.FileNameIndexes - call TSparseArray__GetItemValue - jmp short loc_1959755 -; --------------------------------------------------------------------------- - -loc_19596E9: ; CODE XREF: TFileNameDatabase__sub_1959460+18Cj - mov eax, [esi+TStruct40.ItemCount] - cmp eax, 1 - jz loc_1959778 - mov ecx, [esi+TStruct40.array_18.field_4] - lea eax, [eax+eax*4] - inc dword ptr [ecx+eax*4-14h] - lea eax, [ecx+eax*4-14h] - mov eax, [esi+TStruct40.ItemCount] - lea edx, [eax+eax*4] - mov eax, [esi+TStruct40.array_18.field_4] - mov edi, [eax+edx*4-20h] - mov eax, [esi+TStruct40.array_00.MaxItemCount] - cmp edi, eax - jbe short loc_1959749 - mov edx, edi - shr edx, 1 - mov ecx, edi - cmp eax, edx - jbe short loc_1959741 - cmp eax, 7FFFFFFFh - jbe short loc_195973E - or ecx, 0FFFFFFFFh - push ecx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - dec [esi+TStruct40.ItemCount] - mov [esi+TStruct40.array_00.ItemCount], edi - jmp loc_1959522 -; --------------------------------------------------------------------------- - -loc_195973E: ; CODE XREF: TFileNameDatabase__sub_1959460+2C6j - lea ecx, [eax+eax] - -loc_1959741: ; CODE XREF: TFileNameDatabase__sub_1959460+2BFj - push ecx - mov ecx, esi - call TGenericArray__SetMaxItems_BYTE - -loc_1959749: ; CODE XREF: TFileNameDatabase__sub_1959460+2B5j - dec [esi+TStruct40.ItemCount] - mov [esi+TStruct40.array_00.ItemCount], edi - jmp loc_1959522 -; --------------------------------------------------------------------------- - -loc_1959754: ; CODE XREF: TFileNameDatabase__sub_1959460+277j - inc eax - -loc_1959755: ; CODE XREF: TFileNameDatabase__sub_1959460+287j - mov [edi+TStruct14.field_10], eax - mov ecx, [esi+TStruct40.array_00.ItemCount] - mov edx, [esi+TStruct40.array_00.field_4] - mov eax, [ebp+pStruct1C] - mov [eax+TMndxFindResult.szFoundPath], edx - mov [eax+TMndxFindResult.cchFoundPath], ecx - mov ecx, [edi+TStruct14.field_10] - pop edi - pop esi - mov [eax+TMndxFindResult.FileNameIndex], ecx - mov al, 1 - pop ebx - mov esp, ebp - pop ebp - retn 4 -; --------------------------------------------------------------------------- - -loc_1959778: ; CODE XREF: TFileNameDatabase__sub_1959460+42j - ; TFileNameDatabase__sub_1959460+28Fj - mov [esi+TStruct40.SearchPhase], 4 - -return_false: ; CODE XREF: TFileNameDatabase__sub_1959460+1Aj - pop edi - pop esi - xor al, al - pop ebx - mov esp, ebp - pop ebp - retn 4 -TFileNameDatabase__sub_1959460 endp - -; --------------------------------------------------------------------------- - -;------------------------------------------------------------------------------ -; Public functions callable from C++ - -; -; DWORD _cdecl sub_19573D0_x86(TFileNameDatabase * pDB, DWORD arg_0, DWORD arg_4); -; - -_sub_19573D0_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+10h] ; arg_4 - push [ebp+0Ch] ; arg_0 - call sub_19573D0 - mov esp, ebp - pop ebp - ret - -_sub_19573D0_x86 ENDP - -; -; DWORD _cdecl sub_1957EF0_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); -; - -_sub_1957EF0_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+0Ch] ; pStruct1C - call TFileNameDatabase__FindFileInDatabase - mov esp, ebp - pop ebp - ret - -_sub_1957EF0_x86 ENDP - -; -; bool _cdecl _sub_1959460_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); -; - -_sub_1959460_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+0Ch] ; pStruct1C - call TFileNameDatabase__sub_1959460 - mov esp, ebp - pop ebp - ret - -_sub_1959460_x86 ENDP - -; -; bool _cdecl sub_1958B00_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); -; - -_sub_1958B00_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+0Ch] ; pStruct1C - call TFileNameDatabase__sub_1959460 - mov esp, ebp - pop ebp - ret - -_sub_1958B00_x86 ENDP - -; -; DWORD _cdecl GetItemValue_x86(TSparseArray * pStruct, DWORD dwKey); -; - -_GetItemValue_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pStruct68 - push [ebp+0Ch] ; dwKey - call TSparseArray__GetItemValue - mov esp, ebp - pop ebp - ret - -_GetItemValue_x86 ENDP - -; -; DWORD _cdecl sub_1959CB0_x86(TFileNameDatabase * pDB, DWORD dwKey); -; - -_sub_1959CB0_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+0Ch] ; dwKey - call TArchiveDatabase__sub_1959CB0 - mov esp, ebp - pop ebp - ret - -_sub_1959CB0_x86 ENDP - -; -; DWORD _cdecl sub_1959F50_x86(TFileNameDatabase * pDB, DWORD arg_0); -; - -_sub_1959F50_x86 PROC - - push ebp - mov ebp, esp - mov ecx, [ebp+8] ; pDB - push [ebp+0Ch] ; dwKey - call sub_1959F50 - mov esp, ebp - pop ebp - ret - -_sub_1959F50_x86 ENDP - -END diff --git a/dep/CascLib/src/CascRootFile_TVFS.cpp b/dep/CascLib/src/CascRootFile_TVFS.cpp index b115a215037..7ccb376b621 100644 --- a/dep/CascLib/src/CascRootFile_TVFS.cpp +++ b/dep/CascLib/src/CascRootFile_TVFS.cpp @@ -98,6 +98,19 @@ typedef struct _TVFS_PATH_TABLE_ENTRY DWORD NodeValue; // Node value } TVFS_PATH_TABLE_ENTRY, *PTVFS_PATH_TABLE_ENTRY; +// In-memory layout of VFS span entry +typedef struct _TVFS_SPAN_ENTRY +{ + LPBYTE pbCftFileTable; + LPBYTE pbCftFileEntry; + LPBYTE pbCftFileEnd; + + DWORD dwFileOffset; // Offset into the referenced file + DWORD dwSpanSize; // Size of the span + DWORD dwCftOffset; // Offset relative to the beginning of the container file table + +} TVFS_SPAN_ENTRY, *PTVFS_SPAN_ENTRY; + //----------------------------------------------------------------------------- // Handler definition for TVFS root file @@ -235,37 +248,31 @@ struct TRootHandler_TVFS : public TFileTreeRoot return ERROR_SUCCESS; } - int CaptureVfsSpanEntries(TVFS_DIRECTORY_HEADER & DirHeader, PENCODED_KEY pEKey, PDWORD PtrSpanSize, DWORD dwVfsOffset) + LPBYTE CaptureVfsSpanCount(TVFS_DIRECTORY_HEADER & DirHeader, DWORD dwVfsOffset, DWORD & SpanCount) { LPBYTE pbVfsFileTable = DirHeader.pbDirectoryData + DirHeader.VfsTableOffset; LPBYTE pbVfsFileEntry = pbVfsFileTable + dwVfsOffset; LPBYTE pbVfsFileEnd = pbVfsFileTable + DirHeader.VfsTableSize; - LPBYTE pbCftFileTable; - LPBYTE pbCftFileEntry; - LPBYTE pbCftFileEnd; - LPBYTE pbTemp = NULL; - size_t ItemSize = sizeof(DWORD) + sizeof(DWORD) + DirHeader.CftOffsSize; - DWORD dwCftOffset; - DWORD dwSpanCount; - DWORD dwSpanSize; // Get the number of span entries - if(!(pbVfsFileTable <= pbVfsFileEntry && pbVfsFileEntry <= pbVfsFileEnd)) - return ERROR_INVALID_PARAMETER; - dwSpanCount = *pbVfsFileEntry++; + if(!(pbVfsFileTable <= pbVfsFileEntry && pbVfsFileEntry < pbVfsFileEnd)) + return NULL; + SpanCount = *pbVfsFileEntry++; // 1 - 224 = valid file, 225-254 = other file, 255 = deleted file // We will ignore all files with unsupported span count - if(dwSpanCount == 0 || dwSpanCount > 224) - return ERROR_BAD_FORMAT; + return (1 <= SpanCount && SpanCount <= 224) ? pbVfsFileEntry : NULL; + } - // So far we've only saw entries with 1 span. - // Need to test files with multiple spans. Ignore such files for now. - assert(dwSpanCount == 1); + LPBYTE CaptureVfsSpanEntry(TVFS_DIRECTORY_HEADER & DirHeader, LPBYTE pbVfsSpanEntry, TVFS_SPAN_ENTRY & SpanEntry) + { + LPBYTE pbVfsFileTable = DirHeader.pbDirectoryData + DirHeader.VfsTableOffset; + LPBYTE pbVfsFileEnd = pbVfsFileTable + DirHeader.VfsTableSize; + size_t ItemSize = sizeof(DWORD) + sizeof(DWORD) + DirHeader.CftOffsSize; - // Capture the array of span items - if(CaptureArray_(pbVfsFileEntry, pbVfsFileEnd, &pbTemp, ItemSize, dwSpanCount) == NULL) - return ERROR_BAD_FORMAT; + // Check the range being captured + if(pbVfsSpanEntry < pbVfsFileTable || (pbVfsSpanEntry + ItemSize) > pbVfsFileEnd) + return NULL; // // Structure of the span entry: @@ -274,21 +281,15 @@ struct TRootHandler_TVFS : public TFileTreeRoot // (?bytes): Offset into Container File Table. Length depends on container file table size // - // Get the offset to the Container File Table - dwCftOffset = ConvertBytesToInteger_X(pbVfsFileEntry + sizeof(DWORD) + sizeof(DWORD), DirHeader.CftOffsSize); - dwSpanSize = ConvertBytesToInteger_4(pbVfsFileEntry + sizeof(DWORD)); + SpanEntry.dwFileOffset = ConvertBytesToInteger_4(pbVfsSpanEntry); + SpanEntry.dwSpanSize = ConvertBytesToInteger_4(pbVfsSpanEntry + sizeof(DWORD)); + SpanEntry.dwCftOffset = ConvertBytesToInteger_X(pbVfsSpanEntry + sizeof(DWORD) + sizeof(DWORD), DirHeader.CftOffsSize); - // Go to the Container File Table and fetch the EKey from there - pbCftFileTable = DirHeader.pbDirectoryData + DirHeader.CftTableOffset; - pbCftFileEntry = pbCftFileTable + dwCftOffset; - pbCftFileEnd = pbCftFileTable + DirHeader.CftTableSize; - if((pbCftFileEntry + DirHeader.EKeySize) > pbCftFileEnd) - return ERROR_BAD_FORMAT; - - // Give the pointer to the EKey - memcpy(pEKey->Value, pbCftFileEntry, DirHeader.EKeySize); - PtrSpanSize[0] = dwSpanSize; - return ERROR_SUCCESS; + // Resolve the Container File Table entries + SpanEntry.pbCftFileTable = DirHeader.pbDirectoryData + DirHeader.CftTableOffset; + SpanEntry.pbCftFileEntry = SpanEntry.pbCftFileTable + SpanEntry.dwCftOffset; + SpanEntry.pbCftFileEnd = SpanEntry.pbCftFileTable + DirHeader.CftTableSize; + return pbVfsSpanEntry + ItemSize; } // @@ -439,8 +440,9 @@ struct TRootHandler_TVFS : public TFileTreeRoot TVFS_PATH_TABLE_ENTRY PathEntry; PCASC_CKEY_ENTRY pCKeyEntry; ENCODED_KEY EKey; + LPBYTE pbVfsSpanEntry; char * szSavePathPtr = PathBuffer.szPtr; - DWORD dwSpanSize = 0; + DWORD dwSpanCount = 0; int nError; // Prepare the EKey structure to be filled with zeros @@ -480,43 +482,67 @@ struct TRootHandler_TVFS : public TFileTreeRoot } else { - // Capture the VFS and Container Table Entry in order to get the file EKey - nError = CaptureVfsSpanEntries(DirHeader, &EKey, &dwSpanSize, PathEntry.NodeValue); - if (nError != ERROR_SUCCESS) - return nError; - - // We need to check whether this is another TVFS directory file - if (IsVfsSubDirectory(hs, DirHeader, SubHeader, EKey, dwSpanSize) == ERROR_SUCCESS) + // Capture the number of VFS spans + pbVfsSpanEntry = CaptureVfsSpanCount(DirHeader, PathEntry.NodeValue, dwSpanCount); + if(pbVfsSpanEntry == NULL) + return ERROR_BAD_FORMAT; +#ifdef _DEBUG + // So far we've only saw entries with 1 span. + // Need to test files with multiple spans. Ignore such files for now. + if(dwSpanCount != 1) + __debugbreak(); + dwSpanCount = 1; +#endif + // Parse all span entries + for(DWORD i = 0; i < dwSpanCount; i++) { - // Add colon (':') - PathBuffer_AddChar(PathBuffer, ':'); + TVFS_SPAN_ENTRY SpanEntry; - // Insert the file to the file tree - if((pCKeyEntry = FindCKeyEntry_EKey(hs, EKey.Value)) != NULL) + // Capture the n-th span entry + pbVfsSpanEntry = CaptureVfsSpanEntry(DirHeader, pbVfsSpanEntry, SpanEntry); + if(pbVfsSpanEntry == NULL) + return ERROR_FILE_CORRUPT; + + // Capture the encoded key + if((SpanEntry.pbCftFileEntry + DirHeader.EKeySize) > SpanEntry.pbCftFileEnd) + return ERROR_BAD_FORMAT; + + // Copy the EKey + memcpy(EKey.Value, SpanEntry.pbCftFileEntry, DirHeader.EKeySize); + + // We need to check whether this is another TVFS directory file + if (IsVfsSubDirectory(hs, DirHeader, SubHeader, EKey, SpanEntry.dwSpanSize) == ERROR_SUCCESS) { - // The file content size should already be there - assert(pCKeyEntry->ContentSize == dwSpanSize); - FileTree.InsertByName(pCKeyEntry, PathBuffer.szBegin); + // Add colon (':') + PathBuffer_AddChar(PathBuffer, ':'); + + // Insert the file to the file tree + if((pCKeyEntry = FindCKeyEntry_EKey(hs, EKey.Value)) != NULL) + { + // The file content size should already be there + assert(pCKeyEntry->ContentSize == SpanEntry.dwSpanSize); + FileTree.InsertByName(pCKeyEntry, PathBuffer.szBegin); + } + + ParseDirectoryData(hs, SubHeader, PathBuffer); + CASC_FREE(SubHeader.pbDirectoryData); } - - ParseDirectoryData(hs, SubHeader, PathBuffer); - CASC_FREE(SubHeader.pbDirectoryData); - } - else - { -// if (fp != NULL) -// { -// fwrite(PathBuffer.szBegin, 1, (PathBuffer.szPtr - PathBuffer.szBegin), fp); -// fprintf(fp, "\n"); -// } - - // Insert the file to the file tree - if((pCKeyEntry = FindCKeyEntry_EKey(hs, EKey.Value)) != NULL) + else { - // If the file content is not there, supply it now - if(pCKeyEntry->ContentSize == CASC_INVALID_SIZE) - pCKeyEntry->ContentSize = dwSpanSize; - FileTree.InsertByName(pCKeyEntry, PathBuffer.szBegin); +// if (fp != NULL) +// { +// fwrite(PathBuffer.szBegin, 1, (PathBuffer.szPtr - PathBuffer.szBegin), fp); +// fprintf(fp, "\n"); +// } + + // Insert the file to the file tree + if((pCKeyEntry = FindCKeyEntry_EKey(hs, EKey.Value)) != NULL) + { + // If the file content is not there, supply it now + if(pCKeyEntry->ContentSize == CASC_INVALID_SIZE) + pCKeyEntry->ContentSize = SpanEntry.dwSpanSize; + FileTree.InsertByName(pCKeyEntry, PathBuffer.szBegin); + } } } } diff --git a/dep/CascLib/src/CascRootFile_WoW.cpp b/dep/CascLib/src/CascRootFile_WoW.cpp index 780220bbe40..766e226a2b1 100644 --- a/dep/CascLib/src/CascRootFile_WoW.cpp +++ b/dep/CascLib/src/CascRootFile_WoW.cpp @@ -395,14 +395,24 @@ struct TRootHandler_WoW : public TFileTreeRoot { PCASC_FILE_NODE pFileNode; ULONGLONG FileNameHash; + size_t nLength; DWORD FileDataId = CASC_INVALID_ID; char szFileName[MAX_PATH]; if(RootFormat == RootFormatWoW82) { // Keep going through the listfile - while(ListFile_GetNext(pSearch->pCache, szFileName, _countof(szFileName), &FileDataId)) + for(;;) { + // Retrieve the next line from the list file. Ignore lines that are too long to fit in the buffer + nLength = ListFile_GetNext(pSearch->pCache, szFileName, _countof(szFileName), &FileDataId); + if(nLength == 0) + { + if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + continue; + break; + } + // Try to find the file node by file data id pFileNode = FileTree.FindById(FileDataId); if(pFileNode != NULL && pFileNode->NameLength == 0) @@ -414,8 +424,17 @@ struct TRootHandler_WoW : public TFileTreeRoot else { // Keep going through the listfile - while(ListFile_GetNextLine(pSearch->pCache, szFileName, MAX_PATH)) + for(;;) { + // Retrieve the next line from the list file. Ignore lines that are too long to fit in the buffer + nLength = ListFile_GetNextLine(pSearch->pCache, szFileName, _countof(szFileName)); + if(nLength == 0) + { + if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) + continue; + break; + } + // Calculate the hash of the file name FileNameHash = CalcFileNameHash(szFileName); diff --git a/dep/CascLib/src/DllMain.rc b/dep/CascLib/src/DllMain.rc new file mode 100644 index 00000000000..2951666c6f7 --- /dev/null +++ b/dep/CascLib/src/DllMain.rc @@ -0,0 +1,106 @@ +// Microsoft Visual C++ generated resource script. + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,50,0,155 + PRODUCTVERSION 1,50,0,155 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040504b0" + BEGIN + VALUE "FileDescription", "CascLib library for reading Blizzard CASC storages" + VALUE "FileVersion", "1, 50, 0, 155\0" + VALUE "InternalName", "CascLib" + VALUE "LegalCopyright", "Copyright (c) 2014 - 2019 Ladislav Zezula" + VALUE "OriginalFilename", "CascLib.dll" + VALUE "ProductName", "CascLib" + VALUE "ProductVersion", "1, 50, 0, 155\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x405, 1200 + END +END + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp index fafa00e7739..2860671227b 100644 --- a/dep/CascLib/src/common/Common.cpp +++ b/dep/CascLib/src/common/Common.cpp @@ -336,7 +336,7 @@ TCHAR * AppendPathFragment(TCHAR * szBuffer, TCHAR * szBufferEnd, const XCHAR * return szBuffer; } -TCHAR * GetLastPathPart(TCHAR * szWorkPath) +LPTSTR GetLastPathPart(LPTSTR szWorkPath) { size_t nLength = _tcslen(szWorkPath); @@ -375,51 +375,56 @@ bool CutLastPathPart(TCHAR * szWorkPath) return true; } -TCHAR * CombinePath(const TCHAR * szDirectory, const TCHAR * szSubDir) +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, va_list argList) { - TCHAR * szFullPathEnd; - TCHAR * szFullPath = NULL; - TCHAR * szPathPtr; - size_t nLength1 = (szDirectory != NULL) ? _tcslen(szDirectory) : 0; - size_t nLength2 = (szSubDir != NULL) ? _tcslen(szSubDir) : 0; + LPTSTR szSaveBuffer = szBuffer; + LPTSTR szBufferEnd = szBuffer + nMaxChars - 1; + LPTSTR szFragment; + bool bFirstFragment = true; - // Allocate the entire buffer - szFullPath = szPathPtr = CASC_ALLOC(TCHAR, nLength1 + nLength2 + 2); - szFullPathEnd = szFullPath + nLength1 + nLength2 + 1; - if(szFullPath != NULL) + // Combine all parts of the path here + while((szFragment = va_arg(argList, LPTSTR)) != NULL) { - szPathPtr = AppendPathFragment(szPathPtr, szFullPathEnd, szDirectory, PATH_SEP_CHAR, true); - szPathPtr = AppendPathFragment(szPathPtr, szFullPathEnd, szSubDir, PATH_SEP_CHAR); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szFragment, chSeparator, bFirstFragment); + bFirstFragment = false; } - return szFullPath; + return (szBuffer - szSaveBuffer); } -size_t CombineFilePath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szPath, const TCHAR * szSubPath1, const TCHAR * szSubPath2) +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, ...) { - TCHAR * szSaveBuffer = szBuffer; - TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; + va_list argList; + size_t nLength; - // Append all three parts and return length - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szPath, PATH_SEP_CHAR, true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath1, PATH_SEP_CHAR); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath2, PATH_SEP_CHAR); - return (szBuffer - szSaveBuffer); + va_start(argList, chSeparator); + nLength = CombinePath(szBuffer, nMaxChars, chSeparator, argList); + va_end(argList); + + return nLength; } -size_t CombineUrlPath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szHost, const TCHAR * szSubPath1, const TCHAR * szSubPath2) +LPTSTR CombinePath(LPCTSTR szDirectory, LPCTSTR szSubDir) { - TCHAR * szSaveBuffer = szBuffer; - TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; + LPTSTR szFullPath; + size_t nLength = 0; - // Append all three parts and return length - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHost, '/', true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath1, '/'); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubPath2, '/'); - return (szBuffer - szSaveBuffer); + // Calculate length + if(szDirectory != NULL) + nLength += (_tcslen(szDirectory) + 1); + if(szSubDir != NULL) + nLength += (_tcslen(szSubDir) + 1); + + // Allocate buffer + if((szFullPath = CASC_ALLOC(TCHAR, nLength)) != NULL) + { + CombinePath(szFullPath, nLength, PATH_SEP_CHAR, szDirectory, szSubDir, NULL); + } + + return szFullPath; } -size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szSubDir, const TCHAR * szExtension, LPBYTE pbEKey) +size_t CreateCascSubdirectoryName(LPTSTR szBuffer, size_t nMaxChars, LPCTSTR szSubDir, LPCTSTR szExtension, LPBYTE pbEKey) { TCHAR * szSaveBuffer = szBuffer; TCHAR * szBufferEnd = szBuffer + nMaxChars - 1; @@ -430,9 +435,10 @@ size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHA StringFromBinary(pbEKey, MD5_HASH_SIZE, szHashText); CascStrPrintf(szHashSubPath, _countof(szHashSubPath), "%02x/%02x/%s", pbEKey[0], pbEKey[1], szHashText); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubDir, '/', true); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHashSubPath, '/'); - szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szExtension, '/', true); + // Combine the path together + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szSubDir, URL_SEP_CHAR, true); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szHashSubPath, URL_SEP_CHAR); + szBuffer = AppendPathFragment(szBuffer, szBufferEnd, szExtension, URL_SEP_CHAR, true); return (szBuffer - szSaveBuffer); } @@ -610,16 +616,33 @@ char * StringFromMD5(LPBYTE md5, char * szBuffer) bool IsFileDataIdName(const char * szFileName, DWORD & FileDataId) { + const char * szFilePtr; BYTE BinaryValue[4]; - // File name must begin with "File", case insensitive - if(AsciiToUpperTable_BkSlash[szFileName[0]] == 'F' && - AsciiToUpperTable_BkSlash[szFileName[1]] == 'I' && - AsciiToUpperTable_BkSlash[szFileName[2]] == 'L' && - AsciiToUpperTable_BkSlash[szFileName[3]] == 'E') + // If the file name begins with "File", then a decimal file data ID must follow + if(!strncmp(szFileName, "File", 4)) + { + DWORD Accumulator = 0; + + for(szFilePtr = szFileName + 4; szFilePtr[0] != 0 && szFilePtr[0] != '.'; szFilePtr++) + { + if(!('0' <= szFilePtr[0] && szFilePtr[0] <= '9')) + return false; + Accumulator = (Accumulator * 10) + (szFilePtr[0] - '0'); + } + + if(szFilePtr[0] == '.' || szFilePtr[0] == 0) + { + FileDataId = Accumulator; + return true; + } + } + + // If the file name begins with "FILE", then a hexadecimal file data ID must follow + if(!strncmp(szFileName, "FILE", 4) && strlen(szFileName) >= 0x0C) { - // Then, 8 hexadecimal digits must follow - if(ConvertStringToBinary(szFileName + 4, 8, BinaryValue) == ERROR_SUCCESS) + // Convert the hexadecimal number to integer + if(ConvertStringToBinary(szFileName+4, 8, BinaryValue) == ERROR_SUCCESS) { // Must be followed by an extension or end-of-string if(szFileName[0x0C] == 0 || szFileName[0x0C] == '.') diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h index 705777b7b0b..45a2ec93e6b 100644 --- a/dep/CascLib/src/common/Common.h +++ b/dep/CascLib/src/common/Common.h @@ -271,10 +271,10 @@ size_t CascStrPrintf(wchar_t * buffer, size_t nCount, const wchar_t * format, .. char * CascNewStr(const char * szString, size_t nCharsToReserve = 0); wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve = 0); -TCHAR * CombinePath(const TCHAR * szPath, const TCHAR * szSubDir); -size_t CombineFilePath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szPath, const TCHAR * szSubPath1, const TCHAR * szSubPath2 = NULL); -size_t CombineUrlPath(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szHost, const TCHAR * szSubPath1, const TCHAR * szSubPath2 = NULL); -TCHAR * GetLastPathPart(TCHAR * szWorkPath); +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, va_list argList); +size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, ...); +LPTSTR CombinePath(LPCTSTR szPath, LPCTSTR szSubDir); +LPTSTR GetLastPathPart(LPTSTR szWorkPath); bool CutLastPathPart(TCHAR * szWorkPath); size_t CreateCascSubdirectoryName(TCHAR * szBuffer, size_t nMaxChars, const TCHAR * szSubDir, const TCHAR * szExtension, LPBYTE pbEKey); @@ -383,4 +383,23 @@ int ScanIndexDirectory( void * pvContext ); +//----------------------------------------------------------------------------- +// Argument structure versioning +// Safely retrieves field value from a structure +// intended for cases where users upgrade CascLib by simply dropping in a new .dll without recompiling their app + +template <typename ARG, typename ARG_HOLDER> +bool ExtractVersionedArgument(const ARG_HOLDER * pHolder, size_t ArgOffset, ARG * pArg) +{ + if (pHolder == NULL) + return false; + + // Check input structure size + if (ArgOffset + sizeof(ARG) > pHolder->Size) + return false; + + *pArg = *((ARG *)(((char*)pHolder) + ArgOffset)); + return true; +} + #endif // __COMMON_H__ diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp index 351ea226188..36607d39186 100644 --- a/dep/CascLib/src/common/ListFile.cpp +++ b/dep/CascLib/src/common/ListFile.cpp @@ -225,26 +225,34 @@ size_t ListFile_GetNextLine(void * pvListFile, char * szBuffer, size_t nMaxChars const char * szLineBegin = NULL; const char * szLineEnd = NULL; size_t nLength; + DWORD dwErrCode = ERROR_SUCCESS; // Retrieve the next line nLength = ListFile_GetNextLine(pvListFile, &szLineBegin, &szLineEnd); // Check the length - if(nLength > nMaxChars) + if(nLength < nMaxChars) { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return 0; + // Copy the line to the user buffer + memcpy(szBuffer, szLineBegin, nLength); + szBuffer[nLength] = 0; + } + else + { + dwErrCode = ERROR_INSUFFICIENT_BUFFER; + nLength = 0; } - // Copy the line to the user buffer - memcpy(szBuffer, szLineBegin, nLength); - szBuffer[nLength] = 0; + // If we didn't read anything, set the error code + if(nLength == 0) + SetLastError(dwErrCode); return nLength; } size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PDWORD PtrFileDataId) { PLISTFILE_CACHE pCache = (PLISTFILE_CACHE)pvListFile; + const char * szTemp; size_t nLength = 0; int nError = ERROR_SUCCESS; @@ -257,18 +265,24 @@ size_t ListFile_GetNext(void * pvListFile, char * szBuffer, size_t nMaxChars, PD // Lines that contain bogus data, invalid numbers or too big values will be skipped if(pCache->Flags & LISTFILE_FLAG_USES_FILEDATAID) { + // Retrieve the data ID from the current position nError = ListFile_GetFileDataId(pCache, &FileDataId); if(nError == ERROR_NO_MORE_FILES) break; + + // If there was an error, skip the current line if(nError != ERROR_SUCCESS || FileDataId == CASC_INVALID_ID) + { + ListFile_GetNextLine(pvListFile, &szTemp, &szTemp); continue; + } } // Read the (next) line nLength = ListFile_GetNextLine(pvListFile, szBuffer, nMaxChars); if(nLength == 0) { - nError = ERROR_NO_MORE_FILES; + nError = GetLastError(); break; } |