aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib')
-rw-r--r--dep/CascLib/CMakeLists.txt8
-rw-r--r--dep/CascLib/src/CascCommon.h40
-rw-r--r--dep/CascLib/src/CascFiles.cpp289
-rw-r--r--dep/CascLib/src/CascIndexFiles.cpp4
-rw-r--r--dep/CascLib/src/CascLib.def2
-rw-r--r--dep/CascLib/src/CascLib.h74
-rw-r--r--dep/CascLib/src/CascOpenStorage.cpp445
-rw-r--r--dep/CascLib/src/CascPort.h3
-rw-r--r--dep/CascLib/src/CascRootFile_Mndx_x86.asm4369
-rw-r--r--dep/CascLib/src/CascRootFile_TVFS.cpp160
-rw-r--r--dep/CascLib/src/CascRootFile_WoW.cpp23
-rw-r--r--dep/CascLib/src/DllMain.rc106
-rw-r--r--dep/CascLib/src/common/Common.cpp105
-rw-r--r--dep/CascLib/src/common/Common.h27
-rw-r--r--dep/CascLib/src/common/ListFile.cpp28
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;
}