summaryrefslogtreecommitdiff
path: root/StormLib/src/SFileCreateArchive.cpp
diff options
context:
space:
mode:
authorbriaguya <70942617+briaguya-ai@users.noreply.github.com>2022-11-14 05:22:34 -0500
committerGitHub <noreply@github.com>2022-11-14 11:22:34 +0100
commit3914781ebfd5cb22717cc207cb3d37d8754d0eb7 (patch)
tree2e412b87e66b1deef47bef242e7189a200cea0ff /StormLib/src/SFileCreateArchive.cpp
parent9eb29ed81cb497a6a216811255f8af7daf3f8bd8 (diff)
Import libultraship as a submodule (#1943)
Co-authored-by: briaguya <briaguya> Co-authored-by: Christopher Leggett <chris@leggett.dev> Co-authored-by: David Chavez <davi@dcvz.io>
Diffstat (limited to 'StormLib/src/SFileCreateArchive.cpp')
-rw-r--r--StormLib/src/SFileCreateArchive.cpp276
1 files changed, 0 insertions, 276 deletions
diff --git a/StormLib/src/SFileCreateArchive.cpp b/StormLib/src/SFileCreateArchive.cpp
deleted file mode 100644
index 6f398add5..000000000
--- a/StormLib/src/SFileCreateArchive.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/*****************************************************************************/
-/* SFileCreateArchive.cpp Copyright (c) Ladislav Zezula 2003 */
-/*---------------------------------------------------------------------------*/
-/* MPQ Editing functions */
-/*---------------------------------------------------------------------------*/
-/* Date Ver Who Comment */
-/* -------- ---- --- ------- */
-/* 24.03.03 1.00 Lad Splitted from SFileOpenArchive.cpp */
-/* 08.06.10 1.00 Lad Renamed to SFileCreateArchive.cpp */
-/*****************************************************************************/
-
-#define __STORMLIB_SELF__
-#include "StormLib.h"
-#include "StormCommon.h"
-
-//-----------------------------------------------------------------------------
-// Local variables
-
-static const DWORD MpqHeaderSizes[] =
-{
- MPQ_HEADER_SIZE_V1,
- MPQ_HEADER_SIZE_V2,
- MPQ_HEADER_SIZE_V3,
- MPQ_HEADER_SIZE_V4
-};
-
-//-----------------------------------------------------------------------------
-// Local functions
-
-static USHORT GetSectorSizeShift(DWORD dwSectorSize)
-{
- USHORT wSectorSizeShift = 0;
-
- while(dwSectorSize > 0x200)
- {
- dwSectorSize >>= 1;
- wSectorSizeShift++;
- }
-
- return wSectorSizeShift;
-}
-
-static DWORD WriteNakedMPQHeader(TMPQArchive * ha)
-{
- TMPQHeader * pHeader = ha->pHeader;
- TMPQHeader Header;
- DWORD dwBytesToWrite = pHeader->dwHeaderSize;
- DWORD dwErrCode = ERROR_SUCCESS;
-
- // Prepare the naked MPQ header
- memset(&Header, 0, sizeof(TMPQHeader));
- Header.dwID = pHeader->dwID;
- Header.dwHeaderSize = pHeader->dwHeaderSize;
- Header.dwArchiveSize = pHeader->dwHeaderSize;
- Header.wFormatVersion = pHeader->wFormatVersion;
- Header.wSectorSize = pHeader->wSectorSize;
-
- // 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))
- dwErrCode = GetLastError();
-
- return dwErrCode;
-}
-
-//-----------------------------------------------------------------------------
-// Creates a new MPQ archive.
-
-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 = (dwCreateFlags & MPQ_CREATE_ARCHIVE_VMASK) >> FLAGS_TO_FORMAT_SHIFT;
- CreateInfo.dwStreamFlags = STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE;
- CreateInfo.dwFileFlags1 = (dwCreateFlags & MPQ_CREATE_LISTFILE) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
- CreateInfo.dwFileFlags2 = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
- CreateInfo.dwFileFlags3 = (dwCreateFlags & MPQ_CREATE_SIGNATURE) ? MPQ_FILE_DEFAULT_INTERNAL : 0;
- CreateInfo.dwAttrFlags = (dwCreateFlags & MPQ_CREATE_ATTRIBUTES) ? (MPQ_ATTRIBUTE_CRC32 | MPQ_ATTRIBUTE_FILETIME | MPQ_ATTRIBUTE_MD5) : 0;
- CreateInfo.dwSectorSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) ? 0x4000 : 0x1000;
- CreateInfo.dwRawChunkSize = (CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_4) ? 0x4000 : 0;
- CreateInfo.dwMaxFileCount = dwMaxFileCount;
-
- // Set the proper attribute parts
- if((CreateInfo.dwMpqVersion >= MPQ_FORMAT_VERSION_3) && (dwCreateFlags & MPQ_CREATE_ATTRIBUTES))
- CreateInfo.dwAttrFlags |= MPQ_ATTRIBUTE_PATCH_BIT;
-
- // Backward compatibility: SFileCreateArchive always used to add (listfile)
- // We would break loads of applications if we change that
- CreateInfo.dwFileFlags1 = MPQ_FILE_DEFAULT_INTERNAL;
-
- // Let the main function create the archive
- 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
- TMPQHeader * pHeader;
- ULONGLONG MpqPos = 0; // Position of MPQ header in the file
- HANDLE hMpq = NULL;
- DWORD dwBlockTableSize = 0; // Initial block table size
- DWORD dwHashTableSize = 0;
- DWORD dwReservedFiles = 0; // Number of reserved file entries
- DWORD dwMpqFlags = 0;
- DWORD dwErrCode = ERROR_SUCCESS;
-
- // Check the parameters, if they are valid
- 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)))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return false;
- }
-
- // One time initialization of MPQ cryptography
- InitializeMpqCryptography();
-
- // 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, STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE | MPQ_OPEN_NO_ATTRIBUTES | MPQ_OPEN_NO_LISTFILE, &hMpq))
- {
- SFileCloseArchive(hMpq);
- SetLastError(ERROR_ALREADY_EXISTS);
- return false;
- }
-
- //
- // At this point, we have to create the archive.
- // - If the file exists, convert it to MPQ archive.
- // - If the file doesn't exist, create new empty file
- //
-
- pStream = FileStream_OpenFile(szMpqName, pCreateInfo->dwStreamFlags);
- if(pStream == NULL)
- {
- pStream = FileStream_CreateFile(szMpqName, pCreateInfo->dwStreamFlags);
- if(pStream == NULL)
- return false;
- }
-
- // Increment the maximum amount of files to have space for (listfile)
- if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags1)
- {
- dwMpqFlags |= MPQ_FLAG_LISTFILE_NEW;
- dwReservedFiles++;
- }
-
- // Increment the maximum amount of files to have space for (attributes)
- if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags2 && pCreateInfo->dwAttrFlags)
- {
- dwMpqFlags |= MPQ_FLAG_ATTRIBUTES_NEW;
- dwReservedFiles++;
- }
-
- // Increment the maximum amount of files to have space for (signature)
- if(pCreateInfo->dwMaxFileCount && pCreateInfo->dwFileFlags3)
- {
- dwMpqFlags |= MPQ_FLAG_SIGNATURE_NEW;
- dwReservedFiles++;
- }
-
- // If file count is not zero, initialize the hash table size
- dwHashTableSize = GetNearestPowerOfTwo(pCreateInfo->dwMaxFileCount + dwReservedFiles);
-
- // Retrieve the file size and round it up to 0x200 bytes
- FileStream_GetSize(pStream, &MpqPos);
- MpqPos = (MpqPos + 0x1FF) & (ULONGLONG)0xFFFFFFFFFFFFFE00ULL;
- if(!FileStream_SetSize(pStream, MpqPos))
- dwErrCode = GetLastError();
-
-#ifdef _DEBUG
- // Debug code, used for testing StormLib
-// dwBlockTableSize = dwHashTableSize * 2;
-#endif
-
- // Create the archive handle
- if(dwErrCode == ERROR_SUCCESS)
- {
- if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL)
- dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Fill the MPQ archive handle structure
- if(dwErrCode == ERROR_SUCCESS)
- {
- memset(ha, 0, sizeof(TMPQArchive));
- ha->pfnHashString = HashStringSlash;
- ha->pStream = pStream;
- ha->dwSectorSize = pCreateInfo->dwSectorSize;
- ha->UserDataPos = MpqPos;
- ha->MpqPos = MpqPos;
- ha->pHeader = pHeader = (TMPQHeader *)ha->HeaderData;
- ha->dwMaxFileCount = dwHashTableSize;
- ha->dwFileTableSize = 0;
- ha->dwReservedFiles = dwReservedFiles;
- ha->dwFileFlags1 = pCreateInfo->dwFileFlags1;
- ha->dwFileFlags2 = pCreateInfo->dwFileFlags2;
- ha->dwFileFlags3 = pCreateInfo->dwFileFlags3 ? MPQ_FILE_EXISTS : 0;
- ha->dwAttrFlags = pCreateInfo->dwAttrFlags;
- ha->dwFlags = dwMpqFlags | MPQ_FLAG_CHANGED;
- ha->useFreeSpaceOptimization = true;
- ha->lastFreeSpaceEntry = nullptr;
- pStream = NULL;
-
- // Fill the MPQ header
- memset(pHeader, 0, sizeof(ha->HeaderData));
- pHeader->dwID = g_dwMpqSignature;
- pHeader->dwHeaderSize = MpqHeaderSizes[pCreateInfo->dwMpqVersion];
- pHeader->dwArchiveSize = pHeader->dwHeaderSize + dwHashTableSize * sizeof(TMPQHash);
- pHeader->wFormatVersion = (USHORT)pCreateInfo->dwMpqVersion;
- pHeader->wSectorSize = GetSectorSizeShift(ha->dwSectorSize);
- pHeader->dwHashTablePos = pHeader->dwHeaderSize;
- pHeader->dwHashTableSize = dwHashTableSize;
- pHeader->dwBlockTablePos = pHeader->dwHashTablePos + dwHashTableSize * sizeof(TMPQHash);
- pHeader->dwBlockTableSize = dwBlockTableSize;
-
- // For MPQs version 4 and higher, we set the size of raw data block
- // for calculating MD5
- if(pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_4)
- pHeader->dwRawChunkSize = pCreateInfo->dwRawChunkSize;
-
- // Write the naked MPQ header
- dwErrCode = WriteNakedMPQHeader(ha);
- }
-
- // Create initial HET table, if the caller required an MPQ format 3.0 or newer
- if(dwErrCode == ERROR_SUCCESS && pCreateInfo->dwMpqVersion >= MPQ_FORMAT_VERSION_3 && pCreateInfo->dwMaxFileCount != 0)
- {
- ha->pHetTable = CreateHetTable(ha->dwFileTableSize, 0, 0x40, NULL);
- if(ha->pHetTable == NULL)
- dwErrCode = ERROR_NOT_ENOUGH_MEMORY;
- }
-
- // Create initial hash table
- if(dwErrCode == ERROR_SUCCESS && dwHashTableSize != 0)
- {
- dwErrCode = CreateHashTable(ha, dwHashTableSize);
- }
-
- // Create initial file table
- if(dwErrCode == ERROR_SUCCESS && ha->dwMaxFileCount != 0)
- {
- dwErrCode = CreateFileTable(ha, ha->dwMaxFileCount);
- }
-
- // Cleanup : If an error, delete all buffers and return
- if(dwErrCode != ERROR_SUCCESS)
- {
- FileStream_Close(pStream);
- FreeArchiveHandle(ha);
- SetLastError(dwErrCode);
- ha = NULL;
- }
-
- // Return the values
- *phMpq = (HANDLE)ha;
- return (dwErrCode == ERROR_SUCCESS);
-}