|
|
1.1 ! root 1: /*++ ! 2: ! 3: ! 4: Copyright (c) 1992 Microsoft Corporation ! 5: ! 6: Module Name: ! 7: ! 8: file.c ! 9: ! 10: Abstract: ! 11: ! 12: This module handles all file i/o for SYMCVT. This includes the ! 13: mapping of all files and establishing all file pointers for the ! 14: mapped file(s). ! 15: ! 16: Author: ! 17: ! 18: Wesley A. Witt (wesw) 19-April-1993 ! 19: ! 20: Environment: ! 21: ! 22: Win32, User Mode ! 23: ! 24: --*/ ! 25: ! 26: #include <windows.h> ! 27: #include <stdlib.h> ! 28: #include <string.h> ! 29: #include <stdio.h> ! 30: ! 31: #include "symcvt.h" ! 32: ! 33: ! 34: static BOOL CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po ); ! 35: static BOOL CalculateInputFilePointers( PIMAGEPOINTERS p ); ! 36: ! 37: ! 38: ! 39: BOOL ! 40: MapInputFile ( ! 41: PPOINTERS p, ! 42: HANDLE hFile, ! 43: char * fname ! 44: ) ! 45: /*++ ! 46: ! 47: Routine Description: ! 48: ! 49: Maps the input file specified by the fname argument and saves the ! 50: file handle & file pointer in the POINTERS structure. ! 51: ! 52: ! 53: Arguments: ! 54: ! 55: p - Supplies pointer to a POINTERS structure (see cofftocv.h) ! 56: hFile - OPTIONAL Supplies handle for file if already open ! 57: fname - Supplies ascii string for the file name ! 58: ! 59: Return Value: ! 60: ! 61: TRUE - file mapped ok ! 62: FALSE - file could not be mapped ! 63: ! 64: --*/ ! 65: ! 66: { ! 67: BOOL rVal = TRUE; ! 68: DWORD lwFsize; ! 69: ! 70: memset( p, 0, sizeof(POINTERS) ); ! 71: ! 72: strcpy( p->iptrs.szName, fname ); ! 73: ! 74: if (hFile != NULL) { ! 75: ! 76: p->iptrs.hFile = hFile; ! 77: ! 78: } else { ! 79: ! 80: p->iptrs.hFile = CreateFile( p->iptrs.szName, ! 81: GENERIC_READ, ! 82: FILE_SHARE_READ | FILE_SHARE_WRITE, ! 83: NULL, ! 84: OPEN_EXISTING, ! 85: 0, ! 86: NULL ); ! 87: } ! 88: ! 89: if (p->iptrs.hFile == INVALID_HANDLE_VALUE) { ! 90: ! 91: rVal = FALSE; ! 92: ! 93: } else { ! 94: ! 95: p->iptrs.fsize = GetFileSize( p->iptrs.hFile, NULL ); ! 96: if (lwFsize == 0xffffffff) { ! 97: ; ! 98: } ! 99: p->iptrs.hMap = CreateFileMapping( p->iptrs.hFile, ! 100: NULL, ! 101: PAGE_READONLY, ! 102: 0, ! 103: 0, ! 104: NULL ! 105: ); ! 106: ! 107: if (p->iptrs.hMap == INVALID_HANDLE_VALUE) { ! 108: ! 109: p->iptrs.hMap = NULL; ! 110: rVal = FALSE; ! 111: ! 112: } else { ! 113: ! 114: p->iptrs.fptr = MapViewOfFile( p->iptrs.hMap, ! 115: FILE_MAP_READ, ! 116: 0, 0, 0 ); ! 117: if (p->iptrs.fptr == NULL) { ! 118: CloseHandle( p->iptrs.hMap ); ! 119: p->iptrs.hMap = NULL; ! 120: rVal = FALSE; ! 121: } ! 122: } ! 123: } ! 124: ! 125: if (!hFile && p->iptrs.hFile != INVALID_HANDLE_VALUE) { ! 126: CloseHandle(p->iptrs.hFile); ! 127: p->iptrs.hFile = NULL; ! 128: } ! 129: ! 130: return rVal; ! 131: } /* MapInputFile() */ ! 132: ! 133: ! 134: ! 135: BOOL ! 136: UnMapInputFile ( ! 137: PPOINTERS p ! 138: ) ! 139: /*++ ! 140: ! 141: Routine Description: ! 142: ! 143: Unmaps the input file specified by the fname argument and then ! 144: closes the file. ! 145: ! 146: ! 147: Arguments: ! 148: ! 149: p - pointer to a POINTERS structure (see cofftocv.h) ! 150: ! 151: Return Value: ! 152: ! 153: TRUE - file mapped ok ! 154: FALSE - file could not be mapped ! 155: ! 156: --*/ ! 157: ! 158: { ! 159: if ( p->iptrs.fptr ) { ! 160: UnmapViewOfFile( p->iptrs.fptr ); ! 161: p->iptrs.fptr = NULL; ! 162: } ! 163: if ( p->iptrs.hMap ) { ! 164: CloseHandle( p->iptrs.hMap ); ! 165: p->iptrs.hMap = NULL; ! 166: } ! 167: if (p->iptrs.hFile != NULL) { ! 168: CloseHandle( p->iptrs.hFile ); ! 169: p->iptrs.hFile = NULL; ! 170: } ! 171: return TRUE; ! 172: } /* UnMapInputFile() */ ! 173: ! 174: ! 175: BOOL ! 176: FillInSeparateImagePointers( ! 177: PIMAGEPOINTERS p ! 178: ) ! 179: /*++ ! 180: ! 181: Routine Description: ! 182: ! 183: This routine will go through the exe file and fill in the ! 184: pointers needed relative to the separate debug information files ! 185: ! 186: Arguments: ! 187: ! 188: p - Supplies the structure to fill in ! 189: ! 190: Return Value: ! 191: ! 192: TRUE if successful and FALSE otherwise. ! 193: ! 194: --*/ ! 195: ! 196: { ! 197: int li; ! 198: int numDebugDirs; ! 199: PIMAGE_DEBUG_DIRECTORY pDebugDir; ! 200: PIMAGE_COFF_SYMBOLS_HEADER pCoffHdr; ! 201: ! 202: p->sectionHdrs = (PIMAGE_SECTION_HEADER) ! 203: (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER)); ! 204: ! 205: numDebugDirs = p->sepHdr->DebugDirectorySize/sizeof(IMAGE_DEBUG_DIRECTORY); ! 206: ! 207: if (numDebugDirs == 0) { ! 208: return FALSE; ! 209: } ! 210: ! 211: /* ! 212: * For each debug directory, determine the debug directory type ! 213: * and cache any information about them. ! 214: */ ! 215: ! 216: pDebugDir = (PIMAGE_DEBUG_DIRECTORY) ! 217: (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER) + ! 218: p->sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) + ! 219: p->sepHdr->ExportedNamesSize); ! 220: ! 221: for (li=0; li<numDebugDirs; li++, pDebugDir++) { ! 222: if (((int) pDebugDir->Type) > p->cDebugDir) { ! 223: p->cDebugDir += 10; ! 224: p->rgDebugDir = realloc((char *) p->rgDebugDir, ! 225: p->cDebugDir * sizeof(p->rgDebugDir[0])); ! 226: memset(&p->rgDebugDir[p->cDebugDir-10], 0, ! 227: 10*sizeof(p->rgDebugDir[0])); ! 228: } ! 229: ! 230: p->rgDebugDir[pDebugDir->Type] = pDebugDir; ! 231: } ! 232: ! 233: if (p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) { ! 234: pCoffHdr = (PIMAGE_COFF_SYMBOLS_HEADER) (p->fptr + ! 235: p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF]->PointerToRawData); ! 236: p->AllSymbols = (PIMAGE_SYMBOL) ! 237: ((char *) pCoffHdr + pCoffHdr->LvaToFirstSymbol); ! 238: p->stringTable = pCoffHdr->NumberOfSymbols * IMAGE_SIZEOF_SYMBOL + ! 239: (char *) p->AllSymbols; ! 240: p->numberOfSymbols = pCoffHdr->NumberOfSymbols; ! 241: } ! 242: p->numberOfSections = p->sepHdr->NumberOfSections; ! 243: ! 244: return TRUE; ! 245: } /* FillInSeparateImagePointers() */ ! 246: ! 247: ! 248: ! 249: BOOL ! 250: CalculateNtImagePointers( ! 251: PIMAGEPOINTERS p ! 252: ) ! 253: /*++ ! 254: ! 255: Routine Description: ! 256: ! 257: This function reads an NT image and its associated COFF headers ! 258: and file pointers and build a set of pointers into the mapped image. ! 259: The pointers are all relative to the image's mapped file pointer ! 260: and allow direct access to the necessary data. ! 261: ! 262: Arguments: ! 263: ! 264: p - pointer to a IMAGEPOINTERS structure (see cofftocv.h) ! 265: ! 266: Return Value: ! 267: ! 268: TRUE - pointers were created ! 269: FALSE - pointers could not be created ! 270: ! 271: --*/ ! 272: { ! 273: PIMAGE_DEBUG_DIRECTORY debugDir; ! 274: PIMAGE_SECTION_HEADER sh; ! 275: DWORD i, li, rva, numDebugDirs; ! 276: PIMAGE_FILE_HEADER pFileHdr; ! 277: PIMAGE_OPTIONAL_HEADER pOptHdr; ! 278: DWORD offDebugInfo; ! 279: ! 280: try { ! 281: /* ! 282: * Based on wheither or not we find the dos (MZ) header ! 283: * at the beginning of the file, attempt to get a pointer ! 284: * to where the PE header is suppose to be. ! 285: */ ! 286: ! 287: p->dosHdr = (PIMAGE_DOS_HEADER) p->fptr; ! 288: if (p->dosHdr->e_magic == IMAGE_DOS_SIGNATURE) { ! 289: p->ntHdr = (PIMAGE_NT_HEADERS) ! 290: ((DWORD)p->dosHdr->e_lfanew + p->fptr); ! 291: } else if (p->dosHdr->e_magic == IMAGE_SEPARATE_DEBUG_SIGNATURE) { ! 292: p->sepHdr = (PIMAGE_SEPARATE_DEBUG_HEADER) p->fptr; ! 293: p->dosHdr = NULL; ! 294: return FillInSeparateImagePointers(p); ! 295: } else { ! 296: p->ntHdr = (PIMAGE_NT_HEADERS) p->fptr; ! 297: p->dosHdr = NULL; ! 298: } ! 299: ! 300: /* ! 301: * What comes next must be a PE header. If not then pop out ! 302: */ ! 303: ! 304: if (p->ntHdr->Signature != IMAGE_NT_SIGNATURE) { ! 305: return FALSE; ! 306: } ! 307: ! 308: /* ! 309: * We did find a PE header so start setting pointers to various ! 310: * structures in the exe file. ! 311: */ ! 312: ! 313: pFileHdr = p->fileHdr = &p->ntHdr->FileHeader; ! 314: pOptHdr = p->optHdr = &p->ntHdr->OptionalHeader; ! 315: ! 316: if (!(pFileHdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) { ! 317: return FALSE; ! 318: } ! 319: ! 320: /* ! 321: * If they exists then get a pointer to the symbol table and ! 322: * the string table ! 323: */ ! 324: ! 325: if (pFileHdr->PointerToSymbolTable) { ! 326: p->AllSymbols = (PIMAGE_SYMBOL) (pFileHdr->PointerToSymbolTable + ! 327: p->fptr); ! 328: p->stringTable = pFileHdr->PointerToSymbolTable + p->fptr + ! 329: (IMAGE_SIZEOF_SYMBOL * pFileHdr->NumberOfSymbols); ! 330: p->numberOfSymbols = pFileHdr->NumberOfSymbols; ! 331: } ! 332: p->numberOfSections = pFileHdr->NumberOfSections; ! 333: ! 334: /* ! 335: * Locate the debug directory ! 336: */ ! 337: ! 338: rva = ! 339: pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; ! 340: ! 341: numDebugDirs = ! 342: pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / ! 343: sizeof(IMAGE_DEBUG_DIRECTORY); ! 344: ! 345: if (numDebugDirs == 0) { ! 346: return FALSE; ! 347: } ! 348: ! 349: sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr ); ! 350: ! 351: /* ! 352: * Find the section the debug directory is in. ! 353: */ ! 354: ! 355: for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) { ! 356: if (rva >= sh->VirtualAddress && ! 357: rva < sh->VirtualAddress+sh->SizeOfRawData) { ! 358: break; ! 359: } ! 360: } ! 361: ! 362: /* ! 363: * For each debug directory, determine the debug directory ! 364: * type and cache any information about them. ! 365: */ ! 366: ! 367: debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress + ! 368: sh->PointerToRawData + ! 369: p->fptr ); ! 370: for (li=0; li<numDebugDirs; li++, debugDir++) { ! 371: if (((int) debugDir->Type) > p->cDebugDir) { ! 372: p->cDebugDir += 10; ! 373: p->rgDebugDir = realloc((char *) p->rgDebugDir, ! 374: p->cDebugDir * sizeof(p->rgDebugDir[0])); ! 375: memset(&p->rgDebugDir[p->cDebugDir-10], 0, ! 376: 10*sizeof(p->rgDebugDir[0])); ! 377: } ! 378: p->rgDebugDir[debugDir->Type] = debugDir; ! 379: offDebugInfo = debugDir->AddressOfRawData; ! 380: } ! 381: ! 382: /* ! 383: * Check to see if the debug information is mapped and if ! 384: * there is a section called .debug ! 385: */ ! 386: ! 387: sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr ); ! 388: for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) { ! 389: if ((offDebugInfo >= sh->VirtualAddress) && ! 390: (offDebugInfo < sh->VirtualAddress+sh->SizeOfRawData)) { ! 391: p->debugSection = sh; ! 392: break; ! 393: } ! 394: } ! 395: return TRUE; ! 396: } except (EXCEPTION_EXECUTE_HANDLER) { ! 397: return FALSE; ! 398: } ! 399: } /* CalcuateNtImagePointers() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.