static int SFileAddInternalListFile( TMPQArchive * ha, HANDLE hMpq) { TMPQArchive * haMpq = (TMPQArchive *)hMpq; TMPQHash * pFirstHash; TMPQHash * pHash; HANDLE hListFile; LCID lcSaveLocale = lcFileLocale; int nError = ERROR_SUCCESS; // If there is hash table, we need to support multiple listfiles // with different locales (BrooDat.mpq) if(haMpq->pHashTable != NULL) { pFirstHash = pHash = GetFirstHashEntry(haMpq, LISTFILE_NAME); while(nError == ERROR_SUCCESS && pHash != NULL) { // Set the prefered locale to that from list file SFileSetLocale(pHash->lcLocale); if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) { // Add the data from the listfile to MPQ nError = SFileAddArbitraryListFile(ha, hListFile); SFileCloseFile(hListFile); } // Restore the original locale SFileSetLocale(lcSaveLocale); // Move to the next hash pHash = GetNextHashEntry(haMpq, pFirstHash, pHash); } } else { // Open the external list file if(SFileOpenFileEx(hMpq, LISTFILE_NAME, 0, &hListFile)) { // Add the data from the listfile to MPQ // The function also closes the listfile handle nError = SFileAddArbitraryListFile(ha, hListFile); SFileCloseFile(hListFile); } } // Return the result of the operation return nError; }
int WINAPI SFileEnumLocales( HANDLE hMpq, const char * szFileName, LCID * PtrLocales, LPDWORD PtrMaxLocales, DWORD dwSearchScope) { TMPQArchive * ha = (TMPQArchive *)hMpq; TMPQHash * pFirstHash; TMPQHash * pHash; DWORD dwFileIndex = 0; DWORD dwMaxLocales; DWORD dwLocales = 0; // Test the parameters if(!IsValidMpqHandle(hMpq)) return ERROR_INVALID_HANDLE; if(szFileName == NULL || *szFileName == 0) return ERROR_INVALID_PARAMETER; if(ha->pHashTable == NULL) return ERROR_NOT_SUPPORTED; if(PtrMaxLocales == NULL) return ERROR_INVALID_PARAMETER; if(IsPseudoFileName(szFileName, &dwFileIndex)) return ERROR_INVALID_PARAMETER; // Keep compiler happy dwMaxLocales = PtrMaxLocales[0]; dwSearchScope = dwSearchScope; // Parse all files with that name pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); while(pHash != NULL) { // Put the locales to the buffer if(PtrLocales != NULL && dwLocales < dwMaxLocales) *PtrLocales++ = pHash->lcLocale; dwLocales++; // Get the next locale pHash = GetNextHashEntry(ha, pFirstHash, pHash); } // Give the caller the number of locales and return PtrMaxLocales[0] = dwLocales; return (dwLocales <= dwMaxLocales) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; }
// Adds a name into the list of all names. For each locale in the MPQ, // one entry will be created // If the file name is already there, does nothing. static int SListFileCreateNodeForAllLocales(TMPQArchive * ha, const char * szFileName) { TMPQHeader * pHeader = ha->pHeader; TFileEntry * pFileEntry; TMPQHash * pFirstHash; TMPQHash * pHash; bool bNameEntryCreated = false; // If we have HET table, use that one if(ha->pHetTable != NULL) { pFileEntry = GetFileEntryAny(ha, szFileName); if(pFileEntry != NULL) { // Allocate file name for the file entry AllocateFileName(pFileEntry, szFileName); bNameEntryCreated = true; } return ERROR_SUCCESS; } // If we have hash table, we use it if(bNameEntryCreated == false && ha->pHashTable != NULL) { // Look for the first hash table entry for the file pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); // Go while we found something while(pHash != NULL) { // Is it a valid file table index ? if(pHash->dwBlockIndex < pHeader->dwBlockTableSize) { // Allocate file name for the file entry AllocateFileName(ha->pFileTable + pHash->dwBlockIndex, szFileName); bNameEntryCreated = true; } // Now find the next language version of the file pHash = GetNextHashEntry(ha, pFirstHash, pHash); } } return ERROR_CAN_NOT_COMPLETE; }
int WINAPI SFileEnumLocales( HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope) { TMPQArchive * ha = (TMPQArchive *)hMpq; TMPQHash * pFirstHash; TMPQHash * pHash; DWORD dwLocales = 0; // Test the parameters if (!IsValidMpqHandle(ha)) return ERROR_INVALID_HANDLE; if (pdwMaxLocales == NULL) return ERROR_INVALID_PARAMETER; if (dwSearchScope == SFILE_OPEN_BY_INDEX && (DWORD_PTR)szFileName > ha->pHeader->dwBlockTableSize) return ERROR_INVALID_PARAMETER; if (dwSearchScope != SFILE_OPEN_BY_INDEX && *szFileName == 0) return ERROR_INVALID_PARAMETER; // Parse hash table entries for all locales if (dwSearchScope == SFILE_OPEN_FROM_MPQ) { pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); while(pHash != NULL) { dwLocales++; pHash = GetNextHashEntry(ha, pFirstHash, pHash); } } else { // For nameless access, always return 1 locale // pHash = GetFileEntryByIndex(ha, (DWORD)(DWORD_PTR)szFileName); // if (pHash != NULL) // dwLocales++; } // Test if there is enough space to copy the locales if (*pdwMaxLocales < dwLocales) { *pdwMaxLocales = dwLocales; return ERROR_INSUFFICIENT_BUFFER; } // Now find all locales if (dwSearchScope == SFILE_OPEN_FROM_MPQ) { pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); while(pHash != NULL) { *plcLocales++ = pHash->lcLocale; pHash = GetNextHashEntry(ha, pFirstHash, pHash); } } else { // For nameless access, always return 1 locale // pHash = GetFileEntryByIndex(ha, (DWORD)(DWORD_PTR)szFileName); // if (pHash != NULL) // *plcLocales++ = pHash->lcLocale; } // Give the caller the total number of found locales *pdwMaxLocales = dwLocales; return ERROR_SUCCESS; }
int WINAPI SFileEnumLocales( HANDLE hMpq, const char * szFileName, LCID * plcLocales, LPDWORD pdwMaxLocales, DWORD dwSearchScope) { TMPQArchive * ha = (TMPQArchive *)hMpq; TFileEntry * pFileEntry; TMPQHash * pFirstHash; TMPQHash * pHash; DWORD dwFileIndex = 0; DWORD dwLocales = 0; // Test the parameters if(!IsValidMpqHandle(ha)) return ERROR_INVALID_HANDLE; if(szFileName == NULL || *szFileName == 0) return ERROR_INVALID_PARAMETER; if(pdwMaxLocales == NULL) return ERROR_INVALID_PARAMETER; // Keep compiler happy dwSearchScope = dwSearchScope; // Parse hash table entries for all locales if(!IsPseudoFileName(szFileName, &dwFileIndex)) { // Calculate the number of locales pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); while(pHash != NULL) { dwLocales++; pHash = GetNextHashEntry(ha, pFirstHash, pHash); } // Test if there is enough space to copy the locales if(*pdwMaxLocales < dwLocales) { *pdwMaxLocales = dwLocales; return ERROR_INSUFFICIENT_BUFFER; } // Enum the locales pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); while(pHash != NULL) { *plcLocales++ = pHash->lcLocale; pHash = GetNextHashEntry(ha, pFirstHash, pHash); } } else { // There must be space for 1 locale if(*pdwMaxLocales < 1) { *pdwMaxLocales = 1; return ERROR_INSUFFICIENT_BUFFER; } // For nameless access, always return 1 locale pFileEntry = GetFileEntryByIndex(ha, dwFileIndex); pHash = ha->pHashTable + pFileEntry->dwHashIndex; *plcLocales = pHash->lcLocale; dwLocales = 1; } // Give the caller the total number of found locales *pdwMaxLocales = dwLocales; return ERROR_SUCCESS; }