Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1032 lines
23 KiB

/***********************************************************************
* Microsoft (R) 32-Bit Incremental Linker
*
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
*
* File: image.cpp
*
* File Comments:
*
* This file contains functions that manipulate the image data structure.
*
***********************************************************************/
#include "link.h"
#include "image_.h" // private definitions
const BYTE DosHeaderArray[] = {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#ifdef JAPAN
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x82, 0xb1,
0x82, 0xcc, 0x83, 0x76, 0x83, 0x8d, 0x83, 0x4f, 0x83, 0x89, 0x83, 0x80, 0x82, 0xcd, 0x81, 0x41,
0x4d, 0x53, 0x2d, 0x44, 0x4f, 0x53, 0x20, 0x83, 0x82, 0x81, 0x5b, 0x83, 0x68, 0x82, 0xc5, 0x82,
0xcd, 0x8e, 0xc0, 0x8d, 0x73, 0x82, 0xc5, 0x82, 0xab, 0x82, 0xdc, 0x82, 0xb9, 0x82, 0xf1, 0x81,
0x42, 0x20, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#else // !JAPAN
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 'T', 'h',
'i', 's', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'c', 'a', 'n', 'n', 'o',
't', ' ', 'b', 'e', ' ', 'r', 'u', 'n', ' ', 'i', 'n', ' ', 'D', 'O', 'S', ' ',
'm', 'o', 'd', 'e', 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif // !JAPAN
0x50, 0x45, 0x00, 0x00 // PE Signature
};
#define cbDosHeaderArray sizeof(DosHeaderArray)
const LONG DosHeaderSize = cbDosHeaderArray;
static const BYTE MacDosHeaderArray[] = {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 'T', 'h',
'i', 's', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm', ' ', 'i', 's', ' ', 'a', ' ',
'M', 'a', 'c', 'i', 'n', 't', 'o', 's', 'h', ' ', 'E', 'X', 'E', 0x2e, 0x0d, 0x0d,
0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x45, 0x00, 0x00 // PE Signature
};
#define cbMacDosHeaderArray sizeof(MacDosHeaderArray);
void
InitImage (
IN OUT PPIMAGE ppimage,
IN IMAGET imaget
)
/*++
Routine Description:
Initializes an IMAGE structure.
Arguments:
ppimage - pointer to an image struct ptr.
Return Value:
None.
--*/
{
// Alloc space & initialize image struct
*ppimage = (PIMAGE) Calloc(1, sizeof(IMAGE));
(*ppimage)->imaget = imaget;
// initialize headers/switches with default values
(*ppimage)->pvBase = *ppimage;
(*ppimage)->MajVersNum = INCDB_MAJVERSNUM;
(*ppimage)->MinVersNum = INCDB_MINVERSNUM;
strcpy((*ppimage)->Sig, INCDB_SIGNATURE);
(*ppimage)->ImgFileHdr = DefImageFileHdr;
(*ppimage)->ImgOptHdr = DefImageOptionalHdr;
(*ppimage)->Switch = DefSwitch;
(*ppimage)->SwitchInfo = DefSwitchInfo;
// initialize the symbol table
InitExternalSymbolTable(&(*ppimage)->pst, celementInChunkSym, cchunkInDirSym);
InitExternalSymbolTable(&(*ppimage)->pstDirective,
celementInChunkDirective, cchunkInDirDirective);
// initialize libs
InitLibs(&(*ppimage)->libs);
// initialize section list
(*ppimage)->secs.psecHead = NULL;
(*ppimage)->secs.ppsecTail = &(*ppimage)->secs.psecHead;
switch (imaget) {
case imagetPE:
(*ppimage)->pbDosHeader = DosHeaderArray;
(*ppimage)->cbDosHeader = cbDosHeaderArray;
(*ppimage)->CbHdr = CbHdrPE;
(*ppimage)->WriteSectionHeader = WriteSectionHeaderPE;
(*ppimage)->WriteHeader = WriteHeaderPE;
break;
case imagetVXD:
(*ppimage)->pbDosHeader = DosHeaderArray;
(*ppimage)->cbDosHeader = cbDosHeaderArray - 4; // no "PE00" needed
(*ppimage)->CbHdr = CbHdrVXD;
(*ppimage)->WriteSectionHeader = WriteSectionHeaderVXD;
(*ppimage)->WriteHeader = WriteHeaderVXD;
InitImageVXD(*ppimage);
break;
default:
assert(FALSE);
}
}
void
SetMacImage(PIMAGE pimage)
{
pimage->pbDosHeader = MacDosHeaderArray;
pimage->cbDosHeader = cbMacDosHeaderArray;
}
// incremental init of image
void
IncrInitImage (
IN OUT PPIMAGE ppimage
)
{
assert(ppimage);
assert(*ppimage);
assert((*ppimage)->pst);
// init symbol tables
IncrInitExternalSymbolTable(&(*ppimage)->pst);
IncrInitExternalSymbolTable(&(*ppimage)->pstDirective);
imodidx = (*ppimage)->imodidx;
}
// get next addr for Win95
PVOID
NextMapAddrWin95 (
PVOID pvCur
)
{
if (!pvCur) {
return (PVOID) 0x90000000;
}
if (pvCur < (PVOID) 0xC0000000) {
return (PVOID) ((BYTE *) pvCur + ILKMAP_MAX);
} else {
return (PVOID) (-1);
}
}
// return map address for NT
PVOID
NextMapAddrWinNT (
PVOID pvCur
)
{
if (!pvCur) {
return (PVOID) 0x3FFF0000;
}
if (pvCur < (PVOID) 0x7FFFFFFF) {
return (PVOID)((BYTE *) pvCur+ILKMAP_MAX);
} else {
return (PVOID)(-1);
}
}
// returns the next map address to try
PVOID
NextMapAddr (
BOOL fOnWin95,
PVOID pvCur
)
{
return (fOnWin95 ? NextMapAddrWin95(pvCur) : NextMapAddrWinNT(pvCur));
}
BOOL
FVerifyEXE(
const char *szExe,
PIMAGE pimage
)
/*++
Routine Description:
Verifies size & timestamp of EXE.
Arguments:
szExe - name of EXE.
pimage - ptr to IMAGE struct.
Return Value:
TRUE if EXE verified as what was left during previous link.
--*/
{
struct _stat statfile;
if (_stat(szExe, &statfile) == -1) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "didn't find exe - %s", szExe);
#endif // INSTRUMENT
return(FALSE);
}
if (pimage->tsExe != (DWORD)statfile.st_mtime ||
pimage->cbExe != (DWORD)statfile.st_size) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "exe size or timestamp differ - %s", szExe);
#endif // INSTRUMENT
return(FALSE);
}
return(TRUE);
}
// figure out if we are running on NT
BOOL
IsOSWin95 (
VOID
)
{
DWORD dw = GetVersion();
return ( (HIWORD(dw) & ~(0x7FFF)) &&
(LOBYTE(LOWORD(dw)) >= 0x4) );
}
void
DetachMiscFromHeap (
PIMAGE pimage
)
/*++
Routine Description:
This is the reverse of AppendMiscToHeap(). Anything
that could be realloc'ed for instance needs to be
detached from the heap.
The order in which things get detached should be the
reverse of their attachment.
Currently only the string block is detached
Arguments:
pimage - pointer to an image.
Return Value:
None.
--*/
{
BYTE *pbNew;
// empty string table
if (!pimage->pst->blkStringTable.cb) {
return;
}
// alloc space
pbNew = (BYTE *) PvAlloc(pimage->pst->blkStringTable.cbAlloc);
// copy from heap
memcpy(pbNew, pimage->pst->blkStringTable.pb,
pimage->pst->blkStringTable.cb);
// free up heap space
Free(pimage->pst->blkStringTable.pb, Align(sizeof(DWORD),pimage->pst->blkStringTable.cb));
// update string blk
pimage->pst->blkStringTable.pb = pbNew;
}
// sets up for a full ilink
void
SetupForFullIlinkBuild (
PPIMAGE ppimage
)
{
PIMAGE pimageO = (*ppimage); // save a pointer to image on heap
BOOL fOnWin95 = IsOSWin95(); // figure out if we are on NT
PVOID pvCur = (PVOID)0;
DWORD dwErr = 0;
// create the private heap
while ((pvCur = NextMapAddr(fOnWin95, pvCur)) != (PVOID)-1) {
if (CreateHeap(pvCur, 0, TRUE, &dwErr) == (PVOID)-1) {
switch (dwErr) {
case ERROR_DISK_FULL:
Warning(NULL, LOWSPACE);
fINCR = FALSE;
return;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
Fatal(NULL, CANTOPENFILE, OutFilename);
default: // address busy etc.
// for Win95 only
if (fOnWin95 && !FFreeDiskSpace(cbInitialILKMapSize)) {
Warning(NULL, LOWSPACE);
fINCR = FALSE;
return;
}
continue;
} // end switch
} else {
break;
}
} // end while
// check to see if we succeeded in creating the map
if (pvCur == (PVOID)-1) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "failed to create heap");
#endif // INSTRUMENT
PostNote(NULL, UNABLETOCREATEMAP);
fINCR = FALSE;
return;
}
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "created heap at 0x%.8lx", pvCur);
#endif // INSTRUMENT
// create and initialize image on private heap
InitImage(ppimage, pimageO->imaget);
// transfer switches & related info to image on private heap
TransferLinkerSwitchValues((*ppimage), pimageO);
// free the image on ordinary heap
FreeImage(&pimageO, FALSE);
}
// sets up for an incremental ilink
void
SetupForIncrIlinkBuild (
PPIMAGE ppimage,
PVOID pvbase,
DWORD cbLen
)
{
PVOID pv;
PIMAGE pimageN = (*ppimage); // save a pointer to new image on heap
PST pst;
DWORD dwErr;
// try to create private heap at base specified
if ((pv = CreateHeap(pvbase, cbLen, FALSE, &dwErr)) == (PVOID)-1) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "failed to create heap at 0x%.8lx", pvbase);
#endif // INSTRUMENT
if (fTest) {
PostNote(NULL, UNABLETOLOADILK);
}
// failed to create heap at base: try to do a full ilink
SetupForFullIlinkBuild(ppimage);
return;
}
// set the base map address
*ppimage = (PIMAGE) pv;
// check the string table ptr and verify nothing beyond it.
pst = (*ppimage)->pst;
if (pst->blkStringTable.cb &&
(!FValidPtrInfo((DWORD)pv, cbLen, (DWORD)pst->blkStringTable.pb, pst->blkStringTable.cb)
|| (Align(sizeof(DWORD),((DWORD)pst->blkStringTable.pb+pst->blkStringTable.cb-(DWORD)pv)) != cbLen))) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "inavlid ptrs in symbol table");
#endif // INSTRUMENT
if (fTest) {
PostNote(NULL, CORRUPTILK);
}
// cannot do an incr ilink; try to do a full ilink
FreeHeap();
(*ppimage) = pimageN;
SetupForFullIlinkBuild(ppimage);
return;
}
// detach string table etc from heap
DetachMiscFromHeap(*ppimage);
// compare switches to see if we can continue
if (!CheckAndUpdateLinkerSwitches(pimageN, (*ppimage))) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "incompatible switches");
#endif // INSTRUMENT
// cannot do an incr ilink; try to do a full ilink
if (fTest) {
PostNote(NULL, LNKOPTIONSCHNG);
}
FreeHeap();
(*ppimage) = pimageN;
SetupForFullIlinkBuild(ppimage);
return;
}
// OK to proceed with incr ilink
FreeImage(&pimageN, FALSE);
fIncrDbFile = TRUE;
}
char *
SzGenIncrDbFilename (
PIMAGE pimage
)
/*++
Routine Description:
Generates the ILK filename.
Either uses -out: specified by user or first name of
obj file & then uses default name. Incr db name may
not match output filename if it is specified via
a directive in one of the objs.
Arguments:
pimage - pointer to an image.
Return Value:
Pointer to (malloc'ed) name of incr db filename
--*/
{
char szDrive[_MAX_DRIVE];
char szDir[_MAX_DIR];
char szFname[_MAX_FNAME];
char szIncrDbPath[_MAX_PATH];
// Generate incr db filename
if (OutFilename == NULL) {
DWORD i;
PARGUMENT_LIST arg;
// Capture first object name for output filename.
for (i = 0, arg = FilenameArguments.First;
i < FilenameArguments.Count;
i++, arg = arg->Next) {
INT Handle;
BOOL fArchive;
Handle = FileOpen(arg->OriginalName, O_RDONLY | O_BINARY, 0);
fArchive = IsArchiveFile(arg->OriginalName, Handle);
FileClose(Handle, FALSE);
if (fArchive) {
continue;
}
SetDefaultOutFilename(pimage, arg);
break;
}
}
if (OutFilename == NULL) {
return NULL;
}
assert(OutFilename);
_splitpath(OutFilename, szDrive, szDir, szFname, NULL);
_makepath(szIncrDbPath, szDrive, szDir, szFname, INCDB_EXT);
return(SzDup(szIncrDbPath));
}
void
SaveStringTable (
IN PST pst
)
/*++
Routine Description:
Saves the string table.
Arguments:
pst - pointer to symbol table whose string table is to be saved.
Return Value:
None.
--*/
{
BYTE *pb;
// empty string table
if (!pst->blkStringTable.cb) {
return;
}
// append long name string table
pb = (BYTE *) Malloc(pst->blkStringTable.cb);
memcpy(pb, pst->blkStringTable.pb,
pst->blkStringTable.cb);
pst->blkStringTable.pb = pb;
}
void
AppendMiscToHeap (
PIMAGE pimage
)
/*++
Routine Description:
Appends anything that could not be allocated on the heap
to during the link process. Currently only the long name
table is appended.
Arguments:
pimage - pointer to an image.
Return Value:
None.
--*/
{
// save the string table holding all the directives (full-link only)
if (!fIncrDbFile) {
SaveStringTable(pimage->pstDirective);
}
// save the string table of the symbols
SaveStringTable(pimage->pst);
}
void
WriteIncrDbFile (
PIMAGE pimage
)
/*++
Routine Description:
Writes out an image to database. Assumes that file is open
if it already existed. Currently simply writes out entire
image.
Arguments:
pimage - pointer to an image.
fExists - TRUE if incr db file already exists.
Return Value:
None.
--*/
{
assert(FileIncrDbHandle);
// copy over long name table (etc.) to heap
AppendMiscToHeap(pimage);
// do cleanup
CloseHeap();
// write out & close file
FileClose(FileIncrDbHandle, TRUE);
}
void
ReadIncrDbFile (
PPIMAGE ppimage
)
/*++
Routine Description:
Reads in an image database. Reads in header alone,
verifies, read in rest of db.
Arguments:
ppimage - pointer to an image struct pointer
Handle - handle of image file
Return Value:
None.
--*/
{
struct _stat statfile;
IMAGE image;
HANDLE hFile;
// establish name of the db file
szIncrDbFilename = SzGenIncrDbFilename(*ppimage);
if (!szIncrDbFilename) {
fINCR = FALSE;
return;
}
// verify that ILK file exists and is valid
if (!FValidILKFile(szIncrDbFilename, TRUE, &image, &statfile)) {
// full build possible if ILK is corrupt or has an old format etc.
if (fINCR) {
SetupForFullIlinkBuild(ppimage);
}
return;
}
// ensure that the previously built EXE is valid and still around.
assert(OutFilename);
if (!FVerifyEXE(OutFilename, &image)) {
PostNote(NULL, FILECHANGED, OutFilename);
(*ppimage)->Switch.Link.fNotifyFullBuild = FALSE;
SetupForFullIlinkBuild(ppimage);
return;
}
// check to see if file isn't locked by another process
hFile = CreateFile(OutFilename,
GENERIC_READ | GENERIC_WRITE,
0, NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
FatalNoDelete(NULL, INVALID_FILEPERM, OutFilename);
exit(INVALID_FILEPERM);
} else {
CloseHandle(hFile);
}
if (image.Switch.Link.DebugInfo != None) {
// Ensure that the PDB file exists and has the right permissions
char *szPdb;
szPdb = DeterminePDBFilename(OutFilename, PdbFilename);
if (_access(szPdb, 0) == -1) {
PostNote(NULL, PDBMISSING, szPdb);
FreePv(szPdb);
SetupForFullIlinkBuild(ppimage);
return;
}
if (_access(szPdb, 2) == -1) {
FatalNoDelete(NULL, INVALID_FILEPERM, szPdb);
exit(INVALID_FILEPERM);
}
PdbFilename = szPdb;
}
// set up for an incr ilink.
SetupForIncrIlinkBuild(ppimage, image.pvBase, (DWORD)statfile.st_size);
if (!fIncrDbFile) {
return;
}
// incremental initialization
IncrInitImage(ppimage);
DBEXEC(DB_DUMPIMAGE, DumpImage(*ppimage));
}
BOOL
FValidPtrInfo (
IN DWORD pvBase,
IN DWORD fileLen,
IN DWORD ptr,
IN DWORD cbOffset
)
/*++
Routine Description:
Ensures that the ptr and offset are valid.
Arguments:
pvBase - base of image.
fileLen - length of file.
ptr - ptr to validate.
cbOffset - cbOffset from ptr that has to be valid as well.
Return Value:
TRUE if info is valid.
--*/
{
if (ptr <= (DWORD)pvBase) {
// Invalid ptr?
return(FALSE);
}
ptr -= (DWORD) pvBase; // take out the base value
if ((ptr + cbOffset) <= fileLen) {
return(TRUE);
}
return(FALSE);
}
void
FreeImage (
PPIMAGE ppimage,
BOOL fIncrBuild
)
/*++
Routine Description:
Free space occupied by image blowing away structures as needed
Arguments:
pimage - pointer to image struct pointer
Return Value:
None.
--*/
{
// free stuff according to whether it is an incr build
if (fIncrBuild) {
FreeHeap();
} else {
// FreeImageMap(ppimage);
FreeExternalSymbolTable(&((*ppimage)->pst));
// UNDONE: This memory is allocated via Calloc() and isn't safe to free
free(*ppimage);
}
// done
*ppimage = NULL;
}
void
SaveEXEInfo(
const char *szExe,
PIMAGE pimage
)
/*++
Routine Description:
Saves size & timestamp of EXE.
Arguments:
szExe - name of EXE.
pimage - ptr to IMAGE struct.
Return Value:
None.
--*/
{
struct _stat statfile;
if (_stat(szExe, &statfile) == -1) {
Fatal(NULL, CANTOPENFILE, szExe);
}
pimage->tsExe = statfile.st_mtime;
pimage->cbExe = statfile.st_size;
}
BOOL
FValidILKFile (
const char *szIncrDbFilename,
BOOL fIlink,
PIMAGE pimage,
struct _stat *pstat
)
/*++
Routine Description:
Verifies that file is a valid ILK file.
Arguments:
szIncrDbFilename - name of ILK file.
fIlink - is TRUE if we are attempting to do an ilink.
pimage - ptr to IMAGE struct.
pstat - ptr to a statfile struct.
Return Value:
TRUE if file is a valid ILK file.
--*/
{
// stat the incremental db file to make sure it is around.
if (_stat(szIncrDbFilename, pstat)) {
return(FALSE);
}
// the ILK file is around and so we are not doing a full link
// if we do, the resulting warning will let the user know about anyway.
pimage->Switch.Link.fNotifyFullBuild = FALSE;
// make sure the file is of proper size
if (pstat->st_size < sizeof(IMAGE) || pstat->st_size > ILKMAP_MAX) {
if (fIlink) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "invalid size for a ILK file");
#endif // INSTRUMENT
Warning(NULL, INVALID_DBFILE, szIncrDbFilename);
fINCR = FALSE;
}
return(FALSE);
}
// make sure file has proper permissions.
if ((pstat->st_mode & (S_IREAD | S_IWRITE)) != (S_IREAD | S_IWRITE)) {
if (fIlink) {
Warning(NULL, INVALID_FILE_ATTRIB, szIncrDbFilename);
fINCR = FALSE;
}
return(FALSE);
}
// open the incremental db file
FileIncrDbHandle = FileOpen(szIncrDbFilename, O_RDWR | O_BINARY, 0);
// read in just the image structure
if (FileRead(FileIncrDbHandle, pimage, sizeof(IMAGE)) != sizeof(IMAGE)) {
FileClose(FileIncrDbHandle, TRUE);
if (fIlink) {
Warning(NULL, INVALID_DBFILE, szIncrDbFilename);
fINCR = FALSE;
}
return(FALSE);
}
// close the incremental db file
FileClose(FileIncrDbHandle, TRUE);
FileIncrDbHandle = 0;
// look for the incr db signature
if (strcmp(pimage->Sig, INCDB_SIGNATURE)) {
if (fIlink) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "invalid sig found");
#endif // INSTRUMENT
Warning(NULL, INVALID_DBFILE, szIncrDbFilename);
fINCR = FALSE;
}
return(FALSE);
}
// if not doing an ilink, just verifying the signature will do for now
if (!fIlink) {
return(TRUE);
}
// verify the version numbers; mimatch => do a full inc build
if (pimage->MajVersNum != INCDB_MAJVERSNUM) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "invalid version found");
#endif // INSTRUMENT
if (fTest) {
PostNote(NULL, INVALIDILKFORMAT);
}
return(FALSE);
}
// verify ptrs in image struct
if (!FValidPtrInfo((DWORD)pimage->pvBase, (DWORD)pstat->st_size, (DWORD)pimage->secs.psecHead, sizeof(SEC)) ||
!FValidPtrInfo((DWORD)pimage->pvBase, (DWORD)pstat->st_size, (DWORD)pimage->libs.plibHead, sizeof(LIB)) ||
!FValidPtrInfo((DWORD)pimage->pvBase, (DWORD)pstat->st_size, (DWORD)pimage->plibCmdLineObjs, sizeof(LIB)) ||
!FValidPtrInfo((DWORD)pimage->pvBase, (DWORD)pstat->st_size, (DWORD)pimage->pst, sizeof(ST))) {
#ifdef INSTRUMENT
LogNoteEvent(Log, SZILINK, NULL, letypeEvent, "invalid ptrs found in image struct");
#endif // INSTRUMENT
if (fTest) {
PostNote(NULL, CORRUPTILK);
}
return(FALSE);
}
return(TRUE);
}
#if DBG
void
DumpImage (
PIMAGE pimage
)
/*++
Routine Description:
Dumps an image. Others dump routines may be added
as required.
Arguments:
pimage - pointer to an image.
Return Value:
None.
--*/
{
assert(pimage);
assert(pimage->secs.psecHead);
assert(pimage->libs.plibHead);
assert(pimage->pst);
assert(pimage->pst->pht);
DBPRINT("---------------- IMAGE DUMP ----------------\n");
DBPRINT("Image Base...........0x%.8lx\n\n",(LONG)(pimage->pvBase));
DumpImageMap(&pimage->secs);
DumpDriverMap(pimage->libs.plibHead);
Statistics_HT(pimage->pst->pht);
Dump_HT(pimage->pst->pht, &pimage->pst->blkStringTable);
DBPRINT("------------ END IMAGE DUMP ----------------\n");
}
#endif // DBG