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.

279 lines
7.3 KiB

  1. //
  2. // MODULE: CRC.CPP
  3. //
  4. // PURPOSE: Cache File CRC Calculator Class
  5. //
  6. // PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
  7. //
  8. // COMPANY: Saltmine Creative, Inc. (206)-284-7511 [email protected]
  9. //
  10. // AUTHOR: Richard Meadows
  11. //
  12. // ORIGINAL DATE: 8/7/97
  13. //
  14. // NOTES:
  15. // 1.
  16. //
  17. // Version Date By Comments
  18. //--------------------------------------------------------------------
  19. // V0.2 8/7/97 RM Local Version for Memphis
  20. // V0.3 04/09/98 JM/OK+ Local Version for NT5
  21. //
  22. #include "stdafx.h"
  23. #include "crc.h"
  24. #include <stdlib.h>
  25. #include <memory.h>
  26. #include "ChmRead.h"
  27. CCRC::CCRC() : POLYNOMIAL(0x04C11DB7)
  28. {
  29. dwCrcTable[0] = 0;
  30. BuildCrcTable();
  31. return;
  32. }
  33. DWORD CCRC::DscEncode(LPCTSTR szDsc)
  34. {
  35. DWORD dwBytesRead;
  36. DWORD dwCRCValue;
  37. const int BUF_SIZE = 4096;
  38. char sznInputFileBuf[BUF_SIZE + 1];
  39. if (NULL == szDsc)
  40. {
  41. CGenException *pErr = new CGenException;
  42. pErr->m_OsError = 0;
  43. pErr->m_strError = _T("The dsc file was not specified.");
  44. throw pErr;
  45. }
  46. // Read the source file.
  47. HANDLE hFile = CreateFile(szDsc,
  48. GENERIC_READ,
  49. FILE_SHARE_READ,
  50. NULL,
  51. OPEN_EXISTING,
  52. FILE_FLAG_SEQUENTIAL_SCAN,
  53. NULL);
  54. if (INVALID_HANDLE_VALUE == hFile)
  55. {
  56. CString strErr;
  57. CGenException *pErr = new CGenException;
  58. pErr->m_OsError = GetLastError();
  59. strErr = GlobFormatMessage(pErr->m_OsError);
  60. pErr->m_strError.Format(_T("Dsc file, %s was not opened.\nReason: %s"),
  61. szDsc, (LPCTSTR) strErr);
  62. throw pErr;
  63. }
  64. // Get the crc.
  65. dwCRCValue = 0xFFFFFFFF;
  66. do
  67. {
  68. if (!ReadFile(hFile, (LPVOID) sznInputFileBuf, BUF_SIZE, &dwBytesRead, NULL))
  69. {
  70. CString strErr;
  71. CGenException *pErr = new CGenException;
  72. pErr->m_OsError = GetLastError();
  73. strErr = GlobFormatMessage(pErr->m_OsError);
  74. pErr->m_strError.Format(_T("The dsc file, %s could not be read.\nReason: %s"),
  75. szDsc, (LPCTSTR) strErr);
  76. CloseHandle(hFile);
  77. throw pErr;
  78. }
  79. sznInputFileBuf[dwBytesRead] = NULL;
  80. dwCRCValue = ComputeCRC(sznInputFileBuf, dwBytesRead, dwCRCValue);
  81. } while(BUF_SIZE == dwBytesRead);
  82. CloseHandle(hFile);
  83. return dwCRCValue;
  84. }
  85. void CCRC::AppendCRC(LPCTSTR szCache, DWORD dwCRCValue)
  86. {
  87. DWORD dwBytesWritten;
  88. // Open the cache file.
  89. HANDLE hDestFile = CreateFile(szCache,
  90. GENERIC_WRITE,
  91. 0, // No Sharing.
  92. NULL,
  93. OPEN_EXISTING,
  94. FILE_FLAG_WRITE_THROUGH |
  95. FILE_FLAG_SEQUENTIAL_SCAN,
  96. NULL);
  97. if (INVALID_HANDLE_VALUE == hDestFile)
  98. {
  99. CString strErr;
  100. CGenException *pErr = new CGenException;
  101. pErr->m_OsError = GetLastError();
  102. strErr = GlobFormatMessage(pErr->m_OsError);
  103. pErr->m_strError.Format(_T("The cache file, %s could not be opened.\nReason: %s"),
  104. szCache, (LPCTSTR) strErr);
  105. throw pErr;
  106. }
  107. if (0xFFFFFFFF == SetFilePointer(hDestFile, 0, NULL, FILE_END))
  108. {
  109. CString strErr;
  110. CGenException *pErr = new CGenException;
  111. pErr->m_OsError = GetLastError();
  112. strErr = GlobFormatMessage(pErr->m_OsError);
  113. pErr->m_strError.Format(_T("Seek to end of the cache file, %s failed.\nReason: %s"),
  114. szCache, (LPCTSTR) strErr);
  115. CloseHandle(hDestFile);
  116. throw pErr;
  117. }
  118. // Append crc value.
  119. if (!WriteFile(hDestFile, (LPVOID) &dwCRCValue, 4, &dwBytesWritten, NULL))
  120. {
  121. CString strErr;
  122. CGenException *pErr = new CGenException;
  123. pErr->m_OsError = GetLastError();
  124. strErr = GlobFormatMessage(pErr->m_OsError);
  125. pErr->m_strError.Format(_T("The crc value was not appened to cache file %s.\nReason: %s"),
  126. szCache, (LPCTSTR) strErr);
  127. CloseHandle(hDestFile);
  128. throw pErr;
  129. }
  130. CloseHandle(hDestFile);
  131. if (4 != dwBytesWritten)
  132. {
  133. CString strErr;
  134. CGenException *pErr = new CGenException;
  135. pErr->m_OsError = GetLastError();
  136. strErr = GlobFormatMessage(pErr->m_OsError);
  137. pErr->m_strError.Format(_T("%d bytes of the crc were not appended to the cache file %s.Reason: %s"),
  138. 4 - dwBytesWritten, szCache, (LPCTSTR) strErr);
  139. throw pErr;
  140. }
  141. return;
  142. }
  143. bool CCRC::Decode(LPCTSTR szDsc, LPCTSTR szCache, const CString& strCacheFileWithinCHM)
  144. {
  145. DWORD dwDecodeFileCrc;
  146. DWORD dwComputedCrc;
  147. DWORD dwBytesRead;
  148. DWORD dwLen;
  149. char sznDecodeBytes[5] = {0};
  150. bool bRet = true;
  151. bool bUseCHM = strCacheFileWithinCHM.GetLength() != 0;
  152. if (NULL == szDsc)
  153. {
  154. CGenException *pErr = new CGenException;
  155. pErr->m_OsError = 0;
  156. pErr->m_strError = _T("The source file was not specified.");
  157. throw pErr;
  158. }
  159. if (NULL == szCache)
  160. {
  161. CGenException *pErr = new CGenException;
  162. pErr->m_OsError = 0;
  163. pErr->m_strError = _T("The destination file was not specified.");
  164. throw pErr;
  165. }
  166. if (bUseCHM)
  167. {
  168. void* buf =NULL;
  169. if (S_OK != ::ReadChmFile(szCache, strCacheFileWithinCHM, &buf, &dwBytesRead))
  170. {
  171. CGenException *pErr = new CGenException;
  172. pErr->m_OsError = 0;
  173. pErr->m_strError = _T("Can not read cache from the CHM file.");
  174. throw pErr;
  175. }
  176. if (dwBytesRead < 5)
  177. return false;
  178. memcpy(sznDecodeBytes, (char*)buf + dwBytesRead - 4, 4);
  179. }
  180. else
  181. {
  182. // Read the source file.
  183. HANDLE hDecodeFile = CreateFile(szCache,
  184. GENERIC_READ,
  185. FILE_SHARE_READ,
  186. NULL,
  187. OPEN_EXISTING,
  188. FILE_FLAG_SEQUENTIAL_SCAN,
  189. NULL);
  190. if (INVALID_HANDLE_VALUE == hDecodeFile)
  191. { // Should continue as if the check sums did not match.
  192. return false;
  193. }
  194. // Return false if the file is shorter than 1 byte + crc length.
  195. dwLen = GetFileSize(hDecodeFile, NULL);
  196. if (0xFFFFFFFF == dwLen)
  197. {
  198. CGenException *pExc = new CGenException;
  199. pExc->m_OsError = GetLastError();
  200. pExc->m_strOsMsg = GlobFormatMessage(pExc->m_OsError);
  201. pExc->m_strError.Format(
  202. _T("Could not get the size of cache file %s.\nReason: %s"),
  203. szCache, (LPCTSTR) pExc->m_strOsMsg);
  204. CloseHandle(hDecodeFile);
  205. throw pExc;
  206. }
  207. if (dwLen < 5)
  208. {
  209. CloseHandle(hDecodeFile);
  210. return false;
  211. }
  212. // Seek to end and backup 4 bytes.
  213. if (0xFFFFFFFF == SetFilePointer(hDecodeFile, -4, NULL, FILE_END))
  214. {
  215. CString strErr;
  216. CGenException *pErr = new CGenException;
  217. pErr->m_OsError = GetLastError();
  218. strErr = GlobFormatMessage(pErr->m_OsError);
  219. pErr->m_strError.Format(_T("Seek to end of the cache file, %s failed.\nReason: %s"),
  220. szCache, (LPCTSTR) strErr);
  221. CloseHandle(hDecodeFile);
  222. throw pErr;
  223. }
  224. if (!ReadFile(hDecodeFile, (LPVOID) sznDecodeBytes, 4, &dwBytesRead, NULL))
  225. {
  226. CString strErr;
  227. CGenException *pErr = new CGenException;
  228. pErr->m_OsError = GetLastError();
  229. strErr = GlobFormatMessage(pErr->m_OsError);
  230. pErr->m_strError.Format(_T("The cache file, %s could not be read.\nReason: %s"),
  231. szDsc, (LPCTSTR) strErr);
  232. CloseHandle(hDecodeFile);
  233. throw pErr;
  234. }
  235. if (4 != dwBytesRead)
  236. {
  237. CString strErr;
  238. CGenException *pErr = new CGenException;
  239. pErr->m_OsError = GetLastError();
  240. strErr = GlobFormatMessage(pErr->m_OsError);
  241. pErr->m_strError.Format(_T("%d bytes of the cache file were not read.\nReason: %s"),
  242. 4 - dwBytesRead, szDsc, (LPCTSTR) strErr);
  243. CloseHandle(hDecodeFile);
  244. throw pErr;
  245. }
  246. CloseHandle(hDecodeFile);
  247. }
  248. // Read the crc.
  249. sznDecodeBytes[4] = NULL;
  250. DWORD byte;
  251. byte = (BYTE) sznDecodeBytes[0];
  252. dwDecodeFileCrc = byte;
  253. byte = (BYTE) sznDecodeBytes[1];
  254. byte <<= 8;
  255. dwDecodeFileCrc |= byte;
  256. byte = (BYTE) sznDecodeBytes[2];
  257. byte <<= 16;
  258. dwDecodeFileCrc |= byte;
  259. byte = (BYTE) sznDecodeBytes[3];
  260. byte <<= 24;
  261. dwDecodeFileCrc |= byte;
  262. // Get the crc value.
  263. dwComputedCrc = DscEncode(szDsc);
  264. if (dwComputedCrc != dwDecodeFileCrc)
  265. bRet = false;
  266. return bRet;
  267. }