home *** CD-ROM | disk | FTP | other *** search
- /*++
-
-
- Copyright 1996 - 1997 Microsoft Corporation
-
- Module Name:
-
- file.c
-
- Abstract:
-
- This module handles all file i/o for SYMCVT. This includes the
- mapping of all files and establishing all file pointers for the
- mapped file(s).
-
- Author:
-
- Wesley A. Witt (wesw) 19-April-1993
-
- Environment:
-
- Win32, User Mode
-
- --*/
-
- #include <windows.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
-
- #define _SYMCVT_SOURCE_
- #include "symcvt.h"
-
- static BOOL CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po );
- static BOOL CalculateInputFilePointers( PIMAGEPOINTERS p );
-
-
-
- BOOL
- MapInputFile (
- PPOINTERS p,
- HANDLE hFile,
- char * fname
- )
- /*++
-
- Routine Description:
-
- Maps the input file specified by the fname argument and saves the
- file handle & file pointer in the POINTERS structure.
-
-
- Arguments:
-
- p - Supplies pointer to a POINTERS structure
- hFile - OPTIONAL Supplies handle for file if already open
- fname - Supplies ascii string for the file name
-
- Return Value:
-
- TRUE - file mapped ok
- FALSE - file could not be mapped
-
- --*/
-
- {
- BOOL rVal = TRUE;
- DWORD lwFsize;
-
- memset( p, 0, sizeof(POINTERS) );
-
- strcpy( p->iptrs.szName, fname );
-
- if (hFile != NULL) {
-
- p->iptrs.hFile = hFile;
-
- } else {
-
- p->iptrs.hFile = CreateFile( p->iptrs.szName,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL );
- }
-
- if (p->iptrs.hFile == INVALID_HANDLE_VALUE) {
-
- rVal = FALSE;
-
- } else {
-
- p->iptrs.fsize = GetFileSize( p->iptrs.hFile, NULL );
- if (lwFsize == 0xffffffff) {
- ;
- }
- p->iptrs.hMap = CreateFileMapping( p->iptrs.hFile,
- NULL,
- PAGE_READONLY,
- 0,
- 0,
- NULL
- );
-
- if (p->iptrs.hMap == INVALID_HANDLE_VALUE) {
-
- p->iptrs.hMap = NULL;
- rVal = FALSE;
-
- } else {
-
- p->iptrs.fptr = MapViewOfFile( p->iptrs.hMap,
- FILE_MAP_READ,
- 0, 0, 0 );
- if (p->iptrs.fptr == NULL) {
- CloseHandle( p->iptrs.hMap );
- p->iptrs.hMap = NULL;
- rVal = FALSE;
- }
- }
- }
-
- if (!hFile && p->iptrs.hFile != INVALID_HANDLE_VALUE) {
- CloseHandle(p->iptrs.hFile);
- p->iptrs.hFile = NULL;
- }
-
- return rVal;
- } /* MapInputFile() */
-
-
-
- BOOL
- UnMapInputFile (
- PPOINTERS p
- )
- /*++
-
- Routine Description:
-
- Unmaps the input file specified by the fname argument and then
- closes the file.
-
-
- Arguments:
-
- p - pointer to a POINTERS structure
-
- Return Value:
-
- TRUE - file mapped ok
- FALSE - file could not be mapped
-
- --*/
-
- {
- if ( p->iptrs.fptr ) {
- UnmapViewOfFile( p->iptrs.fptr );
- p->iptrs.fptr = NULL;
- }
- if ( p->iptrs.hMap ) {
- CloseHandle( p->iptrs.hMap );
- p->iptrs.hMap = NULL;
- }
- if (p->iptrs.hFile != NULL) {
- CloseHandle( p->iptrs.hFile );
- p->iptrs.hFile = NULL;
- }
- return TRUE;
- } /* UnMapInputFile() */
-
-
- BOOL
- FillInSeparateImagePointers(
- PIMAGEPOINTERS p
- )
- /*++
-
- Routine Description:
-
- This routine will go through the exe file and fill in the
- pointers needed relative to the separate debug information files
-
- Arguments:
-
- p - Supplies the structure to fill in
-
- Return Value:
-
- TRUE if successful and FALSE otherwise.
-
- --*/
-
- {
- int li;
- int numDebugDirs;
- PIMAGE_DEBUG_DIRECTORY pDebugDir;
- PIMAGE_COFF_SYMBOLS_HEADER pCoffHdr;
-
- p->sectionHdrs = (PIMAGE_SECTION_HEADER)
- (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER));
-
- numDebugDirs = p->sepHdr->DebugDirectorySize/sizeof(IMAGE_DEBUG_DIRECTORY);
-
- if (numDebugDirs == 0) {
- return FALSE;
- }
-
- /*
- * For each debug directory, determine the debug directory type
- * and cache any information about them.
- */
-
- pDebugDir = (PIMAGE_DEBUG_DIRECTORY)
- (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
- p->sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
- p->sepHdr->ExportedNamesSize);
-
- for (li=0; li<numDebugDirs; li++, pDebugDir++) {
- if (((int) pDebugDir->Type) > p->cDebugDir) {
- p->cDebugDir += 10;
- p->rgDebugDir = realloc((char *) p->rgDebugDir,
- p->cDebugDir * sizeof(p->rgDebugDir[0]));
- memset(&p->rgDebugDir[p->cDebugDir-10], 0,
- 10*sizeof(p->rgDebugDir[0]));
- }
-
- p->rgDebugDir[pDebugDir->Type] = pDebugDir;
- }
-
- if (p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) {
- pCoffHdr = (PIMAGE_COFF_SYMBOLS_HEADER) (p->fptr +
- p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF]->PointerToRawData);
- p->AllSymbols = (PIMAGE_SYMBOL)
- ((char *) pCoffHdr + pCoffHdr->LvaToFirstSymbol);
- p->stringTable = pCoffHdr->NumberOfSymbols * IMAGE_SIZEOF_SYMBOL +
- (char *) p->AllSymbols;
- p->numberOfSymbols = pCoffHdr->NumberOfSymbols;
- }
- p->numberOfSections = p->sepHdr->NumberOfSections;
-
- return TRUE;
- } /* FillInSeparateImagePointers() */
-
-
-
- BOOL
- CalculateNtImagePointers(
- PIMAGEPOINTERS p
- )
- /*++
-
- Routine Description:
-
- This function reads an NT image and its associated COFF headers
- and file pointers and build a set of pointers into the mapped image.
- The pointers are all relative to the image's mapped file pointer
- and allow direct access to the necessary data.
-
- Arguments:
-
- p - pointer to a IMAGEPOINTERS structure
-
- Return Value:
-
- TRUE - pointers were created
- FALSE - pointers could not be created
-
- --*/
- {
- PIMAGE_DEBUG_DIRECTORY debugDir;
- PIMAGE_SECTION_HEADER sh;
- DWORD i, li, rva, numDebugDirs;
- PIMAGE_FILE_HEADER pFileHdr;
- PIMAGE_OPTIONAL_HEADER pOptHdr;
- DWORD offDebugInfo;
-
- try {
- /*
- * Based on wheither or not we find the dos (MZ) header
- * at the beginning of the file, attempt to get a pointer
- * to where the PE header is suppose to be.
- */
-
- p->dosHdr = (PIMAGE_DOS_HEADER) p->fptr;
- if (p->dosHdr->e_magic == IMAGE_DOS_SIGNATURE) {
- p->ntHdr = (PIMAGE_NT_HEADERS)
- ((DWORD)p->dosHdr->e_lfanew + p->fptr);
- p->fRomImage = FALSE;
- } else if (p->dosHdr->e_magic == IMAGE_SEPARATE_DEBUG_SIGNATURE) {
- p->sepHdr = (PIMAGE_SEPARATE_DEBUG_HEADER) p->fptr;
- p->dosHdr = NULL;
- p->fRomImage = FALSE;
- return FillInSeparateImagePointers(p);
- } else {
- p->romHdr = (PIMAGE_ROM_HEADERS) p->fptr;
- if (p->romHdr->FileHeader.SizeOfOptionalHeader ==
- IMAGE_SIZEOF_ROM_OPTIONAL_HEADER &&
- p->romHdr->OptionalHeader.Magic ==
- IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
- //
- // its a rom image
- //
- p->fRomImage = TRUE;
- p->ntHdr = NULL;
- p->dosHdr = NULL;
- } else {
- p->fRomImage = FALSE;
- p->ntHdr = (PIMAGE_NT_HEADERS) p->fptr;
- p->dosHdr = NULL;
- p->romHdr = NULL;
- }
- }
-
- /*
- * What comes next must be a PE header. If not then pop out
- */
-
- if ( p->ntHdr ) {
- if ( p->dosHdr && (DWORD)p->dosHdr->e_lfanew > (DWORD)p->fsize ) {
- return FALSE;
- }
-
- if ( p->ntHdr->Signature != IMAGE_NT_SIGNATURE ) {
- return FALSE;
- }
-
- /*
- * We did find a PE header so start setting pointers to various
- * structures in the exe file.
- */
-
- pFileHdr = p->fileHdr = &p->ntHdr->FileHeader;
- pOptHdr = p->optHdr = &p->ntHdr->OptionalHeader;
- } else if (p->romHdr) {
- pFileHdr = p->fileHdr = &p->romHdr->FileHeader;
- pOptHdr = (PIMAGE_OPTIONAL_HEADER) &p->romHdr->OptionalHeader;
- p->optHdr = (PIMAGE_OPTIONAL_HEADER) &p->romHdr->OptionalHeader;
- } else {
- return FALSE;
- }
-
- if (!(pFileHdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {
- return FALSE;
- }
-
- if (pFileHdr->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
- return(FALSE);
- }
-
- /*
- * If they exists then get a pointer to the symbol table and
- * the string table
- */
-
- if (pFileHdr->PointerToSymbolTable) {
- p->AllSymbols = (PIMAGE_SYMBOL)
- (pFileHdr->PointerToSymbolTable + p->fptr);
- p->stringTable = (LPSTR)((ULONG)p->AllSymbols +
- (IMAGE_SIZEOF_SYMBOL * pFileHdr->NumberOfSymbols));
- p->numberOfSymbols = pFileHdr->NumberOfSymbols;
- }
-
- p->numberOfSections = pFileHdr->NumberOfSections;
-
- if (p->romHdr) {
-
- sh = p->sectionHdrs = (PIMAGE_SECTION_HEADER) (p->romHdr+1);
-
- p->cDebugDir = 10;
- p->rgDebugDir = calloc(sizeof(IMAGE_DEBUG_DIRECTORY) * 10, 1);
-
- debugDir = 0;
-
- for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
- if (!strcmp(sh->Name, ".rdata")) {
- debugDir = (PIMAGE_DEBUG_DIRECTORY)(sh->PointerToRawData + p->fptr);
- }
-
- if (strncmp(sh->Name,".debug",8)==0) {
- p->debugSection = sh;
- }
- }
-
- if (debugDir) {
- do {
- if ((int)debugDir->Type > p->cDebugDir) {
- p->cDebugDir += 10;
- p->rgDebugDir = realloc((char *) p->rgDebugDir,
- p->cDebugDir * sizeof(p->rgDebugDir[0]));
- memset(&p->rgDebugDir[p->cDebugDir-10],
- 0,
- 10*sizeof(IMAGE_DEBUG_DIRECTORY));
- }
- p->rgDebugDir[debugDir->Type] = debugDir;
- debugDir++;
- } while (debugDir->Type != 0);
- }
- } else {
-
- /*
- * Locate the debug directory
- */
-
- rva =
- pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
-
- numDebugDirs =
- pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size /
- sizeof(IMAGE_DEBUG_DIRECTORY);
-
- if (numDebugDirs == 0) {
- return FALSE;
- }
-
- sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
-
- /*
- * Find the section the debug directory is in.
- */
-
- for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
- if (rva >= sh->VirtualAddress &&
- rva < sh->VirtualAddress+sh->SizeOfRawData) {
- break;
- }
- }
-
- /*
- * For each debug directory, determine the debug directory
- * type and cache any information about them.
- */
-
- debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress +
- sh->PointerToRawData +
- p->fptr );
-
- for (li=0; li<numDebugDirs; li++, debugDir++) {
- if (((int) debugDir->Type) > p->cDebugDir) {
- p->cDebugDir += 10;
- p->rgDebugDir = realloc((char *) p->rgDebugDir,
- p->cDebugDir * sizeof(p->rgDebugDir[0]));
- memset(&p->rgDebugDir[p->cDebugDir-10], 0,
- 10*sizeof(p->rgDebugDir[0]));
- }
- p->rgDebugDir[debugDir->Type] = debugDir;
- offDebugInfo = debugDir->AddressOfRawData;
- }
-
- /*
- * Check to see if the debug information is mapped and if
- * there is a section called .debug
- */
-
- sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
-
- for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
- if ((offDebugInfo >= sh->VirtualAddress) &&
- (offDebugInfo < sh->VirtualAddress+sh->SizeOfRawData)) {
- p->debugSection = sh;
- break;
- }
- }
- }
-
- return TRUE;
- } except (EXCEPTION_EXECUTE_HANDLER) {
- return FALSE;
- }
- } /* CalcuateNtImagePointers() */
-