Source code of Windows XP (NT5)
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

//
// 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;
}