test: checksum.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# checksum.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1991  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     imagedir.c
    00008
    00009 Abstract:
    00010
    00011     The module contains the code to translate an image directory type to
    00012     the address of the data for that entry.
    00013
    00014 Author:
    00015
    00016     Steve Wood (stevewo) 18-Aug-1989
    00017
    00018 Environment:
    00019
    00020     User Mode or Kernel Mode
    00021
    00022 Revision History:
    00023
    00024 --*/
    00025
    00026 #include "ntrtlp.h"
    00027
    00028 //
    00029 // Define forward referenced prootypes.
    00030 //
    00031
    00032 USHORT
    00033 ChkSum(
    00034     ULONG PartialSum,
    00035     PUSHORT Source,
    00036     ULONG Length
    00037     );
    00038
    00039 #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
    00040 #if !defined(_IA64_)
    00041 #pragma alloc_text(PAGE,ChkSum)
    00042 #endif // !defined(_IA64_)
    00043 #pragma alloc_text(PAGE,LdrVerifyMappedImageMatchesChecksum)
    00044 #endif
    00045
    00046 #if !defined(_IA64_)
    00047 USHORT
    00048 ChkSum(
    00049     ULONG PartialSum,
    00050     PUSHORT Source,
    00051     ULONG Length
    00052     )
    00053
    00054 /*++
    00055
    00056 Routine Description:
    00057
    00058     Compute a partial checksum on a portion of an imagefile.
    00059
    00060 Arguments:
    00061
    00062     PartialSum - Supplies the initial checksum value.
    00063
    00064     Sources - Supplies a pointer to the array of words for which the
    00065         checksum is computed.
    00066
    00067     Length - Supplies the length of the array in words.
    00068
    00069 Return Value:
    00070
    00071     The computed checksum value is returned as the function value.
    00072
    00073 --*/
    00074
    00075 {
    00076
    00077     RTL_PAGED_CODE();
    00078
    00079     //
    00080     // Compute the word wise checksum allowing carries to occur into the
    00081     // high order half of the checksum longword.
    00082     //
    00083
    00084     while (Length--) {
    00085         PartialSum += *Source++;
    00086         PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff);
    00087     }
    00088
    00089     //
    00090     // Fold final carry into a single word result and return the resultant
    00091     // value.
    00092     //
    00093
    00094     return (USHORT)(((PartialSum >> 16) + PartialSum) & 0xffff);
    00095 }
    00096 #endif // !defined(_IA64_)
    00097
    00098 BOOLEAN
    00099 LdrVerifyMappedImageMatchesChecksum (
    00100     IN PVOID BaseAddress,
    00101     IN ULONG FileLength
    00102     )
    00103
    00104 /*++
    00105
    00106 Routine Description:
    00107
    00108     This functions computes the checksum of an image mapped as a data file.
    00109
    00110 Arguments:
    00111
    00112     BaseAddress - Supplies a pointer to the base of the mapped file.
    00113
    00114     FileLength - Supplies the length of the file in bytes.
    00115
    00116 Return Value:
    00117
    00118     TRUE - The checksum stored in the image matches the checksum of the data.
    00119
    00120     FALSE - The checksum in the image is not correct.
    00121
    00122 --*/
    00123
    00124 {
    00125
    00126     PUSHORT AdjustSum;
    00127     PIMAGE_NT_HEADERS NtHeaders;
    00128     USHORT PartialSum;
    00129     ULONG HeaderSum;
    00130     ULONG CheckSum;
    00131
    00132     RTL_PAGED_CODE();
    00133
    00134     //
    00135     // Compute the checksum of the file and zero the header checksum value.
    00136     //
    00137
    00138     HeaderSum = 0;
    00139     PartialSum = ChkSum(0, (PUSHORT)BaseAddress, (FileLength + 1) >> 1);
    00140
    00141     //
    00142     // If the file is an image file, then subtract the two checksum words
    00143     // in the optional header from the computed checksum before adding
    00144     // the file length, and set the value of the header checksum.
    00145     //
    00146
    00147     NtHeaders = RtlImageNtHeader(BaseAddress);
    00148     if (NtHeaders != NULL) {
    00149         HeaderSum = NtHeaders->OptionalHeader.CheckSum;
    00150
    00151 #ifndef NTOS_KERNEL_RUNTIME
    00152         //
    00153         // On Nt 3.1 and 3.5, we allowed printer drivers with 0 checksums into
    00154         // csrss unintentionally. This means that we must allow this forever.
    00155         // I don't want to allow this for kernel mode drivers, so I will only
    00156         // allow 0 checksums of the high order bit is clear ?
    00157         //
    00158
    00159
    00160         if ( HeaderSum == 0 ) {
    00161             return TRUE;
    00162         }
    00163 #endif // NTOS_KERNEL_RUNTIME
    00164
    00165         AdjustSum = (PUSHORT)(&NtHeaders->OptionalHeader.CheckSum);
    00166         PartialSum -= (PartialSum < AdjustSum[0]);
    00167         PartialSum -= AdjustSum[0];
    00168         PartialSum -= (PartialSum < AdjustSum[1]);
    00169         PartialSum -= AdjustSum[1];
    00170     } else {
    00171         PartialSum = 0;
    00172         HeaderSum = FileLength;
    00173     }
    00174
    00175     //
    00176     // Compute the final checksum value as the sum of the paritial checksum
    00177     // and the file length.
    00178     //
    00179
    00180     CheckSum = (ULONG)PartialSum + FileLength;
    00181     return (CheckSum == HeaderSum);
    00182 }