Annotation of mstools/samples/sdktools/image/imagehlp/debug.c, revision 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.