mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[Build] Larger build system update
FIXED: Core now builds under cmake for Windows TODO: Map and mmap gen currently does not build TODO: More sync work is required for Eluna, thus Eluna is temporarily disabled This has only been tested under Windows with CMAKE and VS
This commit is contained in:
parent
c2f9316581
commit
13292befd6
640 changed files with 100354 additions and 29918 deletions
|
|
@ -6,6 +6,7 @@
|
|||
/* Date Ver Who Comment */
|
||||
/* -------- ---- --- ------- */
|
||||
/* 27.03.10 1.00 Lad Splitted from SFileCreateArchiveEx.cpp */
|
||||
/* 21.04.13 1.01 Dea AddFile callback now part of TMPQArchive */
|
||||
/*****************************************************************************/
|
||||
|
||||
#define __STORMLIB_SELF__
|
||||
|
|
@ -13,7 +14,17 @@
|
|||
#include "StormCommon.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures
|
||||
// Local variables
|
||||
|
||||
// Mask for lossy compressions
|
||||
#define MPQ_LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN)
|
||||
|
||||
// Data compression for SFileAddFile
|
||||
// Kept here for compatibility with code that was created with StormLib version < 6.50
|
||||
static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// WAVE verification
|
||||
|
||||
#define FILE_SIGNATURE_RIFF 0x46464952
|
||||
#define FILE_SIGNATURE_WAVE 0x45564157
|
||||
|
|
@ -25,8 +36,8 @@ typedef struct _WAVE_FILE_HEADER
|
|||
DWORD dwChunkId; // 0x52494646 ("RIFF")
|
||||
DWORD dwChunkSize; // Size of that chunk, in bytes
|
||||
DWORD dwFormat; // Must be 0x57415645 ("WAVE")
|
||||
|
||||
// Format sub-chunk
|
||||
|
||||
// Format sub-chunk
|
||||
DWORD dwSubChunk1Id; // 0x666d7420 ("fmt ")
|
||||
DWORD dwSubChunk1Size; // 0x16 for PCM
|
||||
USHORT wAudioFormat; // 1 = PCM. Other value means some sort of compression
|
||||
|
|
@ -39,36 +50,29 @@ typedef struct _WAVE_FILE_HEADER
|
|||
// Followed by "data" sub-chunk (we don't care)
|
||||
} WAVE_FILE_HEADER, *PWAVE_FILE_HEADER;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local variables
|
||||
|
||||
// Data compression for SFileAddFile
|
||||
// Kept here for compatibility with code that was created with StormLib version < 6.50
|
||||
static DWORD DefaultDataCompression = MPQ_COMPRESSION_PKWARE;
|
||||
|
||||
static SFILE_ADDFILE_CALLBACK AddFileCB = NULL;
|
||||
static void * pvUserData = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MPQ write data functions
|
||||
|
||||
#define LOSSY_COMPRESSION_MASK (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN)
|
||||
|
||||
static int IsWaveFile(
|
||||
LPBYTE pbFileData,
|
||||
DWORD cbFileData,
|
||||
LPDWORD pdwChannels)
|
||||
static bool IsWaveFile_16BitsPerAdpcmSample(
|
||||
LPBYTE pbFileData,
|
||||
DWORD cbFileData,
|
||||
LPDWORD pdwChannels)
|
||||
{
|
||||
PWAVE_FILE_HEADER pWaveHdr = (PWAVE_FILE_HEADER)pbFileData;
|
||||
|
||||
// The amount of file data must be at least size of WAVE header
|
||||
if(cbFileData > sizeof(WAVE_FILE_HEADER))
|
||||
{
|
||||
// Check for the RIFF header
|
||||
if(pWaveHdr->dwChunkId == FILE_SIGNATURE_RIFF && pWaveHdr->dwFormat == FILE_SIGNATURE_WAVE)
|
||||
{
|
||||
// Check for ADPCM format
|
||||
if(pWaveHdr->dwSubChunk1Id == FILE_SIGNATURE_FMT && pWaveHdr->wAudioFormat == AUDIO_FORMAT_PCM)
|
||||
{
|
||||
*pdwChannels = pWaveHdr->wChannels;
|
||||
return true;
|
||||
// Now the number of bits per sample must be at least 16.
|
||||
// If not, the WAVE file gets corrupted by the ADPCM compression
|
||||
if(pWaveHdr->wBitsPerSample >= 0x10)
|
||||
{
|
||||
*pdwChannels = pWaveHdr->wChannels;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,33 +80,29 @@ static int IsWaveFile(
|
|||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MPQ write data functions
|
||||
|
||||
static int WriteDataToMpqFile(
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hf,
|
||||
LPBYTE pbFileData,
|
||||
DWORD dwDataSize,
|
||||
DWORD dwCompression)
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hf,
|
||||
LPBYTE pbFileData,
|
||||
DWORD dwDataSize,
|
||||
DWORD dwCompression)
|
||||
{
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
ULONGLONG ByteOffset;
|
||||
LPBYTE pbCompressed = NULL; // Compressed (target) data
|
||||
LPBYTE pbToWrite = NULL; // Data to write to the file
|
||||
int nCompressionLevel = -1; // ADPCM compression level (only used for wave files)
|
||||
LPBYTE pbCompressed = NULL; // Compressed (target) data
|
||||
LPBYTE pbToWrite = hf->pbFileSector; // Data to write to the file
|
||||
int nCompressionLevel; // ADPCM compression level (only used for wave files)
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// If the caller wants ADPCM compression, we will set wave compression level to 4,
|
||||
// which corresponds to medium quality
|
||||
if(dwCompression & LOSSY_COMPRESSION_MASK)
|
||||
nCompressionLevel = 4;
|
||||
|
||||
// Make sure that the caller won't overrun the previously initiated file size
|
||||
assert(hf->dwFilePos + dwDataSize <= pFileEntry->dwFileSize);
|
||||
assert(hf->dwSectorCount != 0);
|
||||
assert(hf->pbFileSector != NULL);
|
||||
if((hf->dwFilePos + dwDataSize) > pFileEntry->dwFileSize)
|
||||
return ERROR_DISK_FULL;
|
||||
pbToWrite = hf->pbFileSector;
|
||||
|
||||
// Now write all data to the file sector buffer
|
||||
if(nError == ERROR_SUCCESS)
|
||||
|
|
@ -111,11 +111,11 @@ static int WriteDataToMpqFile(
|
|||
DWORD dwSectorIndex = hf->dwFilePos / hf->dwSectorSize;
|
||||
DWORD dwBytesToCopy;
|
||||
|
||||
// Process all data.
|
||||
// Process all data.
|
||||
while(dwDataSize != 0)
|
||||
{
|
||||
dwBytesToCopy = dwDataSize;
|
||||
|
||||
|
||||
// Check for sector overflow
|
||||
if(dwBytesToCopy > (hf->dwSectorSize - dwBytesInSector))
|
||||
dwBytesToCopy = (hf->dwSectorSize - dwBytesInSector);
|
||||
|
|
@ -141,7 +141,7 @@ static int WriteDataToMpqFile(
|
|||
hf->dwCrc32 = crc32(hf->dwCrc32, hf->pbFileSector, dwBytesInSector);
|
||||
|
||||
// Compress the file sector, if needed
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED)
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK)
|
||||
{
|
||||
int nOutBuffer = (int)dwBytesInSector;
|
||||
int nInBuffer = (int)dwBytesInSector;
|
||||
|
|
@ -160,27 +160,33 @@ static int WriteDataToMpqFile(
|
|||
}
|
||||
|
||||
//
|
||||
// Note that both SCompImplode and SCompCompress give original buffer,
|
||||
// if they are unable to comperss the data.
|
||||
// Note that both SCompImplode and SCompCompress copy data as-is,
|
||||
// if they are unable to compress the data.
|
||||
//
|
||||
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE)
|
||||
{
|
||||
SCompImplode((char *)pbCompressed,
|
||||
&nOutBuffer,
|
||||
(char *)hf->pbFileSector,
|
||||
nInBuffer);
|
||||
SCompImplode(pbCompressed, &nOutBuffer, hf->pbFileSector, nInBuffer);
|
||||
}
|
||||
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS)
|
||||
{
|
||||
SCompCompress((char *)pbCompressed,
|
||||
&nOutBuffer,
|
||||
(char *)hf->pbFileSector,
|
||||
nInBuffer,
|
||||
(unsigned)dwCompression,
|
||||
0,
|
||||
nCompressionLevel);
|
||||
// If this is the first sector, we need to override the given compression
|
||||
// by the first sector compression. This is because the entire sector must
|
||||
// be compressed by the same compression.
|
||||
//
|
||||
// Test case:
|
||||
//
|
||||
// WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_PKWARE) // Write 0x10 bytes (sector 0)
|
||||
// WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0)
|
||||
// WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0)
|
||||
// WRITE_FILE(hFile, pvBuffer, 0x10, MPQ_COMPRESSION_ADPCM_MONO) // Write 0x10 bytes (still sector 0)
|
||||
dwCompression = (dwSectorIndex == 0) ? hf->dwCompression0 : dwCompression;
|
||||
|
||||
// If the caller wants ADPCM compression, we will set wave compression level to 4,
|
||||
// which corresponds to medium quality
|
||||
nCompressionLevel = (dwCompression & MPQ_LOSSY_COMPRESSION_MASK) ? 4 : -1;
|
||||
SCompCompress(pbCompressed, &nOutBuffer, hf->pbFileSector, nInBuffer, (unsigned)dwCompression, 0, nCompressionLevel);
|
||||
}
|
||||
|
||||
// Update sector positions
|
||||
|
|
@ -191,7 +197,7 @@ static int WriteDataToMpqFile(
|
|||
// We have to calculate sector CRC, if enabled
|
||||
if(hf->SectorChksums != NULL)
|
||||
hf->SectorChksums[dwSectorIndex] = adler32(0, pbCompressed, nOutBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt the sector, if necessary
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
|
|
@ -209,8 +215,8 @@ static int WriteDataToMpqFile(
|
|||
}
|
||||
|
||||
// Call the compact callback, if any
|
||||
if(AddFileCB != NULL)
|
||||
AddFileCB(pvUserData, hf->dwFilePos, hf->dwDataSize, false);
|
||||
if(ha->pfnAddFileCB != NULL)
|
||||
ha->pfnAddFileCB(ha->pvAddFileUserData, hf->dwFilePos, hf->dwDataSize, false);
|
||||
|
||||
// Update the compressed file size
|
||||
pFileEntry->dwCmpSize += dwBytesInSector;
|
||||
|
|
@ -230,10 +236,10 @@ static int WriteDataToMpqFile(
|
|||
// Recrypts file data for file renaming
|
||||
|
||||
static int RecryptFileData(
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hf,
|
||||
const char * szFileName,
|
||||
const char * szNewFileName)
|
||||
TMPQArchive * ha,
|
||||
TMPQFile * hf,
|
||||
const char * szFileName,
|
||||
const char * szNewFileName)
|
||||
{
|
||||
ULONGLONG RawFilePos;
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
|
|
@ -246,8 +252,8 @@ static int RecryptFileData(
|
|||
assert(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED);
|
||||
|
||||
// File decryption key is calculated from the plain name
|
||||
szNewFileName = GetPlainFileNameA(szNewFileName);
|
||||
szFileName = GetPlainFileNameA(szFileName);
|
||||
szNewFileName = GetPlainFileName(szNewFileName);
|
||||
szFileName = GetPlainFileName(szFileName);
|
||||
|
||||
// Calculate both file keys
|
||||
dwOldKey = DecryptFileKey(szFileName, pFileEntry->ByteOffset, pFileEntry->dwFileSize, pFileEntry->dwFlags);
|
||||
|
|
@ -277,7 +283,7 @@ static int RecryptFileData(
|
|||
if(hf->SectorOffsets != NULL)
|
||||
{
|
||||
// Allocate secondary buffer for sectors copy
|
||||
DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]);
|
||||
DWORD * SectorOffsetsCopy = STORM_ALLOC(DWORD, hf->SectorOffsets[0] / sizeof(DWORD));
|
||||
DWORD dwSectorOffsLen = hf->SectorOffsets[0];
|
||||
|
||||
if(SectorOffsetsCopy == NULL)
|
||||
|
|
@ -325,7 +331,7 @@ static int RecryptFileData(
|
|||
}
|
||||
|
||||
// If necessary, re-encrypt the sector
|
||||
// Note: Recompression is not necessary here. Unlike encryption,
|
||||
// Note: Recompression is not necessary here. Unlike encryption,
|
||||
// the compression does not depend on the position of the file in MPQ.
|
||||
BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector);
|
||||
DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwOldKey + dwSector);
|
||||
|
|
@ -351,13 +357,13 @@ static int RecryptFileData(
|
|||
// Support functions for adding files to the MPQ
|
||||
|
||||
int SFileAddFile_Init(
|
||||
TMPQArchive * ha,
|
||||
const char * szFileName,
|
||||
ULONGLONG FileTime,
|
||||
DWORD dwFileSize,
|
||||
LCID lcLocale,
|
||||
DWORD dwFlags,
|
||||
TMPQFile ** phf)
|
||||
TMPQArchive * ha,
|
||||
const char * szFileName,
|
||||
ULONGLONG FileTime,
|
||||
DWORD dwFileSize,
|
||||
LCID lcLocale,
|
||||
DWORD dwFlags,
|
||||
TMPQFile ** phf)
|
||||
{
|
||||
TFileEntry * pFileEntry = NULL;
|
||||
ULONGLONG TempPos; // For various file offset calculations
|
||||
|
|
@ -375,9 +381,9 @@ int SFileAddFile_Init(
|
|||
dwFlags &= ~MPQ_FILE_SECTOR_CRC;
|
||||
|
||||
// Sector CRC is not allowed if the file is not compressed
|
||||
if(!(dwFlags & MPQ_FILE_COMPRESSED))
|
||||
if(!(dwFlags & MPQ_FILE_COMPRESS_MASK))
|
||||
dwFlags &= ~MPQ_FILE_SECTOR_CRC;
|
||||
|
||||
|
||||
// Fix Key is not allowed if the file is not enrypted
|
||||
if(!(dwFlags & MPQ_FILE_ENCRYPTED))
|
||||
dwFlags &= ~MPQ_FILE_FIX_KEY;
|
||||
|
|
@ -388,21 +394,18 @@ int SFileAddFile_Init(
|
|||
lcLocale = 0;
|
||||
|
||||
// Allocate the TMPQFile entry for newly added file
|
||||
hf = CreateMpqFile(ha);
|
||||
hf = CreateFileHandle(ha, NULL);
|
||||
if(hf == NULL)
|
||||
nError = ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
// Find a free space in the MPQ, as well as free block table entry
|
||||
// Find a free space in the MPQ and verify if it's not over 4 GB on MPQs v1
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Find the position where the file will be stored
|
||||
FindFreeMpqSpace(ha, &hf->MpqFilePos);
|
||||
hf->MpqFilePos = FindFreeMpqSpace(ha);
|
||||
hf->RawFilePos = ha->MpqPos + hf->MpqFilePos;
|
||||
hf->bIsWriteHandle = true;
|
||||
|
||||
// Sanity check: The MPQ must be marked as changed at this point
|
||||
assert((ha->dwFlags & MPQ_FLAG_CHANGED) != 0);
|
||||
|
||||
// When format V1, the size of the archive cannot exceed 4 GB
|
||||
if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
|
||||
{
|
||||
|
|
@ -428,34 +431,31 @@ int SFileAddFile_Init(
|
|||
}
|
||||
else
|
||||
{
|
||||
// If the file exists and "replace existing" is not set, fail it
|
||||
// If the caller didn't set MPQ_FILE_REPLACEEXISTING, fail it
|
||||
if((dwFlags & MPQ_FILE_REPLACEEXISTING) == 0)
|
||||
nError = ERROR_ALREADY_EXISTS;
|
||||
|
||||
// If the file entry already contains a file
|
||||
// and it is a pseudo-name, replace it
|
||||
// When replacing an existing file,
|
||||
// we still need to invalidate the (attributes) file
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
AllocateFileName(pFileEntry, szFileName);
|
||||
}
|
||||
InvalidateInternalFiles(ha);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// At this point, the file name in file entry must be non-NULL
|
||||
//
|
||||
|
||||
// Create key for file encryption
|
||||
if(nError == ERROR_SUCCESS && (dwFlags & MPQ_FILE_ENCRYPTED))
|
||||
{
|
||||
hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags);
|
||||
}
|
||||
|
||||
// Fill the file entry and TMPQFile structure
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// At this point, the file name in the file entry must be set
|
||||
assert(pFileEntry->szFileName != NULL);
|
||||
assert(_stricmp(pFileEntry->szFileName, szFileName) == 0);
|
||||
|
||||
// Initialize the hash entry for the file
|
||||
hf->pFileEntry = pFileEntry;
|
||||
hf->dwDataSize = dwFileSize;
|
||||
|
||||
// Decrypt the file key
|
||||
if(dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
hf->dwFileKey = DecryptFileKey(szFileName, hf->MpqFilePos, dwFileSize, dwFlags);
|
||||
|
||||
// Initialize the block table entry for the file
|
||||
pFileEntry->ByteOffset = hf->MpqFilePos;
|
||||
|
|
@ -473,14 +473,20 @@ int SFileAddFile_Init(
|
|||
// If the caller gave us a file time, use it.
|
||||
pFileEntry->FileTime = FileTime;
|
||||
|
||||
// Mark the archive as modified
|
||||
ha->dwFlags |= MPQ_FLAG_CHANGED;
|
||||
|
||||
// Call the callback, if needed
|
||||
if(AddFileCB != NULL)
|
||||
AddFileCB(pvUserData, 0, hf->dwDataSize, false);
|
||||
if(ha->pfnAddFileCB != NULL)
|
||||
ha->pfnAddFileCB(ha->pvAddFileUserData, 0, hf->dwDataSize, false);
|
||||
hf->nAddFileError = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// If an error occured, remember it
|
||||
if(nError != ERROR_SUCCESS)
|
||||
hf->bErrorOccured = true;
|
||||
// Fre the file handle if failed
|
||||
if(nError != ERROR_SUCCESS && hf != NULL)
|
||||
FreeFileHandle(hf);
|
||||
|
||||
// Give the handle to the caller
|
||||
*phf = hf;
|
||||
return nError;
|
||||
}
|
||||
|
|
@ -505,12 +511,9 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
ULONGLONG RawFilePos = hf->RawFilePos;
|
||||
|
||||
// Allocate buffer for file sector
|
||||
nError = AllocateSectorBuffer(hf);
|
||||
hf->nAddFileError = nError = AllocateSectorBuffer(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
hf->bErrorOccured = true;
|
||||
return nError;
|
||||
}
|
||||
|
||||
// Allocate patch info, if the data is patch
|
||||
if(hf->pPatchInfo == NULL && IsIncrementalPatchFile(pvData, dwSize, &hf->dwPatchedFileSize))
|
||||
|
|
@ -519,34 +522,25 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
hf->pFileEntry->dwFlags |= MPQ_FILE_PATCH_FILE;
|
||||
|
||||
// Allocate the patch info
|
||||
nError = AllocatePatchInfo(hf, false);
|
||||
hf->nAddFileError = nError = AllocatePatchInfo(hf, false);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
hf->bErrorOccured = true;
|
||||
return nError;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate sector offsets
|
||||
if(hf->SectorOffsets == NULL)
|
||||
{
|
||||
nError = AllocateSectorOffsets(hf, false);
|
||||
hf->nAddFileError = nError = AllocateSectorOffsets(hf, false);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
hf->bErrorOccured = true;
|
||||
return nError;
|
||||
}
|
||||
}
|
||||
|
||||
// Create array of sector checksums
|
||||
if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC))
|
||||
{
|
||||
nError = AllocateSectorChecksums(hf, false);
|
||||
hf->nAddFileError = nError = AllocateSectorChecksums(hf, false);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
{
|
||||
hf->bErrorOccured = true;
|
||||
return nError;
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-save the patch info, if any
|
||||
|
|
@ -554,7 +548,7 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
{
|
||||
if(!FileStream_Write(ha->pStream, &RawFilePos, hf->pPatchInfo, hf->pPatchInfo->dwLength))
|
||||
nError = GetLastError();
|
||||
|
||||
|
||||
pFileEntry->dwCmpSize += hf->pPatchInfo->dwLength;
|
||||
RawFilePos += hf->pPatchInfo->dwLength;
|
||||
}
|
||||
|
|
@ -574,7 +568,16 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
|
||||
// Write the MPQ data to the file
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Save the first sector compression to the file structure
|
||||
// Note that the entire first file sector will be compressed
|
||||
// by compression that was passed to the first call of SFileAddFile_Write
|
||||
if(hf->dwFilePos == 0)
|
||||
hf->dwCompression0 = dwCompression;
|
||||
|
||||
// Write the data to the MPQ
|
||||
nError = WriteDataToMpqFile(ha, hf, (LPBYTE)pvData, dwSize, dwCompression);
|
||||
}
|
||||
|
||||
// If it succeeded and we wrote all the file data,
|
||||
// we need to re-save sector offset table
|
||||
|
|
@ -592,8 +595,6 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
if(hf->SectorChksums != NULL)
|
||||
{
|
||||
nError = WriteSectorChecksums(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
|
||||
// Now write patch info
|
||||
|
|
@ -603,16 +604,12 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
hf->pPatchInfo->dwDataSize = hf->pFileEntry->dwFileSize;
|
||||
hf->pFileEntry->dwFileSize = hf->dwPatchedFileSize;
|
||||
nError = WritePatchInfo(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
|
||||
// Now write sector offsets to the file
|
||||
if(hf->SectorOffsets != NULL)
|
||||
{
|
||||
nError = WriteSectorOffsets(hf);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
|
||||
// Write the MD5 hashes of each file chunk, if required
|
||||
|
|
@ -622,16 +619,12 @@ int SFileAddFile_Write(TMPQFile * hf, const void * pvData, DWORD dwSize, DWORD d
|
|||
ha->MpqPos + hf->pFileEntry->ByteOffset,
|
||||
hf->pFileEntry->dwCmpSize,
|
||||
ha->pHeader->dwRawChunkSize);
|
||||
if(nError != ERROR_SUCCESS)
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
|
||||
// Store the error code from the Write File operation
|
||||
hf->nAddFileError = nError;
|
||||
return nError;
|
||||
}
|
||||
|
||||
|
|
@ -639,88 +632,87 @@ int SFileAddFile_Finish(TMPQFile * hf)
|
|||
{
|
||||
TMPQArchive * ha = hf->ha;
|
||||
TFileEntry * pFileEntry = hf->pFileEntry;
|
||||
int nError = ERROR_SUCCESS;
|
||||
int nError = hf->nAddFileError;
|
||||
|
||||
// If all previous operations succeeded, we can update the MPQ
|
||||
if(!hf->bErrorOccured)
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Verify if the caller wrote the file properly
|
||||
if(hf->pPatchInfo == NULL)
|
||||
{
|
||||
assert(pFileEntry != NULL);
|
||||
if(hf->dwFilePos != pFileEntry->dwFileSize)
|
||||
{
|
||||
nError = ERROR_CAN_NOT_COMPLETE;
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hf->dwFilePos != hf->pPatchInfo->dwDataSize)
|
||||
{
|
||||
nError = ERROR_CAN_NOT_COMPLETE;
|
||||
hf->bErrorOccured = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!hf->bErrorOccured)
|
||||
// Now we need to recreate the HET table, if exists
|
||||
if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
|
||||
{
|
||||
nError = RebuildHetTable(ha);
|
||||
}
|
||||
|
||||
// Update the block table size
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Call the user callback, if any
|
||||
if(AddFileCB != NULL)
|
||||
AddFileCB(pvUserData, hf->dwDataSize, hf->dwDataSize, true);
|
||||
|
||||
// Update the size of the block table
|
||||
ha->pHeader->dwBlockTableSize = ha->dwFileTableSize;
|
||||
if(ha->pfnAddFileCB != NULL)
|
||||
ha->pfnAddFileCB(ha->pvAddFileUserData, hf->dwDataSize, hf->dwDataSize, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Free the file entry in MPQ tables
|
||||
if(pFileEntry != NULL)
|
||||
FreeFileEntry(ha, pFileEntry);
|
||||
DeleteFileEntry(ha, pFileEntry);
|
||||
}
|
||||
|
||||
// Clear the add file callback
|
||||
FreeMPQFile(hf);
|
||||
pvUserData = NULL;
|
||||
AddFileCB = NULL;
|
||||
FreeFileHandle(hf);
|
||||
return nError;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds data as file to the archive
|
||||
// Adds data as file to the archive
|
||||
|
||||
bool WINAPI SFileCreateFile(
|
||||
HANDLE hMpq,
|
||||
const char * szArchivedName,
|
||||
ULONGLONG FileTime,
|
||||
DWORD dwFileSize,
|
||||
LCID lcLocale,
|
||||
DWORD dwFlags,
|
||||
HANDLE * phFile)
|
||||
HANDLE hMpq,
|
||||
const char * szArchivedName,
|
||||
ULONGLONG FileTime,
|
||||
DWORD dwFileSize,
|
||||
LCID lcLocale,
|
||||
DWORD dwFlags,
|
||||
HANDLE * phFile)
|
||||
{
|
||||
TMPQArchive * ha = (TMPQArchive *)hMpq;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check valid parameters
|
||||
if(!IsValidMpqHandle(ha))
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(szArchivedName == NULL || *szArchivedName == 0)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
if(phFile == NULL)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
|
||||
// Don't allow to add file if the MPQ is open for read only
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
nError = ERROR_ACCESS_DENIED;
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(ha->dwFlags & MPQ_FLAG_READ_ONLY)
|
||||
nError = ERROR_ACCESS_DENIED;
|
||||
|
||||
// Don't allow to add a file under pseudo-file name
|
||||
if(IsPseudoFileName(szArchivedName, NULL))
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
// Don't allow to add a file under pseudo-file name
|
||||
if(IsPseudoFileName(szArchivedName, NULL))
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Don't allow to add any of the internal files
|
||||
if(IsInternalMpqFileName(szArchivedName))
|
||||
nError = ERROR_INTERNAL_FILE;
|
||||
// Don't allow to add any of the internal files
|
||||
if(IsInternalMpqFileName(szArchivedName))
|
||||
nError = ERROR_INTERNAL_FILE;
|
||||
}
|
||||
|
||||
// Perform validity check of the MPQ flags
|
||||
if(nError == ERROR_SUCCESS)
|
||||
|
|
@ -733,17 +725,18 @@ bool WINAPI SFileCreateFile(
|
|||
nError = ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Create the file in MPQ
|
||||
// Check for MPQs that have invalid block table size
|
||||
// Example: size of block table: 0x41, size of hash table: 0x40
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
// Invalidate the entries for (listfile) and (attributes)
|
||||
// After we are done with MPQ changes, we need to re-create them anyway
|
||||
InvalidateInternalFiles(ha);
|
||||
|
||||
// Initiate the add file operation
|
||||
nError = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile);
|
||||
if(ha->dwFileTableSize > ha->dwMaxFileCount)
|
||||
nError = ERROR_DISK_FULL;
|
||||
}
|
||||
|
||||
// Initiate the add file operation
|
||||
if(nError == ERROR_SUCCESS)
|
||||
nError = SFileAddFile_Init(ha, szArchivedName, FileTime, dwFileSize, lcLocale, dwFlags, (TMPQFile **)phFile);
|
||||
|
||||
// Deal with the errors
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
|
|
@ -751,16 +744,16 @@ bool WINAPI SFileCreateFile(
|
|||
}
|
||||
|
||||
bool WINAPI SFileWriteFile(
|
||||
HANDLE hFile,
|
||||
const void * pvData,
|
||||
DWORD dwSize,
|
||||
DWORD dwCompression)
|
||||
HANDLE hFile,
|
||||
const void * pvData,
|
||||
DWORD dwSize,
|
||||
DWORD dwCompression)
|
||||
{
|
||||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check the proper parameters
|
||||
if(!IsValidFileHandle(hf))
|
||||
if(!IsValidFileHandle(hFile))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(hf->bIsWriteHandle == false)
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
|
|
@ -774,14 +767,14 @@ bool WINAPI SFileWriteFile(
|
|||
// the calling application must ensure that such flag combination doesn't get here
|
||||
//
|
||||
|
||||
// if(dwFlags & MPQ_FILE_IMPLODE)
|
||||
// nError = ERROR_INVALID_PARAMETER;
|
||||
//
|
||||
// if(dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
// nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// if(dwFlags & MPQ_FILE_IMPLODE)
|
||||
// nError = ERROR_INVALID_PARAMETER;
|
||||
//
|
||||
// if(dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
// nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Lossy compression is not allowed on single unit files
|
||||
if(dwCompression & LOSSY_COMPRESSION_MASK)
|
||||
if(dwCompression & MPQ_LOSSY_COMPRESSION_MASK)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
|
@ -789,7 +782,7 @@ bool WINAPI SFileWriteFile(
|
|||
// Write the data to the file
|
||||
if(nError == ERROR_SUCCESS)
|
||||
nError = SFileAddFile_Write(hf, pvData, dwSize, dwCompression);
|
||||
|
||||
|
||||
// Deal with errors
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
|
|
@ -802,7 +795,7 @@ bool WINAPI SFileFinishFile(HANDLE hFile)
|
|||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check the proper parameters
|
||||
if(!IsValidFileHandle(hf))
|
||||
if(!IsValidFileHandle(hFile))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(hf->bIsWriteHandle == false)
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
|
|
@ -810,7 +803,7 @@ bool WINAPI SFileFinishFile(HANDLE hFile)
|
|||
// Finish the file
|
||||
if(nError == ERROR_SUCCESS)
|
||||
nError = SFileAddFile_Finish(hf);
|
||||
|
||||
|
||||
// Deal with errors
|
||||
if(nError != ERROR_SUCCESS)
|
||||
SetLastError(nError);
|
||||
|
|
@ -818,15 +811,15 @@ bool WINAPI SFileFinishFile(HANDLE hFile)
|
|||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds a file to the archive
|
||||
// Adds a file to the archive
|
||||
|
||||
bool WINAPI SFileAddFileEx(
|
||||
HANDLE hMpq,
|
||||
const TCHAR * szFileName,
|
||||
const char * szArchivedName,
|
||||
DWORD dwFlags,
|
||||
DWORD dwCompression, // Compression of the first sector
|
||||
DWORD dwCompressionNext) // Compression of next sectors
|
||||
HANDLE hMpq,
|
||||
const TCHAR * szFileName,
|
||||
const char * szArchivedName,
|
||||
DWORD dwFlags,
|
||||
DWORD dwCompression, // Compression of the first sector
|
||||
DWORD dwCompressionNext) // Compression of next sectors
|
||||
{
|
||||
ULONGLONG FileSize = 0;
|
||||
ULONGLONG FileTime = 0;
|
||||
|
|
@ -842,13 +835,13 @@ bool WINAPI SFileAddFileEx(
|
|||
int nError = ERROR_SUCCESS;
|
||||
|
||||
// Check parameters
|
||||
if(szFileName == NULL || *szFileName == 0)
|
||||
if(hMpq == NULL || szFileName == NULL || *szFileName == 0)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
||||
// Open added file
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_LINEAR | BASE_PROVIDER_FILE);
|
||||
pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE);
|
||||
if(pStream == NULL)
|
||||
nError = GetLastError();
|
||||
}
|
||||
|
|
@ -858,7 +851,7 @@ bool WINAPI SFileAddFileEx(
|
|||
{
|
||||
FileStream_GetTime(pStream, &FileTime);
|
||||
FileStream_GetSize(pStream, &FileSize);
|
||||
|
||||
|
||||
// Files bigger than 4GB cannot be added to MPQ
|
||||
if(FileSize >> 32)
|
||||
nError = ERROR_DISK_FULL;
|
||||
|
|
@ -880,15 +873,18 @@ bool WINAPI SFileAddFileEx(
|
|||
// we will copy the compression for the first sector
|
||||
if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME)
|
||||
dwCompressionNext = dwCompression;
|
||||
|
||||
|
||||
// If the caller wants ADPCM compression, we make sure
|
||||
// that the first sector is not compressed with lossy compression
|
||||
if(dwCompressionNext & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
|
||||
{
|
||||
// The first compression must not be WAVE
|
||||
// The compression of the first file sector must not be ADPCM
|
||||
// in order not to corrupt the headers
|
||||
if(dwCompression & (MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO))
|
||||
dwCompression = MPQ_COMPRESSION_PKWARE;
|
||||
|
||||
|
||||
// Remove both flag mono and stereo flags.
|
||||
// They will be re-added according to WAVE type
|
||||
dwCompressionNext &= ~(MPQ_COMPRESSION_ADPCM_MONO | MPQ_COMPRESSION_ADPCM_STEREO);
|
||||
bIsAdpcmCompression = true;
|
||||
}
|
||||
|
|
@ -916,15 +912,19 @@ bool WINAPI SFileAddFileEx(
|
|||
// If the file being added is a WAVE file, we check number of channels
|
||||
if(bIsFirstSector && bIsAdpcmCompression)
|
||||
{
|
||||
// The file must really be a wave file, otherwise it's data corruption
|
||||
if(!IsWaveFile(pbFileData, dwBytesToRead, &dwChannels))
|
||||
// The file must really be a WAVE file with at least 16 bits per sample,
|
||||
// otherwise the ADPCM compression will corrupt it
|
||||
if(IsWaveFile_16BitsPerAdpcmSample(pbFileData, dwBytesToRead, &dwChannels))
|
||||
{
|
||||
nError = ERROR_BAD_FORMAT;
|
||||
break;
|
||||
// Setup the compression of next sectors according to number of channels
|
||||
dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setup the compression of next sectors to a lossless compression
|
||||
dwCompressionNext = (dwCompression & MPQ_LOSSY_COMPRESSION_MASK) ? MPQ_COMPRESSION_PKWARE : dwCompression;
|
||||
}
|
||||
|
||||
// Setup the compression according to number of channels
|
||||
dwCompressionNext |= (dwChannels == 1) ? MPQ_COMPRESSION_ADPCM_MONO : MPQ_COMPRESSION_ADPCM_STEREO;
|
||||
bIsFirstSector = false;
|
||||
}
|
||||
|
||||
|
|
@ -956,7 +956,7 @@ bool WINAPI SFileAddFileEx(
|
|||
SetLastError(nError);
|
||||
return (nError == ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
// Adds a data file into the archive
|
||||
bool WINAPI SFileAddFile(HANDLE hMpq, const TCHAR * szFileName, const char * szArchivedName, DWORD dwFlags)
|
||||
{
|
||||
|
|
@ -983,25 +983,25 @@ bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szA
|
|||
// Starcraft files are packed as Mono (0x41) on medium quality.
|
||||
// Because this compression is not used anymore, our compression functions
|
||||
// will default to WaveCompressionLevel = 4 when using ADPCM compression
|
||||
//
|
||||
//
|
||||
|
||||
// Convert quality to data compression
|
||||
switch(dwQuality)
|
||||
{
|
||||
case MPQ_WAVE_QUALITY_HIGH:
|
||||
// WaveCompressionLevel = -1;
|
||||
dwCompression = MPQ_COMPRESSION_PKWARE;
|
||||
break;
|
||||
case MPQ_WAVE_QUALITY_HIGH:
|
||||
// WaveCompressionLevel = -1;
|
||||
dwCompression = MPQ_COMPRESSION_PKWARE;
|
||||
break;
|
||||
|
||||
case MPQ_WAVE_QUALITY_MEDIUM:
|
||||
// WaveCompressionLevel = 4;
|
||||
dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
|
||||
break;
|
||||
case MPQ_WAVE_QUALITY_MEDIUM:
|
||||
// WaveCompressionLevel = 4;
|
||||
dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
|
||||
break;
|
||||
|
||||
case MPQ_WAVE_QUALITY_LOW:
|
||||
// WaveCompressionLevel = 2;
|
||||
dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
|
||||
break;
|
||||
case MPQ_WAVE_QUALITY_LOW:
|
||||
// WaveCompressionLevel = 2;
|
||||
dwCompression = MPQ_COMPRESSION_ADPCM_STEREO | MPQ_COMPRESSION_HUFFMANN;
|
||||
break;
|
||||
}
|
||||
|
||||
return SFileAddFileEx(hMpq,
|
||||
|
|
@ -1017,7 +1017,7 @@ bool WINAPI SFileAddWave(HANDLE hMpq, const TCHAR * szFileName, const char * szA
|
|||
//
|
||||
// This function removes a file from the archive. The file content
|
||||
// remains there, only the entries in the hash table and in the block
|
||||
// table are updated.
|
||||
// table are updated.
|
||||
|
||||
bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope)
|
||||
{
|
||||
|
|
@ -1032,7 +1032,7 @@ bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearch
|
|||
// Check the parameters
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(!IsValidMpqHandle(ha))
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(szFileName == NULL || *szFileName == 0)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
|
@ -1075,8 +1075,12 @@ bool WINAPI SFileRemoveFile(HANDLE hMpq, const char * szFileName, DWORD dwSearch
|
|||
// After we are done with MPQ changes, we need to re-create them anyway
|
||||
InvalidateInternalFiles(ha);
|
||||
|
||||
// Mark the file entry as free
|
||||
nError = FreeFileEntry(ha, pFileEntry);
|
||||
// Delete the file entry in the file table and defragment the file table
|
||||
DeleteFileEntry(ha, pFileEntry);
|
||||
|
||||
// We also need to rebuild the HET table, if present
|
||||
if(ha->pHetTable != NULL)
|
||||
nError = RebuildHetTable(ha);
|
||||
}
|
||||
|
||||
// Resolve error and exit
|
||||
|
|
@ -1097,7 +1101,7 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
// Test the valid parameters
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
if(!IsValidMpqHandle(ha))
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
nError = ERROR_INVALID_HANDLE;
|
||||
if(szFileName == NULL || *szFileName == 0 || szNewFileName == NULL || *szNewFileName == 0)
|
||||
nError = ERROR_INVALID_PARAMETER;
|
||||
|
|
@ -1127,7 +1131,7 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
if(pFileEntry == NULL)
|
||||
nError = ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
// Also try to find file entry for the new file.
|
||||
// This verifies if we are not overwriting an existing file
|
||||
// (whose name we perhaps don't know)
|
||||
|
|
@ -1144,6 +1148,10 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
nError = RenameFileEntry(ha, pFileEntry, szNewFileName);
|
||||
}
|
||||
|
||||
// Now we need to recreate the HET table, if we have one
|
||||
if(nError == ERROR_SUCCESS && ha->pHetTable != NULL)
|
||||
nError = RebuildHetTable(ha);
|
||||
|
||||
// Now we copy the existing file entry to the new one
|
||||
if(nError == ERROR_SUCCESS)
|
||||
{
|
||||
|
|
@ -1151,14 +1159,12 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
// with the new decryption key
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)
|
||||
{
|
||||
hf = CreateMpqFile(ha);
|
||||
hf = CreateFileHandle(ha, pFileEntry);
|
||||
if(hf != NULL)
|
||||
{
|
||||
// Recrypt the file data in the MPQ
|
||||
hf->pFileEntry = pFileEntry;
|
||||
hf->dwDataSize = pFileEntry->dwFileSize;
|
||||
nError = RecryptFileData(ha, hf, szFileName, szNewFileName);
|
||||
|
||||
|
||||
// Update the MD5
|
||||
if(ha->pHeader->dwRawChunkSize != 0)
|
||||
{
|
||||
|
|
@ -1168,8 +1174,8 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
pFileEntry->dwCmpSize,
|
||||
ha->pHeader->dwRawChunkSize);
|
||||
}
|
||||
|
||||
FreeMPQFile(hf);
|
||||
|
||||
FreeFileHandle(hf);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1178,9 +1184,8 @@ bool WINAPI SFileRenameFile(HANDLE hMpq, const char * szFileName, const char * s
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Note: MPQ_FLAG_CHANGED is set by RenameFileEntry
|
||||
//
|
||||
// assert((ha->dwFlags & MPQ_FLAG_CHANGED) != 0);
|
||||
|
||||
// Resolve error and return
|
||||
if(nError != ERROR_SUCCESS)
|
||||
|
|
@ -1215,7 +1220,7 @@ bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
|
|||
TMPQFile * hf = (TMPQFile *)hFile;
|
||||
|
||||
// Invalid handle => do nothing
|
||||
if(!IsValidFileHandle(hf))
|
||||
if(!IsValidFileHandle(hFile))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
|
|
@ -1278,9 +1283,17 @@ bool WINAPI SFileSetFileLocale(HANDLE hFile, LCID lcNewLocale)
|
|||
//-----------------------------------------------------------------------------
|
||||
// Sets add file callback
|
||||
|
||||
bool WINAPI SFileSetAddFileCallback(HANDLE /* hMpq */, SFILE_ADDFILE_CALLBACK aAddFileCB, void * pvData)
|
||||
bool WINAPI SFileSetAddFileCallback(HANDLE hMpq, SFILE_ADDFILE_CALLBACK AddFileCB, void * pvUserData)
|
||||
{
|
||||
pvUserData = pvData;
|
||||
AddFileCB = aAddFileCB;
|
||||
TMPQArchive * ha = (TMPQArchive *) hMpq;
|
||||
|
||||
if(!IsValidMpqHandle(hMpq))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return false;
|
||||
}
|
||||
|
||||
ha->pvAddFileUserData = pvUserData;
|
||||
ha->pfnAddFileCB = AddFileCB;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue