2 * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>
\r
5 // see http://cvs.winehq.com/cvsweb/wine/dlls/imagehlp/modify.c
\r
6 // starting from Revision 1.8
\r
11 namespace Mono.PEToolkit {
\r
13 public sealed class CheckSum {
\r
17 // Never instantiated.
\r
21 public static uint Calc(string peFile)
\r
25 FileInfo pe = new FileInfo(peFile);
\r
27 throw new Exception("CheckSum : Invalid file path.");
\r
30 using (BinaryReader reader = new BinaryReader(pe.OpenRead())) {
\r
31 if (!reader.BaseStream.CanSeek) {
\r
32 throw new Exception("Can't seek.");
\r
35 DOSHeader dosHdr = new DOSHeader();
\r
36 COFFHeader coffHdr = new COFFHeader();
\r
37 PEHeader peHdr = new PEHeader();
\r
39 dosHdr.Read (reader);
\r
40 reader.BaseStream.Position = dosHdr.Lfanew;
\r
41 ExeSignature peSig = (ExeSignature) reader.ReadUInt16();
\r
42 if (peSig != ExeSignature.NT) {
\r
43 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
\r
46 peSig = (ExeSignature) reader.ReadUInt16();
\r
47 if (peSig != ExeSignature.NT2) {
\r
48 throw new BadImageException("Checksum : Invalid image format, cannot find PE signature.");
\r
51 coffHdr.Read(reader);
\r
54 uint oldSum = peHdr.CheckSum;
\r
55 reader.BaseStream.Position = 0;
\r
56 long len = pe.Length;
\r
57 long whole = len >> 1;
\r
60 for (long i = whole; --i >= 0;) {
\r
61 sum += reader.ReadUInt16();
\r
64 sum = hi + (sum & 0xFFFF);
\r
67 if ((len & 1L) != 0) {
\r
68 sum += (uint) reader.ReadByte();
\r
71 sum = hi + (sum & 0xFFFF);
\r
75 // fix low word of checksum
\r
76 lo = oldSum & 0xFFFF;
\r
77 if ((sum & 0xFFFF) >= lo) {
\r
80 sum = (((sum & 0xFFFF) - lo) & 0xFFFF) - 1;
\r
83 // fix high word of checksum
\r
85 if ((sum & 0xFFFF) >= hi) {
\r
88 sum = (((sum & 0xFFFF) - hi) & 0xFFFF) - 1;
\r