diff options
Diffstat (limited to 'src/SFileCreateArchive.cpp')
-rw-r--r-- | src/SFileCreateArchive.cpp | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/src/SFileCreateArchive.cpp b/src/SFileCreateArchive.cpp index 78ddd71..2b51efa 100644 --- a/src/SFileCreateArchive.cpp +++ b/src/SFileCreateArchive.cpp @@ -57,6 +57,7 @@ static int WriteNakedMPQHeader(TMPQArchive * ha) // Write it to the file BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_1); + BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_2); BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_3); BSWAP_TMPQHEADER(&Header, MPQ_FORMAT_VERSION_4); if(!FileStream_Write(ha->pStream, &ha->MpqPos, &Header, dwBytesToWrite)) @@ -68,19 +69,27 @@ static int WriteNakedMPQHeader(TMPQArchive * ha) //----------------------------------------------------------------------------- // Creates a new MPQ archive. -bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwMaxFileCount, HANDLE * phMpq) +bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwCreateFlags, DWORD dwMaxFileCount, HANDLE * phMpq) { SFILE_CREATE_MPQ CreateInfo; // Fill the create structure memset(&CreateInfo, 0, sizeof(SFILE_CREATE_MPQ)); CreateInfo.cbSize = sizeof(SFILE_CREATE_MPQ); - CreateInfo.dwMpqVersion = (dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT; + CreateInfo.dwMpqVersion = (dwCreateFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT; CreateInfo.dwStreamFlags = STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE; - CreateInfo.dwAttrFlags = (dwFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_ATTRIBUTE_ALL : 0; + CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_EXISTS : 0; + CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_EXISTS : 0; + CreateInfo.dwAttrFlags = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_ATTRIBUTE_ALL : 0; CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000; CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0; CreateInfo.dwMaxFileCount = dwMaxFileCount; + + // Backward compatibility: SFileCreateArchive always used to add (listfile) + // We would break loads of applications if we change that + CreateInfo.dwFileFlags1 = MPQ_FILE_EXISTS; + + // Let the main function create the archive return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq); } @@ -93,7 +102,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea HANDLE hMpq = NULL; DWORD dwBlockTableSize = 0; // Initial block table size DWORD dwHashTableSize = 0; - DWORD dwMaxFileCount; + DWORD dwReservedFiles = 0; // Number of reserved file entries int nError = ERROR_SUCCESS; // Check the parameters, if they are valid @@ -109,8 +118,7 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) || (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) || (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) || - (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)) || - (pCreateInfo->dwMaxFileCount < 4)) + (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1))) { SetLastError(ERROR_INVALID_PARAMETER); return false; @@ -142,15 +150,14 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea return false; } - // Increment the maximum amount of files to have space - // for listfile and attributes file - dwMaxFileCount = pCreateInfo->dwMaxFileCount; - if(pCreateInfo->dwAttrFlags != 0) - dwMaxFileCount++; - dwMaxFileCount++; + // Increment the maximum amount of files to have space for (listfile) and (attributes) + if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags1) + dwReservedFiles++; + if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags2 && pCreateInfo->dwAttrFlags) + dwReservedFiles++; // If file count is not zero, initialize the hash table size - dwHashTableSize = GetHashTableSizeForFileCount(dwMaxFileCount); + dwHashTableSize = GetHashTableSizeForFileCount(pCreateInfo->dwMaxFileCount + dwReservedFiles); // Retrieve the file size and round it up to 0x200 bytes FileStream_GetSize(pStream, &MpqPos); @@ -180,14 +187,13 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea ha->UserDataPos = MpqPos; ha->MpqPos = MpqPos; ha->pHeader = pHeader = (TMPQHeader *)ha->HeaderData; - ha->dwMaxFileCount = dwMaxFileCount; + ha->dwMaxFileCount = dwHashTableSize; ha->dwFileTableSize = 0; + ha->dwReservedFiles = dwReservedFiles; ha->dwFileFlags1 = pCreateInfo->dwFileFlags1; ha->dwFileFlags2 = pCreateInfo->dwFileFlags2; - ha->dwFlags = 0; - - // Setup the attributes ha->dwAttrFlags = pCreateInfo->dwAttrFlags; + ha->dwFlags = 0; pStream = NULL; // Fill the MPQ header @@ -215,21 +221,21 @@ bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCrea } // Create initial HET table, if the caller required an MPQ format 3.0 or newer - if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3) + if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3 && pCreateInfo->dwMaxFileCount != 0) { - ha->pHetTable = CreateHetTable(0, ha->dwFileTableSize, 0x40, true); + ha->pHetTable = CreateHetTable(ha->dwFileTableSize, 0x40, NULL); if(ha->pHetTable == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; } // Create initial hash table - if(nError == ERROR_SUCCESS) + if(nError == ERROR_SUCCESS && dwHashTableSize != 0) { nError = CreateHashTable(ha, dwHashTableSize); } // Create initial file table - if(nError == ERROR_SUCCESS) + if(nError == ERROR_SUCCESS && ha->dwMaxFileCount != 0) { ha->pFileTable = STORM_ALLOC(TFileEntry, ha->dwMaxFileCount); if(ha->pFileTable != NULL) |