aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/CascBuildCfg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dep/CascLib/src/CascBuildCfg.cpp')
-rw-r--r--dep/CascLib/src/CascBuildCfg.cpp1032
1 files changed, 0 insertions, 1032 deletions
diff --git a/dep/CascLib/src/CascBuildCfg.cpp b/dep/CascLib/src/CascBuildCfg.cpp
deleted file mode 100644
index f39f09d886a..00000000000
--- a/dep/CascLib/src/CascBuildCfg.cpp
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*****************************************************************************/
-/* CascBuildCfg.cpp Copyright (c) Ladislav Zezula 2014 */
-/*---------------------------------------------------------------------------*/
-/* Build configuration for CascLib */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 29.04.14 1.00 Lad The first version of CascBuildCfg.cpp */
-/*****************************************************************************/
-
-#define __CASCLIB_SELF__
-#include "CascLib.h"
-#include "CascCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static bool inline IsValueSeparator(LPBYTE pbVarValue)
-{
- return ((0 <= pbVarValue[0] && pbVarValue[0] <= 0x20) || (pbVarValue[0] == '|'));
-}
-
-static bool IsCharDigit(BYTE OneByte)
-{
- return ('0' <= OneByte && OneByte <= '9');
-}
-
-static void FreeCascBlob(PQUERY_KEY pBlob)
-{
- if(pBlob != NULL)
- {
- if(pBlob->pbData != NULL)
- CASC_FREE(pBlob->pbData);
-
- pBlob->pbData = NULL;
- pBlob->cbData = 0;
- }
-}
-
-static DWORD GetLocaleMask(const char * szTag)
-{
- if(!strcmp(szTag, "enUS"))
- return CASC_LOCALE_ENUS;
-
- if(!strcmp(szTag, "koKR"))
- return CASC_LOCALE_KOKR;
-
- if(!strcmp(szTag, "frFR"))
- return CASC_LOCALE_FRFR;
-
- if(!strcmp(szTag, "deDE"))
- return CASC_LOCALE_DEDE;
-
- if(!strcmp(szTag, "zhCN"))
- return CASC_LOCALE_ZHCN;
-
- if(!strcmp(szTag, "esES"))
- return CASC_LOCALE_ESES;
-
- if(!strcmp(szTag, "zhTW"))
- return CASC_LOCALE_ZHTW;
-
- if(!strcmp(szTag, "enGB"))
- return CASC_LOCALE_ENGB;
-
- if(!strcmp(szTag, "enCN"))
- return CASC_LOCALE_ENCN;
-
- if(!strcmp(szTag, "enTW"))
- return CASC_LOCALE_ENTW;
-
- if(!strcmp(szTag, "esMX"))
- return CASC_LOCALE_ESMX;
-
- if(!strcmp(szTag, "ruRU"))
- return CASC_LOCALE_RURU;
-
- if(!strcmp(szTag, "ptBR"))
- return CASC_LOCALE_PTBR;
-
- if(!strcmp(szTag, "itIT"))
- return CASC_LOCALE_ITIT;
-
- if(!strcmp(szTag, "ptPT"))
- return CASC_LOCALE_PTPT;
-
- return 0;
-}
-
-static bool IsInfoVariable(const char * szLineBegin, const char * szLineEnd, const char * szVarName, const char * szVarType)
-{
- size_t nLength;
-
- // Check the variable name
- nLength = strlen(szVarName);
- if((size_t)(szLineEnd - szLineBegin) > nLength)
- {
- // Check the variable name
- if(!_strnicmp(szLineBegin, szVarName, nLength))
- {
- // Skip variable name and the exclamation mark
- szLineBegin += nLength;
- if(szLineBegin < szLineEnd && szLineBegin[0] == '!')
- {
- // Skip the exclamation mark
- szLineBegin++;
-
- // Check the variable type
- nLength = strlen(szVarType);
- if((size_t)(szLineEnd - szLineBegin) > nLength)
- {
- // Check the variable name
- if(!_strnicmp(szLineBegin, szVarType, nLength))
- {
- // Skip variable type and the doublecolon
- szLineBegin += nLength;
- return (szLineBegin < szLineEnd && szLineBegin[0] == ':');
- }
- }
- }
- }
- }
-
- return false;
-}
-
-static const char * SkipInfoVariable(const char * szLineBegin, const char * szLineEnd)
-{
- while(szLineBegin < szLineEnd)
- {
- if(szLineBegin[0] == '|')
- return szLineBegin + 1;
-
- szLineBegin++;
- }
-
- return NULL;
-}
-
-static TCHAR * CheckForIndexDirectory(TCascStorage * hs, const TCHAR * szSubDir)
-{
- TCHAR * szIndexPath;
-
- // Cpmbine the index path
- szIndexPath = CombinePath(hs->szDataPath, szSubDir);
- if(DirectoryExists(szIndexPath))
- {
- hs->szIndexPath = szIndexPath;
- return hs->szIndexPath;
- }
-
- CASC_FREE(szIndexPath);
- return NULL;
-}
-
-TCHAR * AppendBlobText(TCHAR * szBuffer, LPBYTE pbData, DWORD cbData, TCHAR chSeparator)
-{
- // Put the separator, if any
- if(chSeparator != 0)
- *szBuffer++ = chSeparator;
-
- // Copy the blob data as text
- for(DWORD i = 0; i < cbData; i++)
- {
- *szBuffer++ = IntToHexChar[pbData[0] >> 0x04];
- *szBuffer++ = IntToHexChar[pbData[0] & 0x0F];
- pbData++;
- }
-
- // Terminate the string
- *szBuffer = 0;
-
- // Return new buffer position
- return szBuffer;
-}
-
-static int StringBlobToBinaryBlob(
- PQUERY_KEY pBlob,
- LPBYTE pbBlobBegin,
- LPBYTE pbBlobEnd)
-{
- // Sanity checks
- assert(pBlob != NULL && pBlob->pbData != NULL);
-
- // Reset the blob length
- pBlob->cbData = 0;
-
- // Convert the blob
- while(pbBlobBegin < pbBlobEnd)
- {
- BYTE DigitOne;
- BYTE DigitTwo;
-
- DigitOne = (BYTE)(AsciiToUpperTable_BkSlash[pbBlobBegin[0]] - '0');
- if(DigitOne > 9)
- DigitOne -= 'A' - '9' - 1;
-
- DigitTwo = (BYTE)(AsciiToUpperTable_BkSlash[pbBlobBegin[1]] - '0');
- if(DigitTwo > 9)
- DigitTwo -= 'A' - '9' - 1;
-
- if(DigitOne > 0x0F || DigitTwo > 0x0F || pBlob->cbData >= MAX_CASC_KEY_LENGTH)
- return ERROR_BAD_FORMAT;
-
- pBlob->pbData[pBlob->cbData++] = (DigitOne << 0x04) | DigitTwo;
- pbBlobBegin += 2;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-static LPBYTE FindNextSeparator(PQUERY_KEY pFileBlob, LPBYTE pbFilePtr)
-{
- LPBYTE pbFileBegin = pFileBlob->pbData;
- LPBYTE pbFileEnd = pFileBlob->pbData + pFileBlob->cbData;
-
- if(pbFileBegin <= pbFilePtr && pbFilePtr < pbFileEnd)
- {
- while(pbFilePtr < pbFileEnd && pbFilePtr[0] != '|')
- pbFilePtr++;
-
- return pbFilePtr;
- }
-
- return NULL;
-}
-
-static bool GetNextFileLine(PQUERY_KEY pFileBlob, LPBYTE * ppbLineBegin, LPBYTE * ppbLineEnd)
-{
- LPBYTE pbLineBegin = *ppbLineBegin;
- LPBYTE pbLineEnd = *ppbLineEnd;
- LPBYTE pbFileEnd = pFileBlob->pbData + pFileBlob->cbData;
-
- // If there was a previous line, skip all end-of-line chars
- if(pbLineEnd != NULL)
- {
- // Go to the next line
- while(pbLineEnd < pbFileEnd && (pbLineEnd[0] == 0x0A || pbLineEnd[0] == 0x0D))
- pbLineEnd++;
- pbLineBegin = pbLineEnd;
-
- // If there is no more data, return false
- if(pbLineEnd >= pbFileEnd)
- return false;
- }
-
- // Skip all spaces before the line begins
- while(pbLineBegin < pbFileEnd && (pbLineBegin[0] == 0x09 || pbLineBegin[0] == 0x20))
- pbLineBegin++;
- pbLineEnd = pbLineBegin;
-
- // Go to the end of the line
- while(pbLineEnd < pbFileEnd && pbLineEnd[0] != 0x0A && pbLineEnd[0] != 0x0D)
- pbLineEnd++;
-
- // Give the results to the caller
- *ppbLineBegin = pbLineBegin;
- *ppbLineEnd = pbLineEnd;
- return true;
-}
-
-static LPBYTE CheckLineVariable(LPBYTE pbLineBegin, LPBYTE pbLineEnd, const char * szVarName)
-{
- size_t nLineLength = (size_t)(pbLineEnd - pbLineBegin);
- size_t nNameLength = strlen(szVarName);
-
- // If the line longer than the variable name?
- if(nLineLength > nNameLength)
- {
- if(!_strnicmp((const char *)pbLineBegin, szVarName, nNameLength))
- {
- // Skip the variable name
- pbLineBegin += nNameLength;
-
- // Skip the separator(s)
- while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
- pbLineBegin++;
-
- // Check if there is "="
- if(pbLineBegin >= pbLineEnd || pbLineBegin[0] != '=')
- return NULL;
- pbLineBegin++;
-
- // Skip the separator(s)
- while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
- pbLineBegin++;
-
- // Check if there is "="
- if(pbLineBegin >= pbLineEnd)
- return NULL;
-
- // Return the begin of the variable
- return pbLineBegin;
- }
- }
-
- return NULL;
-}
-
-static int LoadInfoVariable(PQUERY_KEY pVarBlob, const char * szLineBegin, const char * szLineEnd, bool bHexaValue)
-{
- const char * szLinePtr = szLineBegin;
-
- // Sanity checks
- assert(pVarBlob->pbData == NULL);
- assert(pVarBlob->cbData == 0);
-
- // Check length of the variable
- while(szLinePtr < szLineEnd && szLinePtr[0] != '|')
- szLinePtr++;
-
- // Allocate space for the blob
- if(bHexaValue)
- {
- // Initialize the blob
- pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) / 2);
- return StringBlobToBinaryBlob(pVarBlob, (LPBYTE)szLineBegin, (LPBYTE)szLinePtr);
- }
-
- // Initialize the blob
- pVarBlob->pbData = CASC_ALLOC(BYTE, (szLinePtr - szLineBegin) + 1);
- pVarBlob->cbData = (DWORD)(szLinePtr - szLineBegin);
-
- // Check for success
- if(pVarBlob->pbData == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Copy the string
- memcpy(pVarBlob->pbData, szLineBegin, pVarBlob->cbData);
- pVarBlob->pbData[pVarBlob->cbData] = 0;
- return ERROR_SUCCESS;
-}
-
-
-static void AppendConfigFilePath(TCHAR * szFileName, PQUERY_KEY pFileKey)
-{
- // Get to the end of the file name
- szFileName = szFileName + _tcslen(szFileName);
-
- // Append the "config" directory
- _tcscat(szFileName, _T("/config"));
- szFileName += 7;
-
- // Append the first level directory
- szFileName = AppendBlobText(szFileName, pFileKey->pbData, 1, _T('/'));
- szFileName = AppendBlobText(szFileName, pFileKey->pbData + 1, 1, _T('/'));
- szFileName = AppendBlobText(szFileName, pFileKey->pbData, pFileKey->cbData, _T('/'));
-}
-
-static DWORD GetBlobCount(LPBYTE pbLineBegin, LPBYTE pbLineEnd)
-{
- DWORD dwBlobCount = 0;
-
- // Until we find an end of the line
- while(pbLineBegin < pbLineEnd)
- {
- // Skip the blob
- while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin) == false)
- pbLineBegin++;
-
- // Increment the number of blobs
- dwBlobCount++;
-
- // Skip the separator
- while(pbLineBegin < pbLineEnd && IsValueSeparator(pbLineBegin))
- pbLineBegin++;
- }
-
- return dwBlobCount;
-}
-
-static int LoadBlobArray(
- PQUERY_KEY pBlob,
- DWORD dwMaxBlobs,
- LPBYTE pbLineBegin,
- LPBYTE pbLineEnd,
- LPBYTE pbBuffer,
- DWORD dwBufferSize)
-{
- LPBYTE pbBlobBegin = pbLineBegin;
- LPBYTE pbBlobEnd = pbLineBegin;
- int nError = ERROR_SUCCESS;
-
- // Sanity check
- assert(pbBuffer != NULL);
-
- // Until we find an end of the line
- while(pbBlobBegin < pbLineEnd)
- {
- // Convert the blob from string to binary
- if(dwBufferSize < MAX_CASC_KEY_LENGTH)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Find the end of the text blob
- while(pbBlobEnd < pbLineEnd && IsValueSeparator(pbBlobEnd) == false)
- pbBlobEnd++;
-
- // Convert the blob from ANSI to binary
- pBlob->pbData = pbBuffer;
- nError = StringBlobToBinaryBlob(pBlob, pbBlobBegin, pbBlobEnd);
- if(nError != ERROR_SUCCESS || dwMaxBlobs == 1)
- break;
-
- // Move the blob, buffer, and limits
- dwBufferSize -= MAX_CASC_KEY_LENGTH;
- pbBuffer += MAX_CASC_KEY_LENGTH;
- dwMaxBlobs--;
- pBlob++;
-
- // Skip the separator
- while(pbBlobEnd < pbLineEnd && IsValueSeparator(pbBlobEnd))
- pbBlobEnd++;
- pbBlobBegin = pbBlobEnd;
- }
-
- return nError;
-}
-
-static int LoadSingleBlob(PQUERY_KEY pBlob, LPBYTE pbBlobBegin, LPBYTE pbBlobEnd)
-{
- LPBYTE pbBuffer;
- size_t nLength = (pbBlobEnd - pbBlobBegin) / 2;
-
- // Check maximum size
- if(nLength > MAX_CASC_KEY_LENGTH)
- return ERROR_INVALID_PARAMETER;
-
- // Allocate the blob buffer
- pbBuffer = CASC_ALLOC(BYTE, MAX_CASC_KEY_LENGTH);
- if(pbBuffer == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- return LoadBlobArray(pBlob, 1, pbBlobBegin, pbBlobEnd, pbBuffer, MAX_CASC_KEY_LENGTH);
-}
-
-static PQUERY_KEY LoadMultipleBlobs(LPBYTE pbLineBegin, LPBYTE pbLineEnd, DWORD * pdwBlobCount)
-{
- PQUERY_KEY pBlobArray = NULL;
- LPBYTE pbBuffer = NULL;
- DWORD dwBlobCount = GetBlobCount(pbLineBegin, pbLineEnd);
- int nError;
-
- // Only if there is at least 1 blob
- if(dwBlobCount != 0)
- {
- // Allocate the array of blobs
- pBlobArray = CASC_ALLOC(QUERY_KEY, dwBlobCount);
- if(pBlobArray != NULL)
- {
- // Zero the blob array
- memset(pBlobArray, 0, dwBlobCount * sizeof(QUERY_KEY));
-
- // Allocate buffer for the blobs
- pbBuffer = CASC_ALLOC(BYTE, dwBlobCount * MAX_CASC_KEY_LENGTH);
- if(pbBuffer != NULL)
- {
- // Zero the buffer
- memset(pbBuffer, 0, dwBlobCount * MAX_CASC_KEY_LENGTH);
-
- // Load the entire blob array
- nError = LoadBlobArray(pBlobArray, dwBlobCount, pbLineBegin, pbLineEnd, pbBuffer, dwBlobCount * MAX_CASC_KEY_LENGTH);
- if(nError == ERROR_SUCCESS)
- {
- *pdwBlobCount = dwBlobCount;
- return pBlobArray;
- }
-
- // Free the buffer
- CASC_FREE(pbBuffer);
- }
-
- // Free the array of blobs
- CASC_FREE(pBlobArray);
- pBlobArray = NULL;
- }
-
- // Reset the blob count
- dwBlobCount = 0;
- }
-
- *pdwBlobCount = dwBlobCount;
- return pBlobArray;
-}
-
-static int LoadTextFile(const TCHAR * szFileName, PQUERY_KEY pFileBlob)
-{
- TFileStream * pStream;
- ULONGLONG FileSize = 0;
- int nError = ERROR_SUCCESS;
-
- // Open the agent file
- pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
- if(pStream != NULL)
- {
- // Retrieve its size
- FileStream_GetSize(pStream, &FileSize);
-
- // Load the file to memory
- if(0 < FileSize && FileSize < 0x100000)
- {
- // Initialize the blob
- pFileBlob->cbData = (DWORD)FileSize;
- pFileBlob->pbData = CASC_ALLOC(BYTE, pFileBlob->cbData + 1);
-
- // Load the file data into the blob
- if(pFileBlob->pbData != NULL)
- {
- FileStream_Read(pStream, NULL, pFileBlob->pbData, (DWORD)FileSize);
- pFileBlob->pbData[pFileBlob->cbData] = 0;
- }
- else
- nError = ERROR_NOT_ENOUGH_MEMORY;
- }
- else
- nError = ERROR_INVALID_PARAMETER;
-
- FileStream_Close(pStream);
- }
- else
- nError = GetLastError();
-
- return nError;
-}
-
-static int GetGameType(TCascStorage * hs, LPBYTE pbVarBegin, LPBYTE pbLineEnd)
-{
- // Alpha build of Heroes of the Storm
- if((pbLineEnd - pbVarBegin) == 4 && !_strnicmp((const char *)pbVarBegin, "Hero", 4))
- {
- hs->dwGameInfo = CASC_GAME_HOTS;
- return ERROR_SUCCESS;
- }
-
- // Alpha build of World of Warcraft - Warlords of Draenor
- if((pbLineEnd - pbVarBegin) == 3 && !_strnicmp((const char *)pbVarBegin, "WoW", 3))
- {
- hs->dwGameInfo = CASC_GAME_WOW6;
- return ERROR_SUCCESS;
- }
-
- // Diablo III BETA 2.2.0
- if((pbLineEnd - pbVarBegin) == 7 && !_strnicmp((const char *)pbVarBegin, "Diablo3", 7))
- {
- hs->dwGameInfo = CASC_GAME_DIABLO3;
- return ERROR_SUCCESS;
- }
-
- // An unknown game
- assert(false);
- return ERROR_BAD_FORMAT;
-}
-
-// "B29049"
-// "WOW-18125patch6.0.1"
-// "30013_Win32_2_2_0_Ptr_ptr"
-static int GetBuildNumber(TCascStorage * hs, LPBYTE pbVarBegin, LPBYTE pbLineEnd)
-{
- DWORD dwBuildNumber = 0;
-
- // Skip all non-digit characters
- while(pbVarBegin < pbLineEnd && IsCharDigit(pbVarBegin[0]) == false)
- pbVarBegin++;
-
- // Convert the build number
- while(pbVarBegin < pbLineEnd && IsCharDigit(pbVarBegin[0]))
- dwBuildNumber = (dwBuildNumber * 10) + (*pbVarBegin++ - '0');
-
- assert(dwBuildNumber != 0);
- hs->dwBuildNumber = dwBuildNumber;
- return (dwBuildNumber != 0) ? ERROR_SUCCESS : ERROR_BAD_FORMAT;
-}
-
-static int GetDefaultLocaleMask(TCascStorage * hs, PQUERY_KEY pTagsString)
-{
- char * szTagEnd = (char *)pTagsString->pbData + pTagsString->cbData;
- char * szTagPtr = (char *)pTagsString->pbData;
- char * szNext;
- DWORD dwLocaleMask = 0;
-
- while(szTagPtr < szTagEnd)
- {
- // Get the next part
- szNext = strchr(szTagPtr, ' ');
- if(szNext != NULL)
- *szNext++ = 0;
-
- // Check whether the current tag is a language identifier
- dwLocaleMask = dwLocaleMask | GetLocaleMask(szTagPtr);
-
- // Get the next part
- if(szNext == NULL)
- break;
-
- // Skip spaces
- while(szNext < szTagEnd && szNext[0] == ' ')
- szNext++;
- szTagPtr = szNext;
- }
-
- hs->dwDefaultLocale = dwLocaleMask;
- return ERROR_SUCCESS;
-}
-
-static int FetchAndVerifyConfigFile(TCascStorage * hs, PQUERY_KEY pFileKey, PQUERY_KEY pFileBlob)
-{
- TCHAR * szFileName;
- int nError;
-
- // Construct the local file name
- szFileName = NewStr(hs->szDataPath, 8 + 3 + 3 + 32);
- if(szFileName == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Add the part where the config file path is
- AppendConfigFilePath(szFileName, pFileKey);
-
- // Load the config file
- nError = LoadTextFile(szFileName, pFileBlob);
- if(nError == ERROR_SUCCESS)
- {
- // Verify the blob's MD5
- if(!VerifyDataBlockHash(pFileBlob->pbData, pFileBlob->cbData, pFileKey->pbData))
- {
- FreeCascBlob(pFileBlob);
- nError = ERROR_BAD_FORMAT;
- }
- }
-
- CASC_FREE(szFileName);
- return nError;
-}
-
-static int ParseInfoFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
-{
- QUERY_KEY Active = {NULL, 0};
- QUERY_KEY TagString = {NULL, 0};
- QUERY_KEY CdnHost = {NULL, 0};
- QUERY_KEY CdnPath = {NULL, 0};
- const char * szLineBegin1 = NULL;
- const char * szLinePtr1 = NULL;
- const char * szLineBegin2 = NULL;
- const char * szLineEnd1 = NULL;
- const char * szLineEnd2 = NULL;
- const char * szFileEnd = (const char *)(pFileBlob->pbData + pFileBlob->cbData);
- const char * szFilePtr = (const char *)pFileBlob->pbData;
- int nError = ERROR_BAD_FORMAT;
-
- // Find the first line
- szLineBegin1 = szFilePtr;
- while(szFilePtr < szFileEnd)
- {
- // Check for the end of the line
- if(szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A)
- {
- szLineEnd1 = szFilePtr;
- break;
- }
-
- szFilePtr++;
- }
-
- while (szFilePtr < szFileEnd)
- {
- szLinePtr1 = szLineBegin1;
-
- // Skip the newline character(s)
- while (szFilePtr < szFileEnd && (szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A))
- szFilePtr++;
-
- // Find the next line
- szLineBegin2 = szFilePtr;
- while (szFilePtr < szFileEnd)
- {
- // Check for the end of the line
- if (szFilePtr[0] == 0x0D || szFilePtr[0] == 0x0A)
- {
- szLineEnd2 = szFilePtr;
- break;
- }
-
- szFilePtr++;
- }
-
- // Find the build key, CDN config key and the URL path
- while (szLinePtr1 < szLineEnd1)
- {
- // Check for variables we need
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "Active", "DEC"))
- LoadInfoVariable(&Active, szLineBegin2, szLineEnd2, false);
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "Build Key", "HEX"))
- LoadInfoVariable(&hs->CdnBuildKey, szLineBegin2, szLineEnd2, true);
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "CDN Key", "HEX"))
- LoadInfoVariable(&hs->CdnConfigKey, szLineBegin2, szLineEnd2, true);
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "CDN Hosts", "STRING"))
- LoadInfoVariable(&CdnHost, szLineBegin2, szLineEnd2, false);
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "CDN Path", "STRING"))
- LoadInfoVariable(&CdnPath, szLineBegin2, szLineEnd2, false);
- if (IsInfoVariable(szLinePtr1, szLineEnd1, "Tags", "STRING"))
- LoadInfoVariable(&TagString, szLineBegin2, szLineEnd2, false);
-
- // Move both line pointers
- szLinePtr1 = SkipInfoVariable(szLinePtr1, szLineEnd1);
- if (szLineBegin1 == NULL)
- break;
-
- szLineBegin2 = SkipInfoVariable(szLineBegin2, szLineEnd2);
- if (szLineBegin2 == NULL)
- break;
- }
-
- // Stop parsing if found active config
- if (Active.pbData != NULL && *Active.pbData == '1')
- break;
- }
-
- // All four must be present
- if(hs->CdnBuildKey.pbData != NULL &&
- hs->CdnConfigKey.pbData != NULL &&
- CdnHost.pbData != NULL &&
- CdnPath.pbData != NULL)
- {
- // Merge the CDN host and CDN path
- hs->szUrlPath = CASC_ALLOC(TCHAR, CdnHost.cbData + CdnPath.cbData + 1);
- if(hs->szUrlPath != NULL)
- {
- CopyString(hs->szUrlPath, (char *)CdnHost.pbData, CdnHost.cbData);
- CopyString(hs->szUrlPath + CdnHost.cbData, (char *)CdnPath.pbData, CdnPath.cbData);
- nError = ERROR_SUCCESS;
- }
- }
-
- // If we found tags, we can extract language build from it
- if(TagString.pbData != NULL)
- GetDefaultLocaleMask(hs, &TagString);
-
- FreeCascBlob(&CdnHost);
- FreeCascBlob(&CdnPath);
- FreeCascBlob(&TagString);
- return nError;
-}
-
-static int ParseAgentFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
-{
- LPBYTE pbBlobBegin = pFileBlob->pbData;
- LPBYTE pbBlobEnd;
- int nError = ERROR_SUCCESS;
-
- // Extract the CDN build hash
- pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
- if(pbBlobEnd != NULL)
- {
- // Convert the string to a blob
- nError = LoadSingleBlob(&hs->CdnBuildKey, pbBlobBegin, pbBlobEnd);
-
- // Move to the next part
- if(pbBlobEnd[0] == _T('|'))
- pbBlobEnd++;
- pbBlobBegin = pbBlobEnd;
- }
-
- // Extract the CDN config hash
- pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
- if(pbBlobEnd != NULL)
- {
- // Convert the string to a blob
- nError = LoadSingleBlob(&hs->CdnConfigKey, pbBlobBegin, pbBlobEnd);
-
- // Move to the next part
- if(pbBlobEnd[0] == _T('|'))
- pbBlobEnd++;
- pbBlobBegin = pbBlobEnd;
- }
-
- // Skip the intermediate part
- pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
- if(pbBlobEnd != NULL)
- {
- // Move to the next part
- if(pbBlobEnd[0] == _T('|'))
- pbBlobEnd++;
- pbBlobBegin = pbBlobEnd;
- }
-
- // Extract the URL config hash
- pbBlobEnd = FindNextSeparator(pFileBlob, pbBlobBegin);
- if(pbBlobEnd != NULL)
- {
- // Convert the string to a blob
- hs->szUrlPath = NewStrFromAnsi(pbBlobBegin, pbBlobEnd);
- }
-
- // Verify all variables
- if(hs->CdnBuildKey.pbData == NULL || hs->CdnConfigKey.pbData == NULL || hs->szUrlPath == NULL)
- nError = ERROR_BAD_FORMAT;
- return nError;
-}
-
-static int LoadCdnConfigFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
-{
- LPBYTE pbLineBegin = pFileBlob->pbData;
- LPBYTE pbVarBegin;
- LPBYTE pbLineEnd = NULL;
- int nError;
-
- while(pbLineBegin != NULL)
- {
- // Get the next line
- if(!GetNextFileLine(pFileBlob, &pbLineBegin, &pbLineEnd))
- break;
-
- // Archive group
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "archive-group");
- if(pbVarBegin != NULL)
- {
- nError = LoadSingleBlob(&hs->ArchiveGroup, pbVarBegin, pbLineEnd);
- if(nError != ERROR_SUCCESS)
- return nError;
- continue;
- }
-
- // Archives
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "archives");
- if(pbVarBegin != NULL)
- {
- hs->pArchiveArray = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->ArchiveCount);
- if(hs->pArchiveArray == NULL || hs->ArchiveCount == 0)
- return ERROR_BAD_FORMAT;
- continue;
- }
-
- // Patch archive group
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch-archive-group");
- if(pbVarBegin != NULL)
- {
- LoadSingleBlob(&hs->PatchArchiveGroup, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Patch archives
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch-archives");
- if(pbVarBegin != NULL)
- {
- hs->pPatchArchiveArray = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->PatchArchiveCount);
- continue;
- }
- }
-
- // Check if all required fields are present
- if(hs->ArchiveGroup.pbData == NULL || hs->ArchiveGroup.cbData == 0 || hs->pArchiveArray == NULL || hs->ArchiveCount == 0)
- return ERROR_BAD_FORMAT;
-
- return ERROR_SUCCESS;
-}
-
-static int LoadCdnBuildFile(TCascStorage * hs, PQUERY_KEY pFileBlob)
-{
- LPBYTE pbLineBegin = pFileBlob->pbData;
- LPBYTE pbVarBegin;
- LPBYTE pbLineEnd = NULL;
-
- while(pbLineBegin != NULL)
- {
- // Get the next line
- if(!GetNextFileLine(pFileBlob, &pbLineBegin, &pbLineEnd))
- break;
-
- // Game name
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "build-product");
- if(pbVarBegin != NULL)
- {
- GetGameType(hs, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Game build number
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "build-name");
- if(pbVarBegin != NULL)
- {
- GetBuildNumber(hs, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Root
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "root");
- if(pbVarBegin != NULL)
- {
- LoadSingleBlob(&hs->RootKey, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Patch
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "patch");
- if(pbVarBegin != NULL)
- {
- LoadSingleBlob(&hs->PatchKey, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Download
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "download");
- if(pbVarBegin != NULL)
- {
- LoadSingleBlob(&hs->DownloadKey, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Install
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "install");
- if(pbVarBegin != NULL)
- {
- LoadSingleBlob(&hs->InstallKey, pbVarBegin, pbLineEnd);
- continue;
- }
-
- // Encoding keys
- pbVarBegin = CheckLineVariable(pbLineBegin, pbLineEnd, "encoding");
- if(pbVarBegin != NULL)
- {
- hs->pEncodingKeys = LoadMultipleBlobs(pbVarBegin, pbLineEnd, &hs->EncodingKeys);
- if(hs->pEncodingKeys == NULL || hs->EncodingKeys != 2)
- return ERROR_BAD_FORMAT;
-
- hs->EncodingKey = hs->pEncodingKeys[0];
- hs->EncodingEKey = hs->pEncodingKeys[1];
- continue;
- }
- }
-
- // Check the encoding keys
- if(hs->pEncodingKeys == NULL || hs->EncodingKeys == 0)
- return ERROR_BAD_FORMAT;
- return ERROR_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// Public functions
-
-int LoadBuildInfo(TCascStorage * hs)
-{
- QUERY_KEY InfoFile = {NULL, 0};
- QUERY_KEY FileData = {NULL, 0};
- TCHAR * szAgentFile;
- TCHAR * szInfoFile;
- bool bBuildConfigComplete = false;
- int nError = ERROR_SUCCESS;
-
- // Since HOTS build 30027, the game uses build.info file for storage info
- if(bBuildConfigComplete == false)
- {
- szInfoFile = CombinePath(hs->szRootPath, _T(".build.info"));
- if(szInfoFile != NULL)
- {
- nError = LoadTextFile(szInfoFile, &InfoFile);
- if(nError == ERROR_SUCCESS)
- {
- // Parse the info file
- nError = ParseInfoFile(hs, &InfoFile);
- if(nError == ERROR_SUCCESS)
- bBuildConfigComplete = true;
-
- // Free the loaded blob
- FreeCascBlob(&InfoFile);
- }
-
- CASC_FREE(szInfoFile);
- }
- }
-
- // If the info file has not been loaded, try the legacy .build.db
- if(bBuildConfigComplete == false)
- {
- szAgentFile = CombinePath(hs->szRootPath, _T(".build.db"));
- if(szAgentFile != NULL)
- {
- nError = LoadTextFile(szAgentFile, &FileData);
- if(nError == ERROR_SUCCESS)
- {
- nError = ParseAgentFile(hs, &FileData);
- if(nError == ERROR_SUCCESS)
- bBuildConfigComplete = true;
-
- FreeCascBlob(&FileData);
- }
- CASC_FREE(szAgentFile);
- }
- }
-
- // If the .build.info and .build.db file hasn't been loaded,
- if(nError == ERROR_SUCCESS && bBuildConfigComplete == false)
- {
- nError = ERROR_FILE_CORRUPT;
- }
-
- // Load the configuration file
- if(nError == ERROR_SUCCESS)
- {
- nError = FetchAndVerifyConfigFile(hs, &hs->CdnConfigKey, &FileData);
- if(nError == ERROR_SUCCESS)
- {
- nError = LoadCdnConfigFile(hs, &FileData);
- FreeCascBlob(&FileData);
- }
- }
-
- // Load the build file
- if(nError == ERROR_SUCCESS)
- {
- nError = FetchAndVerifyConfigFile(hs, &hs->CdnBuildKey, &FileData);
- if(nError == ERROR_SUCCESS)
- {
- nError = LoadCdnBuildFile(hs, &FileData);
- FreeCascBlob(&FileData);
- }
- }
-
- // Fill the index directory
- if(nError == ERROR_SUCCESS)
- {
- // First, check for more common "data" subdirectory
- if((hs->szIndexPath = CheckForIndexDirectory(hs, _T("data"))) != NULL)
- return ERROR_SUCCESS;
-
- // Second, try the "darch" subdirectory (older builds of HOTS - Alpha)
- if((hs->szIndexPath = CheckForIndexDirectory(hs, _T("darch"))) != NULL)
- return ERROR_SUCCESS;
-
- nError = ERROR_FILE_NOT_FOUND;
- }
-
- return nError;
-}