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