mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 03:42:37 +01:00
Dep/CascLib: Update to ladislav-zezula/CascLib@a5080b5794
This commit is contained in:
@@ -61,7 +61,8 @@ TCascStorage::TCascStorage()
|
||||
pRootHandler = NULL;
|
||||
dwRefCount = 1;
|
||||
|
||||
szRootPath = szDataPath = szIndexPath = szBuildFile = szCdnServers = szCdnPath = szCdnHostUrl = szCodeName = NULL;
|
||||
szRootPath = szDataPath = szIndexPath = szFilesPath = szConfigPath = szMainFile = NULL;
|
||||
szCdnHostUrl = szCdnServers = szCdnPath = szCodeName = NULL;
|
||||
szIndexFormat = NULL;
|
||||
szRegion = NULL;
|
||||
szBuildKey = NULL;
|
||||
@@ -100,14 +101,16 @@ TCascStorage::~TCascStorage()
|
||||
CascFreeLock(StorageLock);
|
||||
|
||||
// Free the file paths
|
||||
CASC_FREE(szDataPath);
|
||||
CASC_FREE(szRootPath);
|
||||
CASC_FREE(szBuildFile);
|
||||
CASC_FREE(szDataPath);
|
||||
CASC_FREE(szIndexPath);
|
||||
CASC_FREE(szFilesPath);
|
||||
CASC_FREE(szConfigPath);
|
||||
CASC_FREE(szMainFile);
|
||||
CASC_FREE(szCdnHostUrl);
|
||||
CASC_FREE(szCdnServers);
|
||||
CASC_FREE(szCdnPath);
|
||||
CASC_FREE(szCodeName);
|
||||
CASC_FREE(szCdnHostUrl);
|
||||
CASC_FREE(szRegion);
|
||||
CASC_FREE(szBuildKey);
|
||||
|
||||
@@ -166,20 +169,6 @@ void * ProbeOutputBuffer(void * pvBuffer, size_t cbLength, size_t cbMinLength, s
|
||||
return pvBuffer;
|
||||
}
|
||||
|
||||
static LPTSTR CheckForIndexDirectory(TCascStorage * hs, LPCTSTR szSubDir)
|
||||
{
|
||||
TCHAR szIndexPath[MAX_PATH];
|
||||
|
||||
// Combine the index path
|
||||
CombinePath(szIndexPath, _countof(szIndexPath), hs->szDataPath, szSubDir, NULL);
|
||||
|
||||
// Check whether the path exists
|
||||
if(!DirectoryExists(szIndexPath))
|
||||
return NULL;
|
||||
|
||||
return CascNewStr(szIndexPath);
|
||||
}
|
||||
|
||||
// Inserts an entry from the text build file
|
||||
static PCASC_CKEY_ENTRY InsertCKeyEntry(TCascStorage * hs, CASC_CKEY_ENTRY & CKeyEntry)
|
||||
{
|
||||
@@ -451,8 +440,7 @@ static int LoadEncodingCKeyPage(TCascStorage * hs, CASC_ENCODING_HEADER & EnHead
|
||||
static int LoadEncodingManifest(TCascStorage * hs)
|
||||
{
|
||||
CASC_CKEY_ENTRY & CKeyEntry = hs->EncodingCKey;
|
||||
LPBYTE pbEncodingFile;
|
||||
DWORD cbEncodingFile = 0;
|
||||
CASC_BLOB EncodingFile;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Inform the user about what we are doing
|
||||
@@ -465,24 +453,25 @@ static int LoadEncodingManifest(TCascStorage * hs)
|
||||
InsertCKeyEntry(hs, CKeyEntry);
|
||||
|
||||
// Load the entire encoding file to memory
|
||||
pbEncodingFile = LoadInternalFileToMemory(hs, &hs->EncodingCKey, &cbEncodingFile);
|
||||
if(pbEncodingFile != NULL && cbEncodingFile != 0)
|
||||
dwErrCode = LoadInternalFileToMemory(hs, &hs->EncodingCKey, EncodingFile);
|
||||
if(dwErrCode == ERROR_SUCCESS && EncodingFile.cbData != 0)
|
||||
{
|
||||
CASC_ENCODING_HEADER EnHeader;
|
||||
|
||||
// Capture the header of the ENCODING file
|
||||
dwErrCode = CaptureEncodingHeader(EnHeader, pbEncodingFile, cbEncodingFile);
|
||||
dwErrCode = CaptureEncodingHeader(EnHeader, EncodingFile.pbData, EncodingFile.cbData);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Get the CKey page header and the first page
|
||||
PFILE_CKEY_PAGE pPageHeader = (PFILE_CKEY_PAGE)(pbEncodingFile + sizeof(FILE_ENCODING_HEADER) + EnHeader.ESpecBlockSize);
|
||||
PFILE_CKEY_PAGE pPageHeader = (PFILE_CKEY_PAGE)(EncodingFile.pbData + sizeof(FILE_ENCODING_HEADER) + EnHeader.ESpecBlockSize);
|
||||
LPBYTE pbEncodingEnd = EncodingFile.pbData + EncodingFile.cbData;
|
||||
LPBYTE pbCKeyPage = (LPBYTE)(pPageHeader + EnHeader.CKeyPageCount);
|
||||
|
||||
// Go through all CKey pages and verify them
|
||||
for(DWORD i = 0; i < EnHeader.CKeyPageCount; i++)
|
||||
{
|
||||
// Check if there is enough space in the buffer
|
||||
if((pbCKeyPage + EnHeader.CKeyPageSize) > (pbEncodingFile + cbEncodingFile))
|
||||
if((pbCKeyPage + EnHeader.CKeyPageSize) > pbEncodingEnd)
|
||||
{
|
||||
dwErrCode = ERROR_FILE_CORRUPT;
|
||||
break;
|
||||
@@ -519,9 +508,6 @@ static int LoadEncodingManifest(TCascStorage * hs)
|
||||
{
|
||||
dwErrCode = CopyBuildFileItemsToCKeyArray(hs);
|
||||
}
|
||||
|
||||
// Free the loaded ENCODING file
|
||||
CASC_FREE(pbEncodingFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -735,15 +721,18 @@ static int LoadDownloadManifest(TCascStorage * hs, CASC_DOWNLOAD_HEADER & DlHead
|
||||
// Insert the entry to the central CKey table
|
||||
if((pCKeyEntry = InsertCKeyEntry(hs, DlEntry)) != NULL)
|
||||
{
|
||||
// Supply the tag bits
|
||||
for(size_t j = 0; j < TagItemCount; j++)
|
||||
if(TagArray != NULL)
|
||||
{
|
||||
// Set the bit in the entry, if the tag for it is present
|
||||
if((BitMaskOffset < TagArray[j].BitmapLength) && (TagArray[j].Bitmap[BitMaskOffset] & BitMaskBit))
|
||||
pCKeyEntry->TagBitMask |= TagBit;
|
||||
// Supply the tag bits
|
||||
for(size_t j = 0; j < TagItemCount; j++)
|
||||
{
|
||||
// Set the bit in the entry, if the tag for it is present
|
||||
if((BitMaskOffset < TagArray[j].BitmapLength) && (TagArray[j].Bitmap[BitMaskOffset] & BitMaskBit))
|
||||
pCKeyEntry->TagBitMask |= TagBit;
|
||||
|
||||
// Move to the next bit
|
||||
TagBit <<= 1;
|
||||
// Move to the next bit
|
||||
TagBit <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,8 +751,7 @@ static int LoadDownloadManifest(TCascStorage * hs, CASC_DOWNLOAD_HEADER & DlHead
|
||||
static int LoadDownloadManifest(TCascStorage * hs)
|
||||
{
|
||||
PCASC_CKEY_ENTRY pCKeyEntry = FindCKeyEntry_CKey(hs, hs->DownloadCKey.CKey);
|
||||
LPBYTE pbDownloadFile = NULL;
|
||||
DWORD cbDownloadFile = 0;
|
||||
CASC_BLOB DownloadFile;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Inform the user about what we are doing
|
||||
@@ -771,21 +759,18 @@ static int LoadDownloadManifest(TCascStorage * hs)
|
||||
return ERROR_CANCELLED;
|
||||
|
||||
// Load the entire DOWNLOAD file to memory
|
||||
pbDownloadFile = LoadInternalFileToMemory(hs, pCKeyEntry, &cbDownloadFile);
|
||||
if(pbDownloadFile != NULL && cbDownloadFile != 0)
|
||||
dwErrCode = LoadInternalFileToMemory(hs, pCKeyEntry, DownloadFile);
|
||||
if(dwErrCode == ERROR_SUCCESS && DownloadFile.cbData != 0)
|
||||
{
|
||||
CASC_DOWNLOAD_HEADER DlHeader;
|
||||
|
||||
// Capture the header of the DOWNLOAD file
|
||||
dwErrCode = CaptureDownloadHeader(DlHeader, pbDownloadFile, cbDownloadFile);
|
||||
dwErrCode = CaptureDownloadHeader(DlHeader, DownloadFile.pbData, DownloadFile.cbData);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Parse the entire download manifest
|
||||
dwErrCode = LoadDownloadManifest(hs, DlHeader, pbDownloadFile, pbDownloadFile + cbDownloadFile);
|
||||
dwErrCode = LoadDownloadManifest(hs, DlHeader, DownloadFile.pbData, DownloadFile.pbData + DownloadFile.cbData);
|
||||
}
|
||||
|
||||
// Free the loaded manifest
|
||||
CASC_FREE(pbDownloadFile);
|
||||
}
|
||||
|
||||
// If the DOWNLOAD manifest is not present, we won't abort the downloading process.
|
||||
@@ -799,8 +784,7 @@ static int LoadDownloadManifest(TCascStorage * hs)
|
||||
static int LoadInstallManifest(TCascStorage * hs)
|
||||
{
|
||||
PCASC_CKEY_ENTRY pCKeyEntry = FindCKeyEntry_CKey(hs, hs->InstallCKey.CKey);
|
||||
LPBYTE pbInstallFile = NULL;
|
||||
DWORD cbInstallFile = 0;
|
||||
CASC_BLOB InstallFile;
|
||||
DWORD dwErrCode = ERROR_SUCCESS;
|
||||
|
||||
// Inform the user about what we are doing
|
||||
@@ -808,11 +792,10 @@ static int LoadInstallManifest(TCascStorage * hs)
|
||||
return ERROR_CANCELLED;
|
||||
|
||||
// Load the entire DOWNLOAD file to memory
|
||||
pbInstallFile = LoadInternalFileToMemory(hs, pCKeyEntry, &cbInstallFile);
|
||||
if(pbInstallFile != NULL && cbInstallFile != 0)
|
||||
dwErrCode = LoadInternalFileToMemory(hs, pCKeyEntry, InstallFile);
|
||||
if(dwErrCode == ERROR_SUCCESS && InstallFile.cbData != 0)
|
||||
{
|
||||
dwErrCode = RootHandler_CreateInstall(hs, pbInstallFile, cbInstallFile);
|
||||
CASC_FREE(pbInstallFile);
|
||||
dwErrCode = RootHandler_CreateInstall(hs, InstallFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -864,9 +847,8 @@ static int LoadBuildManifest(TCascStorage * hs, DWORD dwLocaleMask)
|
||||
{
|
||||
PCASC_CKEY_ENTRY pCKeyEntry = &hs->RootFile;
|
||||
TRootHandler * pOldRootHandler = NULL;
|
||||
CASC_BLOB RootFile;
|
||||
PDWORD FileSignature;
|
||||
LPBYTE pbRootFile = NULL;
|
||||
DWORD cbRootFile = 0;
|
||||
DWORD dwErrCode = ERROR_BAD_FORMAT;
|
||||
|
||||
// Sanity checks
|
||||
@@ -888,30 +870,30 @@ __LoadRootFile:
|
||||
|
||||
// Load the entire ROOT file to memory
|
||||
pCKeyEntry = FindCKeyEntry_CKey(hs, pCKeyEntry->CKey);
|
||||
pbRootFile = LoadInternalFileToMemory(hs, pCKeyEntry, &cbRootFile);
|
||||
if(pbRootFile != NULL)
|
||||
dwErrCode = LoadInternalFileToMemory(hs, pCKeyEntry, RootFile);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
// Ignore ROOT files that contain just a MD5 hash
|
||||
if(cbRootFile > MD5_STRING_SIZE)
|
||||
if(RootFile.cbData > MD5_STRING_SIZE)
|
||||
{
|
||||
// Check the type of the ROOT file
|
||||
FileSignature = (PDWORD)pbRootFile;
|
||||
FileSignature = (PDWORD)(RootFile.pbData);
|
||||
switch(FileSignature[0])
|
||||
{
|
||||
case CASC_MNDX_ROOT_SIGNATURE:
|
||||
dwErrCode = RootHandler_CreateMNDX(hs, pbRootFile, cbRootFile);
|
||||
dwErrCode = RootHandler_CreateMNDX(hs, RootFile);
|
||||
break;
|
||||
|
||||
case CASC_DIABLO3_ROOT_SIGNATURE:
|
||||
dwErrCode = RootHandler_CreateDiablo3(hs, pbRootFile, cbRootFile);
|
||||
dwErrCode = RootHandler_CreateDiablo3(hs, RootFile);
|
||||
break;
|
||||
|
||||
case CASC_TVFS_ROOT_SIGNATURE:
|
||||
dwErrCode = RootHandler_CreateTVFS(hs, pbRootFile, cbRootFile);
|
||||
dwErrCode = RootHandler_CreateTVFS(hs, RootFile);
|
||||
break;
|
||||
|
||||
case CASC_WOW82_ROOT_SIGNATURE:
|
||||
dwErrCode = RootHandler_CreateWoW(hs, pbRootFile, cbRootFile, dwLocaleMask);
|
||||
dwErrCode = RootHandler_CreateWoW(hs, RootFile, dwLocaleMask);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -921,21 +903,18 @@ __LoadRootFile:
|
||||
// If the format was not recognized, they need to return ERROR_BAD_FORMAT
|
||||
//
|
||||
|
||||
dwErrCode = RootHandler_CreateOverwatch(hs, pbRootFile, cbRootFile);
|
||||
dwErrCode = RootHandler_CreateOverwatch(hs, RootFile);
|
||||
if(dwErrCode == ERROR_BAD_FORMAT)
|
||||
{
|
||||
dwErrCode = RootHandler_CreateStarcraft1(hs, pbRootFile, cbRootFile);
|
||||
dwErrCode = RootHandler_CreateStarcraft1(hs, RootFile);
|
||||
if(dwErrCode == ERROR_BAD_FORMAT)
|
||||
{
|
||||
dwErrCode = RootHandler_CreateWoW(hs, pbRootFile, cbRootFile, dwLocaleMask);
|
||||
dwErrCode = RootHandler_CreateWoW(hs, RootFile, dwLocaleMask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the root file
|
||||
CASC_FREE(pbRootFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1109,73 +1088,7 @@ static bool GetStoragePathProduct(TCascStorage * hs, void * pvStorageInfo, size_
|
||||
return (szBuffer != NULL);
|
||||
}
|
||||
|
||||
static DWORD InitializeLocalDirectories(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs)
|
||||
{
|
||||
LPTSTR 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)
|
||||
{
|
||||
// Create the root path
|
||||
hs->szRootPath = CascNewStr(pArgs->szLocalPath);
|
||||
if(hs->szRootPath != NULL)
|
||||
{
|
||||
hs->BuildFileType = CascVersionsDb;
|
||||
hs->dwFeatures |= CASC_FEATURE_ONLINE;
|
||||
hs->dwFeatures |= (pArgs->dwFlags & (CASC_FEATURE_LOCAL_CDNS | CASC_FEATURE_LOCAL_VERSIONS));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs)
|
||||
static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs, LPCTSTR szMainFile, CBLD_TYPE BuildFileType, DWORD dwFeatures)
|
||||
{
|
||||
LPCTSTR szCdnHostUrl = NULL;
|
||||
LPCTSTR szCodeName = NULL;
|
||||
@@ -1206,21 +1119,48 @@ static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs)
|
||||
if(ExtractVersionedArgument(pArgs, FIELD_OFFSET(CASC_OPEN_STORAGE_ARGS, szBuildKey), &szBuildKey) && szBuildKey != NULL)
|
||||
hs->szBuildKey = CascNewStrT2A(szBuildKey);
|
||||
|
||||
// Special handling to online storages
|
||||
if(hs->dwFeatures & CASC_FEATURE_ONLINE)
|
||||
{
|
||||
// Enable caching of the sockets. This will add references
|
||||
// to all existing and all future sockets
|
||||
sockets_set_caching(true);
|
||||
// Merge features
|
||||
hs->dwFeatures |= (dwFeatures & (CASC_FEATURE_DATA_ARCHIVES | CASC_FEATURE_DATA_FILES | CASC_FEATURE_ONLINE));
|
||||
hs->dwFeatures |= (pArgs->dwFlags & CASC_FEATURE_FORCE_DOWNLOAD);
|
||||
hs->BuildFileType = BuildFileType;
|
||||
|
||||
// For online storages, we need to load CDN servers
|
||||
dwErrCode = LoadCdnsFile(hs);
|
||||
// Copy the name of the build file
|
||||
hs->szMainFile = CascNewStr(szMainFile);
|
||||
|
||||
// Construct the root path from the name of the build file
|
||||
CASC_PATH<TCHAR> RootPath(szMainFile, NULL);
|
||||
hs->szRootPath = RootPath.New(true);
|
||||
|
||||
// If either of the root path or build file is known, it's an error
|
||||
if(hs->szRootPath == NULL || hs->szMainFile == NULL)
|
||||
{
|
||||
dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
// Now, load the main storage file ".build.info" (or ".build.db" in old storages)
|
||||
// Initialize variables for local CASC storages
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = LoadBuildInfo(hs);
|
||||
// For local (game) storages, we need the data and indices subdirectory
|
||||
if(hs->dwFeatures & CASC_FEATURE_DATA_ARCHIVES)
|
||||
{
|
||||
if(CheckArchiveFilesDirectories(hs) != ERROR_SUCCESS)
|
||||
hs->dwFeatures &= ~CASC_FEATURE_DATA_ARCHIVES;
|
||||
}
|
||||
|
||||
// For data files storage, we need that folder
|
||||
if(hs->dwFeatures & CASC_FEATURE_DATA_FILES)
|
||||
{
|
||||
if(CheckDataFilesDirectory(hs) != ERROR_SUCCESS)
|
||||
hs->dwFeatures &= ~CASC_FEATURE_DATA_FILES;
|
||||
}
|
||||
|
||||
// Enable caching of the sockets. This will add references
|
||||
// to all existing and all future sockets
|
||||
if(hs->dwFeatures & CASC_FEATURE_ONLINE)
|
||||
sockets_set_caching(true);
|
||||
|
||||
// Now, load the main storage file (".build.info", ".build.db" or "versions")
|
||||
dwErrCode = LoadMainFile(hs);
|
||||
}
|
||||
|
||||
// Proceed with loading the CDN config file
|
||||
@@ -1439,33 +1379,49 @@ bool WINAPI CascOpenStorageEx(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs, b
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the storage structure
|
||||
// Now we need to get the CASC main file, which is either
|
||||
// [*] .build.info - for current local storages
|
||||
// [*] .build.db - for older local storages
|
||||
// [*] versions - for cached online storages
|
||||
// If there is none of these and `bOnlineStorage` is specified,
|
||||
// CascLib will download it, as long as the product code was specified
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
{
|
||||
if((hs = new TCascStorage()) != NULL)
|
||||
{
|
||||
// Setup the directories
|
||||
dwErrCode = (bOnlineStorage) ? InitializeOnlineDirectories(hs, pArgs) : InitializeLocalDirectories(hs, pArgs);
|
||||
if(dwErrCode == ERROR_SUCCESS)
|
||||
CASC_BUILD_FILE BuildFile = {NULL};
|
||||
DWORD dwFeatures = bOnlineStorage ? CASC_FEATURE_ONLINE : 0;
|
||||
|
||||
// Check for one of the supported main files (.build.info, .build.db, versions)
|
||||
if((dwErrCode = CheckCascBuildFileExact(BuildFile, pArgs->szLocalPath)) == ERROR_SUCCESS)
|
||||
{
|
||||
// Perform the entire storage loading
|
||||
dwErrCode = LoadCascStorage(hs, pArgs);
|
||||
dwErrCode = LoadCascStorage(hs, pArgs, BuildFile.szFullPath, BuildFile.BuildFileType, dwFeatures | CASC_FEATURE_DATA_ARCHIVES | CASC_FEATURE_DATA_FILES);
|
||||
}
|
||||
|
||||
// Search the folder and upper folders for the build file
|
||||
else if((dwErrCode = CheckCascBuildFileDirs(BuildFile, pArgs->szLocalPath)) == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = LoadCascStorage(hs, pArgs, BuildFile.szFullPath, BuildFile.BuildFileType, dwFeatures | CASC_FEATURE_DATA_ARCHIVES | CASC_FEATURE_DATA_FILES);
|
||||
}
|
||||
|
||||
// If the caller requested an online storage, we must have the code name
|
||||
else if((dwErrCode = CheckOnlineStorage(pArgs, BuildFile, dwFeatures)) == ERROR_SUCCESS)
|
||||
{
|
||||
dwErrCode = LoadCascStorage(hs, pArgs, BuildFile.szFullPath, BuildFile.BuildFileType, dwFeatures | CASC_FEATURE_DATA_FILES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle errors
|
||||
// Delete the storage on error
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
{
|
||||
SetCascError(dwErrCode);
|
||||
hs = hs->Release();
|
||||
}
|
||||
|
||||
// Free the copy of the parameters
|
||||
CASC_FREE(szParamsCopy);
|
||||
|
||||
// Give the output parameter to the caller
|
||||
*phStorage = (HANDLE)hs;
|
||||
if(phStorage != NULL)
|
||||
phStorage[0] = (HANDLE)hs;
|
||||
if(dwErrCode != ERROR_SUCCESS)
|
||||
SetCascError(dwErrCode);
|
||||
return (dwErrCode == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user