mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
7.3 KiB
280 lines
7.3 KiB
//
|
|
// MODULE: CRC.CPP
|
|
//
|
|
// PURPOSE: Cache File CRC Calculator Class
|
|
//
|
|
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
|
|
//
|
|
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
|
|
//
|
|
// AUTHOR: Richard Meadows
|
|
//
|
|
// ORIGINAL DATE: 8/7/97
|
|
//
|
|
// NOTES:
|
|
// 1.
|
|
//
|
|
// Version Date By Comments
|
|
//--------------------------------------------------------------------
|
|
// V0.2 8/7/97 RM Local Version for Memphis
|
|
// V0.3 04/09/98 JM/OK+ Local Version for NT5
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "crc.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
|
|
#include "ChmRead.h"
|
|
|
|
CCRC::CCRC() : POLYNOMIAL(0x04C11DB7)
|
|
{
|
|
dwCrcTable[0] = 0;
|
|
BuildCrcTable();
|
|
return;
|
|
}
|
|
|
|
DWORD CCRC::DscEncode(LPCTSTR szDsc)
|
|
{
|
|
DWORD dwBytesRead;
|
|
DWORD dwCRCValue;
|
|
const int BUF_SIZE = 4096;
|
|
char sznInputFileBuf[BUF_SIZE + 1];
|
|
if (NULL == szDsc)
|
|
{
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = 0;
|
|
pErr->m_strError = _T("The dsc file was not specified.");
|
|
throw pErr;
|
|
}
|
|
// Read the source file.
|
|
HANDLE hFile = CreateFile(szDsc,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_SEQUENTIAL_SCAN,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hFile)
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("Dsc file, %s was not opened.\nReason: %s"),
|
|
szDsc, (LPCTSTR) strErr);
|
|
throw pErr;
|
|
}
|
|
// Get the crc.
|
|
dwCRCValue = 0xFFFFFFFF;
|
|
do
|
|
{
|
|
if (!ReadFile(hFile, (LPVOID) sznInputFileBuf, BUF_SIZE, &dwBytesRead, NULL))
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("The dsc file, %s could not be read.\nReason: %s"),
|
|
szDsc, (LPCTSTR) strErr);
|
|
CloseHandle(hFile);
|
|
throw pErr;
|
|
}
|
|
sznInputFileBuf[dwBytesRead] = NULL;
|
|
dwCRCValue = ComputeCRC(sznInputFileBuf, dwBytesRead, dwCRCValue);
|
|
} while(BUF_SIZE == dwBytesRead);
|
|
CloseHandle(hFile);
|
|
return dwCRCValue;
|
|
}
|
|
|
|
void CCRC::AppendCRC(LPCTSTR szCache, DWORD dwCRCValue)
|
|
{
|
|
DWORD dwBytesWritten;
|
|
// Open the cache file.
|
|
HANDLE hDestFile = CreateFile(szCache,
|
|
GENERIC_WRITE,
|
|
0, // No Sharing.
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_WRITE_THROUGH |
|
|
FILE_FLAG_SEQUENTIAL_SCAN,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hDestFile)
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("The cache file, %s could not be opened.\nReason: %s"),
|
|
szCache, (LPCTSTR) strErr);
|
|
throw pErr;
|
|
}
|
|
if (0xFFFFFFFF == SetFilePointer(hDestFile, 0, NULL, FILE_END))
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("Seek to end of the cache file, %s failed.\nReason: %s"),
|
|
szCache, (LPCTSTR) strErr);
|
|
CloseHandle(hDestFile);
|
|
throw pErr;
|
|
}
|
|
// Append crc value.
|
|
if (!WriteFile(hDestFile, (LPVOID) &dwCRCValue, 4, &dwBytesWritten, NULL))
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("The crc value was not appened to cache file %s.\nReason: %s"),
|
|
szCache, (LPCTSTR) strErr);
|
|
CloseHandle(hDestFile);
|
|
throw pErr;
|
|
}
|
|
CloseHandle(hDestFile);
|
|
if (4 != dwBytesWritten)
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("%d bytes of the crc were not appended to the cache file %s.Reason: %s"),
|
|
4 - dwBytesWritten, szCache, (LPCTSTR) strErr);
|
|
throw pErr;
|
|
}
|
|
return;
|
|
}
|
|
|
|
bool CCRC::Decode(LPCTSTR szDsc, LPCTSTR szCache, const CString& strCacheFileWithinCHM)
|
|
{
|
|
DWORD dwDecodeFileCrc;
|
|
DWORD dwComputedCrc;
|
|
DWORD dwBytesRead;
|
|
DWORD dwLen;
|
|
char sznDecodeBytes[5] = {0};
|
|
bool bRet = true;
|
|
bool bUseCHM = strCacheFileWithinCHM.GetLength() != 0;
|
|
|
|
if (NULL == szDsc)
|
|
{
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = 0;
|
|
pErr->m_strError = _T("The source file was not specified.");
|
|
throw pErr;
|
|
}
|
|
if (NULL == szCache)
|
|
{
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = 0;
|
|
pErr->m_strError = _T("The destination file was not specified.");
|
|
throw pErr;
|
|
}
|
|
|
|
if (bUseCHM)
|
|
{
|
|
void* buf =NULL;
|
|
|
|
if (S_OK != ::ReadChmFile(szCache, strCacheFileWithinCHM, &buf, &dwBytesRead))
|
|
{
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = 0;
|
|
pErr->m_strError = _T("Can not read cache from the CHM file.");
|
|
throw pErr;
|
|
}
|
|
|
|
if (dwBytesRead < 5)
|
|
return false;
|
|
|
|
memcpy(sznDecodeBytes, (char*)buf + dwBytesRead - 4, 4);
|
|
}
|
|
else
|
|
{
|
|
// Read the source file.
|
|
HANDLE hDecodeFile = CreateFile(szCache,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_SEQUENTIAL_SCAN,
|
|
NULL);
|
|
if (INVALID_HANDLE_VALUE == hDecodeFile)
|
|
{ // Should continue as if the check sums did not match.
|
|
return false;
|
|
}
|
|
// Return false if the file is shorter than 1 byte + crc length.
|
|
dwLen = GetFileSize(hDecodeFile, NULL);
|
|
if (0xFFFFFFFF == dwLen)
|
|
{
|
|
CGenException *pExc = new CGenException;
|
|
pExc->m_OsError = GetLastError();
|
|
pExc->m_strOsMsg = GlobFormatMessage(pExc->m_OsError);
|
|
pExc->m_strError.Format(
|
|
_T("Could not get the size of cache file %s.\nReason: %s"),
|
|
szCache, (LPCTSTR) pExc->m_strOsMsg);
|
|
CloseHandle(hDecodeFile);
|
|
throw pExc;
|
|
}
|
|
if (dwLen < 5)
|
|
{
|
|
CloseHandle(hDecodeFile);
|
|
return false;
|
|
}
|
|
// Seek to end and backup 4 bytes.
|
|
if (0xFFFFFFFF == SetFilePointer(hDecodeFile, -4, NULL, FILE_END))
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("Seek to end of the cache file, %s failed.\nReason: %s"),
|
|
szCache, (LPCTSTR) strErr);
|
|
CloseHandle(hDecodeFile);
|
|
throw pErr;
|
|
}
|
|
if (!ReadFile(hDecodeFile, (LPVOID) sznDecodeBytes, 4, &dwBytesRead, NULL))
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("The cache file, %s could not be read.\nReason: %s"),
|
|
szDsc, (LPCTSTR) strErr);
|
|
CloseHandle(hDecodeFile);
|
|
throw pErr;
|
|
}
|
|
if (4 != dwBytesRead)
|
|
{
|
|
CString strErr;
|
|
CGenException *pErr = new CGenException;
|
|
pErr->m_OsError = GetLastError();
|
|
strErr = GlobFormatMessage(pErr->m_OsError);
|
|
pErr->m_strError.Format(_T("%d bytes of the cache file were not read.\nReason: %s"),
|
|
4 - dwBytesRead, szDsc, (LPCTSTR) strErr);
|
|
CloseHandle(hDecodeFile);
|
|
throw pErr;
|
|
}
|
|
CloseHandle(hDecodeFile);
|
|
}
|
|
|
|
// Read the crc.
|
|
sznDecodeBytes[4] = NULL;
|
|
DWORD byte;
|
|
byte = (BYTE) sznDecodeBytes[0];
|
|
dwDecodeFileCrc = byte;
|
|
byte = (BYTE) sznDecodeBytes[1];
|
|
byte <<= 8;
|
|
dwDecodeFileCrc |= byte;
|
|
byte = (BYTE) sznDecodeBytes[2];
|
|
byte <<= 16;
|
|
dwDecodeFileCrc |= byte;
|
|
byte = (BYTE) sznDecodeBytes[3];
|
|
byte <<= 24;
|
|
dwDecodeFileCrc |= byte;
|
|
// Get the crc value.
|
|
dwComputedCrc = DscEncode(szDsc);
|
|
if (dwComputedCrc != dwDecodeFileCrc)
|
|
bRet = false;
|
|
return bRet;
|
|
}
|