801 lines
21 KiB
C
801 lines
21 KiB
C
|
|
||
|
#include "acFileAttr.h"
|
||
|
#include "attr.h"
|
||
|
#include "version.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <imagehlp.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
// the global array with all the file attributes
|
||
|
|
||
|
FILEATTR g_arrFileAttr[] =
|
||
|
{
|
||
|
{VTID_FILESIZE, "File Size", "SIZE", QueryFileSize, BlobToStringLong, DumpDWORD},
|
||
|
{VTID_EXETYPE, "Module Type", "MODULETYPE*", QueryModuleType, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_BINFILEVER, "Binary File Version", "BIN_FILE_VERSION", QueryBinFileVer, BlobToStringBinVer, DumpBinVer},
|
||
|
{VTID_BINPRODUCTVER, "Binary Product Version", "BIN_PRODUCT_VERSION", QueryBinProductVer, BlobToStringBinVer, DumpBinVer},
|
||
|
{VTID_FILEDATEHI, "File Date (HI)", "VERFILEDATEHI", QueryFileDateHi, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_FILEDATELO, "File Date (LO)", "VERFILEDATELO", QueryFileDateLo, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_FILEVEROS, "File OS Version", "VERFILEOS", QueryFileVerOs, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_FILEVERTYPE, "File Type", "VERFILETYPE", QueryFileVerType, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_CHECKSUM, "File CheckSum", "CHECKSUM", QueryFileCheckSum, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_PECHECKSUM, "File Header CheckSum", "PECHECKSUM", QueryFilePECheckSum, BlobToStringDWORD, DumpDWORD},
|
||
|
{VTID_COMPANYNAME, "Company Name", "COMPANY_NAME", QueryCompanyName, BlobToStringString, DumpString},
|
||
|
{VTID_PRODUCTVERSION, "Product Version", "PRODUCT_VERSION", QueryProductVersion, BlobToStringString, DumpString},
|
||
|
{VTID_PRODUCTNAME, "Product Name", "PRODUCT_NAME", QueryProductName, BlobToStringString, DumpString},
|
||
|
{VTID_FILEDESCRIPTION, "File Description", "FILE_DESCRIPTION", QueryFileDescription, BlobToStringString, DumpString},
|
||
|
{VTID_FILEVERSION, "File Version", "FILEVERSION", QueryFileVersion, BlobToStringString, DumpString},
|
||
|
{VTID_ORIGINALFILENAME, "Original File Name", "ORIGINALFILENAME", QueryOriginalFileName, BlobToStringString, DumpString},
|
||
|
{VTID_INTERNALNAME, "Internal Name", "INTERNALNAME", QueryInternalName, BlobToStringString, DumpString},
|
||
|
{VTID_LEGALCOPYRIGHT, "Legal Copyright", "LEGALCOPYRIGHT", QueryLegalCopyright, BlobToStringString, DumpString},
|
||
|
{VTID_16BITDESCRIPTION, "16 Bit Description", "S16BITDESCRIPTION", Query16BitDescription, BlobToStringString, DumpString},
|
||
|
{VTID_UPTOBINPRODUCTVER,"Up To Binary Product Version", "UPTO_BIN_PRODUCT_VERSION", QueryBinProductVer, BlobToStringUpToBinVer, DumpUpToBinVer}
|
||
|
};
|
||
|
|
||
|
#define FAIL_IF_NO_VERSION() \
|
||
|
{ \
|
||
|
if (pMgr->ver.FixedInfoSize < sizeof(VS_FIXEDFILEINFO)) { \
|
||
|
LogMsg("No version info\n"); \
|
||
|
return FALSE; \
|
||
|
} \
|
||
|
}
|
||
|
|
||
|
#define ALLOC_VALUE_AND_RETURN() \
|
||
|
{ \
|
||
|
pFileAttr->pszValue = (PSTR)Alloc(lstrlen(szBuffer) + 1); \
|
||
|
\
|
||
|
if (pFileAttr->pszValue == NULL) { \
|
||
|
LogMsg("QueryAttr: memory allocation error\n"); \
|
||
|
return FALSE; \
|
||
|
} \
|
||
|
\
|
||
|
lstrcpy(pFileAttr->pszValue, szBuffer); \
|
||
|
\
|
||
|
pFileAttr->dwFlags = ATTR_FLAG_AVAILABLE; \
|
||
|
\
|
||
|
return TRUE; \
|
||
|
}
|
||
|
|
||
|
#define QUERYENTRY(szEntryName) \
|
||
|
{ \
|
||
|
pFileAttr->pszValue = QueryVersionEntry(&pMgr->ver, szEntryName); \
|
||
|
\
|
||
|
if (pFileAttr->pszValue == NULL) { \
|
||
|
LogMsg("QueryEntry: attribute %s N/A\n", szEntryName); \
|
||
|
return FALSE; \
|
||
|
} \
|
||
|
pFileAttr->dwFlags = ATTR_FLAG_AVAILABLE; \
|
||
|
\
|
||
|
return TRUE; \
|
||
|
}
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
void LogMsgDbg(
|
||
|
LPSTR pszFmt, ... )
|
||
|
{
|
||
|
CHAR gszT[1024];
|
||
|
va_list arglist;
|
||
|
|
||
|
va_start(arglist, pszFmt);
|
||
|
_vsnprintf(gszT, 1023, pszFmt, arglist);
|
||
|
gszT[1023] = 0;
|
||
|
va_end(arglist);
|
||
|
|
||
|
OutputDebugString(gszT);
|
||
|
}
|
||
|
|
||
|
#endif // DBG
|
||
|
|
||
|
|
||
|
// dump to blob functions
|
||
|
|
||
|
int
|
||
|
DumpDWORD(
|
||
|
DWORD dwId,
|
||
|
PFILEATTRVALUE pFileAttr,
|
||
|
BYTE* pBlob)
|
||
|
{
|
||
|
*(DWORD*)pBlob = dwId;
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
*(DWORD*)pBlob = sizeof(DWORD);
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
*(DWORD*)pBlob = pFileAttr->dwValue;
|
||
|
return (3 * sizeof(DWORD));
|
||
|
}
|
||
|
|
||
|
int
|
||
|
DumpString(
|
||
|
DWORD dwId,
|
||
|
PFILEATTRVALUE pFileAttr,
|
||
|
BYTE* pBlob)
|
||
|
{
|
||
|
int strLen, nWideChars;
|
||
|
WCHAR wszOut[256];
|
||
|
|
||
|
strLen = lstrlen(pFileAttr->pszValue);
|
||
|
|
||
|
nWideChars = MultiByteToWideChar(
|
||
|
CP_ACP,
|
||
|
0,
|
||
|
pFileAttr->pszValue,
|
||
|
strLen,
|
||
|
wszOut,
|
||
|
256);
|
||
|
|
||
|
wszOut[nWideChars] = 0;
|
||
|
|
||
|
*(DWORD*)pBlob = dwId;
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
*(DWORD*)pBlob = (nWideChars + 1) * sizeof(WCHAR);
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
CopyMemory(pBlob, wszOut, (nWideChars + 1) * sizeof(WCHAR));
|
||
|
|
||
|
return (2 * sizeof(DWORD) + (nWideChars + 1) * sizeof(WCHAR));
|
||
|
}
|
||
|
|
||
|
int
|
||
|
DumpBinVer(
|
||
|
DWORD dwId,
|
||
|
PFILEATTRVALUE pFileAttr,
|
||
|
BYTE* pBlob)
|
||
|
{
|
||
|
*(DWORD*)pBlob = dwId;
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
*(DWORD*)pBlob = 8 * sizeof(WORD);
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
CopyMemory(pBlob, pFileAttr->wValue, 4 * sizeof(WORD));
|
||
|
|
||
|
pBlob += (4 * sizeof(WORD));
|
||
|
|
||
|
CopyMemory(pBlob, pFileAttr->wMask, 4 * sizeof(WORD));
|
||
|
|
||
|
return (8 * sizeof(WORD) + 2 * sizeof(DWORD));
|
||
|
}
|
||
|
|
||
|
int
|
||
|
DumpUpToBinVer(
|
||
|
DWORD dwId,
|
||
|
PFILEATTRVALUE pFileAttr,
|
||
|
BYTE* pBlob)
|
||
|
{
|
||
|
*(DWORD*)pBlob = dwId;
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
*(DWORD*)pBlob = 4 * sizeof(WORD);
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
CopyMemory(pBlob, pFileAttr->wValue, 4 * sizeof(WORD));
|
||
|
|
||
|
return (4 * sizeof(WORD) + 2 * sizeof(DWORD));
|
||
|
}
|
||
|
|
||
|
|
||
|
// blob to string functions
|
||
|
|
||
|
int
|
||
|
BlobToStringBinVer(
|
||
|
BYTE* pBlob,
|
||
|
char* pszOut)
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
|
||
|
// read the size first
|
||
|
dwSize = *(DWORD*)pBlob;
|
||
|
|
||
|
if (dwSize != 8 * sizeof(WORD)) {
|
||
|
LogMsg("BlobToStringBinVer: invalid blob\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
wsprintf(pszOut, "Ver %d.%d.%d.%d Mask %04X.%04X.%04X.%04X\r\n",
|
||
|
*((WORD*)pBlob + 3),
|
||
|
*((WORD*)pBlob + 2),
|
||
|
*((WORD*)pBlob + 1),
|
||
|
*((WORD*)pBlob + 0),
|
||
|
*((WORD*)pBlob + 7),
|
||
|
*((WORD*)pBlob + 6),
|
||
|
*((WORD*)pBlob + 5),
|
||
|
*((WORD*)pBlob + 4));
|
||
|
|
||
|
return sizeof(DWORD) + 8 * sizeof(WORD);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
BlobToStringUpToBinVer(
|
||
|
BYTE* pBlob,
|
||
|
char* pszOut)
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
|
||
|
// read the size first
|
||
|
dwSize = *(DWORD*)pBlob;
|
||
|
|
||
|
if (dwSize != 4 * sizeof(WORD)) {
|
||
|
LogMsg("BlobToStringUpToBinVer: invalid blob\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
wsprintf(pszOut, "Ver %d.%d.%d.%d\r\n",
|
||
|
*((WORD*)pBlob + 3),
|
||
|
*((WORD*)pBlob + 2),
|
||
|
*((WORD*)pBlob + 1),
|
||
|
*((WORD*)pBlob + 0));
|
||
|
|
||
|
return sizeof(DWORD) + 4 * sizeof(WORD);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
BlobToStringDWORD(
|
||
|
BYTE* pBlob,
|
||
|
char* pszOut)
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
|
||
|
// read the size first
|
||
|
dwSize = *(DWORD*)pBlob;
|
||
|
|
||
|
if (dwSize != sizeof(DWORD)) {
|
||
|
LogMsg("BlobToStringDWORD: invalid blob\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
wsprintf(pszOut, "0x%X\r\n", *(DWORD*)pBlob);
|
||
|
|
||
|
return 2 * sizeof(DWORD);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
BlobToStringLong(
|
||
|
BYTE* pBlob,
|
||
|
char* pszOut)
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
|
||
|
// read the size first
|
||
|
dwSize = *(DWORD*)pBlob;
|
||
|
|
||
|
if (dwSize != sizeof(DWORD)) {
|
||
|
LogMsg("BlobToStringLong: invalid blob\n");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
wsprintf(pszOut, "%d\r\n", *(ULONG*)pBlob);
|
||
|
|
||
|
return 2 * sizeof(DWORD);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
BlobToStringString(
|
||
|
BYTE* pBlob,
|
||
|
char* pszOut)
|
||
|
{
|
||
|
DWORD dwSize;
|
||
|
|
||
|
// read the size first
|
||
|
dwSize = *(DWORD*)pBlob;
|
||
|
|
||
|
pBlob += sizeof(DWORD);
|
||
|
|
||
|
WideCharToMultiByte(
|
||
|
CP_ACP,
|
||
|
0,
|
||
|
(LPCWSTR)pBlob,
|
||
|
(int)dwSize,
|
||
|
pszOut,
|
||
|
(int)dwSize,
|
||
|
NULL,
|
||
|
NULL);
|
||
|
|
||
|
lstrcat(pszOut, "\r\n");
|
||
|
|
||
|
return sizeof(DWORD) + (int)dwSize;
|
||
|
}
|
||
|
|
||
|
|
||
|
// query functions
|
||
|
|
||
|
BOOL
|
||
|
QueryFileSize(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
HANDLE findHandle;
|
||
|
WIN32_FIND_DATA findData;
|
||
|
|
||
|
findHandle = FindFirstFile(pMgr->ver.pszFile, &findData);
|
||
|
|
||
|
if (findHandle == INVALID_HANDLE_VALUE) {
|
||
|
LogMsg("QueryFileSize: file not found\n");
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
pFileAttr->dwValue = findData.nFileSizeLow;
|
||
|
|
||
|
FindClose(findHandle);
|
||
|
|
||
|
wsprintf(szBuffer, "%d", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryModuleType(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
// not implemented
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryBinFileVer(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
ULONGLONG binFileVer;
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
*((PDWORD)(&binFileVer)) = pMgr->ver.FixedInfo->dwFileVersionLS;
|
||
|
*(((PDWORD)(&binFileVer)) + 1) = pMgr->ver.FixedInfo->dwFileVersionMS;
|
||
|
|
||
|
CopyMemory(pFileAttr->wValue, &binFileVer, 4 * sizeof(WORD));
|
||
|
|
||
|
wsprintf(szBuffer, "%d.%d.%d.%d",
|
||
|
pFileAttr->wValue[3],
|
||
|
pFileAttr->wValue[2],
|
||
|
pFileAttr->wValue[1],
|
||
|
pFileAttr->wValue[0]);
|
||
|
|
||
|
pFileAttr->wMask[0] = pFileAttr->wMask[1] = pFileAttr->wMask[2] = pFileAttr->wMask[3] = 0xFFFF;
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryBinProductVer(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
ULONGLONG binProdVer;
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
*((PDWORD)(&binProdVer)) = pMgr->ver.FixedInfo->dwProductVersionLS;
|
||
|
*(((PDWORD)(&binProdVer)) + 1) = pMgr->ver.FixedInfo->dwProductVersionMS;
|
||
|
|
||
|
CopyMemory(pFileAttr->wValue, &binProdVer, 4 * sizeof(WORD));
|
||
|
|
||
|
wsprintf(szBuffer, "%d.%d.%d.%d",
|
||
|
pFileAttr->wValue[3],
|
||
|
pFileAttr->wValue[2],
|
||
|
pFileAttr->wValue[1],
|
||
|
pFileAttr->wValue[0]);
|
||
|
|
||
|
pFileAttr->wMask[0] = pFileAttr->wMask[1] = pFileAttr->wMask[2] = pFileAttr->wMask[3] = 0xFFFF;
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFileDateHi(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
pFileAttr->dwValue = pMgr->ver.FixedInfo->dwFileDateMS;
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFileDateLo(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
pFileAttr->dwValue = pMgr->ver.FixedInfo->dwFileDateLS;
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFileVerOs(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
pFileAttr->dwValue = pMgr->ver.FixedInfo->dwFileOS;
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL QueryFileVerType(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
|
||
|
pFileAttr->dwValue = pMgr->ver.FixedInfo->dwFileType;
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
// ComputeFileCheckSum
|
||
|
//
|
||
|
// computes the check sum for 4096 bytes starting at offset 512.
|
||
|
// The offset and the size of the chunk are modified if the
|
||
|
// file size is too small.
|
||
|
DWORD
|
||
|
ComputeFileCheckSum(
|
||
|
PSTR pszFile,
|
||
|
WIN32_FIND_DATA* pFindData)
|
||
|
{
|
||
|
INT i,size = 4096;
|
||
|
DWORD startAddr = 512;
|
||
|
HANDLE fileHandle = INVALID_HANDLE_VALUE;
|
||
|
PCHAR buffer = NULL;
|
||
|
DWORD checkSum = 0;
|
||
|
DWORD dontCare;
|
||
|
|
||
|
if (pFindData->nFileSizeLow < (ULONG)size) {
|
||
|
//
|
||
|
// File size is less than 4096. We set the start address to 0 and set the size for the checksum
|
||
|
// to the actual file size.
|
||
|
//
|
||
|
startAddr = 0;
|
||
|
size = pFindData->nFileSizeLow;
|
||
|
|
||
|
} else if (startAddr + size > pFindData->nFileSizeLow) {
|
||
|
//
|
||
|
// File size is too small. We set the start address so that size of checksum can be 4096 bytes
|
||
|
//
|
||
|
startAddr = pFindData->nFileSizeLow - size;
|
||
|
}
|
||
|
|
||
|
if (size <= 3) {
|
||
|
//
|
||
|
// we need at least 3 bytes to be able to do something here.
|
||
|
//
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
__try {
|
||
|
buffer = (PCHAR)HeapAlloc(GetProcessHeap(), 0, size);
|
||
|
|
||
|
if (buffer == NULL) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
fileHandle = CreateFile(pszFile,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (SetFilePointer(fileHandle, startAddr, NULL, FILE_BEGIN) != startAddr) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (!ReadFile(fileHandle, buffer, size, &dontCare, NULL)) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i<(size - 3); i+=4) {
|
||
|
checkSum += *((PDWORD) (buffer + i));
|
||
|
checkSum = _rotr(checkSum ,1);
|
||
|
}
|
||
|
}
|
||
|
__finally {
|
||
|
if (fileHandle != INVALID_HANDLE_VALUE) {
|
||
|
CloseHandle (fileHandle);
|
||
|
}
|
||
|
if (buffer != NULL) {
|
||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||
|
}
|
||
|
}
|
||
|
return checkSum;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL QueryFileCheckSum(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
WIN32_FIND_DATA findData;
|
||
|
HANDLE findHandle;
|
||
|
char szBuffer[64];
|
||
|
|
||
|
findHandle = FindFirstFile(pMgr->ver.pszFile, &findData);
|
||
|
|
||
|
if (findHandle == INVALID_HANDLE_VALUE) {
|
||
|
|
||
|
LogMsg("QueryFileCheckSum: Cannot find file %s\n",
|
||
|
pMgr->ver.pszFile);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
pFileAttr->dwValue = ComputeFileCheckSum(pMgr->ver.pszFile, &findData);
|
||
|
|
||
|
FindClose(findHandle);
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
// GetImageNtHeader
|
||
|
//
|
||
|
// This function returns the address of the NT Header.
|
||
|
// Returns the address of the NT Header.
|
||
|
PIMAGE_NT_HEADERS
|
||
|
GetImageNtHeader(
|
||
|
IN PVOID Base)
|
||
|
{
|
||
|
PIMAGE_NT_HEADERS NtHeaders;
|
||
|
|
||
|
if (Base != NULL && Base != (PVOID)-1) {
|
||
|
if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) {
|
||
|
NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
|
||
|
if (NtHeaders->Signature == IMAGE_NT_SIGNATURE) {
|
||
|
return NtHeaders;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
GetHeaderCheckSum(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
DWORD* pdwCheckSum)
|
||
|
{
|
||
|
HANDLE fileHandle;
|
||
|
DWORD bytesRead;
|
||
|
IMAGE_DOS_HEADER dh;
|
||
|
LOADED_IMAGE image;
|
||
|
DWORD sign;
|
||
|
PWORD signNE = (PWORD)&sign;
|
||
|
BOOL result = FALSE;
|
||
|
|
||
|
*pdwCheckSum = 0;
|
||
|
|
||
|
fileHandle = CreateFile(pMgr->ver.pszFile,
|
||
|
GENERIC_READ,
|
||
|
FILE_SHARE_READ,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
__try {
|
||
|
__try {
|
||
|
if (!ReadFile(fileHandle, &dh, sizeof(IMAGE_DOS_HEADER), &bytesRead, NULL) ||
|
||
|
bytesRead != sizeof (IMAGE_DOS_HEADER)) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (dh.e_magic != IMAGE_DOS_SIGNATURE) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (SetFilePointer(fileHandle, dh.e_lfanew, NULL, FILE_BEGIN) != (DWORD)dh.e_lfanew) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
if (!ReadFile(fileHandle, &sign, sizeof(DWORD), &bytesRead, NULL) ||
|
||
|
bytesRead != sizeof (DWORD)) {
|
||
|
__leave;
|
||
|
}
|
||
|
|
||
|
CloseHandle(fileHandle);
|
||
|
fileHandle = INVALID_HANDLE_VALUE;
|
||
|
|
||
|
if (sign == IMAGE_NT_SIGNATURE) {
|
||
|
|
||
|
if (MapAndLoad(pMgr->ver.pszFile, NULL, &image, FALSE, TRUE)) {
|
||
|
|
||
|
PIMAGE_NT_HEADERS NtHeaders;
|
||
|
|
||
|
__try {
|
||
|
|
||
|
NtHeaders = GetImageNtHeader(image.MappedAddress);
|
||
|
|
||
|
if (NtHeaders != NULL) {
|
||
|
if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
|
||
|
*pdwCheckSum = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum;
|
||
|
} else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
|
||
|
*pdwCheckSum = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.CheckSum;
|
||
|
}
|
||
|
result = TRUE;
|
||
|
}
|
||
|
}
|
||
|
__except (1) {
|
||
|
LogMsg("Access violation while examining %s\n", pMgr->ver.pszFile);
|
||
|
}
|
||
|
|
||
|
UnMapAndLoad(&image);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
__finally {
|
||
|
if (fileHandle != INVALID_HANDLE_VALUE) {
|
||
|
CloseHandle(fileHandle);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||
|
CloseHandle(fileHandle);
|
||
|
result = FALSE;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFilePECheckSum(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
char szBuffer[64];
|
||
|
|
||
|
if (!GetHeaderCheckSum(pMgr, &pFileAttr->dwValue) || pFileAttr->dwValue == 0) {
|
||
|
LogMsg("QueryFilePECheckSum: Cannot get the header check sum for %s\n",
|
||
|
pMgr->ver.pszFile);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryCompanyName(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("COMPANYNAME");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryProductVersion(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("PRODUCTVERSION");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryProductName(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("PRODUCTNAME");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFileDescription(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("FILEDESCRIPTION");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryFileVersion(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("FILEVERSION");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryOriginalFileName(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("ORIGINALFILENAME");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryInternalName(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("INTERNALNAME");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
QueryLegalCopyright(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
FAIL_IF_NO_VERSION();
|
||
|
QUERYENTRY("LEGALCOPYRIGHT");
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
Query16BitDescription(
|
||
|
PFILEATTRMGR pMgr,
|
||
|
PFILEATTRVALUE pFileAttr)
|
||
|
{
|
||
|
//char szBuffer[64];
|
||
|
|
||
|
pFileAttr->dwValue = 0;
|
||
|
//wsprintf(szBuffer, "0x%X", pFileAttr->dwValue);
|
||
|
|
||
|
return FALSE;
|
||
|
|
||
|
//ALLOC_VALUE_AND_RETURN();
|
||
|
}
|
||
|
|