Leaked source code of windows server 2003
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.

399 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. checksum.c
  5. Abstract:
  6. This module implements a function for computing the checksum of an
  7. image file. It will also compute the checksum of other files as well.
  8. Author:
  9. David N. Cutler (davec) 21-Mar-1993
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <private.h>
  16. //
  17. // Define checksum routine prototype.
  18. //
  19. #ifdef __cplusplus
  20. extern "C"
  21. #endif
  22. USHORT
  23. ChkSum(
  24. DWORD PartialSum,
  25. PUSHORT Source,
  26. DWORD Length
  27. );
  28. PIMAGE_NT_HEADERS
  29. CheckSumMappedFile (
  30. LPVOID BaseAddress,
  31. DWORD FileLength,
  32. LPDWORD HeaderSum,
  33. LPDWORD CheckSum
  34. )
  35. /*++
  36. Routine Description:
  37. This functions computes the checksum of a mapped file.
  38. Arguments:
  39. BaseAddress - Supplies a pointer to the base of the mapped file.
  40. FileLength - Supplies the length of the file in bytes.
  41. HeaderSum - Suppllies a pointer to a variable that receives the checksum
  42. from the image file, or zero if the file is not an image file.
  43. CheckSum - Supplies a pointer to the variable that receive the computed
  44. checksum.
  45. Return Value:
  46. None.
  47. --*/
  48. {
  49. PUSHORT AdjustSum;
  50. PIMAGE_NT_HEADERS NtHeaders;
  51. USHORT PartialSum;
  52. PBYTE pbyte;
  53. //
  54. // Compute the checksum of the file and zero the header checksum value.
  55. //
  56. *CheckSum = 0;
  57. *HeaderSum = 0;
  58. PartialSum = ChkSum(0, (PUSHORT)BaseAddress, FileLength >> 1);
  59. //
  60. // If the file is an image file, then subtract the two checksum words
  61. // in the optional header from the computed checksum before adding
  62. // the file length, and set the value of the header checksum.
  63. //
  64. __try {
  65. NtHeaders = RtlpImageNtHeader(BaseAddress);
  66. } __except(EXCEPTION_EXECUTE_HANDLER) {
  67. NtHeaders = NULL;
  68. }
  69. if ((NtHeaders != NULL) && (NtHeaders != BaseAddress)) {
  70. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  71. *HeaderSum = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum;
  72. AdjustSum = (PUSHORT)(&((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum);
  73. } else
  74. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  75. *HeaderSum = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.CheckSum;
  76. AdjustSum = (PUSHORT)(&((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.CheckSum);
  77. } else {
  78. return(NULL);
  79. }
  80. PartialSum -= (PartialSum < AdjustSum[0]);
  81. PartialSum -= AdjustSum[0];
  82. PartialSum -= (PartialSum < AdjustSum[1]);
  83. PartialSum -= AdjustSum[1];
  84. }
  85. // add the last byte, if needed
  86. if (FileLength % 2) {
  87. pbyte = (PBYTE)BaseAddress + FileLength - 1;
  88. PartialSum += *pbyte;
  89. PartialSum = (PartialSum >> 16) + (PartialSum & 0xFFFF);
  90. }
  91. //
  92. // Compute the final checksum value as the sum of the paritial checksum
  93. // and the file length.
  94. //
  95. *CheckSum = (DWORD)PartialSum + FileLength;
  96. return NtHeaders;
  97. }
  98. DWORD
  99. MapFileAndCheckSumW(
  100. PWSTR Filename,
  101. LPDWORD HeaderSum,
  102. LPDWORD CheckSum
  103. )
  104. /*++
  105. Routine Description:
  106. This functions maps the specified file and computes the checksum of
  107. the file.
  108. Arguments:
  109. Filename - Supplies a pointer to the name of the file whose checksum
  110. is computed.
  111. HeaderSum - Supplies a pointer to a variable that receives the checksum
  112. from the image file, or zero if the file is not an image file.
  113. CheckSum - Supplies a pointer to the variable that receive the computed
  114. checksum.
  115. Return Value:
  116. 0 if successful, else error number.
  117. --*/
  118. {
  119. #ifndef UNICODE_RULES
  120. CHAR FileNameA[ MAX_PATH ];
  121. // Convert the file name to Ansi and call the Ansi version
  122. // of this function.
  123. if (WideCharToMultiByte(
  124. CP_ACP,
  125. 0,
  126. Filename,
  127. -1,
  128. FileNameA,
  129. MAX_PATH,
  130. NULL,
  131. NULL ) ) {
  132. return MapFileAndCheckSumA(FileNameA, HeaderSum, CheckSum);
  133. }
  134. return CHECKSUM_UNICODE_FAILURE;
  135. #else // UNICODE_RULES
  136. HANDLE FileHandle, MappingHandle;
  137. LPVOID BaseAddress;
  138. DWORD FileLength;
  139. //
  140. // Open the file for read access
  141. //
  142. FileHandle = CreateFileW(
  143. Filename,
  144. GENERIC_READ,
  145. FILE_SHARE_READ | FILE_SHARE_WRITE,
  146. NULL,
  147. OPEN_EXISTING,
  148. FILE_ATTRIBUTE_NORMAL,
  149. NULL );
  150. if (FileHandle == INVALID_HANDLE_VALUE) {
  151. return CHECKSUM_OPEN_FAILURE;
  152. }
  153. //
  154. // Create a file mapping, map a view of the file into memory,
  155. // and close the file mapping handle.
  156. //
  157. MappingHandle = CreateFileMapping(FileHandle,
  158. NULL,
  159. PAGE_READONLY,
  160. 0,
  161. 0,
  162. NULL);
  163. if (!MappingHandle) {
  164. CloseHandle( FileHandle );
  165. return CHECKSUM_MAP_FAILURE;
  166. }
  167. //
  168. // Map a view of the file
  169. //
  170. BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_READ, 0, 0, 0);
  171. CloseHandle(MappingHandle);
  172. if (BaseAddress == NULL) {
  173. CloseHandle( FileHandle );
  174. return CHECKSUM_MAPVIEW_FAILURE;
  175. }
  176. //
  177. // Get the length of the file in bytes and compute the checksum.
  178. //
  179. FileLength = GetFileSize( FileHandle, NULL );
  180. CheckSumMappedFile(BaseAddress, FileLength, HeaderSum, CheckSum);
  181. //
  182. // Unmap the view of the file and close file handle.
  183. //
  184. UnmapViewOfFile(BaseAddress);
  185. CloseHandle( FileHandle );
  186. return CHECKSUM_SUCCESS;
  187. #endif // UNICODE_RULES
  188. }
  189. ULONG
  190. MapFileAndCheckSumA (
  191. LPSTR Filename,
  192. LPDWORD HeaderSum,
  193. LPDWORD CheckSum
  194. )
  195. /*++
  196. Routine Description:
  197. This functions maps the specified file and computes the checksum of
  198. the file.
  199. Arguments:
  200. Filename - Supplies a pointer to the name of the file whose checksum
  201. is computed.
  202. HeaderSum - Supplies a pointer to a variable that receives the checksum
  203. from the image file, or zero if the file is not an image file.
  204. CheckSum - Supplies a pointer to the variable that receive the computed
  205. checksum.
  206. Return Value:
  207. 0 if successful, else error number.
  208. --*/
  209. {
  210. #ifdef UNICODE_RULES
  211. WCHAR FileNameW[ MAX_PATH ];
  212. //
  213. // Convert the file name to unicode and call the unicode version
  214. // of this function.
  215. //
  216. if (MultiByteToWideChar(
  217. CP_ACP,
  218. MB_PRECOMPOSED,
  219. Filename,
  220. -1,
  221. FileNameW,
  222. MAX_PATH ) ) {
  223. return MapFileAndCheckSumW(FileNameW, HeaderSum, CheckSum);
  224. }
  225. return CHECKSUM_UNICODE_FAILURE;
  226. #else // UNICODE_RULES
  227. HANDLE FileHandle, MappingHandle;
  228. LPVOID BaseAddress;
  229. DWORD FileLength;
  230. //
  231. // Open the file for read access
  232. //
  233. FileHandle = CreateFileA(
  234. Filename,
  235. GENERIC_READ,
  236. FILE_SHARE_READ | FILE_SHARE_WRITE,
  237. NULL,
  238. OPEN_EXISTING,
  239. FILE_ATTRIBUTE_NORMAL,
  240. NULL );
  241. if (FileHandle == INVALID_HANDLE_VALUE) {
  242. return CHECKSUM_OPEN_FAILURE;
  243. }
  244. //
  245. // Create a file mapping, map a view of the file into memory,
  246. // and close the file mapping handle.
  247. //
  248. MappingHandle = CreateFileMapping(FileHandle,
  249. NULL,
  250. PAGE_READONLY,
  251. 0,
  252. 0,
  253. NULL);
  254. if (!MappingHandle) {
  255. CloseHandle( FileHandle );
  256. return CHECKSUM_MAP_FAILURE;
  257. }
  258. //
  259. // Map a view of the file
  260. //
  261. BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_READ, 0, 0, 0);
  262. CloseHandle(MappingHandle);
  263. if (BaseAddress == NULL) {
  264. CloseHandle( FileHandle );
  265. return CHECKSUM_MAPVIEW_FAILURE;
  266. }
  267. //
  268. // Get the length of the file in bytes and compute the checksum.
  269. //
  270. FileLength = GetFileSize( FileHandle, NULL );
  271. CheckSumMappedFile(BaseAddress, FileLength, HeaderSum, CheckSum);
  272. //
  273. // Unmap the view of the file and close file handle.
  274. //
  275. UnmapViewOfFile(BaseAddress);
  276. CloseHandle( FileHandle );
  277. return CHECKSUM_SUCCESS;
  278. #endif // UNICODE_RULES
  279. }
  280. BOOL
  281. TouchFileTimes(
  282. HANDLE FileHandle,
  283. LPSYSTEMTIME lpSystemTime
  284. )
  285. {
  286. SYSTEMTIME SystemTime;
  287. FILETIME SystemFileTime;
  288. if (lpSystemTime == NULL) {
  289. lpSystemTime = &SystemTime;
  290. GetSystemTime( lpSystemTime );
  291. }
  292. if (SystemTimeToFileTime( lpSystemTime, &SystemFileTime )) {
  293. return SetFileTime( FileHandle, NULL, NULL, &SystemFileTime );
  294. }
  295. else {
  296. return FALSE;
  297. }
  298. }