Current News Archived News Search News Discussion Forum Old Forum Install Programs More Downloads... Troubleshooting Source Code Format Specs. Misc. Information Non-SF Stuff Links Small banner for links to this site: |
- Split some code for archive opening and creation into separate functions.
- Moved header writing into separate function. - Large archive reading should be complete. - Large archive compacting may be complete. - Some work on adding files to large archives, but it is still incomplete and will likely corrupt. - Other large archive write operations should be complete. - SFileFindMpqHeader now takes archive handles and archive file handles.
diff --git a/MpqBlockTable.cpp b/MpqBlockTable.cpp
--- a/MpqBlockTable.cpp
+++ b/MpqBlockTable.cpp
BOOL WriteBlockTable(MPQARCHIVE *mpqOpenArc)
{
DWORD tsz;
+ BOOL bReturnVal = FALSE;
if (mpqOpenArc->MpqHeader.dwBlockTableSize == 0) return TRUE;
if (!mpqOpenArc->lpBlockTable) return FALSE;
if (buffer) {
memcpy(buffer,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
EncryptData((LPBYTE)buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader.dwBlockTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh << 32), FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwBlockTableOffset, mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh), FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile,buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
SFFree(buffer);
}
else {
EncryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader.dwBlockTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh << 32), FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwBlockTableOffset, mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh), FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
}
- return TRUE;
+ if (bReturnVal && mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable) {
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable, FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile, mpqOpenArc->lpFileOffsetsHigh, sizeof(UInt16) * mpqOpenArc->MpqHeader.dwBlockTableSize, &tsz, 0);
+ }
+
+ return bReturnVal;
}
diff --git a/MpqHashTable.cpp b/MpqHashTable.cpp
--- a/MpqHashTable.cpp
+++ b/MpqHashTable.cpp
BOOL WriteHashTable(MPQARCHIVE *mpqOpenArc)
{
DWORD tsz;
+ BOOL bReturnVal = FALSE;
char *buffer = (char *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
if (buffer) {
memcpy(buffer,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
EncryptData((LPBYTE)buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader.dwHashTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh << 32), FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwHashTableOffset, mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh), FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile,buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
SFFree(buffer);
}
else {
EncryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader.dwHashTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh << 32), FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwHashTableOffset, mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh), FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
}
- return TRUE;
+ return bReturnVal;
}
diff --git a/SFTypes.h b/SFTypes.h
--- a/SFTypes.h
+++ b/SFTypes.h
L_Low = (UInt32)(R); \
L_High = (UInt32)((R) >> 32);
-#define MakeUInt64(R_Low, R_High) ((UInt64)(R_Low) + (UInt64)((R_High) << 32))
+#define MakeUInt64(R_Low, R_High) ((UInt64)(R_Low) + ((UInt64)(R_High) << 32))
#endif // #ifndef SFTYPES_INCLUDED
diff --git a/SFmpqapi.cpp b/SFmpqapi.cpp
--- a/SFmpqapi.cpp
+++ b/SFmpqapi.cpp
#endif
}
-BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, MPQHANDLE *hMPQ, DWORD dwFlags2, DWORD dwMaximumFilesInArchive, DWORD dwBlockSize)
+BOOL MpqWriteHeaders(MPQARCHIVE *mpqOpenArc)
{
- UInt64 flen;
- DWORD tsz;
+ DWORD nIOLen;
+ BOOL bReturnVal = FALSE;
+
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart, FILE_BEGIN);
+ bReturnVal = WriteFile(mpqOpenArc->hFile, &mpqOpenArc->MpqHeader, sizeof(MPQHEADER), &nIOLen, 0);
+
+ if (bReturnVal && mpqOpenArc->MpqHeader.wVersion > 0) {
+ bReturnVal = WriteFile(mpqOpenArc->hFile, &mpqOpenArc->MpqHeader_Ex, sizeof(MPQHEADER_EX), &nIOLen, 0);
+ }
+
+ return bReturnVal;
+}
+
+BOOL MpqWriteNewArchive(MPQARCHIVE *mpqOpenArc)
+{
+ DWORD nIOLen;
+
+ memcpy(&mpqOpenArc->MpqHeader.dwMPQID,ID_MPQ,4);
+ mpqOpenArc->MpqHeader.wVersion = wCreationVersion;
+
+ if (mpqOpenArc->MpqHeader.wVersion == 0)
+ mpqOpenArc->MpqHeader.dwHeaderSize = sizeof(MPQHEADER);
+ else
+ mpqOpenArc->MpqHeader.dwHeaderSize = sizeof(MPQHEADER) + sizeof(MPQHEADER_EX);
+ mpqOpenArc->dwHeaderSize = mpqOpenArc->MpqHeader.dwHeaderSize;
+
+ if (mpqOpenArc->MpqHeader.wBlockSize & 0xFFFF0000)
+ mpqOpenArc->MpqHeader.wBlockSize = DEFAULT_BLOCK_SIZE;
+ DWORD i;
+ for (i=1;i<mpqOpenArc->MpqHeader.dwHashTableSize;i*=2) {}
+ mpqOpenArc->MpqHeader.dwHashTableSize = i;
+ mpqOpenArc->MpqHeader.dwBlockTableSize = 0;
+ mpqOpenArc->MpqHeader.dwHashTableOffset = mpqOpenArc->dwHeaderSize;
+ mpqOpenArc->MpqHeader.dwBlockTableOffset = mpqOpenArc->dwHeaderSize + mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY);
+ mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable = 0;
+ mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh = 0;
+ mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh = 0;
+ mpqOpenArc->MpqHeader.dwMPQSize = mpqOpenArc->dwHeaderSize + mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY);
+
+ if (!MpqWriteHeaders(mpqOpenArc))
+ return FALSE;
+
+ mpqOpenArc->lpHashTable = (HASHTABLEENTRY *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
+ if (!mpqOpenArc->lpHashTable) {
+ return FALSE;
+ }
+ memset(mpqOpenArc->lpHashTable, 0xFF, sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
+ EncryptData((LPBYTE)mpqOpenArc->lpHashTable, sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize, dwHashTableKey);
+ if (!WriteFile(mpqOpenArc->hFile, mpqOpenArc->lpHashTable, sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize, &nIOLen, 0)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL MpqReadExistingArchive(MPQARCHIVE *mpqOpenArc)
+{
+ DWORD nIOLen;
+
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart, FILE_BEGIN);
+ if (!ReadFile(mpqOpenArc->hFile, &mpqOpenArc->MpqHeader, sizeof(MPQHEADER), &nIOLen, 0))
+ return FALSE;
+
+ if (mpqOpenArc->MpqHeader.wVersion > 0) {
+ mpqOpenArc->dwHeaderSize = sizeof(MPQHEADER) + sizeof(MPQHEADER_EX);
+ if (!ReadFile(mpqOpenArc->hFile, &mpqOpenArc->MpqHeader_Ex, sizeof(MPQHEADER_EX), &nIOLen, 0))
+ return FALSE;
+ }
+ else {
+ mpqOpenArc->dwHeaderSize = sizeof(MPQHEADER);
+ memset(&mpqOpenArc->MpqHeader_Ex, 0, sizeof(MPQHEADER_EX));
+ }
+
+ mpqOpenArc->lpHashTable = (HASHTABLEENTRY *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
+ if (!mpqOpenArc->lpHashTable)
+ return FALSE;
+
+ if (mpqOpenArc->MpqHeader.dwBlockTableSize) {
+ mpqOpenArc->lpBlockTable = (BLOCKTABLEENTRY *)SFAlloc((sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ mpqOpenArc->lpFileOffsetsHigh = (UInt16 *)(mpqOpenArc->lpBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize);
+ if (!mpqOpenArc->lpBlockTable)
+ return FALSE;
+ }
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwHashTableOffset, mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh), FILE_BEGIN);
+ if (!ReadFile(mpqOpenArc->hFile, mpqOpenArc->lpHashTable, sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize, &nIOLen, 0))
+ return FALSE;
+
+ if (mpqOpenArc->MpqHeader.dwBlockTableSize) {
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->MpqHeader.dwBlockTableOffset, mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh), FILE_BEGIN);
+ if (!ReadFile(mpqOpenArc->hFile, mpqOpenArc->lpBlockTable, sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize, &nIOLen, 0))
+ return FALSE;
+
+ if (mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable) {
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable, FILE_BEGIN);
+ if (!ReadFile(mpqOpenArc->hFile, mpqOpenArc->lpFileOffsetsHigh, sizeof(WORD) * mpqOpenArc->MpqHeader.dwBlockTableSize, &nIOLen, 0))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+BOOL MpqOpenArchiveInit(MPQARCHIVE *mpqOpenArc, LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags1, DWORD dwFlags2, DWORD dwExtraFlags)
+{
+ /*mpqOpenArc->lpFileName = (char *)SFAlloc(strlen(lpFileName)+1);
+ if(!mpqOpenArc->lpFileName)
+ return FALSE;*/
+ DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
+ if (mpqOpenArc->lpBlockTable) DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
+ mpqOpenArc->lpFileName = mpqOpenArc->szFileName;
+ strncpy(mpqOpenArc->lpFileName,lpFileName,259);
+ if (FirstLastMpq[1]) FirstLastMpq[1]->lpNextArc = mpqOpenArc;
+ mpqOpenArc->lpNextArc = (MPQARCHIVE *)FirstLastMpq;
+ mpqOpenArc->lpPrevArc = (MPQARCHIVE *)FirstLastMpq[1];
+ if (!FirstLastMpq[0]) {
+ mpqOpenArc->lpPrevArc = (MPQARCHIVE *)0xEAFC5E23;
+ FirstLastMpq[0] = mpqOpenArc;
+ }
+ FirstLastMpq[1] = mpqOpenArc;
+ mpqOpenArc->dwFlags1 = dwFlags1;
+ mpqOpenArc->dwPriority = dwPriority;
+ mpqOpenArc->lpLastReadFile = 0;
+ mpqOpenArc->dwUnk = 0;
+ mpqOpenArc->dwBlockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
+ mpqOpenArc->lpLastReadBlock = 0;
+ mpqOpenArc->dwBufferSize = 0;
+ mpqOpenArc->qwMPQEnd = mpqOpenArc->qwMPQStart + mpqOpenArc->MpqHeader.dwMPQSize;
+ mpqOpenArc->lpMPQHeader = &mpqOpenArc->MpqHeader;
+ mpqOpenArc->qwReadOffset = mpqOpenArc->qwMPQEnd;
+ mpqOpenArc->dwRefCount = 1;
+ mpqOpenArc->dwFlags = dwFlags2;
+ mpqOpenArc->dwExtraFlags = dwExtraFlags;
+
+ return TRUE;
+}
+
+BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, MPQHANDLE *hMPQ, DWORD dwFlags2, DWORD dwMaximumFilesInArchive, DWORD dwBlockSize)
+{
if (!lpFileName || !hMPQ) {
SetLastError(ERROR_INVALID_PARAMETER);
- if (hMPQ) *hMPQ = 0;
+ if (hMPQ) *hMPQ = (MPQHANDLE)INVALID_HANDLE_VALUE;
return FALSE;
}
+ *hMPQ = (MPQHANDLE)INVALID_HANDLE_VALUE;
if (!*lpFileName) {
SetLastError(ERROR_INVALID_PARAMETER);
- *hMPQ = 0;
return FALSE;
}
@@ -321,7 +457,7 @@ BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags,
else if (dwFlags&2)
dwFlags1 |= 1;
if (dwFlags & SFILE_OPEN_CD_ROM_FILE)
- if (!(dwFlags1&2)) {*hMPQ = 0;return FALSE;}
+ if (!(dwFlags1&2)) {return FALSE;}
#endif
DWORD dwCreateFlags,dwAccessFlags,dwShareFlags;
@@ -332,7 +468,6 @@ BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags,
if (dwFlags2 & MOAU_READ_ONLY) {
if (!(dwFlags2 & MOAU_OPEN_EXISTING)) {
SetLastError(MPQ_ERROR_BAD_OPEN_MODE);
- *hMPQ = 0;
return FALSE;
}
dwAccessFlags = GENERIC_READ;
@@ -359,194 +494,71 @@ BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags,
if (hFile!=INVALID_HANDLE_VALUE)
{
MPQARCHIVE **lpnOpenMpq = (MPQARCHIVE **)SFAlloc(sizeof(MPQARCHIVE *) * (dwOpenMpqCount+1));
- if (lpnOpenMpq==0) {
+ if (!lpnOpenMpq) {
CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
}
- UInt64 qwMpqStart;
MPQARCHIVE *mpqOpenArc;
if (SFGetFileSize(hFile)==0 && !(dwFlags2 & MOAU_READ_ONLY))
{
- qwMpqStart = 0;
mpqOpenArc = (MPQARCHIVE *)SFAlloc(sizeof(MPQARCHIVE));
if (!mpqOpenArc) {
SFFree(lpnOpenMpq);
CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
}
- memcpy(&mpqOpenArc->MpqHeader.dwMPQID,ID_MPQ,4);
- mpqOpenArc->MpqHeader.dwHeaderSize = sizeof(MPQHEADER);
- mpqOpenArc->MpqHeader.wVersion = wCreationVersion;
- if (mpqOpenArc->MpqHeader.wVersion == 0)
- mpqOpenArc->MpqHeader.dwHeaderSize = sizeof(MPQHEADER);
- else
- mpqOpenArc->MpqHeader.dwHeaderSize = sizeof(MPQHEADER) + sizeof(MPQHEADER_EX);
-
- if (dwBlockSize & 0xFFFF0000)
- mpqOpenArc->MpqHeader.wBlockSize = DEFAULT_BLOCK_SIZE;
- else
- mpqOpenArc->MpqHeader.wBlockSize = (WORD)dwBlockSize;
- DWORD i;
- for (i=1;i<dwMaximumFilesInArchive;i*=2) {}
- dwMaximumFilesInArchive = i;
+ mpqOpenArc->hFile = hFile;
+ mpqOpenArc->qwMPQStart = 0;
mpqOpenArc->MpqHeader.dwHashTableSize = dwMaximumFilesInArchive;
- mpqOpenArc->MpqHeader.dwBlockTableSize = 0;
- mpqOpenArc->MpqHeader.dwHashTableOffset = mpqOpenArc->MpqHeader.dwHeaderSize;
- mpqOpenArc->MpqHeader.dwBlockTableOffset = mpqOpenArc->MpqHeader.dwHeaderSize + mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY);
- mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable = 0;
- mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh = 0;
- mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh = 0;
- mpqOpenArc->MpqHeader.dwMPQSize = mpqOpenArc->MpqHeader.dwHeaderSize + mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY);
- if(WriteFile(hFile,&mpqOpenArc->MpqHeader,mpqOpenArc->MpqHeader.dwHeaderSize,&tsz,0)==0) {
- SFFree(lpnOpenMpq);
+ mpqOpenArc->MpqHeader.wBlockSize = (WORD)dwBlockSize;
+
+ if (!MpqWriteNewArchive(mpqOpenArc)) {
+ if (mpqOpenArc->lpHashTable) SFFree(mpqOpenArc->lpHashTable);
SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
- flen = mpqOpenArc->MpqHeader.dwMPQSize;
- mpqOpenArc->lpHashTable = (HASHTABLEENTRY *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if(!mpqOpenArc->lpHashTable) {
SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
- memset(mpqOpenArc->lpHashTable,0xFF,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- EncryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- if(WriteFile(hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0)==0) {
- SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
}
}
else
{
- qwMpqStart = SFileFindMpqHeaderEx(hFile);
+ UInt64 qwMpqStart = SFileFindMpqHeaderEx(hFile);
if (qwMpqStart == (UInt64)-1) {
SFFree(lpnOpenMpq);
CloseHandle(hFile);
SetLastError(MPQ_ERROR_MPQ_INVALID);
- *hMPQ = 0;
return FALSE;
}
- flen = SFGetFileSize(hFile);
mpqOpenArc = (MPQARCHIVE *)SFAlloc(sizeof(MPQARCHIVE));
if (!mpqOpenArc) {
SFFree(lpnOpenMpq);
CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
- SFSetFilePointer(hFile, qwMpqStart, FILE_BEGIN);
- if(ReadFile(hFile,&mpqOpenArc->MpqHeader,sizeof(MPQHEADER),&tsz,0)==0) {
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
}
- if (mpqOpenArc->MpqHeader.wVersion > 0) {
- ReadFile(hFile, &mpqOpenArc->MpqHeader_Ex, sizeof(MPQHEADER_EX), &tsz, 0);
- mpqOpenArc->dwHeaderSize = sizeof(MPQHEADER) + sizeof(MPQHEADER_EX);
- }
- else {
- memset(&mpqOpenArc->MpqHeader_Ex, 0, sizeof(MPQHEADER_EX));
- mpqOpenArc->dwHeaderSize = sizeof(MPQHEADER);
- }
+ mpqOpenArc->hFile = hFile;
+ mpqOpenArc->qwMPQStart = qwMpqStart;
- mpqOpenArc->lpHashTable = (HASHTABLEENTRY *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if(!mpqOpenArc->lpHashTable) {
- SFFree(lpnOpenMpq);
+ if (!MpqReadExistingArchive(mpqOpenArc)) {
+ if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
+ if (mpqOpenArc->lpHashTable) SFFree(mpqOpenArc->lpHashTable);
SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
- if (mpqOpenArc->MpqHeader.dwBlockTableSize!=0) {
- mpqOpenArc->lpBlockTable = (BLOCKTABLEENTRY *)SFAlloc((sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- mpqOpenArc->lpFileOffsetsHigh = (UInt16 *)(mpqOpenArc->lpBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize);
- if(!mpqOpenArc->lpBlockTable) {
- SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
- }
- SFSetFilePointer(hFile, qwMpqStart + mpqOpenArc->MpqHeader.dwHashTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh << 32), FILE_BEGIN);
- if(ReadFile(hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0)==0) {
- if(mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
- SFFree(mpqOpenArc->lpHashTable);
SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
}
- if (mpqOpenArc->MpqHeader.dwBlockTableSize!=0) {
- SFSetFilePointer(hFile, qwMpqStart + mpqOpenArc->MpqHeader.dwBlockTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh << 32), FILE_BEGIN);
- if(ReadFile(hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0)==0) {
- SFFree(mpqOpenArc->lpBlockTable);
- SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- CloseHandle(hFile);
- *hMPQ = 0;
- return FALSE;
- }
-
- if (mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable) {
- SFSetFilePointer(hFile, qwMpqStart + mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable, FILE_BEGIN);
- ReadFile(hFile, mpqOpenArc->lpFileOffsetsHigh, sizeof(WORD) * mpqOpenArc->MpqHeader.dwBlockTableSize, &tsz, 0);
- }
- }
}
- /*mpqOpenArc->lpFileName = (char *)SFAlloc(strlen(lpFileName)+1);
- if(!mpqOpenArc->lpFileName) {
- if(mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
+
+ if (!MpqOpenArchiveInit(mpqOpenArc, lpFileName, dwPriority, dwFlags1, dwFlags2, 0)) {
+ if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
SFFree(mpqOpenArc);
+ SFFree(lpnOpenMpq);
CloseHandle(hFile);
- *hMPQ = 0;
return FALSE;
- }*/
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- if (mpqOpenArc->lpBlockTable) DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- mpqOpenArc->lpFileName = mpqOpenArc->szFileName;
- strncpy(mpqOpenArc->lpFileName,lpFileName,259);
- if (FirstLastMpq[1]) FirstLastMpq[1]->lpNextArc = mpqOpenArc;
- mpqOpenArc->lpNextArc = (MPQARCHIVE *)FirstLastMpq;
- mpqOpenArc->lpPrevArc = (MPQARCHIVE *)FirstLastMpq[1];
- if (!FirstLastMpq[0]) {
- mpqOpenArc->lpPrevArc = (MPQARCHIVE *)0xEAFC5E23;
- FirstLastMpq[0] = mpqOpenArc;
- }
- FirstLastMpq[1] = mpqOpenArc;
- mpqOpenArc->hFile = hFile;
- mpqOpenArc->dwFlags1 = dwFlags1;
- mpqOpenArc->dwPriority = dwPriority;
- mpqOpenArc->lpLastReadFile = 0;
- mpqOpenArc->dwUnk = 0;
- mpqOpenArc->dwBlockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
- mpqOpenArc->lpLastReadBlock = 0;
- mpqOpenArc->dwBufferSize = 0;
- mpqOpenArc->qwMPQStart = qwMpqStart;
- mpqOpenArc->lpMPQHeader = &mpqOpenArc->MpqHeader;
- mpqOpenArc->qwReadOffset = flen;
- mpqOpenArc->dwRefCount = 1;
- mpqOpenArc->dwFlags = dwFlags2;
- mpqOpenArc->dwExtraFlags = 0;
+ }
+
memcpy(lpnOpenMpq,lpOpenMpq,sizeof(MPQARCHIVE *) * dwOpenMpqCount);
lpnOpenMpq[dwOpenMpqCount] = mpqOpenArc;
if (lpOpenMpq) SFFree(lpOpenMpq);
@@ -554,6 +566,7 @@ BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags,
dwOpenMpqCount++;
if (dwOpenMpqCount>1) SortOpenArchivesByPriority();
*hMPQ = (MPQHANDLE)mpqOpenArc;
+
return TRUE;
}
else {
@@ -566,16 +579,14 @@ BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags,
BOOL SFMPQAPI WINAPI SFileOpenFileAsArchive(MPQHANDLE hSourceMPQ, LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, MPQHANDLE *hMPQ)
{
- DWORD flen,tsz;
-
if (!lpFileName || !hMPQ) {
SetLastError(ERROR_INVALID_PARAMETER);
- if (hMPQ) *hMPQ = 0;
+ if (hMPQ) *hMPQ = (MPQHANDLE)INVALID_HANDLE_VALUE;
return FALSE;
}
+ *hMPQ = (MPQHANDLE)INVALID_HANDLE_VALUE;
if (!*lpFileName) {
SetLastError(ERROR_INVALID_PARAMETER);
- *hMPQ = 0;
return FALSE;
}
@@ -590,105 +601,42 @@ BOOL SFMPQAPI WINAPI SFileOpenFileAsArchive(MPQHANDLE hSourceMPQ, LPCSTR lpFileN
hFile = mpqArcFile.lpParentArc->hFile;
MPQARCHIVE **lpnOpenMpq = (MPQARCHIVE **)SFAlloc(sizeof(MPQARCHIVE *) * (dwOpenMpqCount+1));
if (!lpnOpenMpq) {
- *hMPQ = 0;
return FALSE;
}
- UInt64 qwMpqStart;
MPQARCHIVE *mpqOpenArc;
- qwMpqStart = mpqArcFile.lpParentArc->qwMPQStart + mpqArcFile.lpBlockEntry->dwFileOffset + ((UInt64)mpqArcFile.wFileOffsetHigh << 32);
- flen = mpqArcFile.lpBlockEntry->dwFullSize;
+ UInt64 qwMpqStart = mpqArcFile.lpParentArc->qwMPQStart + MakeUInt64(mpqArcFile.lpBlockEntry->dwFileOffset, mpqArcFile.wFileOffsetHigh);
+ UInt64 flen = mpqArcFile.lpBlockEntry->dwFullSize;
qwMpqStart = SFileFindMpqHeaderEx(hFile, qwMpqStart, flen);
if (qwMpqStart == (UInt64)-1) {
SFFree(lpnOpenMpq);
SetLastError(MPQ_ERROR_MPQ_INVALID);
- *hMPQ = 0;
return FALSE;
}
mpqOpenArc = (MPQARCHIVE *)SFAlloc(sizeof(MPQARCHIVE));
if (!mpqOpenArc) {
SFFree(lpnOpenMpq);
- *hMPQ = 0;
return FALSE;
}
- SFSetFilePointer(hFile, qwMpqStart, FILE_BEGIN);
- if(ReadFile(hFile,&mpqOpenArc->MpqHeader,sizeof(MPQHEADER),&tsz,0)==0) {
- SFFree(lpnOpenMpq);
+
+ mpqOpenArc->hFile = hFile;
+ mpqOpenArc->qwMPQStart = qwMpqStart;
+
+ if (!MpqReadExistingArchive(mpqOpenArc)) {
+ if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
+ if (mpqOpenArc->lpHashTable) SFFree(mpqOpenArc->lpHashTable);
SFFree(mpqOpenArc);
- *hMPQ = 0;
- return FALSE;
- }
- mpqOpenArc->lpHashTable = (HASHTABLEENTRY *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if(!mpqOpenArc->lpHashTable) {
SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- *hMPQ = 0;
return FALSE;
}
- if (mpqOpenArc->MpqHeader.dwBlockTableSize!=0) {
- mpqOpenArc->lpBlockTable = (BLOCKTABLEENTRY *)SFAlloc(sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- if(!mpqOpenArc->lpBlockTable) {
- SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- *hMPQ = 0;
- return FALSE;
- }
- }
- SFSetFilePointer(hFile, qwMpqStart + mpqOpenArc->MpqHeader.dwHashTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh << 32), FILE_BEGIN);
- if(ReadFile(hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0)==0) {
- if(mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
+
+ if (!MpqOpenArchiveInit(mpqOpenArc, lpFileName, dwPriority, 0, dwFlags, 1)) {
+ if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
SFFree(mpqOpenArc);
- *hMPQ = 0;
- return FALSE;
- }
- if (mpqOpenArc->MpqHeader.dwBlockTableSize!=0) {
- SFSetFilePointer(hFile, qwMpqStart + mpqOpenArc->MpqHeader.dwBlockTableOffset + ((UINT64)mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh << 32), FILE_BEGIN);
- if(ReadFile(hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0)==0) {
- SFFree(mpqOpenArc->lpBlockTable);
- SFFree(mpqOpenArc->lpHashTable);
- SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- *hMPQ = 0;
- return FALSE;
- }
- }
- /*mpqOpenArc->lpFileName = (char *)SFAlloc(strlen(lpFileName)+1);
- if(!mpqOpenArc->lpFileName) {
- if(mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
- SFFree(mpqOpenArc->lpHashTable);
SFFree(lpnOpenMpq);
- SFFree(mpqOpenArc);
- *hMPQ = 0;
return FALSE;
- }*/
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- if (mpqOpenArc->lpBlockTable) DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- mpqOpenArc->lpFileName = mpqOpenArc->szFileName;
- strncpy(mpqOpenArc->lpFileName,lpFileName,259);
- if (FirstLastMpq[1]) FirstLastMpq[1]->lpNextArc = mpqOpenArc;
- mpqOpenArc->lpNextArc = (MPQARCHIVE *)FirstLastMpq;
- mpqOpenArc->lpPrevArc = (MPQARCHIVE *)FirstLastMpq[1];
- if (!FirstLastMpq[0]) {
- mpqOpenArc->lpPrevArc = (MPQARCHIVE *)0xEAFC5E23;
- FirstLastMpq[0] = mpqOpenArc;
- }
- FirstLastMpq[1] = mpqOpenArc;
- mpqOpenArc->hFile = hFile;
- mpqOpenArc->dwFlags1 = 0;
- mpqOpenArc->dwPriority = dwPriority;
- mpqOpenArc->lpLastReadFile = 0;
- mpqOpenArc->dwUnk = 0;
- mpqOpenArc->dwBlockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
- mpqOpenArc->lpLastReadBlock = 0;
- mpqOpenArc->dwBufferSize = 0;
- mpqOpenArc->qwMPQStart = qwMpqStart;
- mpqOpenArc->lpMPQHeader = &mpqOpenArc->MpqHeader;
- mpqOpenArc->qwReadOffset = flen;
- mpqOpenArc->dwRefCount = 1;
- mpqOpenArc->dwFlags = dwFlags;
- mpqOpenArc->dwExtraFlags = 1;
+ }
+
memcpy(lpnOpenMpq,lpOpenMpq,sizeof(MPQARCHIVE *) * dwOpenMpqCount);
lpnOpenMpq[dwOpenMpqCount] = mpqOpenArc;
if (lpOpenMpq) SFFree(lpOpenMpq);
@@ -696,6 +644,7 @@ BOOL SFMPQAPI WINAPI SFileOpenFileAsArchive(MPQHANDLE hSourceMPQ, LPCSTR lpFileN
dwOpenMpqCount++;
if (dwOpenMpqCount>1) SortOpenArchivesByPriority();
*hMPQ = (MPQHANDLE)mpqOpenArc;
+
return TRUE;
}
else {
@@ -939,6 +888,7 @@ BOOL SFMPQAPI WINAPI SFileOpenFileEx(MPQHANDLE hMPQ, LPCSTR lpFileName, DWORD dw
mpqOpenFile->hFile = INVALID_HANDLE_VALUE;
mpqOpenFile->lpHashEntry = (HASHTABLEENTRY *)hnFile;
mpqOpenFile->lpBlockEntry = &((MPQARCHIVE *)hnMPQ)->lpBlockTable[mpqOpenFile->lpHashEntry->dwBlockTableIndex];
+ mpqOpenFile->wFileOffsetHigh = ((MPQARCHIVE *)hnMPQ)->lpFileOffsetsHigh[mpqOpenFile->lpHashEntry->dwBlockTableIndex];
mpqOpenFile->lpParentArc->dwRefCount++;
if (mpqOpenFile->lpBlockEntry->dwFlags&MAFA_ENCRYPT) {
LPSTR lpOldNameBuffer = mpqOpenFile->lpFileName;
@@ -1256,7 +1206,7 @@ BOOL SFMPQAPI WINAPI SFileReadFile(MPQHANDLE hFile,LPVOID lpBuffer,DWORD nNumber
DWORD HeaderLength=0;
if (memcmp(&mpqOpenArc->MpqHeader.dwMPQID,ID_BN3,4)==0)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenFile->wFileOffsetHigh << 32), FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]), FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,&HeaderLength,4,&nBytesRead,0);
}
DWORD i;
@@ -1273,7 +1223,7 @@ BOOL SFMPQAPI WINAPI SFileReadFile(MPQHANDLE hFile,LPVOID lpBuffer,DWORD nNumber
}
if ((mpqOpenArc->lpBlockTable[BlockIndex].dwFlags & MAFA_COMPRESS) || (mpqOpenArc->lpBlockTable[BlockIndex].dwFlags & MAFA_COMPRESS2))
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenFile->wFileOffsetHigh << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength, FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&nBytesRead,0);
if (mpqOpenArc->lpBlockTable[BlockIndex].dwFlags & MAFA_ENCRYPT) {
DecryptData((LPBYTE)dwBlockPtrTable,(TotalBlocks+1)*4,dwCryptKey-1);
@@ -1299,7 +1249,7 @@ BOOL SFMPQAPI WINAPI SFileReadFile(MPQHANDLE hFile,LPVOID lpBuffer,DWORD nNumber
DWORD blk=0,blki=0;
for (i=blockNum;i<nBlocks;i++) {
if (blk==0) {
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenFile->wFileOffsetHigh << 32) + HeaderLength + mpqOpenFile->lpdwBlockOffsets[i], FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength + mpqOpenFile->lpdwBlockOffsets[i], FILE_BEGIN);
blki=i;
if (i+16>nBlocks) {
if (ReadFile(mpqOpenArc->hFile,blk16Buffer,mpqOpenFile->lpdwBlockOffsets[nBlocks]-mpqOpenFile->lpdwBlockOffsets[i],&nBytesRead,0)==0) {
@@ -1511,7 +1461,7 @@ BOOL SFMPQAPI WINAPI SFileListFiles(MPQHANDLE hMPQ, LPCSTR lpFileLists, FILELIST
lpListBuffer[i].dwFileExists = 1;
else
lpListBuffer[i].dwFileExists=0xFFFFFFFF;
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex] << 32) + 0x40, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex]) + 0x40, FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,lpListBuffer[i].szFileName,260,&tsz,0);
if (mpqOpenArc->lpHashTable[i].dwNameHashA==HashString(lpListBuffer[i].szFileName,HASH_NAME_A) && mpqOpenArc->lpHashTable[i].dwNameHashB==HashString(lpListBuffer[i].szFileName,HASH_NAME_B)) {
@@ -1948,15 +1898,19 @@ BOOL SFMPQAPI WINAPI MpqAddFileToArchiveEx(MPQHANDLE hMPQ, LPCSTR lpSourceFileNa
if ((hashEntry->dwBlockTableIndex&0xFFFFFFFE)==0xFFFFFFFE)
{
BLOCKTABLEENTRY *lpnBlockTable;
- lpnBlockTable = (BLOCKTABLEENTRY *)SFAlloc(sizeof(BLOCKTABLEENTRY) * (mpqOpenArc->MpqHeader.dwBlockTableSize + 1));
+ lpnBlockTable = (BLOCKTABLEENTRY *)SFAlloc((sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)) * (mpqOpenArc->MpqHeader.dwBlockTableSize + 1));
if(!lpnBlockTable) {
SFFree(buffer);
return FALSE;
}
- if (mpqOpenArc->lpBlockTable) memcpy(lpnBlockTable,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ if (mpqOpenArc->lpBlockTable) {
+ memcpy(lpnBlockTable,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ memcpy(lpnBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize + 1, mpqOpenArc->lpFileOffsetsHigh, sizeof(UInt16) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ }
mpqOpenArc->MpqHeader.dwBlockTableSize++;
if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
mpqOpenArc->lpBlockTable = lpnBlockTable;
+ mpqOpenArc->lpFileOffsetsHigh = (UInt16 *)(mpqOpenArc->lpBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize);
IsNewBlockEntry = TRUE;
}
DWORD BlockIndex = mpqOpenArc->MpqHeader.dwBlockTableSize - 1;
@@ -2029,9 +1983,7 @@ BOOL SFMPQAPI WINAPI MpqAddFileToArchiveEx(MPQHANDLE hMPQ, LPCSTR lpSourceFileNa
mpqOpenArc->lpBlockTable[BlockIndex].dwCompressedSize = fsz;
mpqOpenArc->lpBlockTable[BlockIndex].dwFullSize = ucfsz;
mpqOpenArc->lpBlockTable[BlockIndex].dwFlags = dwFlags|MAFA_EXISTS;
- DWORD dwFileOffset = mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset;
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart, FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,&mpqOpenArc->MpqHeader,mpqOpenArc->dwHeaderSize,&tsz,0);
+ MpqWriteHeaders(mpqOpenArc);
if (dwFlags & MAFA_ENCRYPT) {
DWORD dwCryptKey;
if (dwFlags&MAFA_ENCRYPT) dwCryptKey = HashString(lpDestFileName,HASH_KEY);
@@ -2051,7 +2003,7 @@ BOOL SFMPQAPI WINAPI MpqAddFileToArchiveEx(MPQHANDLE hMPQ, LPCSTR lpSourceFileNa
}
}
SFFree(dwBlkpt);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + dwFileOffset, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]), FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,buffer,fsz,&tsz,0);
SFFree(buffer);
WriteHashTable(mpqOpenArc);
@@ -2268,15 +2220,19 @@ BOOL SFMPQAPI WINAPI MpqAddFileFromBufferEx(MPQHANDLE hMPQ, LPVOID lpBuffer, DWO
if ((hashEntry->dwBlockTableIndex&0xFFFFFFFE)==0xFFFFFFFE)
{
BLOCKTABLEENTRY *lpnBlockTable;
- lpnBlockTable = (BLOCKTABLEENTRY *)SFAlloc(sizeof(BLOCKTABLEENTRY) * (mpqOpenArc->MpqHeader.dwBlockTableSize + 1));
- if(lpnBlockTable==0) {
+ lpnBlockTable = (BLOCKTABLEENTRY *)SFAlloc((sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)) * (mpqOpenArc->MpqHeader.dwBlockTableSize + 1));
+ if(!lpnBlockTable) {
SFFree(buffer);
return FALSE;
}
- if (mpqOpenArc->lpBlockTable!=0) memcpy(lpnBlockTable,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ if (mpqOpenArc->lpBlockTable) {
+ memcpy(lpnBlockTable,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ memcpy(lpnBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize + 1, mpqOpenArc->lpFileOffsetsHigh, sizeof(UInt16) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ }
mpqOpenArc->MpqHeader.dwBlockTableSize++;
- if (mpqOpenArc->lpBlockTable!=0) SFFree(mpqOpenArc->lpBlockTable);
+ if (mpqOpenArc->lpBlockTable) SFFree(mpqOpenArc->lpBlockTable);
mpqOpenArc->lpBlockTable = lpnBlockTable;
+ mpqOpenArc->lpFileOffsetsHigh = (UInt16 *)(mpqOpenArc->lpBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize);
IsNewBlockEntry = TRUE;
}
DWORD BlockIndex = mpqOpenArc->MpqHeader.dwBlockTableSize - 1;
@@ -2348,9 +2304,7 @@ BOOL SFMPQAPI WINAPI MpqAddFileFromBufferEx(MPQHANDLE hMPQ, LPVOID lpBuffer, DWO
mpqOpenArc->lpBlockTable[BlockIndex].dwCompressedSize = fsz;
mpqOpenArc->lpBlockTable[BlockIndex].dwFullSize = ucfsz;
mpqOpenArc->lpBlockTable[BlockIndex].dwFlags = dwFlags|MAFA_EXISTS;
- DWORD dwFileOffset = mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset;
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart, FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,&mpqOpenArc->MpqHeader,mpqOpenArc->dwHeaderSize,&tsz,0);
+ MpqWriteHeaders(mpqOpenArc);
if (dwFlags & MAFA_ENCRYPT) {
DWORD dwCryptKey;
if (dwFlags&MAFA_ENCRYPT) dwCryptKey = HashString(lpFileName,HASH_KEY);
@@ -2371,7 +2325,7 @@ BOOL SFMPQAPI WINAPI MpqAddFileFromBufferEx(MPQHANDLE hMPQ, LPVOID lpBuffer, DWO
}
}
SFFree(dwBlkpt);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + dwFileOffset, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]), FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,buffer,fsz,&tsz,0);
SFFree(buffer);
WriteHashTable(mpqOpenArc);
@@ -2448,7 +2402,7 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
DWORD HeaderLength=0;
if (memcmp(&mpqOpenArc->MpqHeader.dwMPQID,ID_BN3,4)==0)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32), FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]), FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,&HeaderLength,4,&tsz,0);
}
@@ -2463,7 +2417,7 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
DWORD i;
if ((mpqOpenArc->lpBlockTable[BlockIndex].dwFlags & MAFA_COMPRESS)==MAFA_COMPRESS || (mpqOpenArc->lpBlockTable[BlockIndex].dwFlags & MAFA_COMPRESS2)==MAFA_COMPRESS2)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength, FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&tsz,0);
DecryptData((LPBYTE)dwBlockPtrTable,(TotalBlocks+1)*4,dwOldCryptKey-1);
char *EncryptedTable = (char *)SFAlloc((TotalBlocks+1)*4);
@@ -2473,7 +2427,7 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
}
memcpy(EncryptedTable,dwBlockPtrTable,(TotalBlocks+1)*4);
EncryptData((LPBYTE)EncryptedTable,(TotalBlocks+1)*4,dwNewCryptKey-1);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength, FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,EncryptedTable,(TotalBlocks+1)*4,&tsz,0);
SFFree(EncryptedTable);
}
@@ -2487,16 +2441,16 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
char *blkBuffer = (char *)SFAlloc(blockSize);
if (blkBuffer==0) {
EncryptData((LPBYTE)dwBlockPtrTable,(TotalBlocks+1)*4,dwOldCryptKey-1);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength, FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&tsz,0);
SFFree(dwBlockPtrTable);
return FALSE;
}
for (i=0;i<TotalBlocks;i++) {
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength + dwBlockPtrTable[i], FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength + dwBlockPtrTable[i], FILE_BEGIN);
if (ReadFile(mpqOpenArc->hFile,blkBuffer,dwBlockPtrTable[i+1]-dwBlockPtrTable[i],&tsz,0)==0) {
EncryptData((LPBYTE)dwBlockPtrTable,(TotalBlocks+1)*4,dwOldCryptKey-1);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength, FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&tsz,0);
SFFree(dwBlockPtrTable);
SFFree(blkBuffer);
@@ -2504,7 +2458,7 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
}
DecryptData((LPBYTE)blkBuffer,dwBlockPtrTable[i+1]-dwBlockPtrTable[i],dwOldCryptKey+i);
EncryptData((LPBYTE)blkBuffer,dwBlockPtrTable[i+1]-dwBlockPtrTable[i],dwNewCryptKey+i);
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[BlockIndex] << 32) + HeaderLength + dwBlockPtrTable[i], FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[BlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[BlockIndex]) + HeaderLength + dwBlockPtrTable[i], FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,blkBuffer,dwBlockPtrTable[i+1]-dwBlockPtrTable[i],&tsz,0);
}
SFFree(dwBlockPtrTable);
DWORD HeaderLength=0;
if (memcmp(&mpqOpenArc->MpqHeader.dwMPQID,ID_BN3,4)==0)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32), FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]), FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,&HeaderLength,4,&tsz,0);
}
DWORD blockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
DeleteFile(lpFileName);
return FALSE;
}
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]) + HeaderLength, FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&tsz,0);
DWORD dwOldCryptKey = DetectFileSeed(dwBlockPtrTable,(TotalBlocks+1)*4,blockSize);
DWORD dwNewCryptKey = (dwOldCryptKey ^ mpqOpenArc->lpBlockTable[i].dwFullSize) - mpqOpenArc->lpBlockTable[i].dwFileOffset;
}
memcpy(EncryptedTable,dwBlockPtrTable,(TotalBlocks+1)*4);
EncryptData((LPBYTE)EncryptedTable,(TotalBlocks+1)*4,dwNewCryptKey-1);
- SFSetFilePointer(hFile,lpBlockTable[i-nBlkOffset].dwFileOffset+HeaderLength,FILE_BEGIN);
+ SFSetFilePointer(hFile, MakeUInt64(lpBlockTable[i-nBlkOffset].dwFileOffset, lpdwFileOffsetsHigh[i-nBlkOffset]) + HeaderLength, FILE_BEGIN);
WriteFile(hFile,EncryptedTable,(TotalBlocks+1)*4,&tsz,0);
SFFree(EncryptedTable);
char *blkBuffer = (char *)SFAlloc(blockSize);
return FALSE;
}
for (DWORD k=0;k<TotalBlocks;k++) {
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32) + HeaderLength + dwBlockPtrTable[k], FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]) + HeaderLength + dwBlockPtrTable[k], FILE_BEGIN);
if (ReadFile(mpqOpenArc->hFile,blkBuffer,dwBlockPtrTable[k+1]-dwBlockPtrTable[k],&tsz,0)==0) {
SFFree(dwBlockPtrTable);
SFFree(blkBuffer);
}
DecryptData((LPBYTE)blkBuffer,dwBlockPtrTable[k+1]-dwBlockPtrTable[k],dwOldCryptKey+k);
EncryptData((LPBYTE)blkBuffer,dwBlockPtrTable[k+1]-dwBlockPtrTable[k],dwNewCryptKey+k);
- SFSetFilePointer(hFile,lpBlockTable[i-nBlkOffset].dwFileOffset+HeaderLength+dwBlockPtrTable[k],FILE_BEGIN);
+ SFSetFilePointer(hFile, MakeUInt64(lpBlockTable[i-nBlkOffset].dwFileOffset, lpdwFileOffsetsHigh[i-nBlkOffset]) + HeaderLength + dwBlockPtrTable[k], FILE_BEGIN);
WriteFile(hFile,blkBuffer,dwBlockPtrTable[k+1]-dwBlockPtrTable[k],&tsz,0);
}
SFFree(blkBuffer);
if (memcmp(&mpqOpenArc->MpqHeader.dwMPQID,ID_BN3,4)==0)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32), FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]), FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,&HeaderLength,4,&tsz,0);
}
DWORD blockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
return FALSE;
}
for (DWORD k=0;k<mpqOpenArc->lpBlockTable[i].dwFullSize;k+=blockSize) {
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32) + HeaderLength + k, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]) + HeaderLength + k, FILE_BEGIN);
if (k+blockSize>mpqOpenArc->lpBlockTable[i].dwFullSize) blockSize = mpqOpenArc->lpBlockTable[i].dwFullSize % blockSize;
if (ReadFile(mpqOpenArc->hFile,blkBuffer,blockSize,&tsz,0)==0) {
SFFree(blkBuffer);
}
DecryptData((LPBYTE)blkBuffer,blockSize,dwOldCryptKey+k);
EncryptData((LPBYTE)blkBuffer,blockSize,dwNewCryptKey+k);
- SFSetFilePointer(hFile,lpBlockTable[i-nBlkOffset].dwFileOffset+HeaderLength+k,FILE_BEGIN);
+ SFSetFilePointer(hFile, MakeUInt64(lpBlockTable[i-nBlkOffset].dwFileOffset, lpdwFileOffsetsHigh[i-nBlkOffset]) + HeaderLength + k, FILE_BEGIN);
WriteFile(hFile,blkBuffer,blockSize,&tsz,0);
}
SFFree(blkBuffer);
if (dwWritten==FALSE) {
ReadSize = 65536;
for (j=0;j<mpqOpenArc->lpBlockTable[i].dwCompressedSize;j+=65536) {
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[i].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[i] << 32) + j, FILE_BEGIN);
- SFSetFilePointer(hFile,lpBlockTable[i-nBlkOffset].dwFileOffset+j,FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[i].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[i]) + j, FILE_BEGIN);
+ SFSetFilePointer(hFile, MakeUInt64(lpBlockTable[i-nBlkOffset].dwFileOffset, lpdwFileOffsetsHigh[i-nBlkOffset]) + j, FILE_BEGIN);
if (j+65536>mpqOpenArc->lpBlockTable[i].dwCompressedSize) ReadSize = mpqOpenArc->lpBlockTable[i].dwCompressedSize-j;
if (ReadFile(mpqOpenArc->hFile,buffer,ReadSize,&tsz,0)==0) {
SFFree(lpBlockTable);
qwLastOffset += mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY);
SplitUInt64(mpqOpenArc->MpqHeader.dwBlockTableOffset, mpqOpenArc->MpqHeader_Ex.wBlockTableOffsetHigh, qwLastOffset);
qwLastOffset += mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY);
+ if (mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable) {
+ mpqOpenArc->MpqHeader_Ex.qwExtendedBlockOffsetTable = qwLastOffset;
+ qwLastOffset += mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(UInt16);
+ }
mpqOpenArc->MpqHeader.dwMPQSize = (UInt32)qwLastOffset;
SFFree(mpqOpenArc->lpHashTable);
mpqOpenArc->lpHashTable = lpHashTable;
if(mpqOpenArc->lpBlockTable!=0) {
SFFree(mpqOpenArc->lpBlockTable);
- mpqOpenArc->lpBlockTable = (BLOCKTABLEENTRY *)SFAlloc(mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY));
+ mpqOpenArc->lpBlockTable = (BLOCKTABLEENTRY *)SFAlloc(mpqOpenArc->MpqHeader.dwBlockTableSize * (sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)));
+ mpqOpenArc->lpFileOffsetsHigh = (UInt16 *)(mpqOpenArc->lpBlockTable + mpqOpenArc->MpqHeader.dwBlockTableSize);
if (mpqOpenArc->lpBlockTable==0) {
mpqOpenArc->lpBlockTable = lpBlockTable;
+ mpqOpenArc->lpFileOffsetsHigh = lpdwFileOffsetsHigh;
}
else {
- memcpy(mpqOpenArc->lpBlockTable,lpBlockTable,mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY));
+ memcpy(mpqOpenArc->lpBlockTable, lpBlockTable, mpqOpenArc->MpqHeader.dwBlockTableSize * (sizeof(BLOCKTABLEENTRY) + sizeof(UInt16)));
SFFree(lpBlockTable);
}
}
SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + qwLastOffset, FILE_BEGIN);
SetEndOfFile(mpqOpenArc->hFile);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->qwMPQStart,FILE_BEGIN);
+ MpqWriteHeaders(mpqOpenArc);
mpqOpenArc->MpqHeader.dwHeaderSize = mpqOpenArc->dwHeaderSize;
- WriteFile(mpqOpenArc->hFile,&mpqOpenArc->MpqHeader,mpqOpenArc->dwHeaderSize,&tsz,0);
qwLastOffset = mpqOpenArc->dwHeaderSize;
ReadSize = 65536;
for (i=qwLastOffset;i<MakeUInt64(mpqOpenArc->MpqHeader.dwHashTableOffset, mpqOpenArc->MpqHeader_Ex.wHashTableOffsetHigh);i+=65536) {
@@ -2985,13 +2944,37 @@ BOOL SFMPQAPI WINAPI MpqSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpFileName, LCID nO
return TRUE;
}
+BOOL SFMPQAPI WINAPI MpqCreateArchiveVersion(WORD wVersion)
+{
+ if (wVersion > 1) return FALSE;
+
+ wCreationVersion = wVersion;
+ return TRUE;
+}
+
DWORD SFMPQAPI WINAPI SFileFindMpqHeader(HANDLE hFile)
{
if (hFile == INVALID_HANDLE_VALUE) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0xFFFFFFFF;
}
- DWORD FileLen = SFGetFileSize(hFile);
+
+ DWORD dwHandleType = GetHandleType((MPQHANDLE)hFile);
+ if (dwHandleType == SFILE_TYPE_FILE) {
+ MPQFILE *mpqOpenFile = (MPQFILE *)hFile;
+ if (mpqOpenFile->hFile == INVALID_HANDLE_VALUE) {
+ return mpqOpenFile->lpParentArc->qwMPQStart;
+ }
+ else {
+ hFile = mpqOpenFile->hFile;
+ }
+ }
+ else if (dwHandleType == SFILE_TYPE_MPQ) {
+ return ((MPQARCHIVE *)hFile)->qwMPQStart;
+ }
+
+ UInt64 FileLen = SFGetFileSize(hFile);
+ if (FileLen >= 0xFFFFFFFF) FileLen = 0xFFFFFFFE;
char pbuf[sizeof(MPQHEADER)];
DWORD tsz;
for (DWORD i=0;i<FileLen;i+=512)
@@ -3475,7 +3458,7 @@ DWORD DetectFileSeedEx(MPQARCHIVE * mpqOpenArc, HASHTABLEENTRY * lpHashEntry, LP
DWORD HeaderLength=0,tsz;
if (memcmp(&mpqOpenArc->MpqHeader.dwMPQID,ID_BN3,4)==0)
{
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex] << 32), FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex]), FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,&HeaderLength,4,&tsz,0);
}
DWORD blockSize = 512 << mpqOpenArc->MpqHeader.wBlockSize;
@@ -3485,7 +3468,7 @@ DWORD DetectFileSeedEx(MPQARCHIVE * mpqOpenArc, HASHTABLEENTRY * lpHashEntry, LP
DWORD *dwBlockPtrTable = (DWORD *)SFAlloc((TotalBlocks+1)*4);
if (dwBlockPtrTable==0)
return 0;
- SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset + ((UInt64)mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex] << 32) + HeaderLength, FILE_BEGIN);
+ SFSetFilePointer(mpqOpenArc->hFile, mpqOpenArc->qwMPQStart + MakeUInt64(mpqOpenArc->lpBlockTable[dwBlockIndex].dwFileOffset, mpqOpenArc->lpFileOffsetsHigh[dwBlockIndex]) + HeaderLength, FILE_BEGIN);
ReadFile(mpqOpenArc->hFile,dwBlockPtrTable,(TotalBlocks+1)*4,&tsz,0);
dwCryptKey = DetectFileSeed(dwBlockPtrTable,(TotalBlocks+1)*4,blockSize);
diff --git a/SFmpqapi.def b/SFmpqapi.def
--- a/SFmpqapi.def
+++ b/SFmpqapi.def
MpqRenameAndSetFileLocale=MpqRenameAndSetFileLocale @28
MpqDeleteFileWithLocale=MpqDeleteFileWithLocale @29
MpqOpenArchiveForUpdateEx=MpqOpenArchiveForUpdateEx @30
+ MpqCreateArchiveVersion=MpqCreateArchiveVersion @31
;Lmpqapi ordinals
SFOpenArchive=SFileOpenArchive @32 NONAME
diff --git a/SFmpqapi.h b/SFmpqapi.h
--- a/SFmpqapi.h
+++ b/SFmpqapi.h
BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFileName, LPCSTR lpcNewFileName, LCID nOldLocale, LCID nNewLocale);
BOOL SFMPQAPI WINAPI MpqDeleteFileWithLocale(MPQHANDLE hMPQ, LPCSTR lpFileName, LCID nLocale);
BOOL SFMPQAPI WINAPI MpqSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpFileName, LCID nOldLocale, LCID nNewLocale);
+BOOL SFMPQAPI WINAPI MpqCreateArchiveVersion(WORD wVersion);
// These functions do nothing. They are only provided for
// compatibility with MPQ extractors that use storm.
|