aboutsummaryrefslogtreecommitdiff
path: root/dep/StormLib/src/SFileCreateArchive.cpp
diff options
context:
space:
mode:
authorLordJZ <a553r7fa1l3d@gmail.com>2012-06-05 04:17:10 +0400
committerShauren <shauren.trinity@gmail.com>2012-07-03 17:16:30 +0200
commit459257b0563f3c085e5e1f3cb988309309377f46 (patch)
treee7d9c2bec0615172518039f0df19ac4b48115532 /dep/StormLib/src/SFileCreateArchive.cpp
parent6fe1657fe98035d9a762d2e92f275826bec6d1fe (diff)
Update StormLib
Diffstat (limited to 'dep/StormLib/src/SFileCreateArchive.cpp')
-rw-r--r--dep/StormLib/src/SFileCreateArchive.cpp69
1 files changed, 45 insertions, 24 deletions
diff --git a/dep/StormLib/src/SFileCreateArchive.cpp b/dep/StormLib/src/SFileCreateArchive.cpp
index 6e8be7c46ec..59f3d3fa9e8 100644
--- a/dep/StormLib/src/SFileCreateArchive.cpp
+++ b/dep/StormLib/src/SFileCreateArchive.cpp
@@ -68,17 +68,46 @@ static int WriteNakedMPQHeader(TMPQArchive * ha)
bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, 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.dwStreamFlags = STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE;
+ CreateInfo.dwAttrFlags = (dwFlags & 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;
+ return SFileCreateArchive2(szMpqName, &CreateInfo, phMpq);
+}
+
+bool WINAPI SFileCreateArchive2(const TCHAR * szMpqName, PSFILE_CREATE_MPQ pCreateInfo, HANDLE * phMpq)
+{
TFileStream * pStream = NULL; // File stream
TMPQArchive * ha = NULL; // MPQ archive handle
ULONGLONG MpqPos = 0; // Position of MPQ header in the file
HANDLE hMpq = NULL;
- USHORT wFormatVersion = MPQ_FORMAT_VERSION_1;
DWORD dwBlockTableSize = 0; // Initial block table size
DWORD dwHashTableSize = 0;
+ DWORD dwMaxFileCount;
int nError = ERROR_SUCCESS;
// Check the parameters, if they are valid
- if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL)
+ if(szMpqName == NULL || *szMpqName == 0 || pCreateInfo == NULL || phMpq == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+
+ // Verify if all variables in SFILE_CREATE_MPQ are correct
+ if((pCreateInfo->cbSize == 0 || pCreateInfo->cbSize > sizeof(SFILE_CREATE_MPQ)) ||
+ (pCreateInfo->dwMpqVersion > MPQ_FORMAT_VERSION_4) ||
+ (pCreateInfo->pvUserData != NULL || pCreateInfo->cbUserData != 0) ||
+ (pCreateInfo->dwAttrFlags & ~MPQ_ATTRIBUTE_ALL) ||
+ (pCreateInfo->dwSectorSize & (pCreateInfo->dwSectorSize - 1)) ||
+ (pCreateInfo->dwRawChunkSize & (pCreateInfo->dwRawChunkSize - 1)) ||
+ (pCreateInfo->dwMaxFileCount < 4))
{
SetLastError(ERROR_INVALID_PARAMETER);
return false;
@@ -89,7 +118,7 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
// We verify if the file already exists and if it's a MPQ archive.
// If yes, we won't allow to overwrite it.
- if(SFileOpenArchive(szMpqName, 0, dwFlags, &hMpq))
+ if(SFileOpenArchive(szMpqName, 0, STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
{
SFileCloseArchive(hMpq);
SetLastError(ERROR_ALREADY_EXISTS);
@@ -102,25 +131,18 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
// - If the file doesn't exist, create new empty file
//
- pStream = FileStream_OpenFile(szMpqName, true);
+ pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
if(pStream == NULL)
{
- pStream = FileStream_CreateFile(szMpqName);
+ pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
if(pStream == NULL)
return false;
}
- // Decide what format to use
- wFormatVersion = (USHORT)((dwFlags & MPQ_CREATE_ARCHIVE_VMASK) >> 16);
- if(wFormatVersion > MPQ_FORMAT_VERSION_4)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
// Increment the maximum amount of files to have space
// for listfile and attributes file
- if(dwFlags & MPQ_CREATE_ATTRIBUTES)
+ dwMaxFileCount = pCreateInfo->dwMaxFileCount;
+ if(pCreateInfo->dwAttrFlags != 0)
dwMaxFileCount++;
dwMaxFileCount++;
@@ -150,19 +172,18 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
{
memset(ha, 0, sizeof(TMPQArchive));
ha->pStream = pStream;
- ha->dwSectorSize = (wFormatVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
+ ha->dwSectorSize = pCreateInfo->dwSectorSize;
ha->UserDataPos = MpqPos;
ha->MpqPos = MpqPos;
ha->pHeader = (TMPQHeader *)ha->HeaderData;
ha->dwMaxFileCount = dwMaxFileCount;
ha->dwFileTableSize = 0;
- ha->dwFileFlags1 = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING;
- ha->dwFileFlags2 = MPQ_FILE_ENCRYPTED | MPQ_FILE_COMPRESS | MPQ_FILE_REPLACEEXISTING;
+ ha->dwFileFlags1 = pCreateInfo->dwFileFlags1;
+ ha->dwFileFlags2 = pCreateInfo->dwFileFlags2;
ha->dwFlags = 0;
// Setup the attributes
- if(dwFlags & MPQ_CREATE_ATTRIBUTES)
- ha->dwAttrFlags = MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5;
+ ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
pStream = NULL;
}
@@ -174,9 +195,9 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
// Fill the MPQ header
memset(pHeader, 0, sizeof(ha->HeaderData));
pHeader->dwID = ID_MPQ;
- pHeader->dwHeaderSize = MpqHeaderSizes[wFormatVersion];
+ pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
- pHeader->wFormatVersion = wFormatVersion;
+ pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion;
pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize);
pHeader->dwHashTablePos = pHeader->dwHeaderSize;
pHeader->dwHashTableSize = dwHashTableSize;
@@ -185,8 +206,8 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
// For MPQs version 4 and higher, we set the size of raw data block
// for calculating MD5
- if(wFormatVersion >= MPQ_FORMAT_VERSION_4)
- pHeader->dwRawChunkSize = 0x4000;
+ if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
+ pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;
// Write the naked MPQ header
nError = WriteNakedMPQHeader(ha);
@@ -196,7 +217,7 @@ bool WINAPI SFileCreateArchive(const TCHAR * szMpqName, DWORD dwFlags, DWORD dwM
}
// Create initial HET table, if the caller required an MPQ format 3.0 or newer
- if(nError == ERROR_SUCCESS && wFormatVersion >= MPQ_FORMAT_VERSION_3)
+ if(nError == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3)
{
ha->pHetTable = CreateHetTable(ha->dwMaxFileCount, 0x40, true);
if(ha->pHetTable == NULL)