1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
/*****************************************************************************/
/* Storm_test.cpp Copyright (c) Ladislav Zezula 2014 */
/*---------------------------------------------------------------------------*/
/* Test module for storm.dll (original Blizzard MPQ dynalic library */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 24.08.14 1.00 Lad The first version of Storm_test.cpp */
/*****************************************************************************/
#define _CRT_NON_CONFORMING_SWPRINTFS
#define _CRT_SECURE_NO_DEPRECATE
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#ifdef _MSC_VER
#include <crtdbg.h>
#endif
#define STORM_ALTERNATE_NAMES // Use Storm* prefix for functions
#include "storm.h" // Header file for Storm.dll
#pragma comment(lib, "storm.lib")
//-----------------------------------------------------------------------------
// List of files
const char * IntToHexChar = "0123456789ABCDEF";
LPCSTR DefFilesToOpen[] =
{
"music\\tdefeat.wav",
"setupdat\\inst.vis",
"setupdat\\audio\\mouseover.wav",
"files\\font\\font12.fnt",
"music\\zvict.wav",
"files\\readme.txt",
"music\\zerg2.wav",
"music\\zerg1.wav",
"setupdat\\inst_regs.ins",
"files\\font\\font50.fnt",
"files\\msv2all.vxp",
"setupdat\\scr_options.vis",
"setupdat\\font\\font16x.fnt",
"setupdat\\setup.vis",
"maps\\128x128_wasteland4.scm",
"setupdat\\scr_main.vis",
"music\\pvict.wav",
"music\\zdefeat.wav",
};
//-----------------------------------------------------------------------------
// Main
static void CalculateMD5(LPBYTE md5_digest, LPBYTE pbData, DWORD cbData)
{
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hCryptHash = NULL;
if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if(CryptCreateHash(hCryptProv, CALG_MD5, NULL, 0, &hCryptHash))
{
DWORD dwHashLen = 0x10;
CryptHashData(hCryptHash, pbData, cbData, 0);
CryptGetHashParam(hCryptHash, HP_HASHVAL, md5_digest, &dwHashLen, 0);
CryptDestroyHash(hCryptHash);
}
CryptReleaseContext(hCryptProv, 0);
}
}
template <typename XCHAR>
DWORD BinaryToString(XCHAR * szBuffer, size_t cchBuffer, LPCVOID pvBinary, size_t cbBinary)
{
LPCBYTE pbBinary = (LPCBYTE)pvBinary;
// The size of the string must be enough to hold the binary + EOS
if(cchBuffer < ((cbBinary * 2) + 1))
return ERROR_INSUFFICIENT_BUFFER;
// Convert the string to the array of MD5
// Copy the blob data as text
for(size_t i = 0; i < cbBinary; i++)
{
*szBuffer++ = IntToHexChar[pbBinary[0] >> 0x04];
*szBuffer++ = IntToHexChar[pbBinary[0] & 0x0F];
pbBinary++;
}
// Terminate the string
*szBuffer = 0;
return ERROR_SUCCESS;
}
int main(int argc, char * argv[])
{
LPCSTR szArchiveName;
LPCSTR szFormat;
HANDLE hMpq = NULL;
HANDLE hFile = NULL;
LPBYTE pbBuffer = NULL;
DWORD dwBytesRead = 0;
DWORD dwFileSize = 0;
BOOL bResult;
BYTE md5_digest[0x10];
char md5_string[0x40];
// Check parameters
if(argc == 1)
{
printf("Error: Missing MPQ name\nUsage: storm_test.exe MpqName [FileName [FileName]]\n");
return 3;
}
// Get both arguments
SetLastError(ERROR_SUCCESS);
szArchiveName = argv[1];
// Break for kernel debugger
//__debugbreak();
// Put Storm.dll to the current folder before running this
//printf("[*] Opening archive '%s' ...\n", szArchiveName);
if(StormOpenArchive(szArchiveName, 0, 0, &hMpq))
{
LPCSTR * FilesToOpen = DefFilesToOpen;
size_t nFilesToOpen = _countof(DefFilesToOpen);
// Set the list of files
if(argc > 2)
{
FilesToOpen = (LPCSTR *)(&argv[2]);
nFilesToOpen = argc - 2;
}
// Attempt to open all files
for(size_t i = 0; i < nFilesToOpen; i++)
{
//printf("[*] Opening file '%s' ...\n", FilesToOpen[i]);
if(StormOpenFileEx(hMpq, FilesToOpen[i], 0, &hFile))
{
//printf("[*] Retrieving file size ... ");
dwFileSize = StormGetFileSize(hFile, NULL);
szFormat = (dwFileSize == INVALID_FILE_SIZE) ? ("(invalid)\n") : ("(%u bytes)\n");
//printf(szFormat, dwFileSize);
// Allocate the buffer for the entire file
//printf("[*] Allocating buffer ...\n");
if((pbBuffer = new BYTE[dwFileSize]) != NULL)
{
//printf("[*] Moving to begin of the file ...\n");
StormSetFilePointer(hFile, 0, NULL, FILE_BEGIN);
//printf("[*] Reading file ... ");
bResult = StormReadFile(hFile, pbBuffer, dwFileSize, &dwBytesRead, NULL);
szFormat = (bResult != FALSE && dwBytesRead == dwFileSize) ? ("(OK)\n") : ("(error %u)\n");
//printf(szFormat, GetLastError());
//printf("[*] Calculating MD5 ... ");
CalculateMD5(md5_digest, pbBuffer, dwFileSize);
BinaryToString(md5_string, _countof(md5_string), md5_digest, sizeof(md5_digest));
printf("%s *%s\n", md5_string, FilesToOpen[i]);
delete[] pbBuffer;
}
//printf("[*] Closing file ...\n");
StormCloseFile(hFile);
}
}
//printf("[*] Closing archive ...\n");
StormCloseArchive(hMpq);
}
//printf("Done.\n\n");
return 0;
}
|