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: |
- Moved hashing, encryption, and decryption to MpqCrypt.cpp
- Moved hash table writes to separate function in MpqHashTable.cpp - Moved block table writes to separate function in MpqBlockTable.cpp - Moved some utility functions to SFUtil.cpp
14 files changed:
diff --git a/MpqBlockTable.cpp b/MpqBlockTable.cpp
--- /dev/null
+++ b/MpqBlockTable.cpp
@@ -0,0 +1,31 @@
+// License information for this code is in license.txt
+
+#include <windows.h>
+#include "SFmpqapi.h"
+#include "SFUtil.h"
+#include "MpqCrypt.h"
+
+BOOL WriteBlockTable(MPQARCHIVE *mpqOpenArc)
+{
+ DWORD tsz;
+
+ if (mpqOpenArc->MpqHeader.dwBlockTableSize == 0) return TRUE;
+ if (!mpqOpenArc->lpBlockTable) return FALSE;
+
+ char *buffer = (char *)SFAlloc(sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ if (buffer) {
+ memcpy(buffer,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
+ EncryptData((LPBYTE)buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
+ SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
+ 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->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
+ WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
+ DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
+ }
+
+ return TRUE;
+}
diff --git a/MpqBlockTable.h b/MpqBlockTable.h
--- /dev/null
+++ b/MpqBlockTable.h
@@ -0,0 +1,11 @@
+// License information for this code is in license.txt
+
+#ifndef MPQBLOCKTABLE_INCLUDED
+#define MPQBLOCKTABLE_INCLUDED
+
+#include "SFmpqapi.h"
+
+BOOL WriteBlockTable(MPQARCHIVE *mpqOpenArc);
+
+#endif // #ifndef MPQBLOCKTABLE_INCLUDED
+
diff --git a/MpqCrypt.cpp b/MpqCrypt.cpp
--- /dev/null
+++ b/MpqCrypt.cpp
@@ -0,0 +1,173 @@
+// License information for this code is in license.txt
+
+#include <string.h>
+#include <ctype.h>
+#include "MpqCrypt.h"
+#include "SFTypes.h"
+
+bool bCryptTableInit = false;
+UInt32 dwCryptTable[0x500];
+UInt32 dwHashTableKey;
+UInt32 dwBlockTableKey;
+
+// The InitCryptTable, HashString, DecryptData, and DetectFileKey are
+// based on the versions in StormLib which were written by Ladislav
+// Zezula, but may have been modified somewhat by Quantam or ShadowFlare.
+bool InitCryptTable()
+{
+ UInt32 seed = 0x00100001;
+ UInt32 index1 = 0;
+ UInt32 index2 = 0;
+ int i;
+
+ if (!bCryptTableInit)
+ {
+ for(index1 = 0; index1 < 0x100; index1++)
+ {
+ for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
+ {
+ UInt32 temp1, temp2;
+
+ seed = (seed * 125 + 3) % 0x2AAAAB;
+ temp1 = (seed & 0xFFFF) << 0x10;
+
+ seed = (seed * 125 + 3) % 0x2AAAAB;
+ temp2 = (seed & 0xFFFF);
+
+ dwCryptTable[index2] = (temp1 | temp2);
+ }
+ }
+
+ bCryptTableInit = true;
+ }
+
+ return true;
+}
+
+UInt32 HashString(const char *lpszString, UInt32 dwHashType)
+{
+ UInt32 seed1 = 0x7FED7FED;
+ UInt32 seed2 = 0xEEEEEEEE;
+ int ch;
+
+ char szNull = 0;
+ if (!lpszString)
+ lpszString = &szNull;
+
+ if (dwHashType==HASH_KEY)
+ while (strchr(lpszString,'\\')!=NULL) lpszString = strchr(lpszString,'\\')+1;
+ while (*lpszString != 0)
+ {
+ ch = toupper(*lpszString++);
+
+ seed1 = dwCryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
+ seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
+ }
+
+ return seed1;
+}
+
+// The EncryptData function is based on the DecryptData function by
+// Ladislav Zezula, but adapted by Quantam to encrypt rather than decrypt.
+bool EncryptData(UInt8 *lpbyBuffer, UInt32 dwLength, UInt32 dwKey)
+{
+ UInt32 *lpdwBuffer = (UInt32 *)lpbyBuffer;
+ UInt32 seed = 0xEEEEEEEE;
+ UInt32 ch;
+
+ if (!lpbyBuffer)
+ return false;
+
+ // Round to DWORDs
+ dwLength >>= 2;
+
+ while(dwLength-- > 0)
+
+ {
+ seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
+ ch = *lpdwBuffer ^ (dwKey + seed);
+
+ dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
+ seed = *lpdwBuffer + seed + (seed << 5) + 3;
+
+ *lpdwBuffer++ = ch;
+ }
+
+ return true;
+}
+
+bool DecryptData(UInt8 *lpbyBuffer, UInt32 dwLength, UInt32 dwKey)
+{
+ UInt32 *lpdwBuffer = (UInt32 *)lpbyBuffer;
+ UInt32 seed = 0xEEEEEEEE;
+ UInt32 ch;
+
+ if (!lpbyBuffer)
+ return false;
+
+ // Round to DWORDs
+ dwLength >>= 2;
+
+ while(dwLength-- > 0)
+ {
+ seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
+ ch = *lpdwBuffer ^ (dwKey + seed);
+
+ dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
+ seed = ch + seed + (seed << 5) + 3;
+
+ *lpdwBuffer++ = ch;
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Functions tries to get file decryption key. The trick comes from block
+// positions which are stored at the begin of each compressed file. We know the
+// file size, that means we know number of blocks that means we know the first
+// DWORD value in block position. And if we know encrypted and decrypted value,
+// we can find the decryption key !!!
+//
+// hf - MPQ file handle
+// block - DWORD array of block positions
+// ch - Decrypted value of the first block pos
+
+UInt32 DetectFileSeed(UInt32 * block, UInt32 decrypted, UInt32 blocksize)
+{
+ UInt32 saveSeed1;
+ UInt32 temp = *block ^ decrypted; // temp = seed1 + seed2
+ // temp = seed1 + stormBuffer[0x400 + (seed1 & 0xFF)] + 0xEEEEEEEE
+ temp -= 0xEEEEEEEE; // temp = seed1 + stormBuffer[0x400 + (seed1 & 0xFF)]
+
+
+ for(int i = 0; i < 0x100; i++) // Try all 256 possibilities
+ {
+ UInt32 seed1;
+ UInt32 seed2 = 0xEEEEEEEE;
+ UInt32 ch;
+
+ // Try the first DWORD (We exactly know the value)
+ seed1 = temp - dwCryptTable[0x400 + i];
+ seed2 += dwCryptTable[0x400 + (seed1 & 0xFF)];
+ ch = block[0] ^ (seed1 + seed2);
+
+ if(ch != decrypted)
+ continue;
+
+ saveSeed1 = seed1 + 1;
+
+ // If OK, continue and test the second value. We don't know exactly the value,
+ // but we know that the second one has a value less than or equal to the
+ // size of the block position table plus the block size
+ seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
+ seed2 = ch + seed2 + (seed2 << 5) + 3;
+
+ seed2 += dwCryptTable[0x400 + (seed1 & 0xFF)];
+ ch = block[1] ^ (seed1 + seed2);
+
+ if(ch <= decrypted + blocksize)
+ return saveSeed1;
+ }
+ return 0;
+}
diff --git a/MpqCrypt.h b/MpqCrypt.h
--- /dev/null
+++ b/MpqCrypt.h
@@ -0,0 +1,23 @@
+// License information for this code is in license.txt
+
+#ifndef MPQCRYPT_INCLUDED
+#define MPQCRYPT_INCLUDED
+
+#include "SFTypes.h"
+
+#define HASH_POSITION 0
+#define HASH_NAME_A 1
+#define HASH_NAME_B 2
+#define HASH_KEY 3
+
+extern UInt32 dwHashTableKey;
+extern UInt32 dwBlockTableKey;
+
+bool InitCryptTable();
+UInt32 HashString(const char *lpszString, UInt32 dwHashType);
+bool EncryptData(UInt8 *lpbyBuffer, UInt32 dwLength, UInt32 dwKey);
+bool DecryptData(UInt8 *lpbyBuffer, UInt32 dwLength, UInt32 dwKey);
+UInt32 DetectFileSeed(UInt32 * block, UInt32 decrypted, UInt32 blocksize);
+
+#endif // #ifndef MPQCRYPT_INCLUDED
+
diff --git a/MpqHashTable.cpp b/MpqHashTable.cpp
--- /dev/null
+++ b/MpqHashTable.cpp
@@ -0,0 +1,28 @@
+// License information for this code is in license.txt
+
+#include <windows.h>
+#include "SFmpqapi.h"
+#include "SFUtil.h"
+#include "MpqCrypt.h"
+
+BOOL WriteHashTable(MPQARCHIVE *mpqOpenArc)
+{
+ DWORD tsz;
+
+ 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
+ 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
+ WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
+ DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
+ }
+
+ return TRUE;
+}
diff --git a/MpqHashTable.h b/MpqHashTable.h
--- /dev/null
+++ b/MpqHashTable.h
@@ -0,0 +1,11 @@
+// License information for this code is in license.txt
+
+#ifndef MPQHASHTABLE_INCLUDED
+#define MPQHASHTABLE_INCLUDED
+
+#include "SFmpqapi.h"
+
+BOOL WriteHashTable(MPQARCHIVE *mpqOpenArc);
+
+#endif // #ifndef MPQHASHTABLE_INCLUDED
+
diff --git a/SFTypes.h b/SFTypes.h
--- a/SFTypes.h
+++ b/SFTypes.h
+// License information for this code is in license.txt
+
#ifndef SFTYPES_INCLUDED
#define SFTYPES_INCLUDED
diff --git a/SFUtil.cpp b/SFUtil.cpp
--- /dev/null
+++ b/SFUtil.cpp
@@ -0,0 +1,96 @@
+// License information for this code is in license.txt
+
+#include <windows.h>
+#include <stdlib.h>
+#include "SFTypes.h"
+
+void WINAPI SFMemZero(LPVOID lpvDestination, DWORD dwLength)
+{
+ DWORD dwPrevLen = dwLength;
+ LPDWORD lpdwDestination = (LPDWORD)lpvDestination;
+ LPBYTE lpbyDestination;
+
+ dwLength >>= 2;
+
+ while (dwLength--)
+ *lpdwDestination++ = 0;
+
+ lpbyDestination = (LPBYTE)lpdwDestination;
+
+ dwLength = dwPrevLen;
+ dwLength &= 3;
+
+ while (dwLength--)
+ *lpbyDestination++ = 0;
+}
+
+LPVOID WINAPI SFAlloc(DWORD dwSize)
+{
+ LPVOID lpMemory = malloc(dwSize);
+ if (lpMemory) SFMemZero(lpMemory,dwSize);
+ return lpMemory;
+}
+
+void WINAPI SFFree(LPVOID lpvMemory)
+{
+ if (lpvMemory) free(lpvMemory);
+}
+
+Int64 SFGetFileSize(HANDLE hFile)
+{
+ IntConv FileSize;
+
+ FileSize.ui64 = 0;
+
+ FileSize.ui32[0] = ::GetFileSize(hFile, &FileSize.ui32[1]);
+
+ if (FileSize.ui32[0] == INVALID_FILE_SIZE) {
+ if (::GetLastError() != NO_ERROR)
+ return -1;
+ }
+
+ return FileSize.i64;
+}
+
+Int64 SFSetFilePointer(HANDLE hFile, Int64 nDistance, UInt32 dwMoveMethod)
+{
+ IntConv FilePos;
+
+ FilePos.i64 = nDistance;
+
+ FilePos.i32[0] = ::SetFilePointer(hFile, FilePos.i32[0], &FilePos.i32[1], dwMoveMethod);
+
+ if (FilePos.i32[0] == INVALID_SET_FILE_POINTER) {
+ if (::GetLastError() != NO_ERROR)
+ return -1;
+ }
+
+ return FilePos.i64;
+}
+
+size_t strlnlen(const char *strline)
+{
+ if (strline==0) return 0;
+ const char *strcr = strchr(strline,'\r');
+ const char *strlf = strchr(strline,'\n');
+ if (strcr==0 && strlf==0) return strlen(strline);
+ if (strcr!=0 && (strcr<strlf || strlf==0)) return strcr-strline;
+ if (strlf!=0 && (strlf<strcr || strcr==0)) return strlf-strline;
+ return strlen(strline);
+}
+
+char *nextline(const char *strline)
+{
+ if (strline==0) return 0;
+ const char *strcr = strchr(strline,'\r');
+ const char *strlf = strchr(strline,'\n');
+ if (strcr==0 && strlf==0) return 0;
+ const char *streol;
+ if (strcr!=0 && (strcr<strlf || strlf==0)) streol = strcr;
+ if (strlf!=0 && (strlf<strcr || strcr==0)) streol = strlf;
+ do {
+ streol++;
+ } while (streol[0]=='\r' || streol[0]=='\n');
+ if (streol[0]==0) return 0;
+ return (char *)streol;
+}
diff --git a/SFUtil.h b/SFUtil.h
--- /dev/null
+++ b/SFUtil.h
@@ -0,0 +1,18 @@
+// License information for this code is in license.txt
+
+#ifndef SFUTIL_INCLUDED
+#define SFUTIL_INCLUDED
+
+#include <windows.h>
+#include "SFTypes.h"
+
+LPVOID WINAPI SFAlloc(DWORD dwSize);
+void WINAPI SFFree(LPVOID lpvMemory);
+void WINAPI SFMemZero(LPVOID lpvDestination, DWORD dwLength);
+Int64 SFGetFileSize(HANDLE hFile);
+Int64 SFSetFilePointer(HANDLE hFile, Int64 nDistance, UInt32 dwMoveMethod);
+size_t strlnlen(const char *strline);
+char *nextline(const char *strline);
+
+#endif // #ifndef SFUTIL_INCLUDED
+
diff --git a/SFmpqapi.cpp b/SFmpqapi.cpp
--- a/SFmpqapi.cpp
+++ b/SFmpqapi.cpp
#include "../SComp/SComp.h"
+#include "MpqCrypt.h"
+#include "MpqHashTable.h"
+#include "MpqBlockTable.h"
#include "SFmpqapi.h"
+#include "SFUtil.h"
#include "SFTypes.h"
struct SFMPQAPIMODULE {
#define MAX_MPQ_PATH 260;
-#define HASH_POSITION 0
-#define HASH_NAME_A 1
-#define HASH_NAME_B 2
-#define HASH_KEY 3
-
-BOOL bCryptTableInit = FALSE;
-DWORD dwCryptTable[0x500];
-DWORD dwHashTableKey;
-DWORD dwBlockTableKey;
MPQARCHIVE **lpOpenMpq = 0;
DWORD dwOpenMpqCount = 0;
MPQARCHIVE * FirstLastMpq[2] = {0,0};
void LoadStorm();
void FreeStorm();
-LPVOID WINAPI SFAlloc(DWORD dwSize);
-void WINAPI SFFree(LPVOID lpvMemory);
-void WINAPI SFMemZero(LPVOID lpvDestination, DWORD dwLength);
BOOL WINAPI MpqOpenArchiveEx(LPCSTR lpFileName, DWORD dwPriority, DWORD dwFlags, MPQHANDLE *hMPQ, DWORD dwFlags2, DWORD dwMaximumFilesInArchive, DWORD dwBlockSize);
DWORD WINAPI FindMpqHeaderAtLocation(HANDLE hFile, DWORD dwStart, DWORD dwLength);
DWORD GetFullPath(LPCSTR lpFileName, char *lpBuffer, DWORD dwBufferLength);
DWORD GetHandleType(MPQHANDLE hFile);
BOOL AddToInternalListing(MPQHANDLE hMPQ, LPCSTR lpFileName);
BOOL RemoveFromInternalListing(MPQHANDLE hMPQ, LPCSTR lpFileName);
-size_t strlnlen(const char *strline);
-char *nextline(const char *strline);
-BOOL InitCryptTable();
-DWORD HashString(LPCSTR lpszString, DWORD dwHashType);
-BOOL EncryptData(LPBYTE lpbyBuffer, DWORD dwLength, DWORD dwKey);
-BOOL DecryptData(LPBYTE lpbyBuffer, DWORD dwLength, DWORD dwKey);
-static DWORD DetectFileSeed(DWORD * block, DWORD decrypted, DWORD blocksize);
DWORD DetectFileSeedEx(MPQARCHIVE * mpqOpenArc, HASHTABLEENTRY * lpHashEntry, LPCSTR * lplpFileName);
BOOL APIENTRY DllMain( HINSTANCE hInstDLL,
return TRUE;
}
-LPVOID WINAPI SFAlloc(DWORD dwSize)
-{
- LPVOID lpMemory = malloc(dwSize);
- if (lpMemory) SFMemZero(lpMemory,dwSize);
- return lpMemory;
-}
-
-void WINAPI SFFree(LPVOID lpvMemory)
-{
- if (lpvMemory) free(lpvMemory);
-}
-
-void WINAPI SFMemZero(LPVOID lpvDestination, DWORD dwLength)
-{
- DWORD dwPrevLen = dwLength;
- LPDWORD lpdwDestination = (LPDWORD)lpvDestination;
- LPBYTE lpbyDestination;
-
- dwLength >>= 2;
-
- while (dwLength--)
- *lpdwDestination++ = 0;
-
- lpbyDestination = (LPBYTE)lpdwDestination;
-
- dwLength = dwPrevLen;
- dwLength &= 3;
-
- while (dwLength--)
- *lpbyDestination++ = 0;
-}
-
-Int64 SFGetFileSize(HANDLE hFile)
-{
- IntConv FileSize;
-
- FileSize.ui64 = 0;
-
- FileSize.ui32[0] = ::GetFileSize(hFile, &FileSize.ui32[1]);
-
- if (FileSize.ui32[0] == INVALID_FILE_SIZE) {
- if (::GetLastError() != NO_ERROR)
- return -1;
- }
-
- return FileSize.i64;
-}
-
-Int64 SFSetFilePointer(HANDLE hFile, Int64 nDistance, UInt32 dwMoveMethod)
-{
- IntConv FilePos;
-
- FilePos.i64 = nDistance;
-
- FilePos.i32[0] = ::SetFilePointer(hFile, FilePos.i32[0], &FilePos.i32[1], dwMoveMethod);
-
- if (FilePos.i32[0] == INVALID_SET_FILE_POINTER) {
- if (::GetLastError() != NO_ERROR)
- return -1;
- }
-
- return FilePos.i64;
-}
-
TempAlloc::TempAlloc()
{
lpAllocAddress = 0;
@@ -2105,34 +2026,8 @@ BOOL SFMPQAPI WINAPI MpqAddFileToArchiveEx(MPQHANDLE hMPQ, LPCSTR lpSourceFileNa
SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+dwFileOffset,FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,buffer,fsz,&tsz,0);
SFFree(buffer);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- }
- buffer = (char *)SFAlloc(sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- if (buffer) {
- memcpy(buffer,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- EncryptData((LPBYTE)buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- }
+ WriteHashTable(mpqOpenArc);
+ WriteBlockTable(mpqOpenArc);
AddToInternalListing(hMPQ,lpDestFileName);
return TRUE;
@@ -2451,34 +2346,8 @@ BOOL SFMPQAPI WINAPI MpqAddFileFromBufferEx(MPQHANDLE hMPQ, LPVOID lpBuffer, DWO
SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+dwFileOffset,FILE_BEGIN);
WriteFile(mpqOpenArc->hFile,buffer,fsz,&tsz,0);
SFFree(buffer);
- buffer = (char *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if (buffer!=0) {
- memcpy(buffer,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- EncryptData((LPBYTE)buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- }
- buffer = (char *)SFAlloc(sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- if (buffer!=0) {
- memcpy(buffer,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize);
- EncryptData((LPBYTE)buffer,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpBlockTable,sizeof(BLOCKTABLEENTRY) * mpqOpenArc->MpqHeader.dwBlockTableSize,dwBlockTableKey);
- }
+ WriteHashTable(mpqOpenArc);
+ WriteBlockTable(mpqOpenArc);
AddToInternalListing(hMPQ,lpFileName);
return TRUE;
}
@@ -2619,20 +2488,7 @@ BOOL SFMPQAPI WINAPI MpqRenameAndSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpcOldFile
oldHashEntry->dwNameHashB = 0xFFFFFFFF;
oldHashEntry->lcLocale = 0xFFFFFFFF;
oldHashEntry->dwBlockTableIndex = 0xFFFFFFFE;
- char *buffer = (char *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if (buffer!=0) {
- memcpy(buffer,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- EncryptData((LPBYTE)buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- }
+ WriteHashTable(mpqOpenArc);
}
LCID dwOldLocale=LocaleID;
LocaleID=nOldLocale;
@@ -2672,22 +2528,7 @@ BOOL SFMPQAPI WINAPI MpqDeleteFileWithLocale(MPQHANDLE hMPQ, LPCSTR lpFileName,
hashEntry->dwNameHashB = 0xFFFFFFFF;
hashEntry->lcLocale = 0xFFFFFFFF;
hashEntry->dwBlockTableIndex = 0xFFFFFFFE;
- DWORD tsz;
- char *buffer = (char *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if (buffer!=0) {
- memcpy(buffer,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- EncryptData((LPBYTE)buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
-
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- }
+ WriteHashTable(mpqOpenArc);
LCID dwOldLocale=LocaleID;
LocaleID=nLocale;
RemoveFromInternalListing(hMPQ,lpFileName);
SFFree(buffer);
CloseHandle(hFile);
DeleteFile(lpFileName);
- EncryptData((BYTE *)mpqOpenArc->lpHashTable,mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY),dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY),&tsz,0);
- DecryptData((BYTE *)mpqOpenArc->lpHashTable,mpqOpenArc->MpqHeader.dwHashTableSize * sizeof(HASHTABLEENTRY),dwHashTableKey);
- if(mpqOpenArc->lpBlockTable!=0) {
- EncryptData((BYTE *)mpqOpenArc->lpBlockTable,mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY),dwBlockTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwBlockTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpBlockTable,mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY),&tsz,0);
- DecryptData((BYTE *)mpqOpenArc->lpBlockTable,mpqOpenArc->MpqHeader.dwBlockTableSize * sizeof(BLOCKTABLEENTRY),dwBlockTableKey);
- }
+ WriteHashTable(mpqOpenArc);
+ WriteBlockTable(mpqOpenArc);
return TRUE;
}
@@ -3110,22 +2943,8 @@ BOOL SFMPQAPI WINAPI MpqSetFileLocale(MPQHANDLE hMPQ, LPCSTR lpFileName, LCID nO
if (hashEntry==0) return FALSE;
if (hashEntry->lcLocale!=nOldLocale) return FALSE;
hashEntry->lcLocale = nNewLocale;
- DWORD tsz;
- char *buffer = (char *)SFAlloc(sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- if (buffer!=0) {
- memcpy(buffer,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize);
- EncryptData((LPBYTE)buffer,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- SFSetFilePointer(mpqOpenArc->hFile,mpqOpenArc->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- 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->dwMPQStart+mpqOpenArc->MpqHeader.dwHashTableOffset,FILE_BEGIN);
- WriteFile(mpqOpenArc->hFile,mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,&tsz,0);
- DecryptData((LPBYTE)mpqOpenArc->lpHashTable,sizeof(HASHTABLEENTRY) * mpqOpenArc->MpqHeader.dwHashTableSize,dwHashTableKey);
- }
+ WriteHashTable(mpqOpenArc);
LCID dwOldLocale=LocaleID;
LocaleID=nOldLocale;
RemoveFromInternalListing(hMPQ,lpFileName);
return TRUE;
}
-size_t strlnlen(const char *strline)
-{
- if (strline==0) return 0;
- const char *strcr = strchr(strline,'\r');
- const char *strlf = strchr(strline,'\n');
- if (strcr==0 && strlf==0) return strlen(strline);
- if (strcr!=0 && (strcr<strlf || strlf==0)) return strcr-strline;
- if (strlf!=0 && (strlf<strcr || strcr==0)) return strlf-strline;
- return strlen(strline);
-}
-
-char *nextline(const char *strline)
-{
- if (strline==0) return 0;
- const char *strcr = strchr(strline,'\r');
- const char *strlf = strchr(strline,'\n');
- if (strcr==0 && strlf==0) return 0;
- const char *streol;
- if (strcr!=0 && (strcr<strlf || strlf==0)) streol = strcr;
- if (strlf!=0 && (strlf<strcr || strcr==0)) streol = strlf;
- do {
- streol++;
- } while (streol[0]=='\r' || streol[0]=='\n');
- if (streol[0]==0) return 0;
- return (char *)streol;
-}
-
-// The InitCryptTable, HashString, DecryptData, and DetectFileKey are
-// based on the versions in StormLib which were written by Ladislav
-// Zezula, but may have been modified somewhat by Quantam or ShadowFlare.
-BOOL InitCryptTable()
-{
- DWORD seed = 0x00100001;
- DWORD index1 = 0;
- DWORD index2 = 0;
- int i;
-
- if (!bCryptTableInit)
- {
- for(index1 = 0; index1 < 0x100; index1++)
- {
- for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
- {
- DWORD temp1, temp2;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp1 = (seed & 0xFFFF) << 0x10;
-
- seed = (seed * 125 + 3) % 0x2AAAAB;
- temp2 = (seed & 0xFFFF);
-
- dwCryptTable[index2] = (temp1 | temp2);
- }
- }
-
- bCryptTableInit = TRUE;
- }
-
- return TRUE;
-}
-
-DWORD HashString(LPCSTR lpszString, DWORD dwHashType)
-{
- DWORD seed1 = 0x7FED7FED;
- DWORD seed2 = 0xEEEEEEEE;
- int ch;
-
- char szNull = 0;
- if (!lpszString)
- lpszString = &szNull;
-
- if (dwHashType==HASH_KEY)
- while (strchr(lpszString,'\\')!=NULL) lpszString = strchr(lpszString,'\\')+1;
- while (*lpszString != 0)
- {
- ch = toupper(*lpszString++);
-
- seed1 = dwCryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
- seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
- }
-
- return seed1;
-}
-
-// The EncryptData function is based on the DecryptData function by
-// Ladislav Zezula, but adapted by Quantam to encrypt rather than decrypt.
-BOOL EncryptData(LPBYTE lpbyBuffer, DWORD dwLength, DWORD dwKey)
-{
- LPDWORD lpdwBuffer = (LPDWORD)lpbyBuffer;
- DWORD seed = 0xEEEEEEEE;
- DWORD ch;
-
- if (!lpbyBuffer)
- return FALSE;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
-
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
- seed = *lpdwBuffer + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-
- return TRUE;
-}
-
-BOOL DecryptData(LPBYTE lpbyBuffer, DWORD dwLength, DWORD dwKey)
-{
- LPDWORD lpdwBuffer = (LPDWORD)lpbyBuffer;
- DWORD seed = 0xEEEEEEEE;
- DWORD ch;
-
- if (!lpbyBuffer)
- return FALSE;
-
- // Round to DWORDs
- dwLength >>= 2;
-
- while(dwLength-- > 0)
- {
- seed += dwCryptTable[0x400 + (dwKey & 0xFF)];
- ch = *lpdwBuffer ^ (dwKey + seed);
-
- dwKey = ((~dwKey << 0x15) + 0x11111111) | (dwKey >> 0x0B);
- seed = ch + seed + (seed << 5) + 3;
-
- *lpdwBuffer++ = ch;
- }
-
- return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// Functions tries to get file decryption key. The trick comes from block
-// positions which are stored at the begin of each compressed file. We know the
-// file size, that means we know number of blocks that means we know the first
-// DWORD value in block position. And if we know encrypted and decrypted value,
-// we can find the decryption key !!!
-//
-// hf - MPQ file handle
-// block - DWORD array of block positions
-// ch - Decrypted value of the first block pos
-
-static DWORD DetectFileSeed(DWORD * block, DWORD decrypted, DWORD blocksize)
-{
- DWORD saveSeed1;
- DWORD temp = *block ^ decrypted; // temp = seed1 + seed2
- // temp = seed1 + stormBuffer[0x400 + (seed1 & 0xFF)] + 0xEEEEEEEE
- temp -= 0xEEEEEEEE; // temp = seed1 + stormBuffer[0x400 + (seed1 & 0xFF)]
-
-
- for(int i = 0; i < 0x100; i++) // Try all 256 possibilities
- {
- DWORD seed1;
- DWORD seed2 = 0xEEEEEEEE;
- DWORD ch;
-
- // Try the first DWORD (We exactly know the value)
- seed1 = temp - dwCryptTable[0x400 + i];
- seed2 += dwCryptTable[0x400 + (seed1 & 0xFF)];
- ch = block[0] ^ (seed1 + seed2);
-
- if(ch != decrypted)
- continue;
-
- saveSeed1 = seed1 + 1;
-
- // If OK, continue and test the second value. We don't know exactly the value,
- // but we know that the second one has a value less than or equal to the
- // size of the block position table plus the block size
- seed1 = ((~seed1 << 0x15) + 0x11111111) | (seed1 >> 0x0B);
- seed2 = ch + seed2 + (seed2 << 5) + 3;
-
- seed2 += dwCryptTable[0x400 + (seed1 & 0xFF)];
- ch = block[1] ^ (seed1 + seed2);
-
- if(ch <= decrypted + blocksize)
- return saveSeed1;
- }
- return 0;
-}
-
DWORD DetectFileSeedEx(MPQARCHIVE * mpqOpenArc, HASHTABLEENTRY * lpHashEntry, LPCSTR * lplpFileName)
{
if (mpqOpenArc==0 || lpHashEntry==0) return 0;
diff --git a/SFmpqapi.dsp b/SFmpqapi.dsp
--- a/SFmpqapi.dsp
+++ b/SFmpqapi.dsp
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
+SOURCE=.\MpqBlockTable.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqCrypt.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqHashTable.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SFmpqapi.cpp\r
# End Source File\r
# Begin Source File\r
\r
SOURCE=.\SFmpqapi.rc\r
# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFUtil.cpp\r
+# End Source File\r
# End Group\r
# Begin Group "Header Files"\r
\r
# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
# Begin Source File\r
\r
+SOURCE=.\MpqBlockTable.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqCrypt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqHashTable.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SFmpqapi.h\r
# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFTypes.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFUtil.h\r
+# End Source File\r
# End Group\r
# Begin Group "Resource Files"\r
\r
diff --git a/SFmpqapi.vcproj b/SFmpqapi.vcproj
--- a/SFmpqapi.vcproj
+++ b/SFmpqapi.vcproj
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl"\r
>\r
+ <File\r
+ RelativePath=".\MpqBlockTable.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqCrypt.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqHashTable.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="SFmpqapi.h"\r
>\r
RelativePath=".\SFTypes.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\SFUtil.h"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="Resource Files"\r
Name="Source Files"\r
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
>\r
+ <File\r
+ RelativePath=".\MpqBlockTable.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqCrypt.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqHashTable.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath="SFmpqapi.cpp"\r
>\r
/>\r
</FileConfiguration>\r
</File>\r
+ <File\r
+ RelativePath=".\SFUtil.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
</Files>\r
<Globals>\r
diff --git a/SFmpqlib.dsp b/SFmpqlib.dsp
--- a/SFmpqlib.dsp
+++ b/SFmpqlib.dsp
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
# Begin Source File\r
\r
+SOURCE=.\MpqBlockTable.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqCrypt.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqHashTable.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SFmpq_static.cpp\r
# End Source File\r
# Begin Source File\r
\r
SOURCE=.\SFmpqapi.cpp\r
# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFUtil.cpp\r
+# End Source File\r
# End Group\r
# Begin Group "Header Files"\r
\r
# PROP Default_Filter "h;hpp;hxx;hm;inl"\r
# Begin Source File\r
\r
+SOURCE=.\MpqBlockTable.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqCrypt.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\MpqHashTable.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=.\SFmpq_static.h\r
# End Source File\r
# Begin Source File\r
\r
SOURCE=.\SFmpqapi.h\r
# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFTypes.h\r
+# End Source File\r
+# Begin Source File\r
+\r
+SOURCE=.\SFUtil.h\r
+# End Source File\r
# End Group\r
# Begin Group "SComp"\r
\r
diff --git a/SFmpqlib.vcproj b/SFmpqlib.vcproj
--- a/SFmpqlib.vcproj
+++ b/SFmpqlib.vcproj
Name="Source Files"\r
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"\r
>\r
+ <File\r
+ RelativePath=".\MpqBlockTable.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqCrypt.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqHashTable.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath="SFmpq_static.cpp"\r
>\r
/>\r
</FileConfiguration>\r
</File>\r
+ <File\r
+ RelativePath=".\SFUtil.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="Header Files"\r
Filter="h;hpp;hxx;hm;inl"\r
>\r
+ <File\r
+ RelativePath=".\MpqBlockTable.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqCrypt.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\MpqHashTable.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="SFmpq_static.h"\r
>\r
RelativePath="SFmpqapi.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\SFTypes.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\SFUtil.h"\r
+ >\r
+ </File>\r
</Filter>\r
<Filter\r
Name="SComp"\r
|