Annotation of mstools/samples/sdktools/image/drwatson/module.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     module.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file implements the module load debug events.
                     12: 
                     13: Author:
                     14: 
                     15:     Wesley Witt (wesw) 1-May-1993
                     16: 
                     17: Environment:
                     18: 
                     19:     User Mode
                     20: 
                     21: --*/
                     22: 
                     23: #include <windows.h>
                     24: #include <stdlib.h>
                     25: #include <stdio.h>
                     26: #include <string.h>
                     27: 
                     28: #include "drwatson.h"
                     29: #include "proto.h"
                     30: #include "messages.h"
                     31: 
                     32: //
                     33: // defines for symbol (.dbg) file searching
                     34: //
                     35: #define SYMBOL_PATH             "_NT_SYMBOL_PATH"
                     36: #define ALTERNATE_SYMBOL_PATH   "_NT_ALT_SYMBOL_PATH"
                     37: 
                     38: //
                     39: // local prototypes
                     40: //
                     41: void ExtractDebugInfoFromImage( PMODULEINFO mi );
                     42: LPSTR GetSymbolSearchPath( void );
                     43: BOOL NormalizeFilename( char *szName );
                     44: HANDLE FindDebugInfoFile( LPSTR FileName, LPSTR SymbolPath, LPSTR DebugFilePath );
                     45: BOOL SearchTreeForFile(LPSTR RootPath,PCHAR InputPathName,PCHAR OutputPathBuffer);
                     46: BOOL GetDebugInfoFromDbg( PMODULEINFO mi, PUCHAR fptr );
                     47: BOOL GetDebugInfoFromExe( PMODULEINFO mi, PUCHAR fptr );
                     48: PMODULEINFO AllocMi( PDEBUGPACKET dp );
                     49: 
                     50: 
                     51: 
                     52: BOOL
                     53: ProcessModuleLoad ( PDEBUGPACKET dp, LPDEBUG_EVENT de )
                     54: 
                     55: /*++
                     56: 
                     57: Routine Description:
                     58: 
                     59:     Process all module load debug events, create process & dll load.
                     60:     The purpose is to allocate a MODULEINFO structure, fill in the
                     61:     necessary values, and load the symbol table.
                     62: 
                     63: Arguments:
                     64: 
                     65:     dp      - pointer to a debug packet
                     66:     de      - pointer to a debug event structure
                     67: 
                     68: Return Value:
                     69: 
                     70:     TRUE    - everything worked
                     71:     FALSE   - we're hosed
                     72: 
                     73: --*/
                     74: 
                     75: {
                     76:     HANDLE                    hFile            = NULL;
                     77:     DWORD                     len              = 0;
                     78:     DWORD                     li               = 0;
                     79:     LPSTR                     lpSymbolPath     = NULL;
                     80:     LPSTR                     DebugFilePath    = NULL;
                     81:     PIMAGE_DOS_HEADER         dosHdr           = NULL;
                     82:     PIMAGE_NT_HEADERS         ntHdr            = NULL;
                     83:     PIMAGE_FILE_HEADER        fileHdr          = NULL;
                     84:     PIMAGE_OPTIONAL_HEADER    optHdr           = NULL;
                     85:     HANDLE                    hMap             = NULL;
                     86:     PUCHAR                    fptr             = NULL;
                     87:     DWORD                     rva              = 0;
                     88:     DWORD                     i                = 0;
                     89:     DWORD                     numDebugDirs     = 0;
                     90:     PIMAGE_DEBUG_DIRECTORY    debugDir         = NULL;
                     91:     PIMAGE_SECTION_HEADER     sh               = NULL;
                     92:     PMODULEINFO               mi               = NULL;
                     93:     DWORD                     dwSize           = 0;
                     94:     PIMAGE_DEBUG_MISC         miscData         = NULL;
                     95:     LPSTR                     pExeName         = NULL;
                     96:     PIMAGE_DEBUG_DIRECTORY    miscDir          = NULL;
                     97:     char                      buf              [MAX_PATH];
                     98: 
                     99: 
                    100:     //
                    101:     // allocate a moduleinfo structure
                    102:     //
                    103:     mi = AllocMi( dp );
                    104:     if (mi == NULL) {
                    105:         return FALSE;
                    106:     }
                    107: 
                    108:     //
                    109:     // setup the debug event specific values
                    110:     //
                    111:     if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
                    112:         hFile = de->u.CreateProcessInfo.hFile;
                    113:         dp->hProcess = de->u.CreateProcessInfo.hProcess;
                    114:         dp->dwProcessId = de->dwProcessId;
                    115:         mi->dwLoadAddress = (DWORD)de->u.CreateProcessInfo.lpBaseOfImage;
                    116:     }
                    117:     else
                    118:     if (de->dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) {
                    119:         hFile = de->u.LoadDll.hFile;
                    120:         mi->dwLoadAddress = (DWORD)de->u.LoadDll.lpBaseOfDll;
                    121:     }
                    122: 
                    123:     //
                    124:     // map the input file (exe or dll)
                    125:     //
                    126:     hMap = CreateFileMapping( hFile,
                    127:                               NULL,
                    128:                               PAGE_READONLY,
                    129:                               0,
                    130:                               0,
                    131:                               NULL
                    132:                             );
                    133: 
                    134:     if (hMap == INVALID_HANDLE_VALUE) {
                    135:        return FALSE;
                    136:     }
                    137: 
                    138:     fptr = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
                    139: 
                    140:     if (fptr == NULL) {
                    141:        return FALSE;
                    142:     }
                    143: 
                    144:     //
                    145:     // next, setup the pointers to the necessary header for access to the
                    146:     // miscellaneous debug directory
                    147:     //
                    148:     dosHdr = (PIMAGE_DOS_HEADER) fptr;
                    149:     if (dosHdr->e_magic != IMAGE_DOS_SIGNATURE) {
                    150:         return FALSE;
                    151:     }
                    152:     ntHdr = (PIMAGE_NT_HEADERS) ((DWORD)dosHdr->e_lfanew + (DWORD)fptr);
                    153:     fileHdr = &ntHdr->FileHeader;
                    154:     optHdr = &ntHdr->OptionalHeader;
                    155: 
                    156:     mi->dwImageSize = optHdr->SizeOfImage;
                    157: 
                    158:     if (optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size > 0) {
                    159: 
                    160:         //
                    161:         // find the section header that contains the debug directories
                    162:         //
                    163:         rva = optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
                    164: 
                    165:         numDebugDirs = optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size /
                    166:                        sizeof(IMAGE_DEBUG_DIRECTORY);
                    167: 
                    168:         sh = IMAGE_FIRST_SECTION( ntHdr );
                    169: 
                    170:         for (li=0; li<ntHdr->FileHeader.NumberOfSections; li++, sh++) {
                    171:             if (rva >= sh->VirtualAddress &&
                    172:                 rva < sh->VirtualAddress+sh->SizeOfRawData) {
                    173:                 break;
                    174:             }
                    175:         }
                    176: 
                    177:         //
                    178:         // set the debugdir pointer to the first debug directory
                    179:         //
                    180:         debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress +
                    181:                                               sh->PointerToRawData +
                    182:                                               fptr
                    183:                                             );
                    184: 
                    185:         //
                    186:         // cruise thru all of the debug directories looking for the
                    187:         // miscellaneous debug directory
                    188:         //
                    189:         for (li=0; li<numDebugDirs; li++, debugDir++) {
                    190:             switch(debugDir->Type) {
                    191:                 case IMAGE_DEBUG_TYPE_FPO:
                    192:                     LoadFpoData( mi,
                    193:                                  (PFPO_DATA)(debugDir->PointerToRawData + fptr),
                    194:                                  debugDir->SizeOfData
                    195:                                );
                    196:                     break;
                    197: 
                    198:                 case IMAGE_DEBUG_TYPE_MISC:
                    199:                     //
                    200:                     // now, look for the data type containing the image name
                    201:                     //
                    202:                     miscData = (PIMAGE_DEBUG_MISC) (debugDir->PointerToRawData +
                    203:                                                     (DWORD)fptr);
                    204:                     li = debugDir->SizeOfData;
                    205:                     do {
                    206:                         if (miscData->DataType == IMAGE_DEBUG_MISC_EXENAME) {
                    207:                             strcpy( mi->szName, (LPSTR)miscData->Data );
                    208:                             break;
                    209:                         }
                    210:                         li -= miscData->Length;
                    211:                         miscData = (PIMAGE_DEBUG_MISC) ( (DWORD)miscData +
                    212:                                                          miscData->Length);
                    213:                     } while (li > 0);
                    214:                     break;
                    215: 
                    216:                 default:
                    217:                     break;
                    218:             }
                    219:         }
                    220:     }
                    221: 
                    222:     //
                    223:     // now find the pdata table, if there is one
                    224:     // this is mips only, but it's ok to do it in this function
                    225:     // because there won't be a pdata section on x86.
                    226:     //
                    227:     sh = IMAGE_FIRST_SECTION( ntHdr );
                    228: 
                    229:     for (i=0; i<fileHdr->NumberOfSections; i++, sh++) {
                    230:         if (strcmp(".pdata", sh->Name) == 0){
                    231:             LoadExceptionData( mi,
                    232:                                (PRUNTIME_FUNCTION)(sh->PointerToRawData+fptr),
                    233:                                sh->SizeOfRawData
                    234:                              );
                    235:             break;
                    236:         }
                    237:     }
                    238: 
                    239:     if (ntHdr->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
                    240: 
                    241:         //
                    242:         // the characteristics are marked as having the symbols stripped
                    243:         // so we must close the file handles and locate the .dbg file
                    244:         //
                    245:         CloseHandle( hMap );
                    246:         CloseHandle( hFile );
                    247: 
                    248:         //
                    249:         // get the path to use for searching for the .dbg file
                    250:         //
                    251:         lpSymbolPath = GetSymbolSearchPath();
                    252: 
                    253:         //
                    254:         // find the .dbg file and open it
                    255:         //
                    256:         buf[0] = '\0';
                    257:         hFile = FindDebugInfoFile( mi->szName, lpSymbolPath, buf );
                    258: 
                    259:         if (hFile == NULL) {
                    260:             lprintf( MSG_CANT_ACCESS_IMAGE, mi->szName );
                    261:             return FALSE;
                    262:         }
                    263: 
                    264:         //
                    265:         // map the .dbg file
                    266:         //
                    267:         hMap = CreateFileMapping( hFile,
                    268:                                   NULL,
                    269:                                   PAGE_READONLY,
                    270:                                   0,
                    271:                                   0,
                    272:                                   NULL
                    273:                                 );
                    274: 
                    275:         if (hMap == INVALID_HANDLE_VALUE) {
                    276:            return FALSE;
                    277:         }
                    278: 
                    279:         fptr = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
                    280: 
                    281:         if (fptr == NULL) {
                    282:            return FALSE;
                    283:         }
                    284: 
                    285:         //
                    286:         // get the debug information from the exe file
                    287:         //
                    288:         if (!GetDebugInfoFromDbg( mi, fptr )) {
                    289:             return FALSE;
                    290:         }
                    291:     }
                    292:     else {
                    293:         //
                    294:         // get the debug information from the dbg file
                    295:         //
                    296:         if (!GetDebugInfoFromExe( mi, fptr )) {
                    297:             return FALSE;
                    298:         }
                    299:     }
                    300: 
                    301:     //
                    302:     // close all file handles
                    303:     //
                    304:     CloseHandle( hMap );
                    305:     CloseHandle( hFile );
                    306: 
                    307:     if (mi->szName[0] == 0) {
                    308:         //
                    309:         // we could not the image name so use the default
                    310:         //
                    311:         if (de->dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT) {
                    312:             dwSize = sizeof(mi->szName);
                    313:             GetTaskName( de->dwProcessId, mi->szName, &dwSize );
                    314:         }
                    315:         else
                    316:         if (de->dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) {
                    317:             strcpy( mi->szName, "app.dll" );
                    318:         }
                    319:     }
                    320:     else {
                    321:         //
                    322:         // put the path name & drive in the file name
                    323:         //
                    324:         NormalizeFilename( mi->szName );
                    325:     }
                    326: 
                    327:     return TRUE;
                    328: }
                    329: 
                    330: BOOL
                    331: GetDebugInfoFromExe( PMODULEINFO mi, PUCHAR fptr )
                    332: 
                    333: /*++
                    334: 
                    335: Routine Description:
                    336: 
                    337:     Loads all of the appropriate debug information from an EXE/DLL file.
                    338: 
                    339: Arguments:
                    340: 
                    341:     mi      - pointer to a module information structure
                    342:     fptr    - base address of the EXE/DLL file
                    343: 
                    344: Return Value:
                    345: 
                    346:     TRUE    - everything worked
                    347:     FALSE   - we're hosed
                    348: 
                    349: --*/
                    350: 
                    351: {
                    352:     DWORD                       i             = 0;
                    353:     DWORD                       li            = 0;
                    354:     DWORD                       rva           = 0;
                    355:     DWORD                       numDebugDirs  = 0;
                    356:     PIMAGE_DEBUG_DIRECTORY      debugDir      = NULL;
                    357:     PIMAGE_SECTION_HEADER       sh            = NULL;
                    358:     PIMAGE_DOS_HEADER           dosHdr        = NULL;
                    359:     PIMAGE_NT_HEADERS           ntHdr         = NULL;
                    360:     PIMAGE_FILE_HEADER          fileHdr       = NULL;
                    361:     PIMAGE_OPTIONAL_HEADER      optHdr        = NULL;
                    362:     PUCHAR                      stringTable   = NULL;
                    363:     PIMAGE_SYMBOL               allSymbols    = NULL;
                    364:     PIMAGE_DEBUG_DIRECTORY      coffDir       = NULL;
                    365:     PIMAGE_DEBUG_DIRECTORY      cvDir         = NULL;
                    366:     PIMAGE_EXPORT_DIRECTORY     exportDir     = NULL;
                    367:     PUCHAR                      exportName    = NULL;
                    368: 
                    369: 
                    370:     //
                    371:     // setup the image header pointers
                    372:     //
                    373:     dosHdr = (PIMAGE_DOS_HEADER) fptr;
                    374:     if (dosHdr->e_magic != IMAGE_DOS_SIGNATURE) {
                    375:         return FALSE;
                    376:     }
                    377: 
                    378:     ntHdr = (PIMAGE_NT_HEADERS) ((DWORD)dosHdr->e_lfanew + (DWORD)fptr);
                    379:     fileHdr = &ntHdr->FileHeader;
                    380:     optHdr = &ntHdr->OptionalHeader;
                    381: 
                    382:     mi->dwImageSize = optHdr->SizeOfImage;
                    383: 
                    384:     if (!(fileHdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {
                    385:         return FALSE;
                    386:     }
                    387: 
                    388:     //
                    389:     // establish the COFF symbol table pointers
                    390:     //
                    391:     if (fileHdr->PointerToSymbolTable > 0 || fileHdr->NumberOfSymbols > 0) {
                    392:         stringTable = fileHdr->PointerToSymbolTable + fptr +
                    393:                       (IMAGE_SIZEOF_SYMBOL * fileHdr->NumberOfSymbols);
                    394:         allSymbols = (PIMAGE_SYMBOL) (fileHdr->PointerToSymbolTable + fptr);
                    395:     }
                    396: 
                    397:     if (optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size > 0) {
                    398: 
                    399:         //
                    400:         // find the section header that the debug directories are in
                    401:         //
                    402:         rva = optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
                    403: 
                    404:         numDebugDirs = optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size /
                    405:                        sizeof(IMAGE_DEBUG_DIRECTORY);
                    406:         if (numDebugDirs == 0) {
                    407:             return FALSE;
                    408:         }
                    409: 
                    410:         sh = IMAGE_FIRST_SECTION( ntHdr );
                    411: 
                    412:         for (i=0; i<fileHdr->NumberOfSections; i++, sh++) {
                    413:             if (rva >= sh->VirtualAddress &&
                    414:                 rva < sh->VirtualAddress+sh->SizeOfRawData) {
                    415:                 break;
                    416:             }
                    417:         }
                    418: 
                    419:         debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress +
                    420:                                               sh->PointerToRawData +
                    421:                                               fptr
                    422:                                             );
                    423: 
                    424:         //
                    425:         // process each debug directory
                    426:         //
                    427:         for (li=0; li<numDebugDirs; li++, debugDir++) {
                    428:             switch(debugDir->Type) {
                    429:                 case IMAGE_DEBUG_TYPE_COFF:
                    430:                     coffDir = debugDir;
                    431:                     break;
                    432: 
                    433:                 case IMAGE_DEBUG_TYPE_CODEVIEW:
                    434:                     cvDir = debugDir;
                    435:                     break;
                    436: 
                    437:                 case IMAGE_DEBUG_TYPE_FPO:
                    438:                     LoadFpoData( mi,
                    439:                                  (PFPO_DATA)(debugDir->PointerToRawData + fptr),
                    440:                                  debugDir->SizeOfData
                    441:                                );
                    442:                     break;
                    443: 
                    444:                 default:
                    445:                     break;
                    446:             }
                    447:         }
                    448: 
                    449:         if (cvDir != NULL) {
                    450:             LoadCodeViewSymbols( mi,
                    451:                                  cvDir->PointerToRawData + fptr,
                    452:                                  IMAGE_FIRST_SECTION( ntHdr ),
                    453:                                  fileHdr->NumberOfSections
                    454:                                );
                    455:         }
                    456:         else
                    457:         if (coffDir != NULL) {
                    458:             LoadCoffSymbols( mi,
                    459:                              stringTable,
                    460:                              allSymbols,
                    461:                              fileHdr->NumberOfSymbols
                    462:                            );
                    463:         }
                    464:     }
                    465: 
                    466:     //
                    467:     // now find the exports table, if there is one
                    468:     //
                    469:     rva = optHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
                    470: 
                    471:     sh = IMAGE_FIRST_SECTION( ntHdr );
                    472: 
                    473:     //
                    474:     // Find the section the where the export table is located in
                    475:     //
                    476:     for (i=0; i<fileHdr->NumberOfSections; i++, sh++) {
                    477:         if (rva >= sh->VirtualAddress &&
                    478:             rva < sh->VirtualAddress+sh->SizeOfRawData) {
                    479:             break;
                    480:         }
                    481:     }
                    482: 
                    483:     //
                    484:     // is there an export table ?
                    485:     //
                    486:     if (i != fileHdr->NumberOfSections) {
                    487:         exportDir = (PIMAGE_EXPORT_DIRECTORY) ( rva -
                    488:                                                 (DWORD)sh->VirtualAddress +
                    489:                                                 sh->PointerToRawData +
                    490:                                                 (DWORD)fptr );
                    491: 
                    492:         exportName = (PUCHAR) ( exportDir->Name -
                    493:                                 (DWORD)sh->VirtualAddress +
                    494:                                 sh->PointerToRawData +
                    495:                                 (DWORD)fptr );
                    496: 
                    497:         if (mi->szName[0] == '\0') {
                    498:             strcpy( mi->szName, exportName );
                    499:         }
                    500:     }
                    501: 
                    502:     return TRUE;
                    503: }
                    504: 
                    505: BOOL
                    506: GetDebugInfoFromDbg( PMODULEINFO mi, PUCHAR fptr )
                    507: 
                    508: /*++
                    509: 
                    510: Routine Description:
                    511: 
                    512:     Loads all of the appropriate debug information from a DBG file.
                    513: 
                    514: Arguments:
                    515: 
                    516:     mi      - pointer to a module information structure
                    517:     fptr    - base address of the EXE/DLL file
                    518: 
                    519: Return Value:
                    520: 
                    521:     TRUE    - everything worked
                    522:     FALSE   - we're hosed
                    523: 
                    524: --*/
                    525: 
                    526: {
                    527:     DWORD                           li           = 0;
                    528:     DWORD                           numDebugDirs = 0;
                    529:     PIMAGE_DEBUG_DIRECTORY          debugDir     = NULL;
                    530:     PIMAGE_SECTION_HEADER           sh           = NULL;
                    531:     PIMAGE_SEPARATE_DEBUG_HEADER    sdh          = NULL;
                    532:     PIMAGE_COFF_SYMBOLS_HEADER      coffSymHead  = NULL;
                    533:     PUCHAR                          stringTable  = NULL;
                    534:     PIMAGE_SYMBOL                   allSymbols   = NULL;
                    535:     PIMAGE_DEBUG_DIRECTORY          coffDir      = NULL;
                    536:     PIMAGE_DEBUG_DIRECTORY          cvDir        = NULL;
                    537: 
                    538: 
                    539:     //
                    540:     // setup the basic image pointers
                    541:     //
                    542:     sdh = (PIMAGE_SEPARATE_DEBUG_HEADER) fptr;
                    543:     sh = (PIMAGE_SECTION_HEADER) (sdh + 1);
                    544:     debugDir = (PIMAGE_DEBUG_DIRECTORY)((DWORD)((DWORD)sh + (sdh->NumberOfSections*IMAGE_SIZEOF_SECTION_HEADER)) + sdh->ExportedNamesSize);
                    545: 
                    546:     mi->dwImageSize = sdh->SizeOfImage;
                    547: 
                    548:     if (sdh->DebugDirectorySize > 0) {
                    549: 
                    550:         //
                    551:         // process each debug directory
                    552:         //
                    553:         numDebugDirs = sdh->DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY);
                    554:         if (numDebugDirs == 0) {
                    555:             return FALSE;
                    556:         }
                    557: 
                    558:         for (li=0; li<numDebugDirs; li++, debugDir++) {
                    559:             switch(debugDir->Type) {
                    560:                 case IMAGE_DEBUG_TYPE_COFF:
                    561:                     coffDir = debugDir;
                    562:                     break;
                    563: 
                    564:                 case IMAGE_DEBUG_TYPE_CODEVIEW:
                    565:                     cvDir = debugDir;
                    566:                     break;
                    567: 
                    568:                 case IMAGE_DEBUG_TYPE_FPO:
                    569:                     LoadFpoData( mi,
                    570:                                  (PFPO_DATA)(debugDir->PointerToRawData + fptr),
                    571:                                  debugDir->SizeOfData
                    572:                                );
                    573:                     break;
                    574: 
                    575:                 case IMAGE_DEBUG_TYPE_EXCEPTION:
                    576:                     if (debugDir->SizeOfData > 0) {
                    577:                         LoadExceptionData( mi,
                    578:                              (PRUNTIME_FUNCTION)(debugDir->PointerToRawData+fptr),
                    579:                              debugDir->SizeOfData );
                    580:                     }
                    581:                     break;
                    582: 
                    583:                 default:
                    584:                     break;
                    585:             }
                    586:         }
                    587:     }
                    588: 
                    589:     if (cvDir != NULL) {
                    590:         LoadCodeViewSymbols( mi,
                    591:                              cvDir->PointerToRawData + fptr,
                    592:                              sh,
                    593:                              sdh->NumberOfSections
                    594:                            );
                    595:     }
                    596:     else
                    597:     if (coffDir != NULL) {
                    598:         //
                    599:         // setup the COFF symbol table pointers & load the COFF symbol table
                    600:         //
                    601:         coffSymHead = (PIMAGE_COFF_SYMBOLS_HEADER)(coffDir->PointerToRawData + fptr);
                    602:         allSymbols = (PIMAGE_SYMBOL) ( (DWORD)coffSymHead +
                    603:                                        coffSymHead->LvaToFirstSymbol
                    604:                                      );
                    605:         stringTable = (PUCHAR)((DWORD)allSymbols +
                    606:                        (IMAGE_SIZEOF_SYMBOL * coffSymHead->NumberOfSymbols));
                    607:         LoadCoffSymbols( mi,
                    608:                          stringTable,
                    609:                          allSymbols,
                    610:                          coffSymHead->NumberOfSymbols
                    611:                        );
                    612:     }
                    613: 
                    614:     return TRUE;
                    615: }
                    616: 
                    617: LPSTR
                    618: GetSymbolSearchPath( void )
                    619: 
                    620: /*++
                    621: 
                    622: Routine Description:
                    623: 
                    624:     Gets the search path to be used for locating a .DBG file.
                    625: 
                    626: Arguments:
                    627: 
                    628:     None.
                    629: 
                    630: Return Value:
                    631: 
                    632:     pointer to the path string
                    633: 
                    634: --*/
                    635: 
                    636: {
                    637:     LPSTR   lpSymPathEnv      = NULL;
                    638:     LPSTR   lpAltSymPathEnv   = NULL;
                    639:     LPSTR   lpSystemRootEnv   = NULL;
                    640:     LPSTR   SymbolSearchPath  = NULL;
                    641:     DWORD   cbSymPath         = 0;
                    642: 
                    643:     cbSymPath = 16;
                    644:     if (lpSymPathEnv = getenv(SYMBOL_PATH)) {
                    645:         cbSymPath += strlen(lpSymPathEnv) + 1;
                    646:     }
                    647:     if (lpAltSymPathEnv = getenv(ALTERNATE_SYMBOL_PATH)) {
                    648:         cbSymPath += strlen(lpAltSymPathEnv) + 1;
                    649:     }
                    650:     if (lpSystemRootEnv = getenv("SystemRoot")) {
                    651:         cbSymPath += strlen(lpSystemRootEnv) + 1;
                    652:     }
                    653: 
                    654:     SymbolSearchPath = calloc(cbSymPath,1);
                    655: 
                    656:     if (lpAltSymPathEnv) {
                    657:         strcat(SymbolSearchPath,lpAltSymPathEnv);
                    658:         strcat(SymbolSearchPath,";");
                    659:     }
                    660:     if (lpSymPathEnv) {
                    661:         strcat(SymbolSearchPath,lpSymPathEnv);
                    662:         strcat(SymbolSearchPath,";");
                    663:     }
                    664:     if (lpSystemRootEnv) {
                    665:         strcat(SymbolSearchPath,lpSystemRootEnv);
                    666:         strcat(SymbolSearchPath,";");
                    667:     }
                    668:     return SymbolSearchPath;
                    669: }
                    670: 
                    671: BOOL
                    672: NormalizeFilename( char *szName )
                    673: 
                    674: /*++
                    675: 
                    676: Routine Description:
                    677: 
                    678:     Prefixes the base name passed in by szName with the fully qualified
                    679:     path name of the file.
                    680: 
                    681: Arguments:
                    682: 
                    683:     szName     - buffer for the file name
                    684: 
                    685: Return Value:
                    686: 
                    687:     TRUE       - file name contains the path & base name
                    688:     FALSE      - file name contains the base name only
                    689: 
                    690: --*/
                    691: 
                    692: {
                    693:     DWORD   rc              = 0;
                    694:     LPSTR   lpszFilePart    = NULL;
                    695:     char    szDrive    [_MAX_DRIVE];
                    696:     char    szDir      [_MAX_DIR];
                    697:     char    szFname    [_MAX_FNAME];
                    698:     char    szExt      [_MAX_EXT];
                    699:     char    buf        [4096];
                    700:     char    szFullPath [4096];
                    701: 
                    702: 
                    703:     //
                    704:     // split the filename apart
                    705:     //
                    706:     _splitpath( szName, szDrive, szDir, szFname, szExt );
                    707: 
                    708:     //
                    709:     // create a base file name excluding any possible path
                    710:     //
                    711:     wsprintf( buf, "%s%s", szFname, szExt );
                    712: 
                    713:     //
                    714:     // create a full path name to the file based on our current
                    715:     // working directory.  this is done so that we can check the
                    716:     // current directory before looking along the path env variable.
                    717:     //
                    718:     _fullpath( szFullPath, buf, sizeof(szFullPath) );
                    719: 
                    720:     //
                    721:     // split the path apart so the constituent parts can be used
                    722:     // by the next call to searchpath
                    723:     //
                    724:     _splitpath( szFullPath, szDrive, szDir, szFname, szExt );
                    725: 
                    726:     //
                    727:     // look in the current working directory for the file
                    728:     //
                    729:     rc = SearchPath( szDir, szFname, szExt, sizeof(buf), buf, &lpszFilePart );
                    730:     if (rc > 0) {
                    731:         //
                    732:         // found it so copy the filename and exit
                    733:         //
                    734:         strcpy( szName, buf );
                    735:         return TRUE;
                    736:     }
                    737: 
                    738:     //
                    739:     // now look along the path environment variable for the filename
                    740:     //
                    741:     rc = SearchPath( NULL, szFname, szExt, sizeof(buf), buf, &lpszFilePart );
                    742:     if (rc > 0) {
                    743:         //
                    744:         // found it so copy the filename and exit
                    745:         //
                    746:         strcpy( szName, buf );
                    747:         return TRUE;
                    748:     }
                    749: 
                    750:     //
                    751:     // could not file the file anywhere so create a base filename
                    752:     // and return
                    753:     //
                    754:     wsprintf( szName, "%s%s", szFname, szExt );
                    755:     return FALSE;
                    756: }
                    757: 
                    758: HANDLE
                    759: FindDebugInfoFile( LPSTR FileName, LPSTR SymbolPath, LPSTR DebugFilePath )
                    760: 
                    761: /*++
                    762: 
                    763: Routine Description:
                    764: 
                    765:     Locates a .DBG file based on the FileName and the SymbolPath.
                    766: 
                    767: Arguments:
                    768: 
                    769:     FileName         - base EXE/DLL file name
                    770:     SymbolPath       - path to search for the .DBG file
                    771:     DebugFilePath    - buffer for .DBG file name
                    772: 
                    773: Return Value:
                    774: 
                    775:     not NULL   - a valid handle to a .DBG file
                    776:     NULL       - could not find the .DBG file
                    777: 
                    778: --*/
                    779: 
                    780: {
                    781:     HANDLE FileHandle;
                    782:     LPSTR s, BaseName, Extension;
                    783:     LPSTR Start, End;
                    784:     UCHAR DirectoryPath[ MAX_PATH ];
                    785: 
                    786:     BaseName = strcpy( DebugFilePath, FileName );
                    787:     BaseName += strlen( BaseName );
                    788:     while (BaseName > DebugFilePath) {
                    789:         if (*--BaseName == '\\' || *BaseName == '/' || *BaseName == ':') {
                    790:             BaseName += 1;
                    791:             break;
                    792:             }
                    793:         }
                    794:     if (!(Extension = strrchr( BaseName, '.' ))) {
                    795:         Extension = strchr( BaseName, '\0' );
                    796:         }
                    797:     strcpy( Extension, ".DBG" );
                    798:     s = BaseName;
                    799:     if (s > DebugFilePath) {
                    800:         s -= 1;
                    801:         }
                    802: 
                    803:     while (TRUE) {
                    804:         FileHandle = CreateFile( DebugFilePath,
                    805:                                  GENERIC_READ,
                    806:                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                    807:                                  NULL,
                    808:                                  OPEN_EXISTING,
                    809:                                  0,
                    810:                                  NULL
                    811:                                );
                    812:         if (FileHandle != INVALID_HANDLE_VALUE) {
                    813:             return FileHandle;
                    814:             }
                    815: 
                    816:         while (s > DebugFilePath) {
                    817:             if (*--s == '\\' || *s == '/' || *s == ':') {
                    818:                 break;
                    819:                 }
                    820:             }
                    821: 
                    822:         if (s == DebugFilePath) {
                    823:             break;
                    824:             }
                    825: 
                    826:         strcpy( s, "\\Symbols\\" );
                    827:         strcat( s, BaseName );
                    828:         }
                    829: 
                    830:     Start = SymbolPath;
                    831:     while (Start && *Start != '\0') {
                    832:         if (End = strchr( Start, ';' )) {
                    833:             strncpy( DirectoryPath, Start, End - Start );
                    834:             DirectoryPath[ End - Start ] = '\0';
                    835:             End += 1;
                    836:             }
                    837:         else {
                    838:             strcpy( DirectoryPath, Start );
                    839:             }
                    840: 
                    841:         if (SearchTreeForFile( DirectoryPath, BaseName, DebugFilePath )) {
                    842:             FileHandle = CreateFile( DebugFilePath,
                    843:                                      GENERIC_READ,
                    844:                                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                    845:                                      NULL,
                    846:                                      OPEN_EXISTING,
                    847:                                      0,
                    848:                                      NULL
                    849:                                    );
                    850:             if (FileHandle != INVALID_HANDLE_VALUE) {
                    851:                 return FileHandle;
                    852:                 }
                    853:             }
                    854: 
                    855:         Start = End;
                    856:         }
                    857: 
                    858:     return NULL;
                    859: }
                    860: 
                    861: #define MAX_DEPTH 32
                    862: 
                    863: BOOL
                    864: SearchTreeForFile(
                    865:     LPSTR RootPath,
                    866:     PCHAR InputPathName,
                    867:     PCHAR OutputPathBuffer
                    868:     )
                    869: 
                    870: /*++
                    871: 
                    872: Routine Description:
                    873: 
                    874:     Searches down the path(RootPath) for a file(InputPathName).
                    875: 
                    876: Arguments:
                    877: 
                    878:     RootPath         - path to search down
                    879:     InputPathName    - file name to look for
                    880:     OutputPathBuffer - buffer for .DBG file name
                    881: 
                    882: Return Value:
                    883: 
                    884:     TRUE       - file found
                    885:     FALSE      - could not find the .DBG file
                    886: 
                    887: --*/
                    888: 
                    889: {
                    890:     PCHAR FileName;
                    891:     PUCHAR Prefix = "";
                    892:     CHAR PathBuffer[ MAX_PATH ];
                    893:     ULONG Depth;
                    894:     PCHAR PathTail[ MAX_DEPTH ];
                    895:     PCHAR FindHandle[ MAX_DEPTH ];
                    896:     LPWIN32_FIND_DATA FindFileData;
                    897:     UCHAR FindFileBuffer[ MAX_PATH + sizeof( WIN32_FIND_DATA ) ];
                    898:     BOOL Result;
                    899: 
                    900:     strcpy( PathBuffer, RootPath );
                    901:     FileName = InputPathName;
                    902:     while (*InputPathName) {
                    903:         if (*InputPathName == ':' || *InputPathName == '\\' || *InputPathName == '/') {
                    904:             FileName = ++InputPathName;
                    905:             }
                    906:         else {
                    907:             InputPathName++;
                    908:             }
                    909:         }
                    910:     FindFileData = (LPWIN32_FIND_DATA)FindFileBuffer;
                    911:     Depth = 0;
                    912:     Result = FALSE;
                    913:     while (TRUE) {
                    914: startDirectorySearch:
                    915:         PathTail[ Depth ] = strchr( PathBuffer, '\0' );
                    916:         if (PathTail[ Depth ] > PathBuffer && PathTail[ Depth ][ -1 ] != '\\') {
                    917:             *(PathTail[ Depth ])++ = '\\';
                    918:             }
                    919: 
                    920:         strcpy( PathTail[ Depth ], "*.*" );
                    921:         FindHandle[ Depth ] = FindFirstFile( PathBuffer, FindFileData );
                    922:         if (FindHandle[ Depth ] != INVALID_HANDLE_VALUE) {
                    923:             do {
                    924:                 if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    925:                     if (strcmp( FindFileData->cFileName, "." ) &&
                    926:                         strcmp( FindFileData->cFileName, ".." ) &&
                    927:                         Depth < MAX_DEPTH
                    928:                        ) {
                    929:                         sprintf( PathTail[ Depth ], "%s\\", FindFileData->cFileName );
                    930:                         Depth++;
                    931:                         goto startDirectorySearch;
                    932:                         }
                    933:                     }
                    934:                 else
                    935:                 if (!stricmp( FindFileData->cFileName, FileName )) {
                    936:                     strcpy( PathTail[ Depth ], FindFileData->cFileName );
                    937:                     strcpy( OutputPathBuffer, PathBuffer );
                    938:                     Result = TRUE;
                    939:                     }
                    940: 
                    941: restartDirectorySearch:
                    942:                 if (Result) {
                    943:                     break;
                    944:                     }
                    945:                 }
                    946:             while (FindNextFile( FindHandle[ Depth ], FindFileData ));
                    947:             FindClose( FindHandle[ Depth ] );
                    948: 
                    949:             if (Depth == 0) {
                    950:                 break;
                    951:                 }
                    952: 
                    953:             Depth--;
                    954:             goto restartDirectorySearch;
                    955:             }
                    956:         }
                    957: 
                    958:     return Result;
                    959: }
                    960: 
                    961: PMODULEINFO
                    962: AllocMi( PDEBUGPACKET dp )
                    963: 
                    964: /*++
                    965: 
                    966: Routine Description:
                    967: 
                    968:     Allocate a module information structure and link it in the
                    969:     list of modules for this debugee.
                    970: 
                    971: Arguments:
                    972: 
                    973:     dp               - debug packet
                    974: 
                    975: Return Value:
                    976: 
                    977:     pointer to module information structure
                    978: 
                    979: --*/
                    980: 
                    981: {
                    982:     PMODULEINFO mi;
                    983: 
                    984:     mi = (PMODULEINFO) malloc( sizeof(MODULEINFO) );
                    985:     if (mi == NULL) {
                    986:         return NULL;
                    987:     }
                    988:     memset( mi, 0, sizeof(MODULEINFO) );
                    989: 
                    990:     if (dp->miHead == NULL) {
                    991:         dp->miHead = dp->miTail = mi;
                    992:     }
                    993:     else {
                    994:         dp->miTail->next = mi;
                    995:         dp->miTail = mi;
                    996:     }
                    997: 
                    998:     return mi;
                    999: }

unix.superglobalmegacorp.com

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