bool MpkManip::removeDir(const char* dir) { bool bOk = true; std::string strDir = dir; if(!strDir.empty()) strDir = strDir + "\\*"; else strDir = "*"; SFILE_FIND_DATA fileFindData; HANDLE hFind = SFileFindFirstFile(m_hMpk,strDir.c_str(),&fileFindData,0); if(hFind) { do { if(!removeFile(fileFindData.cFileName)) { bOk = false; } } while(SFileFindNextFile(hFind,&fileFindData)); SFileFindClose(hFind); } return bOk; }
bool ExtractWmo() { bool success = false; //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; SFILE_FIND_DATA data; HANDLE find = SFileFindFirstFile(WorldMpq, "*.wmo", &data, NULL); if (find != NULL) { do { std::string str = data.cFileName; //printf("Extracting wmo %s\n", str.c_str()); success |= ExtractSingleWmo(str); } while (SFileFindNextFile(find, &data)); } SFileFindClose(find); if (success) printf("\nExtract wmo complete (No (fatal) errors)\n"); return success; }
bool MpkManip::extractDir(const char* source,const char* target,bool replaceExist,IMpkManipCallback *pCallback,void *p) { bool bOk = true; std::string strSource = source; if(!strSource.empty()) strSource = strSource + "\\*"; else strSource = "*"; SFILE_FIND_DATA fileFindData; HANDLE hFind = SFileFindFirstFile(m_hMpk,strSource.c_str(),&fileFindData,0); if(hFind) { do { std::string targetFilename = std::string(target) + "\\" + fileFindData.cFileName; if(pCallback) { pCallback->onProcessFile(fileFindData.cFileName,p); } if(!extractFile(fileFindData.cFileName,targetFilename.c_str(),replaceExist)) { bOk = false; } } while(SFileFindNextFile(hFind,&fileFindData)); SFileFindClose(hFind); } return bOk; }
const char* MpkManip::findNextFile() { if(m_hFind) { if(SFileFindNextFile(m_hFind,&m_FileFindData)) { return m_FileFindData.cFileName; } } return 0; }
bool MpkManip::cleanupFragment(const char* mpkFilename) { bool bOk = false; HANDLE hMpk = 0; char tempFilename[MAX_PATH]; if(SFileCreateArchiveEx(mpkFilename,OPEN_EXISTING,8000,&hMpk)) { uint nTotal = SFileGetFileInfo(hMpk,SFILE_INFO_NUM_FILES); uint nFiles = 0; char tempPath[MAX_PATH]; getTempPath(MAX_PATH, tempPath); getTempFileName(tempPath,tempFilename); HANDLE hTargetMpk = 0; if(SFileCreateArchiveEx(tempFilename,CREATE_ALWAYS,8000,&hTargetMpk)) { SFILE_FIND_DATA fileFindData; HANDLE hFind = SFileFindFirstFile(hMpk,"*",&fileFindData,0); if(hFind) { do { const char* pFilename = fileFindData.cFileName; char tempFilename[MAX_PATH]; getTempFileName(tempPath,tempFilename); if(SFileExtractFile(hMpk,pFilename,tempFilename)) { if(SFileAddFile(hTargetMpk,tempFilename,pFilename,MPK_FILE_REPLACEEXISTING | MPK_FILE_COMPRESS_PKWARE)) { nFiles++; } } } while(SFileFindNextFile(hFind,&fileFindData)); if(nTotal == nFiles)bOk = true; } SFileCloseArchive(hTargetMpk); } SFileCloseArchive(hMpk); } if(bOk && copyFile(tempFilename,mpkFilename,FALSE)) { bOk = true; } return bOk; }
void ExtractDBCFiles(int l, bool basicLocale) { printf("Extracting dbc files...\n"); SFILE_FIND_DATA foundFile; memset(&foundFile, 0, sizeof(foundFile)); HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*dbc", &foundFile, NULL); HANDLE dbcFile = NULL; uint32 count = 0; if (listFile) { std::string outputPath = output_path; outputPath += "/dbc/"; CreateDir(outputPath); if (!basicLocale) { outputPath += Locales[l]; outputPath += "/"; CreateDir(outputPath); } std::string filename; do { if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile)) { printf("Unable to open file %s in the archive\n", foundFile.cFileName); continue; } filename = foundFile.cFileName; filename = outputPath + filename.substr(filename.rfind('\\') + 1); if (FileExists(filename.c_str())) continue; if (ExtractFile(dbcFile, filename.c_str())) ++count; SFileCloseFile(dbcFile); } while (SFileFindNextFile(listFile, &foundFile)); SFileFindClose(listFile); } printf("Extracted %u DBC files\n\n", count); }
void AppendDBCFileListTo(HANDLE mpqHandle, std::set<std::string>& filelist) { SFILE_FIND_DATA findFileData; HANDLE searchHandle = SFileFindFirstFile(mpqHandle, "*.dbc", &findFileData, NULL); if (!searchHandle) return; filelist.insert(findFileData.cFileName); while (SFileFindNextFile(searchHandle, &findFileData)) filelist.insert(findFileData.cFileName); SFileFindClose(searchHandle); }
void MainWindow::listFilesDetails(QString extension, QStringList & list) { extension = "*." + extension; SFILE_FIND_DATA findFileData; HANDLE findHandle = SFileFindFirstFile(mDiabdat, extension.toStdString().c_str(), &findFileData, NULL); list.append(QString(findFileData.cFileName)); while (SFileFindNextFile(findHandle, &findFileData)) { list.append(QString(findFileData.cFileName)); } SFileFindClose(findHandle); }
void MpkManip::dumpListFile() { SFILE_FIND_DATA fileFindData; HANDLE hFind = SFileFindFirstFile(m_hMpk,"*",&fileFindData,0); if(hFind) { do { #ifdef _WIN32 OutputDebugString(fileFindData.cFileName); OutputDebugString("\n"); #endif } while(SFileFindNextFile(hFind,&fileFindData)); SFileFindClose(hFind); } }
std::vector<std::string> listMpqFiles(const std::string& pattern) { SFILE_FIND_DATA findFileData; HANDLE findHandle = SFileFindFirstFile(diabdat, pattern.c_str(), &findFileData, NULL); std::vector<std::string> results; results.push_back(findFileData.cFileName); while (SFileFindNextFile(findHandle, &findFileData)) { results.push_back(findFileData.cFileName); } SFileFindClose(findHandle); return results; }
void CMpqArchive::Load() { int nLen = strlen(m_szName.c_str()) + 1; int nwLen = MultiByteToWideChar(CP_ACP, 0, m_szName.c_str(), nLen, NULL, 0); TCHAR lpszFile[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, m_szName.c_str(), nLen, lpszFile, nwLen); SFileOpenArchive(lpszFile, 0, MPQ_OPEN_FORCE_MPQ_V1 | MPQ_OPEN_READ_ONLY, &m_hMpq); m_szDir = CStringUtil::Combine(m_szName, "", false); SFILE_FIND_DATA data; bool bFind = true; HANDLE hFindFile = SFileFindFirstFile(m_hMpq, "*.*", &data, NULL); while (hFindFile != NULL && bFind) { CFileInfo info; info.m_szName = data.cFileName; info.m_nSize = data.dwFileSize; info.m_nCompSize = data.dwCompSize; m_vecFile.push_back(info); bFind = SFileFindNextFile(hFindFile, &data); } SFileFindClose(hFindFile); }
void LoadCommonMPQFiles(uint32 build) { TCHAR filename[512]; _stprintf(filename, _T("%sworld.MPQ"), input_path); if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq)) { if (GetLastError() != ERROR_FILE_NOT_FOUND) _tprintf(_T("Cannot open archive %s\n"), filename); return; } int count = sizeof(CONF_mpq_list) / sizeof(char*); for (int i = 1; i < count; ++i) { if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ continue; _stprintf(filename, _T("%s%s"), input_path, CONF_mpq_list[i]); if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0)) { if (GetLastError() != ERROR_FILE_NOT_FOUND) _tprintf(_T("Cannot open archive %s\n"), filename); else _tprintf(_T("Not found %s\n"), filename); } else { _tprintf(_T("Loaded %s\n"), filename); bool found = false; int count = 0; SFILE_FIND_DATA data; HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL); if (find != NULL) { do { ++count; if (data.dwFileFlags & MPQ_FILE_PATCH_FILE) { found = true; break; } } while (SFileFindNextFile(find, &data)); } SFileFindClose(find); printf("Scanned %d files, found patch = %d\n", count, found); } } char const* prefix = NULL; for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i) { memset(filename, 0, sizeof(filename)); if (Builds[i] > LAST_DBC_IN_DATA_BUILD) { prefix = ""; _stprintf(filename, _T("%swow-update-base-%u.MPQ"), input_path, Builds[i]); } else { prefix = "base"; _stprintf(filename, _T("%swow-update-%u.MPQ"), input_path, Builds[i]); } if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0)) { if (GetLastError() != ERROR_FILE_NOT_FOUND) _tprintf(_T("Cannot open patch archive %s\n"), filename); else _tprintf(_T("Not found %s\n"), filename); continue; } else { _tprintf(_T("Loaded %s\n"), filename); bool found = false; int count = 0; SFILE_FIND_DATA data; HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL); if (find != NULL) { do { ++count; if (data.dwFileFlags & MPQ_FILE_PATCH_FILE) { found = true; break; } } while (SFileFindNextFile(find, &data)); } SFileFindClose(find); printf("Scanned %d files, found patch = %d\n", count, found); } } }
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------- int ExtractWmo(const std::vector<std::string>& pArchiveNames) { char* szListFile = ""; char szLocalFile[MAX_PATH] = ""; HANDLE hMpq = ""; BOOL bResult = FALSE; //const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"}; int nError = ERROR_SUCCESS; if(szListFile == NULL || *szListFile == 0) szListFile = NULL; //char tmp[1024]; //for (size_t i=0; i<4; i++) for (size_t i=0; i<pArchiveNames.size(); i++) { //sprintf(tmp,"%s\\%s", input_path, ParsArchiveNames[i]); //if(!SFileOpenArchive(tmp, 0, 0, &hMpq)) if(!SFileOpenArchive(pArchiveNames[i].c_str(), 0, 0, &hMpq)) printf("NOT open!!! %s\n",pArchiveNames[i].c_str()); // Copy files from archive if(nError == ERROR_SUCCESS) { SFILE_FIND_DATA wf; HANDLE hFind = SFileFindFirstFile(hMpq,"*.wmo*", &wf, szListFile); bResult = TRUE; while(hFind != NULL && bResult == TRUE) { ShowProcessedFile(wf.cFileName); SFileSetLocale(wf.lcLocale); sprintf(szLocalFile, "%s\\%s", szWorkDirWmo, GetPlainName(wf.cFileName)); fixnamen(szLocalFile,strlen(szLocalFile)); FILE * n; if ((n = fopen(szLocalFile, "rb"))== NULL) { int p = 0; //Select root wmo files const char * rchr = strrchr(GetPlainName(wf.cFileName),0x5f); if(rchr != NULL) { char cpy[4]; strncpy((char*)cpy,rchr,4); for (int i=0;i<4;i++) { int m = cpy[i]; if(isdigit(m)) p++; } } if(p != 3) { //printf("RootWmo!\n"); string s = wf.cFileName; WMORoot * froot = new WMORoot(s); if(!froot->open()) { printf("Not open RootWmo!!!\n"); bResult = SFileFindNextFile(hFind, &wf); continue; } FILE *output=fopen(szLocalFile,"wb"); froot->ConvertToVMAPRootWmo(output); int Wmo_nVertices = 0; if(froot->nGroups !=0) { for (int i=0; i<froot->nGroups; i++) { char temp[512]; strcpy(temp, wf.cFileName); temp[strlen(wf.cFileName)-4] = 0; char groupFileName[512]; sprintf(groupFileName,"%s_%03d.wmo",temp, i); printf("%s\n",groupFileName); //printf("GroupWmo!\n"); string s = groupFileName; WMOGroup * fgroup = new WMOGroup(s); if(!fgroup->open()) { printf("Not all open Group file for: %s\n",GetPlainName(wf.cFileName)); bResult = SFileFindNextFile(hFind, &wf); break; } Wmo_nVertices += fgroup->ConvertToVMAPGroupWmo(output, preciseVectorData); } } fseek(output, 8, SEEK_SET); // store the correct no of vertices fwrite(&Wmo_nVertices,sizeof(int),1,output); fclose(output); } } else { fclose(n); } wf.dwFileFlags &= ~MPQ_FILE_HAS_EXTRA; wf.dwFileFlags &= ~MPQ_FILE_EXISTS; // Find the next file bResult = SFileFindNextFile(hFind, &wf); } // Delete the extracted file in the case of an error if(nError != ERROR_SUCCESS) DeleteFile(szLocalFile); // Close the search handle if(hFind != NULL) SFileFindClose(hFind); } } // Close both archives if(hMpq != NULL) //SFileCloseArchive(hMpq); if(nError == ERROR_SUCCESS) printf("\nExtract wmo complete (No errors)\n"); return nError; }
static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileSeeds) { TMPQHash * pHashTableCopy = NULL; // Copy of the hash table TMPQHash * pHash; TMPQHash * pHashEnd = NULL; // End of the hash table DWORD dwFileCount = 0; int nError = ERROR_SUCCESS; // First of all, create a copy of hash table if(nError == ERROR_SUCCESS) { if((pHashTableCopy = CopyHashTable(ha)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize; // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_FILES, 0, ha->pHeader->dwBlockTableSize); } // Now check all the files from the filelist if(nError == ERROR_SUCCESS) { SFILE_FIND_DATA wf; HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile); BOOL bResult = TRUE; // Do while some files have been found while(hFind != NULL && bResult) { TMPQHash * pHash = GetHashEntry(ha, wf.cFileName); // If the hash table entry has been found, find it's position // in the hash table copy if(pHash != NULL) { pHash = pHashTableCopy + (pHash - ha->pHashTable); if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) { TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex; DWORD dwSeed = 0; // Resolve the file seed. Use plain file name for it if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) { char * szFileName = strrchr(wf.cFileName, '\\'); if(szFileName == NULL) szFileName = wf.cFileName; else szFileName++; dwSeed = DecryptFileSeed(szFileName); if(pBlock->dwFlags & MPQ_FILE_FIXSEED) dwSeed = (dwSeed + pBlock->dwFilePos) ^ pBlock->dwFSize; } pFileSeeds[pHash->dwBlockIndex] = dwSeed; pHash->dwName1 = 0xFFFFFFFF; pHash->dwName2 = 0xFFFFFFFF; pHash->lcLocale = 0xFFFF; pHash->wPlatform = 0xFFFF; pHash->dwBlockIndex = 0xFFFFFFFF; } } // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_FILES, ++dwFileCount, ha->pHeader->dwBlockTableSize); // Find the next file in the archive bResult = SFileFindNextFile(hFind, &wf); } if(hFind != NULL) SFileFindClose(hFind); } // When the filelist checking is complete, parse the hash table copy and find the if(nError == ERROR_SUCCESS) { // Notify the user about checking hash table dwFileCount = 0; if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, dwFileCount, ha->pHeader->dwBlockTableSize); for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++) { // If there is an unresolved entry, try to detect its seed. If it fails, // we cannot complete the work if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) { HANDLE hFile = NULL; DWORD dwFlags = 0; DWORD dwSeed = 0; if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile)) { TMPQFile * hf = (TMPQFile *)hFile; dwFlags = hf->pBlock->dwFlags; dwSeed = hf->dwSeed1; SFileCloseFile(hFile); } // If the file is encrypted, we have to check // If we can apply the file decryption seed if(dwFlags & MPQ_FILE_ENCRYPTED && dwSeed == 0) { nError = ERROR_CAN_NOT_COMPLETE; break; } // Remember the seed pFileSeeds[pHash->dwBlockIndex] = dwSeed; // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, ++dwFileCount, ha->pHeader->dwBlockTableSize); } } } // Delete the copy of hash table if(pHashTableCopy != NULL) FREEMEM(pHashTableCopy); return nError; }
static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileKeys) { TMPQHash * pHashTableCopy = NULL; // Copy of the hash table TMPQHash * pHash; TMPQHash * pHashEnd = NULL; // End of the hash table DWORD dwFileCount = 0; int nError = ERROR_SUCCESS; // First of all, create a copy of hash table if(nError == ERROR_SUCCESS) { if((pHashTableCopy = CopyHashTable(ha)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize; // Notify the user if(CompactCB != NULL) CompactCB(pvUserData, CCB_CHECKING_FILES, &CompactBytesProcessed, &CompactTotalBytes); } // Now check all the files from the listfile if(nError == ERROR_SUCCESS) { SFILE_FIND_DATA wf; HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile); bool bResult = true; // Do while something has been found while(hFind != NULL && bResult) { TMPQHash * pHash = ha->pHashTable + wf.dwHashIndex; // Find the entry in the hash table copy pHash = pHashTableCopy + (pHash - ha->pHashTable); if(pHash->dwBlockIndex != HASH_ENTRY_FREE) { TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex; DWORD dwFileKey = 0; // Resolve the file key. Use plain file name for it if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) { const char * szPlainName = GetPlainMpqFileName(wf.cFileName); dwFileKey = DecryptFileKey(szPlainName); if(pBlock->dwFlags & MPQ_FILE_FIX_KEY) dwFileKey = (dwFileKey + pBlock->dwFilePos) ^ pBlock->dwFSize; } // Give the key to the caller pFileKeys[pHash->dwBlockIndex] = dwFileKey; pHash->dwName1 = 0xFFFFFFFF; pHash->dwName2 = 0xFFFFFFFF; pHash->lcLocale = 0xFFFF; pHash->wPlatform = 0xFFFF; pHash->dwBlockIndex = HASH_ENTRY_FREE; } // Find the next file in the archive bResult = SFileFindNextFile(hFind, &wf); } if(hFind != NULL) SFileFindClose(hFind); } // When the filelist checking is complete, parse the hash table copy and find the if(nError == ERROR_SUCCESS) { // Notify the user about checking hash table dwFileCount = 0; if(CompactCB != NULL) CompactCB(pvUserData, CCB_CHECKING_HASH_TABLE, &CompactBytesProcessed, &CompactTotalBytes); for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++) { // If there is an unresolved entry, try to detect its key. If it fails, // we cannot complete the work if(pHash->dwBlockIndex < ha->pHeader->dwBlockTableSize) { HANDLE hFile = NULL; DWORD dwFlags = 0; DWORD dwFileKey = 0; if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile)) { TMPQFile * hf = (TMPQFile *)hFile; dwFlags = hf->pBlock->dwFlags; dwFileKey = hf->dwFileKey; SFileCloseFile(hFile); } // If the file is encrypted, we have to check // If we can apply the file decryption key if((dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey == 0) { nError = ERROR_CAN_NOT_COMPLETE; break; } // Give the key to the caller pFileKeys[pHash->dwBlockIndex] = dwFileKey; } } } // Delete the copy of hash table if(pHashTableCopy != NULL) FREEMEM(pHashTableCopy); return nError; }