/* Creates and returns a new table with comparison function |compare| using parameter |param| and memory allocator |allocator|. Returns |NULL| if memory allocation failed. */ struct avl_table * avl_create (avl_comparison_func *compare, void *param /*struct libavl_allocator *allocator*/) { struct avl_table *tree; //assert (compare != NULL); // if (allocator == NULL) // allocator = &avl_allocator_default; #if defined(MIKTEX) && defined(__cplusplus) tree = (avl_table *)SMAlloc (/*allocator,*/ sizeof *tree); #else tree =(struct avl_table *) SMAlloc (/*allocator, */sizeof *tree); #endif if (tree == NULL) return NULL; tree->avl_root = NULL; //tree->avl_compare = compare; tree->avl_param = param; //tree->avl_alloc = allocator; tree->avl_count = 0; tree->avl_generation = 0; return tree; }
bool __stdcall GetMatrixMap(chunk *pChunk) { // Verify the chunk size if ( gwVersion == WARCRAFT2 || gwVersion == WARCRAFT2_EXP ) { // Limit Warcraft II map size if ( pChunk->dwSize > (128 * 128 * sizeof(WORD)) ) return false; } else { // Limit Starcraft map size if ( pChunk->dwSize > (256 * 256 * sizeof(WORD)) ) return false; } // Allocate memory for tiles if ( !pwMatrixMap ) { pwMatrixMap = (WORD*)SMAlloc(256 * 256 * sizeof(WORD)); atexit(&FreeMatrix); } // Copy the data memcpy(pwMatrixMap, pChunk->data, pChunk->dwSize); return true; }
void SetResolution(int width, int height) { if ( !isCorrectVersion ) return; // Resize game screen data buffer void *newBuf = SMAlloc(width * height); void *oldBuf = BW::BWDATA_GameScreenBuffer->data; SetBitmap(BW::BWDATA_GameScreenBuffer, width, height, newBuf); if ( oldBuf ) SMFree(oldBuf); // Set new screen limits BW::BWDATA_ScreenLayers[5].width = (WORD)width; BW::BWDATA_ScreenLayers[5].height = (WORD)height; SetRect(BW::BWDATA_ScrLimit, 0, 0, width - 1, height - 1); SetRect(BW::BWDATA_ScrSize, 0, 0, width, height); // Resize game screen console (HUD) buffer newBuf = SMAlloc(width * height); oldBuf = BW::BWDATA_GameScreenConsole->data; SetBitmap(BW::BWDATA_GameScreenConsole, width, height, newBuf); if ( oldBuf ) SMFree(oldBuf); // Recreate STrans thingy BW::BlizzVectorEntry<BW::TransVectorEntry> *transEntry = BW::BWDATA_TransMaskVector->begin; if ( (u32)transEntry && (u32)transEntry != (u32)&BW::BWDATA_TransMaskVector->begin ) { HANDLE oldTrans = transEntry->container.hTrans; SetRect(&transEntry->container.info, 0, 0, width, height); STransCreateE(newBuf, width, height, 8, 0, 0, &transEntry->container.hTrans); if ( oldTrans ) STransDelete(oldTrans); // call a function that does some weird stuff BW::BWFXN_UpdateBltMasks(); } STransSetDirtyArrayInfo(width, height, 16, 16); // re-initialize w-mode or ddraw, this function can do both SetWMode(width, height, wmode); }
BOOLEAN InitializeVirusList (VirusLnk *posVirusLnk) { VirusLnk *posTemp, *posPrevious; UINT32 nIndex; PAGED_CODE(); posVirusLnk->pPrevious = NULL; posTemp = posVirusLnk; posPrevious = NULL; for (nIndex = 0; nIndex < GV.pocSMVirusDatFile->m_osHeader.nGroupTableIndexCount; nIndex++) { ZeroMemory(posTemp, sizeof(VirusLnk)); posTemp->u32VirusId = nIndex; posTemp->posGroupTbl = GV.pocSMVirusDatFile->m_posVirusTable[nIndex]; posTemp->osParam.nCount = GV.pocSMVirusDatFile->m_posVirusTable[nIndex].nParamCount; posTemp->osParam.pnParams = (UINT32 *)SMAlloc(sizeof(UINT32) * GV.pocSMVirusDatFile->m_posVirusTable[nIndex].nParamCount); if( !posTemp->osParam.pnParams ) { UnInitializeVirusList(posVirusLnk); return FALSE; } ZeroMemory(posTemp->osParam.pnParams, sizeof(UINT32) * GV.pocSMVirusDatFile->m_posVirusTable[nIndex].nParamCount); posTemp->pPrevious = posPrevious; posPrevious = posTemp; posTemp->nVirusLength = GV.pocSMVirusDatFile->m_pnVirusLength[nIndex]; if ((nIndex + 1) < GV.pocSMVirusDatFile->m_osHeader.nGroupTableIndexCount) { posTemp->pNext = (VirusLnk*)SMAlloc(sizeof(VirusLnk)); if( !posTemp->pNext ) { UnInitializeVirusList(posVirusLnk); return FALSE; } posTemp = posTemp->pNext; } } return TRUE; }
char* GetPolyVirusName (UINT32 u32VirusID) { LARGE_INTEGER osAddress; UINT32 u32VirusNameLength; ULONG ulSize = sizeof(UINT32); char* pchVirusName; osAddress.QuadPart = GV.pocSMVirusDatFile->m_osHeader.nVirusNameTableAddress + (u32VirusID * ulSize /** 2*/); CryptSeek(GV.pocSMVirusDatFile->m_posFile, &osAddress.QuadPart); CryptRead(GV.pocSMVirusDatFile->m_posFile, &u32VirusNameLength, &ulSize); ulSize = u32VirusNameLength * sizeof(char); pchVirusName = (char *)SMAlloc(ulSize + 1); CryptRead(GV.pocSMVirusDatFile->m_posFile, pchVirusName, &ulSize); return pchVirusName; }
//------------------------------------------ GET MAP HASH -------------------------------------------------- std::string Map::getMapHash() { unsigned char hash[20]; char hexstring[42]; std::string filename = Map::getPathName(); // Open File HANDLE hFile = NULL; if ( !SFileOpenFileEx(NULL, filename.c_str(), SFILE_FROM_ABSOLUTE, &hFile) || !hFile) { char szPath[MAX_PATH]; SStrCopy(szPath, filename.c_str(), MAX_PATH); SStrNCat(szPath, "\\staredit\\scenario.chk", MAX_PATH); if ( !SFileOpenFileEx(NULL, szPath, SFILE_FROM_MPQ, &hFile) || !hFile) return std::string("Error_map_cannot_be_opened"); } // Obtain file size DWORD dwFileSize = SFileGetFileSize(hFile, 0); // Allocate memory void *pBuffer = SMAlloc(dwFileSize); if ( !pBuffer ) { SFileCloseFile(hFile); return std::string("Error_could_not_allocate_memory"); } // Read file DWORD dwBytesRead = 0; SFileReadFile(hFile, pBuffer, dwFileSize, &dwBytesRead, 0); // Calculate hash sha1::calc(pBuffer, dwBytesRead, hash); sha1::toHexString(hash, hexstring); // Free memory and return SMFree(pBuffer); SFileCloseFile(hFile); return string(hexstring); }
BOOLEAN InitializeCleanRoutine (VirtualMachine *posVm, VirusLnk *posVirusLnk, UINT32 nVirusIndex) { PAGED_CODE(); posVm->osCleanVirusLnk.posVirusTbl = GV.pocSMVirusDatFile->m_posCleanVirusTable[nVirusIndex]; posVm->osCleanVirusLnk.osParam.nCount = posVm->osCleanVirusLnk.posVirusTbl.nParamCount; if(posVm->osCleanVirusLnk.osParam.nCount) { posVm->osCleanVirusLnk.osParam.pnParams = (UINT32 *)SMAlloc(posVm->osCleanVirusLnk.osParam.nCount * sizeof(UINT32)); if (!posVm->osCleanVirusLnk.osParam.pnParams) { return FALSE; // Insufficient Resources } } ZeroMemory(posVm->osCleanVirusLnk.osParam.pnParams , posVm->osCleanVirusLnk.osParam.nCount * sizeof(UINT32)); posVm->osCleanVirusLnk.nVirusLength = GetVirusCodeLength(nVirusIndex); posVm->osCleanVirusLnk.pPrevious = NULL; return TRUE; }
Bitmap::Bitmap(int width, int height, void *pBuffer) : wid(static_cast<u16>(width)) , ht(static_cast<u16>(height)) , data(static_cast<u8*>(pBuffer != nullptr ? pBuffer : SMAlloc(width*height))) {}
UINT32 LoadVMDatFile() { SMFile osFile; BOOLEAN bResult; LARGE_INTEGER dnSeekParam; ULONG nSize ; UINT32 nIndex; PAGED_CODE() ; nSize = sizeof(TableHeader); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &GV.pocSMVirusDatFile->m_osHeader, &nSize))) { return -1; // Error Reading File } //dnSeekParam.QuadPart = GetCryptFileLength ( GV.pocSMVirusDatFile->m_posFile); //if(dnSeekParam.QuadPart == 0) //{ // return -1; // Error Getting File Size //} //nSize = (sizeof(TableHeader) + // GV.pocSMVirusDatFile->m_osHeader.nGroupTableIndexCount * sizeof(VirusTables) + // GV.pocSMVirusDatFile->m_osHeader.nStateNumberCount * sizeof(StateTables) + // GV.pocSMVirusDatFile->m_osHeader.nConditionStateCount * sizeof(Condition_State) + // GV.pocSMVirusDatFile->m_osHeader.nFunctionLength + // GV.pocSMVirusDatFile->m_osHeader.nConditionExpsLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * sizeof(VirusTables) + // GV.pocSMVirusDatFile->m_osHeader.nCleanStateNumberCount * sizeof(StateTables) + // GV.pocSMVirusDatFile->m_osHeader.nCleanConditionStateCount * sizeof(Condition_State) + // GV.pocSMVirusDatFile->m_osHeader.nCleanFunctionLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanConditionExpsLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * 2/*3*/ * sizeof(UINT32) + // GV.pocSMVirusDatFile->m_osHeader.nVirusNameLength); //if (dnSeekParam.QuadPart != (sizeof(TableHeader) + // GV.pocSMVirusDatFile->m_osHeader.nGroupTableIndexCount * sizeof(VirusTables) + // GV.pocSMVirusDatFile->m_osHeader.nStateNumberCount * sizeof(StateTables) + // GV.pocSMVirusDatFile->m_osHeader.nConditionStateCount * sizeof(Condition_State) + // GV.pocSMVirusDatFile->m_osHeader.nFunctionLength + // GV.pocSMVirusDatFile->m_osHeader.nConditionExpsLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * sizeof(VirusTables) + // GV.pocSMVirusDatFile->m_osHeader.nCleanStateNumberCount * sizeof(StateTables) + // GV.pocSMVirusDatFile->m_osHeader.nCleanConditionStateCount * sizeof(Condition_State) + // GV.pocSMVirusDatFile->m_osHeader.nCleanFunctionLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanConditionExpsLength + // GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * 2/*3*/ * sizeof(UINT32) + // GV.pocSMVirusDatFile->m_osHeader.nVirusNameLength)) //{ // return -1; //} // Read Group Indexes and Roots nSize = GV.pocSMVirusDatFile->m_osHeader.nGroupTableIndexCount * sizeof(VirusTables); GV.pocSMVirusDatFile->m_posVirusTable = (VirusTables*)SMAlloc(nSize); if(!GV.pocSMVirusDatFile->m_posVirusTable) { return -1;// Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posVirusTable, &nSize))) { return -1; // Error Reading File } // Read State Routing Table nSize = GV.pocSMVirusDatFile->m_osHeader.nStateNumberCount * sizeof(StateTables); GV.pocSMVirusDatFile->m_posStateTables = (StateTables*)SMAlloc(nSize); if(!GV.pocSMVirusDatFile->m_posStateTables) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posStateTables, &nSize))) { return -1; // Error Reading File } // Read Function Binaries nSize = GV.pocSMVirusDatFile->m_osHeader.nFunctionBinariesCount * sizeof(FunctionBinary); GV.pocSMVirusDatFile->m_posFunctionBinaries = (FunctionBinary*)SMAlloc(nSize); if(!GV.pocSMVirusDatFile->m_posFunctionBinaries) { return -1; // Insufficient Resources } for (nIndex = 0 ; nIndex < GV.pocSMVirusDatFile->m_osHeader.nFunctionBinariesCount; nIndex++) { UINT32 nLength; UINT8 byIsChangeContext, byType; nSize = sizeof(UINT32); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &nLength, &nSize))) { return -1; // Error Reading File } GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].nLength = nLength; nSize = sizeof(UINT8); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &byIsChangeContext, &nSize))) { return -1; // Error Reading File } GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].byIsChangeContext = byIsChangeContext; nSize = sizeof(UINT8); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &byType, &nSize))) { return -1; // Error Reading File } GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].byType = byType; GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].pbyExp = (UINT8*)SMAlloc(sizeof(UINT8) * (GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].nLength - (2 * sizeof(UINT8)))); if(!GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].pbyExp) { return -1; // Insufficient Resources } nSize = (GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].nLength - (2 * sizeof(UINT8))); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].pbyExp, &nSize))) { return -1; // Error Reading File } GV.pocSMVirusDatFile->m_posFunctionBinaries[nIndex].nLength = nSize; } // Read Main Table (Condition - State) nSize = GV.pocSMVirusDatFile->m_osHeader.nConditionStateCount * sizeof(Condition_State); GV.pocSMVirusDatFile->m_posCondition_State = (Condition_State*)SMAlloc(nSize); if(!GV.pocSMVirusDatFile->m_posCondition_State) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posCondition_State, &nSize))) { return -1; // Error Reading File } nSize = GV.pocSMVirusDatFile->m_osHeader.nConditionIndexCount * sizeof(ConditionExpression); GV.pocSMVirusDatFile->m_posConditionExpression = (ConditionExpression*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posConditionExpression) { return -1; // Insufficient Resources } for (nIndex = 0 ; nIndex < GV.pocSMVirusDatFile->m_osHeader.nConditionIndexCount; nIndex++) { UINT32 nLength = 0; nSize = sizeof(UINT32); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &nLength, &nSize))) { return -1; // Error Reading File } nSize = nLength; GV.pocSMVirusDatFile->m_posConditionExpression[nIndex].nLength = nLength; GV.pocSMVirusDatFile->m_posConditionExpression[nIndex].pbyExp = (UINT8*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posConditionExpression[nIndex].pbyExp) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posConditionExpression[nIndex].pbyExp, &nSize))) { return -1; // Error Reading File } } ////////////////////////////////////////////////////////////////////////// // Clean Part ////////////////////////////////////////////////////////////////////////// // Read Virus Indexes and Roots nSize = GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * sizeof(VirusTables); GV.pocSMVirusDatFile->m_posCleanVirusTable = (VirusTables*)SMAlloc(nSize); if(!GV.pocSMVirusDatFile->m_posCleanVirusTable) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posCleanVirusTable, &nSize))) { return -1; // Error Reading File } // Read Virus Lengths nSize = GV.pocSMVirusDatFile->m_osHeader.nCleanVirusTableIndexCount * sizeof(UINT32); GV.pocSMVirusDatFile->m_pnVirusLength = (UINT32 *)SMAlloc(nSize); if( !GV.pocSMVirusDatFile->m_pnVirusLength ) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_pnVirusLength, &nSize))) { return -1; // Error Reading File } // Read Clean State Routing Table nSize = GV.pocSMVirusDatFile->m_osHeader.nCleanStateNumberCount * sizeof(StateTables); GV.pocSMVirusDatFile->m_posCleanStateTables = (StateTables*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posCleanStateTables) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posCleanStateTables, &nSize))) { return -1; // Error Reading File } // Jump from Clean Function Binaries dnSeekParam.QuadPart = GV.pocSMVirusDatFile->m_osHeader.nCleanFunctionLength; if ( !NT_SUCCESS (CryptSeekCurrent(GV.pocSMVirusDatFile->m_posFile , &dnSeekParam.QuadPart))) { UnLoadVMDatFile(); return -1; } // Read Clean Main Table (Condition - State) nSize = GV.pocSMVirusDatFile->m_osHeader.nCleanConditionStateCount * sizeof(Condition_State); GV.pocSMVirusDatFile->m_posCleanCondition_State = (Condition_State*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posCleanCondition_State) { return -1; // Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posCleanCondition_State, &nSize))) { return -1; // Error Reading File } nSize = GV.pocSMVirusDatFile->m_osHeader.nCleanConditionIndexCount * sizeof(ConditionExpression); GV.pocSMVirusDatFile->m_posCleanConditionExpression = (ConditionExpression*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posCleanConditionExpression) { return -1;// Insufficient Resources } for (nIndex = 0 ; nIndex < GV.pocSMVirusDatFile->m_osHeader.nCleanConditionIndexCount; nIndex++) { UINT32 nLength = 0; nSize = sizeof(UINT32); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &nLength, &nSize))) { return -1; // Error Reading File } nSize = nLength; GV.pocSMVirusDatFile->m_posCleanConditionExpression[nIndex].nLength = nLength; GV.pocSMVirusDatFile->m_posCleanConditionExpression[nIndex].pbyExp = (UINT8*)SMAlloc(nSize); if (!GV.pocSMVirusDatFile->m_posCleanConditionExpression[nIndex].pbyExp) { return -1;// Insufficient Resources } if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, GV.pocSMVirusDatFile->m_posCleanConditionExpression[nIndex].pbyExp, &nSize))) { return -1; // Error Reading File } } return 0;// No Error }
FunctionBinary* GetCleanFunction(UINT32 nStateConIndex) { ULONG nSize; LARGE_INTEGER dnFuncOffset; FunctionBinary * posCleanReturnValue; PAGED_CODE(); dnFuncOffset.QuadPart = GV.pocSMVirusDatFile->m_posCleanCondition_State[nStateConIndex].nFunctionOffset; posCleanReturnValue = (FunctionBinary *)SMAlloc(sizeof(FunctionBinary)); if ( !posCleanReturnValue ) { return NULL; } ZeroMemory(posCleanReturnValue, sizeof(FunctionBinary)); if ( !NT_SUCCESS (CryptSeek(GV.pocSMVirusDatFile->m_posFile , &dnFuncOffset.QuadPart))) { SMFree(posCleanReturnValue); return NULL; // Error Seeking File } nSize = sizeof(UINT32); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &posCleanReturnValue->nLength, &nSize))) { SMFree(posCleanReturnValue); return NULL; // Error Reading File } nSize = sizeof(UINT8); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &posCleanReturnValue->byIsChangeContext, &nSize))) { SMFree(posCleanReturnValue); return NULL; // Error Reading File } nSize = sizeof(UINT8); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, &posCleanReturnValue->byType, &nSize))) { SMFree(posCleanReturnValue); return NULL; // Error Reading File } posCleanReturnValue->pbyExp = (UINT8*)SMAlloc(sizeof(UINT8) * (posCleanReturnValue->nLength - (2 * sizeof(UINT8)))); if( !posCleanReturnValue->pbyExp ) { SMFree(posCleanReturnValue); return NULL; } ZeroMemory(posCleanReturnValue->pbyExp, sizeof(UINT8) * (posCleanReturnValue->nLength - (2 * sizeof(UINT8)))); nSize = (posCleanReturnValue->nLength - (2 * sizeof(UINT8))); if(!NT_SUCCESS(CryptRead(GV.pocSMVirusDatFile->m_posFile, posCleanReturnValue->pbyExp, &nSize))) { SMFree(posCleanReturnValue); return NULL; // Error Reading File } posCleanReturnValue->nLength = nSize; return posCleanReturnValue; }
//------------------------------------------------- DLL MAIN ------------------------------------------------- BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif // Retrieve the initial configuration stuff if not already InitPrimaryConfig(); // Get revision/build automatically char szDllPath[MAX_PATH]; DWORD dwDesiredRevision = 0; std::string aicfg = LoadConfigString("ai", BUILD_DEBUG ? "ai_dbg" : "ai", "_NULL"); strncpy(szDllPath, aicfg.c_str(), MAX_PATH); if ( aicfg == "_NULL" ) { BWAPIError("Could not find %s under ai in \"%s\" for revision identification.", BUILD_DEBUG ? "ai_dbg" : "ai", szConfigPath); } else { DWORD dwDesiredBuild = 0; // 0 = undefined, 1 = release, 2 = debug // Tokenize and retrieve correct path for the instance number char *pszDll = strtok(szDllPath, ","); for ( unsigned int i = 0; i < gdwProcNum-1; ++i ) { char *pszNext = strtok(NULL, ","); if ( !pszNext ) break; pszDll = pszNext; } // Retrieve revision info if it exists char *pszLoadRevCheck = strchr(pszDll, ':'); if ( pszLoadRevCheck ) { pszLoadRevCheck[0] = 0; ++pszLoadRevCheck; sscanf(pszLoadRevCheck, "%u", &dwDesiredRevision); } // Remove spaces while ( isspace(pszDll[0]) ) ++pszDll; // Open File HANDLE hFile = NULL; if ( !SFileOpenFileEx(NULL, pszDll, SFILE_FROM_ABSOLUTE, &hFile) || !hFile) { BWAPIError("Could not load module \"%s\" for revision identification.", pszDll); } else { // Obtain file size DWORD dwFileSize = SFileGetFileSize(hFile, 0); // Allocate memory char *pbBuffer = (char*)SMAlloc(dwFileSize); if ( !pbBuffer ) { BWAPIError("Unable to allocate enough memory for module \"%s\" for revision identification.", pszDll); } else { // Read file DWORD dwBytesRead = 0; SFileReadFile(hFile, pbBuffer, dwFileSize, &dwBytesRead, 0); for ( u32 i = 0; i < dwBytesRead && (dwDesiredRevision == 0 || dwDesiredBuild == 0); ++i ) { if ( dwDesiredRevision == 0 && memcmp(&pbBuffer[i], "XBWAPIXREVISIONXSTAMPX", 22) == 0 ) { i += 22; sscanf(&pbBuffer[i], "%u", &dwDesiredRevision); i += 5; } // if REVISION if ( memcmp(&pbBuffer[i], "XBWAPIXBUILDXSTAMPX", 19) == 0 ) { i += 19; if ( strcmp(&pbBuffer[i], "DEBUG") == 0 ) { dwDesiredBuild = 2; i += 6; } else if ( strcmp(&pbBuffer[i], "RELEASE") == 0 ) { dwDesiredBuild = 1; i += 8; } } // if BUILD } // for (iterate file) // Free memory and close file SMFree(pbBuffer); SFileCloseFile(hFile); } // buffer was allocated } // file was opened /* Do revision checking */ if ( dwDesiredRevision > 0 && dwDesiredRevision != SVN_REV ) { // revision that ai_dll_# for multiple instances was introduced if ( gdwProcNum && dwDesiredRevision < 2753 && showWarn ) { char err[512]; sprintf(err, "Revision %u is not compatible with multiple instances.\nExpecting revision 2753 (BWAPI Beta 3.1) or greater. If you proceed, the older revision of BWAPI will attempt to load its module from ai_dll instead of the multi-instance specification. Do you want to continue anyway?", dwDesiredRevision); BWAPIError("%s", err); if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO ) return TRUE; } // revision is old if ( dwDesiredBuild == 0 ) dwDesiredBuild = BUILD_DEBUG + 1; char szRevModule[MAX_PATH]; sprintf_s(szRevModule, MAX_PATH, "%sbwapi-data\\revisions\\%u%s.dll", szInstallPath, dwDesiredRevision, dwDesiredBuild == 2 ? "d" : ""); HMODULE hLib = LoadLibrary(szRevModule); if ( hLib ) { if ( showWarn ) { char msg[MAX_PATH+32]; char szLoadedName[MAX_PATH]; GetModuleFileName(hLib, szLoadedName, MAX_PATH); sprintf_s(msg, MAX_PATH+32, "Loaded \"%s\" instead.", szLoadedName); MessageBox(NULL, msg, "Success", MB_OK | MB_ICONINFO); } return TRUE; } if ( showWarn ) { char err[512]; sprintf(err, "Couldn't find revision module \"%s\" of which the AI DLL was compiled for. Do you want to try using the current revision instead?", szRevModule); BWAPIError("%s", err); if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO ) return TRUE; } } // specified rev is not this one else if ( dwDesiredBuild && BUILD_DEBUG + 1 != dwDesiredBuild ) { char envBuffer[MAX_PATH]; if ( !GetEnvironmentVariable("ChaosDir", envBuffer, MAX_PATH) ) if ( !GetCurrentDirectory(MAX_PATH, envBuffer) && showWarn ) BWAPIError("Could not find ChaosDir or current directory for build identification."); SStrNCat(envBuffer, "\\BWAPI", MAX_PATH); if ( dwDesiredBuild == 2 ) SStrNCat(envBuffer, "d", MAX_PATH); SStrNCat(envBuffer, ".dll", MAX_PATH); HMODULE hLib = LoadLibrary(envBuffer); if ( hLib ) { if ( showWarn ) { char msg[MAX_PATH+32]; sprintf_s(msg, MAX_PATH+32, "Loaded \"%s\" instead.", envBuffer); MessageBox(NULL, msg, "Success", MB_OK | MB_ICONINFO); } return TRUE; } if ( showWarn ) { char err[512]; sprintf(err, "Couldn't find build module \"%s\" of which the AI DLL was compiled for. Do you want to try using the current build instead?", envBuffer); BWAPIError("%s", err); if ( MessageBox(NULL, err, "Error", MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON1 | MB_TASKMODAL) == IDNO ) return TRUE; } return TRUE; } } // module str was found // Do version checking CheckVersion(); // Load the auto-menu config BWAPI::BroodwarImpl.loadAutoMenuData(); // Apply all hacks and patches to the game ApplyCodePatches(); // Initialize BWAPI BWAPI::BWAPI_init(); // Create our thread that persistently applies hacks CreateThread(NULL, 0, &PersistentPatch, NULL, 0, NULL); return TRUE; } } return TRUE; }