|
|
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.