diff options
author | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-12-05 15:59:00 +0100 |
---|---|---|
committer | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-12-05 15:59:00 +0100 |
commit | c34c37b3418f1e5ab3678ce65d46f81803dec91d (patch) | |
tree | 4a9cf4c61634691981f9dc367b53dac4070f8d0d /src/SFileCompactArchive.cpp | |
parent | ff0c25952a28a927c48738ab5207b9bda69e588a (diff) |
+ StormLib 9.0 BETA
Diffstat (limited to 'src/SFileCompactArchive.cpp')
-rw-r--r-- | src/SFileCompactArchive.cpp | 159 |
1 files changed, 33 insertions, 126 deletions
diff --git a/src/SFileCompactArchive.cpp b/src/SFileCompactArchive.cpp index a726d43..64c599d 100644 --- a/src/SFileCompactArchive.cpp +++ b/src/SFileCompactArchive.cpp @@ -441,7 +441,8 @@ bool WINAPI SFileSetCompactCallback(HANDLE hMpq, SFILE_COMPACT_CALLBACK pfnCompa { TMPQArchive * ha = (TMPQArchive *) hMpq; - if (!IsValidMpqHandle(ha)) { + if (!IsValidMpqHandle(hMpq)) + { SetLastError(ERROR_INVALID_HANDLE); return false; } @@ -466,7 +467,7 @@ bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bR int nError = ERROR_SUCCESS; // Test the valid parameters - if(!IsValidMpqHandle(ha)) + if(!IsValidMpqHandle(hMpq)) nError = ERROR_INVALID_HANDLE; if(ha->dwFlags & MPQ_FLAG_READ_ONLY) nError = ERROR_ACCESS_DENIED; @@ -544,6 +545,7 @@ bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bR // Write the MPQ header to the file memcpy(&SaveMpqHeader, ha->pHeader, ha->pHeader->dwHeaderSize); BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_1); + BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_2); BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_3); BSWAP_TMPQHEADER(&SaveMpqHeader, MPQ_FORMAT_VERSION_4); if(!FileStream_Write(pTempStream, NULL, &SaveMpqHeader, ha->pHeader->dwHeaderSize)) @@ -555,9 +557,21 @@ bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bR // Now copy all files if(nError == ERROR_SUCCESS) - { nError = CopyMpqFiles(ha, pFileKeys, pTempStream); - ha->dwFlags |= MPQ_FLAG_CHANGED; + + // Defragment the file table + if(nError == ERROR_SUCCESS) + nError = RebuildFileTable(ha, ha->pHeader->dwHashTableSize, ha->dwMaxFileCount); + + // We also need to rebuild the HET table, if any + if(nError == ERROR_SUCCESS) + { + // Invalidate (listfile) and (attributes) + InvalidateInternalFiles(ha); + + // Rebuild the HET table, if we have any + if(ha->pHetTable != NULL) + nError = RebuildHetTable(ha); } // If succeeded, switch the streams @@ -608,25 +622,16 @@ DWORD WINAPI SFileGetMaxFileCount(HANDLE hMpq) bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount) { - TMPQHetTable * pOldHetTable = NULL; TMPQArchive * ha = (TMPQArchive *)hMpq; - TFileEntry * pOldFileTableEnd = ha->pFileTable + ha->dwFileTableSize; - TFileEntry * pOldFileTable = NULL; - TFileEntry * pOldFileEntry; - TFileEntry * pFileEntry; - TMPQHash * pOldHashTable = NULL; - DWORD dwOldHashTableSize = 0; - DWORD dwOldFileTableSize = 0; + DWORD dwNewHashTableSize = 0; int nError = ERROR_SUCCESS; // Test the valid parameters - if(!IsValidMpqHandle(ha)) + if(!IsValidMpqHandle(hMpq)) nError = ERROR_INVALID_HANDLE; if(ha->dwFlags & MPQ_FLAG_READ_ONLY) nError = ERROR_ACCESS_DENIED; - - // The new limit must be greater than the current file table size - if(nError == ERROR_SUCCESS && ha->dwFileTableSize > dwMaxFileCount) + if(dwMaxFileCount < ha->dwFileTableSize) nError = ERROR_DISK_FULL; // ALL file names must be known in order to be able @@ -637,126 +642,28 @@ bool WINAPI SFileSetMaxFileCount(HANDLE hMpq, DWORD dwMaxFileCount) } // If the MPQ has a hash table, then we relocate the hash table - if(nError == ERROR_SUCCESS && ha->pHashTable != NULL) - { - // Save parameters for the current hash table - dwOldHashTableSize = ha->pHeader->dwHashTableSize; - pOldHashTable = ha->pHashTable; - - // Allocate new hash table - ha->pHeader->dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); - ha->pHashTable = STORM_ALLOC(TMPQHash, ha->pHeader->dwHashTableSize); - if(ha->pHashTable != NULL) - memset(ha->pHashTable, 0xFF, ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // If the MPQ has HET table, allocate new one as well - if(nError == ERROR_SUCCESS && ha->pHetTable != NULL) - { - // Save the original HET table - pOldHetTable = ha->pHetTable; - - // Create new one - ha->pHetTable = CreateHetTable(0, dwMaxFileCount, 0x40, true); - if(ha->pHetTable == NULL) - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now reallocate the file table - if(nError == ERROR_SUCCESS) - { - // Save the current file table - dwOldFileTableSize = ha->dwFileTableSize; - pOldFileTable = ha->pFileTable; - - // Create new one - ha->pFileTable = STORM_ALLOC(TFileEntry, dwMaxFileCount); - if(ha->pFileTable != NULL) - memset(ha->pFileTable, 0, dwMaxFileCount * sizeof(TFileEntry)); - else - nError = ERROR_NOT_ENOUGH_MEMORY; - } - - // Now we have to build both classic hash table and HET table. if(nError == ERROR_SUCCESS) { - DWORD dwFileIndex = 0; - DWORD dwHashIndex = 0; + // Calculate the hash table size for the new file limit + dwNewHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); - // Create new hash and HET entry for each file - pFileEntry = ha->pFileTable; - for(pOldFileEntry = pOldFileTable; pOldFileEntry < pOldFileTableEnd; pOldFileEntry++) - { - if(pOldFileEntry->dwFlags & MPQ_FILE_EXISTS) - { - // Copy the old file entry to the new one - memcpy(pFileEntry, pOldFileEntry, sizeof(TFileEntry)); - assert(pFileEntry->szFileName != NULL); - - // Create new entry in the hash table - if(ha->pHashTable != NULL) - { - if(AllocateHashEntry(ha, pFileEntry) == NULL) - { - nError = ERROR_CAN_NOT_COMPLETE; - break; - } - } - - // Create new entry in the HET table, if needed - if(ha->pHetTable != NULL) - { - dwHashIndex = AllocateHetEntry(ha, pFileEntry); - if(dwHashIndex == HASH_ENTRY_FREE) - { - nError = ERROR_CAN_NOT_COMPLETE; - break; - } - } - - // Move to the next file entry in the new table - pFileEntry++; - dwFileIndex++; - } - } + // Rebuild both file tables + nError = RebuildFileTable(ha, dwNewHashTableSize, dwMaxFileCount); } - // Mark the archive as changed - // Note: We always have to rebuild the (attributes) file due to file table change + // We always have to rebuild the (attributes) file due to file table change if(nError == ERROR_SUCCESS) { - ha->dwMaxFileCount = dwMaxFileCount; + // Invalidate (listfile) and (attributes) InvalidateInternalFiles(ha); - } - else - { - // Revert the hash table - if(ha->pHashTable != NULL && pOldHashTable != NULL) - { - STORM_FREE(ha->pHashTable); - ha->pHeader->dwHashTableSize = dwOldHashTableSize; - ha->pHashTable = pOldHashTable; - } - - // Revert the HET table - if(ha->pHetTable != NULL && pOldHetTable != NULL) - { - FreeHetTable(ha->pHetTable); - ha->pHetTable = pOldHetTable; - } - // Revert the file table - if(pOldFileTable != NULL) - { - STORM_FREE(ha->pFileTable); - ha->pFileTable = pOldFileTable; - } - - SetLastError(nError); + // Rebuild the HET table, if we have any + if(ha->pHetTable != NULL) + nError = RebuildHetTable(ha); } - // Return the result + // Return the error + if(nError != ERROR_SUCCESS) + SetLastError(nError); return (nError == ERROR_SUCCESS); } |