Annotation of mstools/samples/sdktools/image/imagehlp/debug.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     debug.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module implements functions for splitting debugging information
                     12:     out of an image file and into a separate .DBG file.
                     13: 
                     14: Author:
                     15: 
                     16:     Steven R. Wood 4-May-1993
                     17: 
                     18: Revision History:
                     19: 
                     20: --*/
                     21: 
                     22: #include <windows.h>
                     23: #include <imagehlp.h>
                     24: #include <stdio.h>
                     25: 
                     26: // Helper routines
                     27: 
                     28: PIMAGE_NT_HEADERS
                     29: ImageNtHeader (
                     30:     IN PVOID Base
                     31:     );
                     32: 
                     33: PVOID
                     34: ImageDirectoryEntryToData (
                     35:     IN PVOID Base,
                     36:     IN BOOLEAN MappedAsImage,
                     37:     IN USHORT DirectoryEntry,
                     38:     OUT PULONG Size
                     39:     );
                     40: 
                     41: BOOL
                     42: SplitSymbols(
                     43:     LPSTR ImageName,
                     44:     LPSTR SymbolsPath,
                     45:     LPSTR SymbolFilePath
                     46:     )
                     47: {
                     48:     HANDLE FileHandle, SymbolFileHandle;
                     49:     HANDLE hMappedFile;
                     50:     LPVOID ImageBase;
                     51:     PIMAGE_NT_HEADERS NtHeaders;
                     52:     LPSTR ImageFileName;
                     53:     LPVOID Symbols, SymbolsToFree;
                     54:     DWORD SizeOfSymbols, Unused, ImageNameOffset, cb;
                     55:     PIMAGE_SECTION_HEADER Sections;
                     56:     DWORD SectionNumber, BytesWritten, BytesRead, NewFileSize, HeaderSum, CheckSum;
                     57:     PIMAGE_DEBUG_DIRECTORY DebugDirectories;
                     58:     PIMAGE_DEBUG_DIRECTORY DebugDirectory;
                     59:     PIMAGE_DEBUG_DIRECTORY MiscDebugDirectory;
                     60:     PIMAGE_DEBUG_DIRECTORY FpoDebugDirectory;
                     61:     DWORD DebugDirectorySize, DbgFileHeaderSize, NumberOfDebugDirectories;
                     62:     IMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader;
                     63:     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
                     64:     DWORD  ExportedNamesSize;
                     65:     LPDWORD pp;
                     66:     LPSTR ExportedNames, Src, Dst;
                     67:     DWORD i, RvaOffset, ExportDirectorySize;
                     68:     PFPO_DATA FpoTable;
                     69:     DWORD FpoTableSize;
                     70:     PIMAGE_RUNTIME_FUNCTION_ENTRY RuntimeFunctionTable, pSrc;
                     71:     DWORD RuntimeFunctionTableSize;
                     72:     PIMAGE_FUNCTION_ENTRY FunctionTable, pDst;
                     73:     DWORD FunctionTableSize;
                     74:     ULONG NumberOfFunctionTableEntries;
                     75:     IMAGE_DEBUG_DIRECTORY PhonyFPODbgDir;
                     76:     DWORD SavedErrorCode;
                     77:     BOOL InsertExtensionSubDir;
                     78:     LPSTR ImageFilePathToSaveInImage;
                     79: 
                     80:     ImageFileName = ImageName + strlen( ImageName );
                     81:     while (ImageFileName > ImageName) {
                     82:         if (ImageFileName[ -1 ] == '\\' ||
                     83:             ImageFileName[ -1 ] == '/' ||
                     84:             ImageFileName[ -1 ] == ':'
                     85:            ) {
                     86:             break;
                     87:             }
                     88:         else {
                     89:             ImageFileName -= 1;
                     90:             }
                     91:         }
                     92: 
                     93:     if (SymbolsPath == NULL ||
                     94:         SymbolsPath[ 0 ] == '\0' ||
                     95:         SymbolsPath[ 0 ] == '.'
                     96:        ) {
                     97:         strncpy( SymbolFilePath, ImageName, ImageFileName - ImageName );
                     98:         SymbolFilePath[ ImageFileName - ImageName ] = '\0';
                     99:         InsertExtensionSubDir = FALSE;
                    100:         }
                    101:     else {
                    102:         strcpy( SymbolFilePath, SymbolsPath );
                    103:         InsertExtensionSubDir = TRUE;
                    104:         }
                    105: 
                    106:     Dst = SymbolFilePath + strlen( SymbolFilePath );
                    107:     if (Dst > SymbolFilePath && Dst[-1] != '\\' && Dst[-1] != '/' && Dst[-1] != ':') {
                    108:         *Dst++ = '\\';
                    109:         }
                    110:     ImageFilePathToSaveInImage = Dst;
                    111:     Src = strrchr( ImageFileName, '.' );
                    112:     if (Src != NULL && InsertExtensionSubDir) {
                    113:         while (*Dst = *++Src) {
                    114:             Dst += 1;
                    115:             }
                    116:         *Dst++ = '\\';
                    117:         }
                    118:     strcpy( Dst, ImageFileName );
                    119:     Dst = strrchr( Dst, '.' );
                    120:     if (Dst == NULL) {
                    121:         Dst = SymbolFilePath + strlen( SymbolFilePath );
                    122:         }
                    123:     strcpy( Dst, ".DBG" );
                    124: 
                    125:     //
                    126:     // open and map the file.
                    127:     //
                    128:     FileHandle = CreateFile( ImageName,
                    129:                              GENERIC_READ | GENERIC_WRITE,
                    130:                              FILE_SHARE_READ,
                    131:                              NULL,
                    132:                              OPEN_EXISTING,
                    133:                              0,
                    134:                              NULL
                    135:                            );
                    136: 
                    137: 
                    138:     if (FileHandle == INVALID_HANDLE_VALUE) {
                    139:         return FALSE;
                    140:         }
                    141: 
                    142:     hMappedFile = CreateFileMapping( FileHandle,
                    143:                                      NULL,
                    144:                                      PAGE_READWRITE,
                    145:                                      0,
                    146:                                      0,
                    147:                                      NULL
                    148:                                    );
                    149:     if (!hMappedFile) {
                    150:         CloseHandle( FileHandle );
                    151:         return FALSE;
                    152:         }
                    153: 
                    154:     ImageBase = MapViewOfFile( hMappedFile,
                    155:                                FILE_MAP_WRITE,
                    156:                                0,
                    157:                                0,
                    158:                                0
                    159:                              );
                    160:     if (!ImageBase) {
                    161:         CloseHandle( hMappedFile );
                    162:         CloseHandle( FileHandle );
                    163:         return FALSE;
                    164:         }
                    165: 
                    166:     //
                    167:     // Everything is mapped. Now check the image and find nt image headers
                    168:     //
                    169: 
                    170:     NtHeaders = ImageNtHeader( ImageBase );
                    171:     if (NtHeaders == NULL) {
                    172:         UnmapViewOfFile( ImageBase );
                    173:         CloseHandle( hMappedFile );
                    174:         CloseHandle( FileHandle );
                    175:         SetLastError( ERROR_BAD_EXE_FORMAT );
                    176:         return FALSE;
                    177:         }
                    178: 
                    179:     if (NtHeaders->OptionalHeader.MajorLinkerVersion < 2 ||
                    180:         NtHeaders->OptionalHeader.MinorLinkerVersion < 5
                    181:        ) {
                    182:         UnmapViewOfFile( ImageBase );
                    183:         CloseHandle( hMappedFile );
                    184:         CloseHandle( FileHandle );
                    185:         SetLastError( ERROR_BAD_EXE_FORMAT );
                    186:         return FALSE;
                    187:         }
                    188: 
                    189:     if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
                    190:         UnmapViewOfFile( ImageBase );
                    191:         CloseHandle( hMappedFile );
                    192:         CloseHandle( FileHandle );
                    193:         SetLastError( ERROR_ALREADY_ASSIGNED );
                    194:         return FALSE;
                    195:         }
                    196: 
                    197:     DebugDirectories = ImageDirectoryEntryToData( ImageBase,
                    198:                                                   FALSE,
                    199:                                                   IMAGE_DIRECTORY_ENTRY_DEBUG,
                    200:                                                   &DebugDirectorySize
                    201:                                                 );
                    202:     if (DebugDirectories == NULL || DebugDirectorySize == 0) {
                    203:         UnmapViewOfFile( ImageBase );
                    204:         CloseHandle( hMappedFile );
                    205:         CloseHandle( FileHandle );
                    206:         SetLastError( ERROR_BAD_EXE_FORMAT );
                    207:         return FALSE;
                    208:         }
                    209:     NumberOfDebugDirectories = DebugDirectorySize / sizeof( IMAGE_DEBUG_DIRECTORY );
                    210: 
                    211:     Sections = IMAGE_FIRST_SECTION( NtHeaders );
                    212:     for (SectionNumber = 0;
                    213:          SectionNumber < NtHeaders->FileHeader.NumberOfSections;
                    214:          SectionNumber++
                    215:         ) {
                    216:         if (Sections[ SectionNumber ].PointerToRawData != 0 &&
                    217:             !stricmp( Sections[ SectionNumber ].Name, ".debug" )
                    218:            ) {
                    219:             break;
                    220:             }
                    221:         }
                    222: 
                    223:     FpoTable = NULL;
                    224:     SymbolsToFree = NULL;
                    225:     ExportedNames = NULL;
                    226:     MiscDebugDirectory = NULL;
                    227:     FpoDebugDirectory = NULL;
                    228:     if (SectionNumber >= NtHeaders->FileHeader.NumberOfSections) {
                    229:         if (NtHeaders->FileHeader.PointerToSymbolTable == 0 ||
                    230:             NtHeaders->FileHeader.NumberOfSymbols == 0
                    231:            ) {
                    232:             goto nosyms;
                    233:             }
                    234: 
                    235:         NewFileSize = NtHeaders->FileHeader.PointerToSymbolTable;
                    236:         DebugDirectory = DebugDirectories;
                    237:         for (i=0; i<NumberOfDebugDirectories; i++) {
                    238:             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_MISC) {
                    239:                 NewFileSize = DebugDirectory->PointerToRawData +
                    240:                               DebugDirectory->SizeOfData;
                    241:                 MiscDebugDirectory = DebugDirectory;
                    242:                 }
                    243:             else
                    244:             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO) {
                    245:                 FpoTableSize = DebugDirectory->SizeOfData;
                    246:                 FpoTable = VirtualAlloc( NULL,
                    247:                                          FpoTableSize,
                    248:                                          MEM_COMMIT,
                    249:                                          PAGE_READWRITE
                    250:                                        );
                    251:                 if ( FpoTable == NULL) {
                    252:                     goto nosyms;
                    253:                     }
                    254:                 if (SetFilePointer( FileHandle,
                    255:                                     DebugDirectory->PointerToRawData,
                    256:                                     NULL,
                    257:                                     FILE_BEGIN
                    258:                                   ) != DebugDirectory->PointerToRawData
                    259:                    ) {
                    260:                     goto nosyms;
                    261:                     }
                    262: 
                    263:                 if (!ReadFile( FileHandle, FpoTable, FpoTableSize, &BytesRead, NULL ) ||
                    264:                     FpoTableSize != BytesRead
                    265:                    ) {
                    266:                     goto nosyms;
                    267:                     }
                    268:                 }
                    269: 
                    270:             DebugDirectory += 1;
                    271:             }
                    272: 
                    273:         SizeOfSymbols = GetFileSize( FileHandle, &Unused ) - NewFileSize;
                    274:         Symbols = VirtualAlloc( NULL,
                    275:                                 SizeOfSymbols,
                    276:                                 MEM_COMMIT,
                    277:                                 PAGE_READWRITE
                    278:                               );
                    279:         if (Symbols == NULL) {
                    280:             goto nosyms;
                    281:             }
                    282:         SymbolsToFree = Symbols;
                    283: 
                    284:         if (SetFilePointer( FileHandle,
                    285:                             NewFileSize,
                    286:                             NULL,
                    287:                             FILE_BEGIN
                    288:                           ) != NewFileSize
                    289:            ) {
                    290:             goto nosyms;
                    291:             }
                    292: 
                    293:         if (!ReadFile( FileHandle, Symbols, SizeOfSymbols, &BytesRead, NULL ) ||
                    294:             SizeOfSymbols != BytesRead
                    295:            ) {
                    296:             goto nosyms;
                    297:             }
                    298:         Sections = NULL;
                    299:         }
                    300:     else {
                    301:         NewFileSize = Sections[ SectionNumber ].PointerToRawData;
                    302:         DebugDirectory = DebugDirectories;
                    303:         for (i=0; i<NumberOfDebugDirectories; i++) {
                    304:             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_MISC) {
                    305:                 NewFileSize = DebugDirectory->PointerToRawData +
                    306:                               DebugDirectory->SizeOfData;
                    307:                 MiscDebugDirectory = DebugDirectory;
                    308:                 }
                    309:             else
                    310:             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO) {
                    311:                 FpoTableSize = DebugDirectory->SizeOfData;
                    312:                 FpoTable = VirtualAlloc( NULL,
                    313:                                          FpoTableSize,
                    314:                                          MEM_COMMIT,
                    315:                                          PAGE_READWRITE
                    316:                                        );
                    317:                 if ( FpoTable == NULL) {
                    318:                     goto nosyms;
                    319:                     }
                    320: 
                    321:                 memmove( FpoTable,
                    322:                          ((PCHAR)ImageBase + DebugDirectory->PointerToRawData),
                    323:                          FpoTableSize
                    324:                        );
                    325:                 }
                    326: 
                    327:             DebugDirectory += 1;
                    328:             }
                    329: 
                    330:         Symbols = (PCHAR)ImageBase + NewFileSize;
                    331:         SizeOfSymbols = GetFileSize( FileHandle, &Unused ) - NewFileSize;
                    332:         }
                    333: 
                    334:     ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
                    335:         ImageDirectoryEntryToData( ImageBase,
                    336:                                    FALSE,
                    337:                                    IMAGE_DIRECTORY_ENTRY_EXPORT,
                    338:                                    &ExportDirectorySize
                    339:                                  );
                    340:     if (ExportDirectory) {
                    341:         //
                    342:         // This particular piece of magic gets us the RVA of the
                    343:         // EXPORT section.  Dont ask.
                    344:         //
                    345: 
                    346:         RvaOffset = (DWORD)
                    347:             ImageDirectoryEntryToData( ImageBase,
                    348:                                        TRUE,
                    349:                                        IMAGE_DIRECTORY_ENTRY_EXPORT,
                    350:                                        &ExportDirectorySize
                    351:                                      ) - (DWORD)ImageBase;
                    352: 
                    353:         pp = (LPDWORD)((DWORD)ExportDirectory +
                    354:                       (DWORD)ExportDirectory->AddressOfNames - RvaOffset
                    355:                      );
                    356: 
                    357:         ExportedNamesSize = 1;
                    358:         for (i=0; i<ExportDirectory->NumberOfNames; i++) {
                    359:             Src = (LPSTR)((DWORD)ExportDirectory + *pp++ - RvaOffset);
                    360:             ExportedNamesSize += strlen( Src ) + 1;
                    361:             }
                    362:         ExportedNamesSize = (ExportedNamesSize + 16) & ~15;
                    363: 
                    364:         Dst = (LPSTR)LocalAlloc( LPTR, ExportedNamesSize );
                    365:         if (Dst != NULL) {
                    366:             ExportedNames = Dst;
                    367:             pp = (LPDWORD)((DWORD)ExportDirectory +
                    368:                           (DWORD)ExportDirectory->AddressOfNames - RvaOffset
                    369:                          );
                    370:             for (i=0; i<ExportDirectory->NumberOfNames; i++) {
                    371:                 Src = (LPSTR)((DWORD)ExportDirectory + *pp++ - RvaOffset);
                    372:                 while (*Dst++ = *Src++) {
                    373:                     }
                    374:                 }
                    375:             }
                    376:         }
                    377:     else {
                    378:         ExportedNamesSize = 0;
                    379:         }
                    380: 
                    381:     RuntimeFunctionTable = (PIMAGE_RUNTIME_FUNCTION_ENTRY)
                    382:         ImageDirectoryEntryToData( ImageBase,
                    383:                                    FALSE,
                    384:                                    IMAGE_DIRECTORY_ENTRY_EXCEPTION,
                    385:                                    &RuntimeFunctionTableSize
                    386:                                  );
                    387:     if (RuntimeFunctionTable == NULL) {
                    388:         RuntimeFunctionTableSize = 0;
                    389:         FunctionTableSize = 0;
                    390:         FunctionTable = NULL;
                    391:         }
                    392:     else {
                    393:         NumberOfFunctionTableEntries = RuntimeFunctionTableSize / sizeof( IMAGE_RUNTIME_FUNCTION_ENTRY );
                    394:         FunctionTableSize = NumberOfFunctionTableEntries * sizeof( IMAGE_FUNCTION_ENTRY );
                    395:         FunctionTable = (PIMAGE_FUNCTION_ENTRY)VirtualAlloc( NULL,
                    396:                                                              FunctionTableSize,
                    397:                                                              MEM_COMMIT,
                    398:                                                              PAGE_READWRITE
                    399:                                                            );
                    400:         if (FunctionTable == NULL) {
                    401:             goto nosyms;
                    402:             }
                    403: 
                    404:         pSrc = RuntimeFunctionTable;
                    405:         pDst = FunctionTable;
                    406:         for (i=0; i<NumberOfFunctionTableEntries; i++) {
                    407:             //
                    408:             // Make .pdata entries in .DBG file relative.
                    409:             //
                    410:             pDst->StartingAddress = pSrc->BeginAddress - NtHeaders->OptionalHeader.ImageBase;
                    411:             pDst->EndingAddress = pSrc->EndAddress - NtHeaders->OptionalHeader.ImageBase;
                    412:             pDst->EndOfPrologue = pSrc->PrologEndAddress - NtHeaders->OptionalHeader.ImageBase;
                    413:             pSrc += 1;
                    414:             pDst += 1;
                    415:             }
                    416:         }
                    417: 
                    418:     if (!MakeSureDirectoryPathExists( SymbolFilePath )) {
                    419:         return FALSE;
                    420:         }
                    421: 
                    422:     SymbolFileHandle = CreateFile( SymbolFilePath,
                    423:                                    GENERIC_WRITE,
                    424:                                    0,
                    425:                                    NULL,
                    426:                                    CREATE_ALWAYS,
                    427:                                    0,
                    428:                                    NULL
                    429:                                  );
                    430:     if (SymbolFileHandle == INVALID_HANDLE_VALUE) {
                    431:         goto nosyms;
                    432:         }
                    433: 
                    434:     DbgFileHeaderSize = sizeof( DbgFileHeader ) +
                    435:                         (NtHeaders->FileHeader.NumberOfSections * sizeof( IMAGE_SECTION_HEADER )) +
                    436:                         ExportedNamesSize +
                    437:                         FunctionTableSize +
                    438:                         DebugDirectorySize;
                    439:     if (FunctionTable != NULL) {
                    440:         DbgFileHeaderSize += sizeof( PhonyFPODbgDir );
                    441:         memset( &PhonyFPODbgDir, 0, sizeof( PhonyFPODbgDir ) );
                    442:         PhonyFPODbgDir.Type = IMAGE_DEBUG_TYPE_EXCEPTION;
                    443:         PhonyFPODbgDir.SizeOfData = FunctionTableSize;
                    444:         PhonyFPODbgDir.PointerToRawData = DbgFileHeaderSize -
                    445:                                           FunctionTableSize;
                    446:         if (Sections != NULL) {
                    447:             PhonyFPODbgDir.PointerToRawData -= sizeof( IMAGE_SECTION_HEADER );
                    448:             }
                    449:         }
                    450:     DbgFileHeaderSize = ((DbgFileHeaderSize + 15) & ~15);
                    451: 
                    452:     if (SetFilePointer( SymbolFileHandle,
                    453:                         DbgFileHeaderSize,
                    454:                         NULL,
                    455:                         FILE_BEGIN
                    456:                       ) != DbgFileHeaderSize
                    457:        ) {
                    458:         BytesWritten = 0;
                    459:         }
                    460:     else {
                    461:         if (!WriteFile( SymbolFileHandle,
                    462:                         Symbols,
                    463:                         SizeOfSymbols,
                    464:                         &BytesWritten,
                    465:                         NULL
                    466:                       )
                    467:            ) {
                    468:             BytesWritten = 0;
                    469:             }
                    470:         }
                    471: 
                    472:     if (BytesWritten == SizeOfSymbols) {
                    473:         cb = DebugDirectorySize;
                    474:         DebugDirectory = DebugDirectories;
                    475:         while (cb >= sizeof( *DebugDirectory )) {
                    476:             if (DebugDirectory->AddressOfRawData) {
                    477:                 DebugDirectory->AddressOfRawData = 0;
                    478:                 }
                    479: 
                    480:             if (NewFileSize <= DebugDirectory->PointerToRawData) {
                    481:                 DebugDirectory->PointerToRawData -= NewFileSize;
                    482:                 DebugDirectory->PointerToRawData += DbgFileHeaderSize;
                    483:                 }
                    484: 
                    485:             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO) {
                    486:                 PhonyFPODbgDir = *DebugDirectory;
                    487:                 DebugDirectory->PointerToRawData = NewFileSize;
                    488:                 }
                    489: 
                    490:             DebugDirectory += 1;
                    491:             cb -= sizeof( *DebugDirectory );
                    492:             }
                    493: 
                    494:         NtHeaders->FileHeader.PointerToSymbolTable = 0;
                    495:         NtHeaders->FileHeader.Characteristics |= IMAGE_FILE_DEBUG_STRIPPED;
                    496: 
                    497:         if (Sections != NULL) {
                    498:             NtHeaders->OptionalHeader.SizeOfImage = Sections[ SectionNumber ].VirtualAddress;
                    499:             NtHeaders->OptionalHeader.SizeOfInitializedData -= Sections[ SectionNumber ].SizeOfRawData;
                    500:             NtHeaders->FileHeader.NumberOfSections -= 1;
                    501:             }
                    502: 
                    503:         if (MiscDebugDirectory != NULL && MiscDebugDirectory->Type == IMAGE_DEBUG_TYPE_MISC) {
                    504:             ImageNameOffset = MiscDebugDirectory->PointerToRawData +
                    505:                               FIELD_OFFSET( IMAGE_DEBUG_MISC, Data );
                    506:             if (SetFilePointer( FileHandle, ImageNameOffset, NULL, FILE_BEGIN ) == ImageNameOffset) {
                    507:                 WriteFile( FileHandle, ImageFilePathToSaveInImage, strlen( ImageFilePathToSaveInImage ) + 1, &Unused, NULL );
                    508:                 }
                    509:             }
                    510: 
                    511:         if (FpoTable) {
                    512:             memcpy( (PCHAR)ImageBase + NewFileSize,
                    513:                     FpoTable,
                    514:                     FpoTableSize
                    515:                   );
                    516: 
                    517:             NewFileSize += PhonyFPODbgDir.SizeOfData;
                    518:             }
                    519: 
                    520:         CheckSumMappedFile( ImageBase,
                    521:                             NewFileSize,
                    522:                             &HeaderSum,
                    523:                             &CheckSum
                    524:                           );
                    525:         NtHeaders->OptionalHeader.CheckSum = CheckSum;
                    526: 
                    527:         DbgFileHeader.Signature = IMAGE_SEPARATE_DEBUG_SIGNATURE;
                    528:         DbgFileHeader.Flags = 0;
                    529:         DbgFileHeader.Machine = NtHeaders->FileHeader.Machine;
                    530:         DbgFileHeader.Characteristics = NtHeaders->FileHeader.Characteristics;
                    531:         DbgFileHeader.TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
                    532:         DbgFileHeader.CheckSum = CheckSum;
                    533:         DbgFileHeader.ImageBase = NtHeaders->OptionalHeader.ImageBase;
                    534:         DbgFileHeader.SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
                    535:         DbgFileHeader.ExportedNamesSize = ExportedNamesSize;
                    536:         DbgFileHeader.DebugDirectorySize = DebugDirectorySize;
                    537:         DbgFileHeader.NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
                    538:         memset( DbgFileHeader.Reserved, 0, sizeof( DbgFileHeader.Reserved ) );
                    539:         DebugDirectory = DebugDirectories;
                    540: 
                    541:         SetFilePointer( SymbolFileHandle, 0, NULL, FILE_BEGIN );
                    542:         WriteFile( SymbolFileHandle,
                    543:                    &DbgFileHeader,
                    544:                    sizeof( DbgFileHeader ),
                    545:                    &BytesWritten,
                    546:                    NULL
                    547:                  );
                    548:         WriteFile( SymbolFileHandle,
                    549:                    IMAGE_FIRST_SECTION( NtHeaders ),
                    550:                    sizeof( IMAGE_SECTION_HEADER ) * NtHeaders->FileHeader.NumberOfSections,
                    551:                    &BytesWritten,
                    552:                    NULL
                    553:                  );
                    554: 
                    555:         if (ExportedNamesSize) {
                    556:             WriteFile( SymbolFileHandle,
                    557:                        ExportedNames,
                    558:                        ExportedNamesSize,
                    559:                        &BytesWritten,
                    560:                        NULL
                    561:                      );
                    562:             }
                    563: 
                    564:         if (FunctionTable) {
                    565:             WriteFile( SymbolFileHandle,
                    566:                        &PhonyFPODbgDir,
                    567:                        sizeof( PhonyFPODbgDir ),
                    568:                        &BytesWritten,
                    569:                        NULL
                    570:                      );
                    571:             }
                    572:         else
                    573:         if (FpoTable) {
                    574:             WriteFile( SymbolFileHandle,
                    575:                        &PhonyFPODbgDir,
                    576:                        sizeof( PhonyFPODbgDir ),
                    577:                        &BytesWritten,
                    578:                        NULL
                    579:                      );
                    580:             DebugDirectory += 1;
                    581:             DebugDirectorySize -= sizeof( PhonyFPODbgDir );
                    582:             }
                    583: 
                    584:         WriteFile( SymbolFileHandle,
                    585:                    DebugDirectory,
                    586:                    DebugDirectorySize,
                    587:                    &BytesWritten,
                    588:                    NULL
                    589:                  );
                    590: 
                    591:         if (FunctionTable) {
                    592:             WriteFile( SymbolFileHandle,
                    593:                        FunctionTable,
                    594:                        FunctionTableSize,
                    595:                        &BytesWritten,
                    596:                        NULL
                    597:                      );
                    598:             }
                    599: 
                    600:         SetFilePointer( SymbolFileHandle, 0, NULL, FILE_END );
                    601:         CloseHandle( SymbolFileHandle );
                    602: 
                    603:         FlushViewOfFile( ImageBase, NewFileSize );
                    604:         UnmapViewOfFile( ImageBase );
                    605:         CloseHandle( hMappedFile );
                    606:         if (SetFilePointer( FileHandle, NewFileSize, NULL, FILE_BEGIN ) != NewFileSize ||
                    607:             !SetEndOfFile( FileHandle )
                    608:            ) {
                    609:             }
                    610: 
                    611:         TouchFileTimes( FileHandle, NULL );
                    612:         CloseHandle( FileHandle );
                    613: 
                    614:         if (ExportedNames != NULL) {
                    615:             LocalFree( ExportedNames );
                    616:             }
                    617: 
                    618:         if (FpoTable != NULL) {
                    619:             VirtualFree( FpoTable, 0, MEM_RELEASE );
                    620:             }
                    621: 
                    622:         if (SymbolsToFree != NULL) {
                    623:             VirtualFree( SymbolsToFree, 0, MEM_RELEASE );
                    624:             }
                    625: 
                    626:         if (FunctionTable != NULL) {
                    627:             VirtualFree( FunctionTable, 0, MEM_RELEASE );
                    628:             }
                    629:         return TRUE;
                    630:         }
                    631:     else {
                    632:         CloseHandle( SymbolFileHandle );
                    633:         DeleteFile( SymbolFilePath );
                    634:         }
                    635: 
                    636: nosyms:
                    637:     SavedErrorCode = GetLastError();
                    638:     if (ExportedNames != NULL) {
                    639:         LocalFree( ExportedNames );
                    640:         }
                    641: 
                    642:     if (FpoTable != NULL) {
                    643:         VirtualFree( FpoTable, 0, MEM_RELEASE );
                    644:         }
                    645: 
                    646:     if (SymbolsToFree != NULL) {
                    647:         VirtualFree( SymbolsToFree, 0, MEM_RELEASE );
                    648:         }
                    649: 
                    650:     if (FunctionTable != NULL) {
                    651:         VirtualFree( FunctionTable, 0, MEM_RELEASE );
                    652:         }
                    653: 
                    654:     UnmapViewOfFile( ImageBase );
                    655:     CloseHandle( hMappedFile );
                    656:     CloseHandle( FileHandle );
                    657:     SetLastError( SavedErrorCode );
                    658:     return FALSE;
                    659: }
                    660: 
                    661: BOOL
                    662: SearchTreeForFile(
                    663:     LPSTR RootPath,
                    664:     PCHAR InputPathName,
                    665:     PCHAR OutputPathBuffer
                    666:     );
                    667: 
                    668: HANDLE
                    669: FindExecutableImage(
                    670:     LPSTR FileName,
                    671:     LPSTR SymbolPath,
                    672:     LPSTR ImageFilePath
                    673:     );
                    674: 
                    675: BOOL
                    676: GetImageNameFromMiscDebugData(
                    677:     HANDLE FileHandle,
                    678:     PVOID MappedBase,
                    679:     PIMAGE_NT_HEADERS NtHeaders,
                    680:     PIMAGE_DEBUG_DIRECTORY DebugDirectories,
                    681:     ULONG NumberOfDebugDirectories,
                    682:     LPSTR ImageFilePath
                    683:     );
                    684: 
                    685: PIMAGE_DEBUG_INFORMATION
                    686: MapDebugInformation(
                    687:     HANDLE FileHandle,
                    688:     LPSTR FileName,
                    689:     LPSTR SymbolPath,
                    690:     ULONG ImageBase
                    691:     )
                    692: {
                    693:     ULONG NumberOfHandlesToClose;
                    694:     HANDLE HandlesToClose[ 4 ];
                    695:     HANDLE MappingHandle;
                    696:     PVOID MappedBase, Next;
                    697:     BOOL SeparateSymbols;
                    698:     UCHAR ImageFilePath[ MAX_PATH ];
                    699:     UCHAR DebugFilePath[ MAX_PATH ];
                    700:     PIMAGE_DEBUG_INFORMATION DebugInfo;
                    701:     PIMAGE_NT_HEADERS NtHeaders;
                    702:     PIMAGE_DEBUG_DIRECTORY DebugDirectories;
                    703:     PIMAGE_DEBUG_DIRECTORY DebugDirectory;
                    704:     PIMAGE_SEPARATE_DEBUG_HEADER DebugFileHeader;
                    705:     PIMAGE_EXPORT_DIRECTORY ExportDirectory;
                    706:     PIMAGE_RUNTIME_FUNCTION_ENTRY RuntimeFunctionTable;
                    707:     PIMAGE_FUNCTION_ENTRY FunctionTable;
                    708:     ULONG NumberOfFunctionTableEntries, FunctionTableSize;
                    709:     PVOID DebugData;
                    710:     LPSTR Src, Dst;
                    711:     PULONG pp;
                    712:     ULONG RvaOffset;
                    713:     ULONG i, j;
                    714:     ULONG ExportedNamesSize;
                    715:     ULONG DebugInfoHeaderSize;
                    716:     ULONG DebugInfoSize;
                    717:     ULONG Size;
                    718:     ULONG NumberOfDebugDirectories;
                    719:     LONG BaseOffset;
                    720:     HANDLE SavedImageFileHandle;
                    721: 
                    722:     if (FileHandle == NULL && (FileName == NULL || FileName[ 0 ] == '\0')) {
                    723:         return NULL;
                    724:         }
                    725: 
                    726:     DebugInfo = NULL;
                    727:     NumberOfHandlesToClose = 0;
                    728:     MappedBase = NULL;
                    729:     SeparateSymbols = FALSE;
                    730:     SavedImageFileHandle = NULL;
                    731:     ImageFilePath[ 0 ] = '\0';
                    732:     NumberOfFunctionTableEntries = 0;
                    733:     FunctionTableSize = 0;
                    734:     FunctionTable = NULL; 
                    735:     try {
                    736:         try {
                    737:             if (FileHandle == NULL) {
                    738:                 FileHandle = FindExecutableImage( FileName, SymbolPath, ImageFilePath );
                    739:                 if (FileHandle == NULL) {
                    740:                     strcpy( ImageFilePath, FileName );
                    741: getDebugFile:
                    742:                     FileHandle = FindDebugInfoFile( FileName, SymbolPath, DebugFilePath );
                    743:                     if (FileHandle == NULL) {
                    744:                         if (SavedImageFileHandle != NULL) {
                    745:                             FileHandle = SavedImageFileHandle;
                    746:                             goto noDebugFile;
                    747:                             }
                    748:                         else {
                    749:                             leave;
                    750:                             }
                    751:                         }
                    752:                     else {
                    753:                         SeparateSymbols = TRUE;
                    754:                         }
                    755:                     }
                    756:                 else {
                    757:                     SavedImageFileHandle = FileHandle;
                    758:                     }
                    759: 
                    760:                 HandlesToClose[ NumberOfHandlesToClose++ ] = FileHandle;
                    761:                 }
                    762:             else {
                    763:                 SavedImageFileHandle = FileHandle;
                    764:                 }
                    765: 
                    766:             //
                    767:             //  map image file and process enough to get the image name and capture
                    768:             //  stuff from header.
                    769:             //
                    770: 
                    771:             MappingHandle = CreateFileMapping( FileHandle,
                    772:                                           NULL,
                    773:                                           PAGE_READONLY,
                    774:                                           0,
                    775:                                           0,
                    776:                                           NULL
                    777:                                         );
                    778:             if (MappingHandle == NULL) {
                    779:                 leave;
                    780:                 }
                    781:             HandlesToClose[ NumberOfHandlesToClose++ ] = MappingHandle;
                    782: 
                    783:             MappedBase = MapViewOfFile( MappingHandle,
                    784:                                         FILE_MAP_READ,
                    785:                                         0,
                    786:                                         0,
                    787:                                         0
                    788:                                       );
                    789:             if (MappedBase == NULL) {
                    790:                 leave;
                    791:                 }
                    792: 
                    793:             DebugInfoSize = sizeof( *DebugInfo ) + strlen( ImageFilePath ) + 1;
                    794:             if (SeparateSymbols) {
                    795:                 DebugInfoSize += strlen( DebugFilePath ) + 1;
                    796:                 }
                    797: 
                    798:             if (!SeparateSymbols) {
                    799:                 NtHeaders = ImageNtHeader( MappedBase );
                    800:                 if (NtHeaders == NULL) {
                    801:                     leave;
                    802:                     }
                    803: 
                    804:                 DebugDirectories = (PIMAGE_DEBUG_DIRECTORY)
                    805:                     ImageDirectoryEntryToData( MappedBase,
                    806:                                                FALSE,
                    807:                                                IMAGE_DIRECTORY_ENTRY_DEBUG,
                    808:                                                &Size
                    809:                                              );
                    810:                 if (DebugDirectories != NULL) {
                    811:                     NumberOfDebugDirectories = Size / sizeof( IMAGE_DEBUG_DIRECTORY );
                    812:                     }
                    813:                 else {
                    814:                     NumberOfDebugDirectories = 0;
                    815:                     }
                    816: 
                    817:                 if (FileName == NULL &&
                    818:                     GetImageNameFromMiscDebugData( FileHandle,
                    819:                                                    MappedBase,
                    820:                                                    NtHeaders,
                    821:                                                    DebugDirectories,
                    822:                                                    NumberOfDebugDirectories,
                    823:                                                    ImageFilePath
                    824:                                                  )
                    825:                    ) {
                    826:                     FileName = ImageFilePath;
                    827:                     DebugInfoSize += strlen( ImageFilePath );
                    828:                     }
                    829: 
                    830:                 DebugInfoSize = (DebugInfoSize + 16) & ~15;
                    831:                 DebugInfoHeaderSize = DebugInfoSize;
                    832: 
                    833:                 if (NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
                    834:                     goto getDebugFile;
                    835:                     }
                    836: 
                    837: noDebugFile:
                    838:                 ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)
                    839:                     ImageDirectoryEntryToData( MappedBase,
                    840:                                                FALSE,
                    841:                                                IMAGE_DIRECTORY_ENTRY_EXPORT,
                    842:                                                &Size
                    843:                                              );
                    844:                 if (ExportDirectory) {
                    845:                     //
                    846:                     // This particular piece of magic gets us the RVA of the
                    847:                     // EXPORT section.  Dont ask.
                    848:                     //
                    849: 
                    850:                     RvaOffset = (ULONG)
                    851:                         ImageDirectoryEntryToData( MappedBase,
                    852:                                                    TRUE,
                    853:                                                    IMAGE_DIRECTORY_ENTRY_EXPORT,
                    854:                                                    &Size
                    855:                                                  ) - (DWORD)MappedBase;
                    856: 
                    857:                     pp = (PULONG)((ULONG)ExportDirectory +
                    858:                                   (ULONG)ExportDirectory->AddressOfNames - RvaOffset
                    859:                                  );
                    860: 
                    861:                     ExportedNamesSize = 1;
                    862:                     for (i=0; i<ExportDirectory->NumberOfNames; i++) {
                    863:                         Src = (LPSTR)((ULONG)ExportDirectory + *pp++ - RvaOffset);
                    864:                         ExportedNamesSize += strlen( Src ) + 1;
                    865:                         }
                    866:                     ExportedNamesSize = (ExportedNamesSize + 16) & ~15;
                    867:                     DebugInfoSize += ExportedNamesSize;
                    868:                     }
                    869:                 else {
                    870:                     ExportedNamesSize = 0;
                    871:                     }
                    872: 
                    873:                 RuntimeFunctionTable = (PIMAGE_RUNTIME_FUNCTION_ENTRY)
                    874:                     ImageDirectoryEntryToData( MappedBase,
                    875:                                                FALSE,
                    876:                                                IMAGE_DIRECTORY_ENTRY_EXCEPTION,
                    877:                                                &Size
                    878:                                              );
                    879:                 if (RuntimeFunctionTable != NULL) {
                    880:                     NumberOfFunctionTableEntries = Size / sizeof( IMAGE_RUNTIME_FUNCTION_ENTRY );
                    881:                     FunctionTableSize = NumberOfFunctionTableEntries *
                    882:                                         sizeof( IMAGE_FUNCTION_ENTRY );
                    883: 
                    884:                     DebugInfoSize += FunctionTableSize;
                    885:                     }
                    886: 
                    887:                 if (NumberOfDebugDirectories != 0) {
                    888:                     DebugDirectory = DebugDirectories;
                    889:                     for (i=0; i<NumberOfDebugDirectories; i++) {
                    890:                         if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO ||
                    891:                             DebugDirectory->Type == IMAGE_DEBUG_TYPE_COFF
                    892:                            ) {
                    893:                             if (DebugDirectory->AddressOfRawData == 0) {
                    894:                                 DebugInfoSize += DebugDirectory->SizeOfData;
                    895:                                 }
                    896:                             }
                    897: 
                    898:                         DebugDirectory += 1;
                    899:                         }
                    900:                     }
                    901:                 }
                    902:             else {
                    903:                 DebugFileHeader = (PIMAGE_SEPARATE_DEBUG_HEADER)MappedBase;
                    904:                 Next = (PVOID)((PIMAGE_SECTION_HEADER)(DebugFileHeader + 1) + DebugFileHeader->NumberOfSections);
                    905:                 if (DebugFileHeader->ExportedNamesSize != 0) {
                    906:                     Next = (PVOID)((PCHAR)Next + DebugFileHeader->ExportedNamesSize);
                    907:                     }
                    908:                 DebugDirectories = (PIMAGE_DEBUG_DIRECTORY)Next;
                    909:                 DebugDirectory = DebugDirectories;
                    910:                 NumberOfDebugDirectories = DebugFileHeader->DebugDirectorySize / sizeof( IMAGE_DEBUG_DIRECTORY );
                    911: 
                    912:                 for (i=0; i<NumberOfDebugDirectories; i++) {
                    913:                     if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_EXCEPTION) {
                    914:                         FunctionTableSize = DebugDirectory->SizeOfData;
                    915:                         NumberOfFunctionTableEntries = FunctionTableSize / sizeof( IMAGE_FUNCTION_ENTRY );
                    916:                         break;
                    917:                         }
                    918: 
                    919:                     DebugDirectory += 1;
                    920:                     }
                    921: 
                    922:                 DebugInfoSize = (DebugInfoSize + 16) & ~15;
                    923:                 DebugInfoHeaderSize = DebugInfoSize;
                    924:                 DebugInfoSize += FunctionTableSize;
                    925:                 }
                    926: 
                    927:             DebugInfo = VirtualAlloc( NULL, DebugInfoSize, MEM_COMMIT, PAGE_READWRITE );
                    928:             if (DebugInfo == NULL) {
                    929:                 leave;
                    930:                 }
                    931: 
                    932:             DebugInfo->Size = DebugInfoSize;
                    933:             DebugInfo->ImageFilePath = (LPSTR)(DebugInfo + 1);
                    934:             strcpy( DebugInfo->ImageFilePath, ImageFilePath );
                    935:             Src = strchr( DebugInfo->ImageFilePath, '\0' );
                    936:             while (Src > DebugInfo->ImageFilePath) {
                    937:                 if (Src[ -1 ] == '\\' || Src[ -1 ] == '/' || Src[ -1 ] == ':') {
                    938:                     break;
                    939:                     }
                    940:                 else {
                    941:                     Src -= 1;
                    942:                     }
                    943:                 }
                    944:             DebugInfo->ImageFileName = Src;
                    945:             DebugInfo->DebugFilePath = DebugInfo->ImageFilePath;
                    946:             if (SeparateSymbols) {
                    947:                 DebugInfo->DebugFilePath += strlen( DebugInfo->ImageFilePath ) + 1;
                    948:                 strcpy( DebugInfo->DebugFilePath, DebugFilePath );
                    949:                 }
                    950: 
                    951:             DebugInfo->MappedBase = MappedBase;
                    952:             if (SeparateSymbols) {
                    953:                 DebugInfo->Machine = DebugFileHeader->Machine;
                    954:                 DebugInfo->Characteristics = DebugFileHeader->Characteristics;
                    955:                 DebugInfo->TimeDateStamp = DebugFileHeader->TimeDateStamp;
                    956:                 DebugInfo->CheckSum = DebugFileHeader->CheckSum;
                    957:                 DebugInfo->ImageBase = DebugFileHeader->ImageBase;
                    958:                 DebugInfo->SizeOfImage = DebugFileHeader->SizeOfImage;
                    959:                 DebugInfo->NumberOfSections = DebugFileHeader->NumberOfSections;
                    960:                 DebugInfo->Sections = (PIMAGE_SECTION_HEADER)(DebugFileHeader + 1);
                    961:                 Next = (PVOID)(DebugInfo->Sections + DebugInfo->NumberOfSections);
                    962: 
                    963:                 DebugInfo->ExportedNamesSize = DebugFileHeader->ExportedNamesSize;
                    964:                 if (DebugInfo->ExportedNamesSize) {
                    965:                     DebugInfo->ExportedNames = (LPSTR)Next;
                    966:                     Next = (PVOID)((PCHAR)Next + DebugInfo->ExportedNamesSize);
                    967:                     }
                    968:                 DebugDirectory = DebugDirectories;
                    969:                 NumberOfDebugDirectories = DebugFileHeader->DebugDirectorySize / sizeof( IMAGE_DEBUG_DIRECTORY );
                    970:                 Next = (PVOID)((PCHAR)Next + DebugFileHeader->DebugDirectorySize);
                    971:                 for (i=0; i<NumberOfDebugDirectories; i++) {
                    972:                     if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_EXCEPTION) {
                    973:                         DebugInfo->NumberOfFunctionTableEntries = NumberOfFunctionTableEntries;
                    974:                         DebugInfo->FunctionTableEntries = (PIMAGE_FUNCTION_ENTRY)
                    975:                             ((PCHAR)MappedBase + DebugDirectory->PointerToRawData);
                    976: 
                    977:                         BaseOffset = ImageBase;
                    978:                         FunctionTable = (PIMAGE_FUNCTION_ENTRY)((ULONG)DebugInfo + DebugInfoHeaderSize);
                    979:                         memmove( FunctionTable, DebugInfo->FunctionTableEntries, FunctionTableSize );
                    980:                         DebugInfo->FunctionTableEntries = FunctionTable;
                    981:                         DebugInfo->LowestFunctionStartingAddress = (ULONG)0xFFFFFFFF;
                    982:                         DebugInfo->HighestFunctionEndingAddress = 0;
                    983:                         for (j=0; j<DebugInfo->NumberOfFunctionTableEntries; j++) {
                    984:                             FunctionTable->StartingAddress += BaseOffset;
                    985:                             if (FunctionTable->StartingAddress < DebugInfo->LowestFunctionStartingAddress) {
                    986:                                 DebugInfo->LowestFunctionStartingAddress = FunctionTable->StartingAddress;
                    987:                                 }
                    988: 
                    989:                             FunctionTable->EndingAddress += BaseOffset;
                    990:                             if (FunctionTable->EndingAddress > DebugInfo->HighestFunctionEndingAddress) {
                    991:                                 DebugInfo->HighestFunctionEndingAddress = FunctionTable->EndingAddress;
                    992:                                 }
                    993: 
                    994:                             FunctionTable->EndOfPrologue += BaseOffset;
                    995:                             FunctionTable += 1;
                    996:                             }
                    997:                         }
                    998:                     else
                    999:                     if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO) {
                   1000:                         DebugInfo->NumberOfFpoTableEntries =
                   1001:                             DebugDirectory->SizeOfData / sizeof( FPO_DATA );
                   1002:                         DebugInfo->FpoTableEntries = (PFPO_DATA)
                   1003:                             ((PCHAR)MappedBase + DebugDirectory->PointerToRawData);
                   1004:                         }
                   1005:                     else
                   1006:                     if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_COFF) {
                   1007:                         DebugInfo->SizeOfCoffSymbols = DebugDirectory->SizeOfData;
                   1008:                         DebugInfo->CoffSymbols = (PIMAGE_COFF_SYMBOLS_HEADER)
                   1009:                             ((PCHAR)MappedBase + DebugDirectory->PointerToRawData);
                   1010:                         }
                   1011: 
                   1012:                     DebugDirectory += 1;
                   1013:                     }
                   1014:                 }
                   1015:             else {
                   1016:                 DebugInfo->Machine = NtHeaders->FileHeader.Machine;
                   1017:                 DebugInfo->Characteristics = NtHeaders->FileHeader.Characteristics;
                   1018:                 DebugInfo->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
                   1019:                 DebugInfo->CheckSum = NtHeaders->OptionalHeader.CheckSum;
                   1020:                 DebugInfo->ImageBase = NtHeaders->OptionalHeader.ImageBase;
                   1021:                 DebugInfo->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
                   1022:                 DebugInfo->NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
                   1023:                 DebugInfo->Sections = IMAGE_FIRST_SECTION( NtHeaders );
                   1024:                 Next = (PVOID)((ULONG)DebugInfo + DebugInfoHeaderSize);
                   1025: 
                   1026:                 DebugInfo->ExportedNamesSize = ExportedNamesSize;
                   1027:                 if (DebugInfo->ExportedNamesSize) {
                   1028:                     DebugInfo->ExportedNames = (LPSTR)Next;
                   1029:                     Next = (PVOID)((LPSTR)Next + ExportedNamesSize);
                   1030: 
                   1031:                     pp = (PULONG)((ULONG)ExportDirectory +
                   1032:                                   (ULONG)ExportDirectory->AddressOfNames - RvaOffset
                   1033:                                  );
                   1034: 
                   1035:                     Dst = DebugInfo->ExportedNames;
                   1036:                     for (i=0; i<ExportDirectory->NumberOfNames; i++) {
                   1037:                         Src = (LPSTR)((ULONG)ExportDirectory + *pp++ - RvaOffset);
                   1038:                         while (*Dst++ = *Src++) {
                   1039:                             }
                   1040:                         }
                   1041:                     }
                   1042: 
                   1043:                 if (RuntimeFunctionTable != NULL) {
                   1044:                     BaseOffset = ImageBase - DebugInfo->ImageBase;
                   1045:                     DebugInfo->FunctionTableEntries = (PIMAGE_FUNCTION_ENTRY)Next;
                   1046:                     DebugInfo->NumberOfFunctionTableEntries = NumberOfFunctionTableEntries;
                   1047:                     Next = (PVOID)((LPSTR)Next + FunctionTableSize);
                   1048: 
                   1049:                     DebugInfo->LowestFunctionStartingAddress = (ULONG)0xFFFFFFFF;
                   1050:                     DebugInfo->HighestFunctionEndingAddress = 0;
                   1051:                     FunctionTable = DebugInfo->FunctionTableEntries;
                   1052:                     for (i=0; i<NumberOfFunctionTableEntries; i++) {
                   1053:                         FunctionTable->StartingAddress = RuntimeFunctionTable->BeginAddress + BaseOffset;
                   1054:                         if (FunctionTable->StartingAddress < DebugInfo->LowestFunctionStartingAddress) {
                   1055:                             DebugInfo->LowestFunctionStartingAddress = FunctionTable->StartingAddress;
                   1056:                             }
                   1057: 
                   1058:                         FunctionTable->EndingAddress = RuntimeFunctionTable->EndAddress + BaseOffset;
                   1059:                         if (FunctionTable->EndingAddress > DebugInfo->HighestFunctionEndingAddress) {
                   1060:                             DebugInfo->HighestFunctionEndingAddress = FunctionTable->EndingAddress;
                   1061:                             }
                   1062: 
                   1063:                         FunctionTable->EndOfPrologue = RuntimeFunctionTable->PrologEndAddress + BaseOffset;
                   1064:                         RuntimeFunctionTable += 1;
                   1065:                         FunctionTable += 1;
                   1066:                         }
                   1067:                     }
                   1068: 
                   1069:                 DebugDirectory = DebugDirectories;
                   1070:                 for (i=0; i<NumberOfDebugDirectories; i++) {
                   1071:                     if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO ||
                   1072:                         ((DebugDirectory->Type == IMAGE_DEBUG_TYPE_COFF) &&
                   1073:                          !(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
                   1074:                         )
                   1075:                        ) {
                   1076:                         DebugData = NULL;
                   1077:                         if (DebugDirectory->AddressOfRawData == 0) {
                   1078:                             if (SetFilePointer( FileHandle,
                   1079:                                                 DebugDirectory->PointerToRawData,
                   1080:                                                 NULL,
                   1081:                                                 FILE_BEGIN
                   1082:                                               ) == DebugDirectory->PointerToRawData
                   1083:                                ) {
                   1084:                                 if (ReadFile( FileHandle,
                   1085:                                               Next,
                   1086:                                               DebugDirectory->SizeOfData,
                   1087:                                               &Size,
                   1088:                                               NULL
                   1089:                                             ) &&
                   1090:                                     DebugDirectory->SizeOfData == Size
                   1091:                                    ) {
                   1092:                                     DebugData = Next;
                   1093:                                     Next = (PVOID)((LPSTR)Next + Size);
                   1094:                                     }
                   1095:                                 }
                   1096:                             }
                   1097:                         else {
                   1098:                             DebugData = (LPSTR)MappedBase + DebugDirectory->PointerToRawData;
                   1099:                             Size = DebugDirectory->SizeOfData;
                   1100:                             }
                   1101: 
                   1102:                         if (DebugData != NULL) {
                   1103:                             if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_FPO) {
                   1104:                                 DebugInfo->FpoTableEntries = DebugData;
                   1105:                                 DebugInfo->NumberOfFpoTableEntries = Size / sizeof( FPO_DATA );
                   1106:                                 }
                   1107:                             else {
                   1108:                                 DebugInfo->CoffSymbols = DebugData;
                   1109:                                 DebugInfo->SizeOfCoffSymbols = Size;
                   1110:                                 }
                   1111:                             }
                   1112:                         }
                   1113: 
                   1114:                     DebugDirectory += 1;
                   1115:                     }
                   1116:                 }
                   1117:             }
                   1118:         except( EXCEPTION_EXECUTE_HANDLER ) {
                   1119:             if (DebugInfo != NULL) {
                   1120:                 VirtualFree( DebugInfo, 0, MEM_RELEASE );
                   1121:                 DebugInfo = NULL;
                   1122:                 }
                   1123:             }
                   1124:         }
                   1125:     finally {
                   1126:         if (DebugInfo == NULL) {
                   1127:             if (MappedBase != NULL) {
                   1128:                 UnmapViewOfFile( MappedBase );
                   1129:                 }
                   1130:             }
                   1131: 
                   1132:         while (NumberOfHandlesToClose--) {
                   1133:             CloseHandle( HandlesToClose[ NumberOfHandlesToClose ] );
                   1134:             }
                   1135:         }
                   1136: 
                   1137:     return DebugInfo;
                   1138: }
                   1139: 
                   1140: 
                   1141: BOOL
                   1142: UnmapDebugInformation(
                   1143:     PIMAGE_DEBUG_INFORMATION DebugInfo
                   1144:     )
                   1145: {
                   1146:     if (DebugInfo != NULL) {
                   1147:         try {
                   1148:             UnmapViewOfFile( DebugInfo->MappedBase );
                   1149:             memset( DebugInfo, 0, sizeof( *DebugInfo ) );
                   1150:             VirtualFree( DebugInfo, 0, MEM_RELEASE );
                   1151:             }
                   1152:         except( EXCEPTION_EXECUTE_HANDLER ) {
                   1153:             return FALSE;
                   1154:             }
                   1155:         }
                   1156: 
                   1157:     return TRUE;
                   1158: }
                   1159: 
                   1160: HANDLE
                   1161: FindExecutableImage(
                   1162:     LPSTR FileName,
                   1163:     LPSTR SymbolPath,
                   1164:     LPSTR ImageFilePath
                   1165:     )
                   1166: {
                   1167:     LPSTR Start, End;
                   1168:     HANDLE FileHandle;
                   1169:     UCHAR DirectoryPath[ MAX_PATH ];
                   1170: 
                   1171:     Start = SymbolPath;
                   1172:     while (Start && *Start != '\0') {
                   1173:         if (End = strchr( Start, ';' )) {
                   1174:             strncpy( DirectoryPath, Start, End - Start );
                   1175:             DirectoryPath[ End - Start ] = '\0';
                   1176:             End += 1;
                   1177:             }
                   1178:         else {
                   1179:             strcpy( DirectoryPath, Start );
                   1180:             }
                   1181: 
                   1182:         if (SearchTreeForFile( DirectoryPath, FileName, ImageFilePath )) {
                   1183:             FileHandle = CreateFile( ImageFilePath,
                   1184:                                      GENERIC_READ,
                   1185:                                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                   1186:                                      NULL,
                   1187:                                      OPEN_EXISTING,
                   1188:                                      0,
                   1189:                                      NULL
                   1190:                                    );
                   1191:             if (FileHandle != INVALID_HANDLE_VALUE) {
                   1192:                 return FileHandle;
                   1193:                 }
                   1194:             }
                   1195: 
                   1196:         Start = End;
                   1197:         }
                   1198: 
                   1199:     return NULL;
                   1200: }
                   1201: 
                   1202: 
                   1203: HANDLE
                   1204: FindDebugInfoFile(
                   1205:     LPSTR FileName,
                   1206:     LPSTR SymbolPath,
                   1207:     LPSTR DebugFilePath
                   1208:     )
                   1209: {
                   1210:     HANDLE FileHandle;
                   1211:     LPSTR s;
                   1212:     LPSTR Start, End;
                   1213:     UCHAR BaseName[ MAX_PATH ];
                   1214:     DWORD n;
                   1215: 
                   1216:     if (!(s = strrchr( FileName, '.' )) || stricmp( s, ".DBG" )) {
                   1217:         if (s != NULL) {
                   1218:             strcpy( BaseName, s+1 );
                   1219:             strcat( BaseName, "\\" );
                   1220:             }
                   1221:         else {
                   1222:             BaseName[ 0 ] = '\0';
                   1223:             }
                   1224: 
                   1225:         s = FileName + strlen( FileName );
                   1226:         while (s > FileName) {
                   1227:             if (*--s == '\\' || *s == '/' || *s == ':') {
                   1228:                 s += 1;
                   1229:                 break;
                   1230:                 }
                   1231:             }
                   1232:         strcat( BaseName, s );
                   1233:         if (!(s = strrchr( BaseName, '.' ))) {
                   1234:             s = strchr( BaseName, '\0' );
                   1235:             }
                   1236:         strcpy( s, ".DBG" );
                   1237:         }
                   1238:     else {
                   1239:         strcpy( BaseName, FileName );
                   1240:         }
                   1241: 
                   1242:     Start = SymbolPath;
                   1243:     while (Start && *Start != '\0') {
                   1244:         if (End = strchr( Start, ';' )) {
                   1245:             *End = '\0';
                   1246:             }
                   1247: 
                   1248:         n = GetFullPathName( Start, MAX_PATH, DebugFilePath, &s );
                   1249:         if (End) {
                   1250:             *End++ = ';';
                   1251:             }
                   1252:         Start = End;
                   1253:         if (n == 0) {
                   1254:             continue;
                   1255:             }
                   1256: 
                   1257:         if (s != NULL && !stricmp( s, "Symbols" )) {
                   1258:             strcat( DebugFilePath, "\\" );
                   1259:             }
                   1260:         else {
                   1261:             strcat( DebugFilePath, "\\Symbols\\" );
                   1262:             }
                   1263:         strcat( DebugFilePath, BaseName );
                   1264: 
                   1265:         FileHandle = CreateFile( DebugFilePath,
                   1266:                                  GENERIC_READ,
                   1267:                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                   1268:                                  NULL,
                   1269:                                  OPEN_EXISTING,
                   1270:                                  0,
                   1271:                                  NULL
                   1272:                                );
                   1273:         if (FileHandle != INVALID_HANDLE_VALUE) {
                   1274:             return FileHandle;
                   1275:             }
                   1276:         }
                   1277: 
                   1278:     return NULL;
                   1279: }
                   1280: 
                   1281: BOOL
                   1282: GetImageNameFromMiscDebugData(
                   1283:     HANDLE FileHandle,
                   1284:     PVOID MappedBase,
                   1285:     PIMAGE_NT_HEADERS NtHeaders,
                   1286:     PIMAGE_DEBUG_DIRECTORY DebugDirectories,
                   1287:     ULONG NumberOfDebugDirectories,
                   1288:     LPSTR ImageFilePath
                   1289:     )
                   1290: {
                   1291:     IMAGE_DEBUG_MISC TempMiscData;
                   1292:     PIMAGE_DEBUG_MISC DebugMiscData;
                   1293:     ULONG BytesToRead, BytesRead;
                   1294:     BOOLEAN FoundImageName;
                   1295:     LPSTR ImageName;
                   1296: 
                   1297:     while (NumberOfDebugDirectories) {
                   1298:         if (DebugDirectories->Type == IMAGE_DEBUG_TYPE_MISC) {
                   1299:             break;
                   1300:             }
                   1301:         else {
                   1302:             DebugDirectories += 1;
                   1303:             NumberOfDebugDirectories -= 1;
                   1304:             }
                   1305:         }
                   1306: 
                   1307:     if (NumberOfDebugDirectories == 0) {
                   1308:         return FALSE;
                   1309:         }
                   1310: 
                   1311:     if (NtHeaders->OptionalHeader.MinorLinkerVersion < 36) {
                   1312:         BytesToRead = FIELD_OFFSET( IMAGE_DEBUG_MISC, Reserved );
                   1313:         }
                   1314:     else {
                   1315:         BytesToRead = FIELD_OFFSET( IMAGE_DEBUG_MISC, Data );
                   1316:         }
                   1317: 
                   1318:     DebugMiscData = NULL;
                   1319:     if (DebugDirectories->AddressOfRawData == 0) {
                   1320:         if (SetFilePointer( FileHandle,
                   1321:                             DebugDirectories->PointerToRawData,
                   1322:                             NULL,
                   1323:                             FILE_BEGIN
                   1324:                           ) == DebugDirectories->PointerToRawData
                   1325:            ) {
                   1326:             if (ReadFile( FileHandle,
                   1327:                           &TempMiscData,
                   1328:                           BytesToRead,
                   1329:                           &BytesRead,
                   1330:                           NULL
                   1331:                         ) &&
                   1332:                 BytesRead == BytesToRead
                   1333:                ) {
                   1334:                 DebugMiscData = &TempMiscData;
                   1335:                 }
                   1336:             }
                   1337:         }
                   1338:     else {
                   1339:         DebugMiscData = (PIMAGE_DEBUG_MISC)((PCHAR)MappedBase +
                   1340:                                             DebugDirectories->PointerToRawData
                   1341:                                            );
                   1342:         }
                   1343: 
                   1344:     FoundImageName = FALSE;
                   1345:     if (DebugMiscData != NULL && DebugMiscData->DataType == IMAGE_DEBUG_MISC_EXENAME) {
                   1346:         if (DebugMiscData == &TempMiscData) {
                   1347:             BytesToRead = DebugMiscData->Length - BytesToRead;
                   1348:             if (ReadFile( FileHandle,
                   1349:                           ImageFilePath,
                   1350:                           BytesToRead,
                   1351:                           &BytesRead,
                   1352:                           NULL
                   1353:                         ) &&
                   1354:                 BytesRead == BytesToRead
                   1355:                ) {
                   1356:                 FoundImageName = TRUE;
                   1357:                 }
                   1358:             }
                   1359:         else {
                   1360:             ImageName = (PCHAR)DebugMiscData + BytesToRead;
                   1361:             BytesToRead = DebugMiscData->Length - BytesToRead;
                   1362:             if (*ImageName != '\0' ) {
                   1363:                 memcpy( ImageFilePath, ImageName, BytesToRead );
                   1364:                 FoundImageName = TRUE;
                   1365:                 }
                   1366:             }
                   1367:         }
                   1368: 
                   1369:     return FoundImageName;
                   1370: }
                   1371: 
                   1372: 
                   1373: 
                   1374: #define MAX_DEPTH 32
                   1375: 
                   1376: BOOL
                   1377: SearchTreeForFile(
                   1378:     LPSTR RootPath,
                   1379:     LPSTR InputPathName,
                   1380:     LPSTR OutputPathBuffer
                   1381:     )
                   1382: {
                   1383:     PCHAR FileName;
                   1384:     PUCHAR Prefix = "";
                   1385:     CHAR PathBuffer[ MAX_PATH ];
                   1386:     ULONG Depth;
                   1387:     PCHAR PathTail[ MAX_DEPTH ];
                   1388:     PCHAR FindHandle[ MAX_DEPTH ];
                   1389:     LPWIN32_FIND_DATA FindFileData;
                   1390:     UCHAR FindFileBuffer[ MAX_PATH + sizeof( WIN32_FIND_DATA ) ];
                   1391:     BOOL Result;
                   1392: 
                   1393:     strcpy( PathBuffer, RootPath );
                   1394:     FileName = InputPathName;
                   1395:     while (*InputPathName) {
                   1396:         if (*InputPathName == ':' || *InputPathName == '\\' || *InputPathName == '/') {
                   1397:             FileName = ++InputPathName;
                   1398:             }
                   1399:         else {
                   1400:             InputPathName++;
                   1401:             }
                   1402:         }
                   1403:     FindFileData = (LPWIN32_FIND_DATA)FindFileBuffer;
                   1404:     Depth = 0;
                   1405:     Result = FALSE;
                   1406:     while (TRUE) {
                   1407: startDirectorySearch:
                   1408:         PathTail[ Depth ] = strchr( PathBuffer, '\0' );
                   1409:         if (PathTail[ Depth ] > PathBuffer && PathTail[ Depth ][ -1 ] != '\\') {
                   1410:             *(PathTail[ Depth ])++ = '\\';
                   1411:             }
                   1412: 
                   1413:         strcpy( PathTail[ Depth ], "*.*" );
                   1414:         FindHandle[ Depth ] = FindFirstFile( PathBuffer, FindFileData );
                   1415:         if (FindHandle[ Depth ] != INVALID_HANDLE_VALUE) {
                   1416:             do {
                   1417:                 if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                   1418:                     if (strcmp( FindFileData->cFileName, "." ) &&
                   1419:                         strcmp( FindFileData->cFileName, ".." ) &&
                   1420:                         Depth < MAX_DEPTH
                   1421:                        ) {
                   1422:                         sprintf( PathTail[ Depth ], "%s\\", FindFileData->cFileName );
                   1423:                         Depth++;
                   1424:                         goto startDirectorySearch;
                   1425:                         }
                   1426:                     }
                   1427:                 else
                   1428:                 if (!stricmp( FindFileData->cFileName, FileName )) {
                   1429:                     strcpy( PathTail[ Depth ], FindFileData->cFileName );
                   1430:                     strcpy( OutputPathBuffer, PathBuffer );
                   1431:                     Result = TRUE;
                   1432:                     }
                   1433: 
                   1434: restartDirectorySearch:
                   1435:                 if (Result) {
                   1436:                     break;
                   1437:                     }
                   1438:                 }
                   1439:             while (FindNextFile( FindHandle[ Depth ], FindFileData ));
                   1440:             FindClose( FindHandle[ Depth ] );
                   1441: 
                   1442:             if (Depth == 0) {
                   1443:                 break;
                   1444:                 }
                   1445: 
                   1446:             Depth--;
                   1447:             goto restartDirectorySearch;
                   1448:             }
                   1449:         }
                   1450: 
                   1451:     return Result;
                   1452: }
                   1453: 
                   1454: 
                   1455: BOOL
                   1456: MakeSureDirectoryPathExists(
                   1457:     LPSTR DirPath
                   1458:     )
                   1459: {
                   1460:     LPSTR Dir,p;
                   1461:     DWORD dw;
                   1462: 
                   1463:     Dir = DirPath;
                   1464:     p = Dir+1;
                   1465: 
                   1466:     //
                   1467:     //  If the second character in the path is "\", then this is a UNC
                   1468:     //  path, and we should skip forward until we reach the 2nd \ in the
                   1469:     //  path.
                   1470:     //
                   1471:     if (*p == '\\') {
                   1472:         p++;            // Skip over the second \ in the name.
                   1473: 
                   1474:         //
                   1475:         //  Skip until we hit the first "\" (\\Server\).
                   1476:         //
                   1477: 
                   1478:         while (*p && *p != '\\') {
                   1479:             p++;
                   1480:             }
                   1481: 
                   1482:         if (*p) {
                   1483:             *p++;
                   1484:             }
                   1485: 
                   1486:         //
                   1487:         //  Skip until we hit the second "\" (\\Server\Share\).
                   1488:         //
                   1489: 
                   1490:         while (*p && *p != '\\') {
                   1491:             p++;
                   1492:             }
                   1493: 
                   1494:         //
                   1495:         //  The directory to check is the "path" part of \\Server\Share\path
                   1496:         //
                   1497: 
                   1498:         if (*p) {
                   1499:             Dir = p-1;
                   1500:             }
                   1501:         }
                   1502:     else if (*p == ':' ) {
                   1503:         p++;
                   1504:         p++;
                   1505:         }
                   1506: 
                   1507:     while( *p ) {
                   1508:         if ( *p == '\\' ) {
                   1509:             *p = '\0';
                   1510:             dw = GetFileAttributes(DirPath);
                   1511:             if ( dw == 0xffffffff || dw & FILE_ATTRIBUTE_DIRECTORY != FILE_ATTRIBUTE_DIRECTORY ) {
                   1512:                 if ( dw == 0xffffffff ) {
                   1513:                     if ( !CreateDirectory(DirPath,NULL) ) {
                   1514:                         return FALSE;
                   1515:                         }
                   1516:                     }
                   1517:                 }
                   1518: 
                   1519:             *p = '\\';
                   1520:             }
                   1521:         p++;
                   1522:         }
                   1523: 
                   1524:     return TRUE;
                   1525: }
                   1526: 
                   1527: 
                   1528: BOOL
                   1529: UpdateDebugInfoFile(
                   1530:     LPSTR ImageFileName,
                   1531:     LPSTR SymbolPath,
                   1532:     LPSTR DebugFilePath,
                   1533:     PIMAGE_NT_HEADERS NtHeaders
                   1534:     )
                   1535: {
                   1536:     HANDLE hDebugFile, hMappedFile;
                   1537:     PVOID MappedAddress;
                   1538:     PIMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader;
                   1539: 
                   1540:     hDebugFile = FindDebugInfoFile(
                   1541:                     ImageFileName,
                   1542:                     SymbolPath,
                   1543:                     DebugFilePath
                   1544:                     );
                   1545:     if ( hDebugFile == NULL ) {
                   1546:         return FALSE;
                   1547:         }
                   1548:     CloseHandle(hDebugFile);
                   1549: 
                   1550:     hDebugFile = CreateFile( DebugFilePath,
                   1551:                              GENERIC_READ | GENERIC_WRITE,
                   1552:                              FILE_SHARE_READ | FILE_SHARE_WRITE,
                   1553:                              NULL,
                   1554:                              OPEN_EXISTING,
                   1555:                              0,
                   1556:                              NULL
                   1557:                            );
                   1558:     if ( hDebugFile == INVALID_HANDLE_VALUE ) {
                   1559:         return FALSE;
                   1560:         }
                   1561: 
                   1562:     hMappedFile = CreateFileMapping(
                   1563:                     hDebugFile,
                   1564:                     NULL,
                   1565:                     PAGE_READWRITE,
                   1566:                     0,
                   1567:                     0,
                   1568:                     NULL
                   1569:                     );
                   1570:     if ( !hMappedFile ) {
                   1571:         CloseHandle(hDebugFile);
                   1572:         return FALSE;
                   1573:         }
                   1574: 
                   1575:     MappedAddress = MapViewOfFile(hMappedFile,
                   1576:                         FILE_MAP_WRITE,
                   1577:                         0,
                   1578:                         0,
                   1579:                         0
                   1580:                         );
                   1581:     CloseHandle(hMappedFile);
                   1582:     if ( !MappedAddress ) {
                   1583:         CloseHandle(hDebugFile);
                   1584:         return FALSE;
                   1585:         }
                   1586: 
                   1587:     DbgFileHeader = (PIMAGE_SEPARATE_DEBUG_HEADER)MappedAddress;
                   1588:     if (DbgFileHeader->ImageBase != NtHeaders->OptionalHeader.ImageBase ||
                   1589:         DbgFileHeader->CheckSum != NtHeaders->OptionalHeader.CheckSum
                   1590:        ) {
                   1591:         DbgFileHeader->ImageBase = NtHeaders->OptionalHeader.ImageBase;
                   1592:         DbgFileHeader->CheckSum = NtHeaders->OptionalHeader.CheckSum;
                   1593:         UnmapViewOfFile(MappedAddress);
                   1594:         FlushViewOfFile(MappedAddress,0);
                   1595:         TouchFileTimes(hDebugFile,NULL);
                   1596:         CloseHandle(hDebugFile);
                   1597:         return TRUE;
                   1598:         }
                   1599:     else {
                   1600:         UnmapViewOfFile(MappedAddress);
                   1601:         FlushViewOfFile(MappedAddress,0);
                   1602:         CloseHandle(hDebugFile);
                   1603:         return FALSE;
                   1604:         }
                   1605: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.