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

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:                 default:
                    569:                     break;
                    570:             }
                    571:         }
                    572:     }
                    573: 
                    574:     if (cvDir != NULL) {
                    575:         LoadCodeViewSymbols( mi,
                    576:                              cvDir->PointerToRawData + fptr,
                    577:                              sh,
                    578:                              sdh->NumberOfSections
                    579:                            );
                    580:     }
                    581:     else
                    582:     if (coffDir != NULL) {
                    583:         //
                    584:         // setup the COFF symbol table pointers & load the COFF symbol table
                    585:         //
                    586:         coffSymHead = (PIMAGE_COFF_SYMBOLS_HEADER)(coffDir->PointerToRawData + fptr);
                    587:         allSymbols = (PIMAGE_SYMBOL) ( (DWORD)coffSymHead +
                    588:                                        coffSymHead->LvaToFirstSymbol
                    589:                                      );
                    590:         stringTable = (PUCHAR)((DWORD)allSymbols +
                    591:                        (IMAGE_SIZEOF_SYMBOL * coffSymHead->NumberOfSymbols));
                    592:         LoadCoffSymbols( mi,
                    593:                          stringTable,
                    594:                          allSymbols,
                    595:                          coffSymHead->NumberOfSymbols
                    596:                        );
                    597:     }
                    598: 
                    599:     return TRUE;
                    600: }
                    601: 
                    602: LPSTR
                    603: GetSymbolSearchPath( void )
                    604: 
                    605: /*++
                    606: 
                    607: Routine Description:
                    608: 
                    609:     Gets the search path to be used for locating a .DBG file.
                    610: 
                    611: Arguments:
                    612: 
                    613:     None.
                    614: 
                    615: Return Value:
                    616: 
                    617:     pointer to the path string
                    618: 
                    619: --*/
                    620: 
                    621: {
                    622:     LPSTR   lpSymPathEnv      = NULL;
                    623:     LPSTR   lpAltSymPathEnv   = NULL;
                    624:     LPSTR   lpSystemRootEnv   = NULL;
                    625:     LPSTR   SymbolSearchPath  = NULL;
                    626:     DWORD   cbSymPath         = 0;
                    627: 
                    628:     cbSymPath = 16;
                    629:     if (lpSymPathEnv = getenv(SYMBOL_PATH)) {
                    630:         cbSymPath += strlen(lpSymPathEnv) + 1;
                    631:     }
                    632:     if (lpAltSymPathEnv = getenv(ALTERNATE_SYMBOL_PATH)) {
                    633:         cbSymPath += strlen(lpAltSymPathEnv) + 1;
                    634:     }
                    635:     if (lpSystemRootEnv = getenv("SystemRoot")) {
                    636:         cbSymPath += strlen(lpSystemRootEnv) + 1;
                    637:     }
                    638: 
                    639:     SymbolSearchPath = calloc(cbSymPath,1);
                    640: 
                    641:     if (lpAltSymPathEnv) {
                    642:         strcat(SymbolSearchPath,lpAltSymPathEnv);
                    643:         strcat(SymbolSearchPath,";");
                    644:     }
                    645:     if (lpSymPathEnv) {
                    646:         strcat(SymbolSearchPath,lpSymPathEnv);
                    647:         strcat(SymbolSearchPath,";");
                    648:     }
                    649:     if (lpSystemRootEnv) {
                    650:         strcat(SymbolSearchPath,lpSystemRootEnv);
                    651:         strcat(SymbolSearchPath,";");
                    652:     }
                    653:     return SymbolSearchPath;
                    654: }
                    655: 
                    656: BOOL
                    657: NormalizeFilename( char *szName )
                    658: 
                    659: /*++
                    660: 
                    661: Routine Description:
                    662: 
                    663:     Prefixes the base name passed in by szName with the fully qualified
                    664:     path name of the file.
                    665: 
                    666: Arguments:
                    667: 
                    668:     szName     - buffer for the file name
                    669: 
                    670: Return Value:
                    671: 
                    672:     TRUE       - file name contains the path & base name
                    673:     FALSE      - file name contains the base name only
                    674: 
                    675: --*/
                    676: 
                    677: {
                    678:     DWORD   rc              = 0;
                    679:     LPSTR   lpszFilePart    = NULL;
                    680:     char    szDrive    [_MAX_DRIVE];
                    681:     char    szDir      [_MAX_DIR];
                    682:     char    szFname    [_MAX_FNAME];
                    683:     char    szExt      [_MAX_EXT];
                    684:     char    buf        [4096];
                    685:     char    szFullPath [4096];
                    686: 
                    687: 
                    688:     //
                    689:     // split the filename apart
                    690:     //
                    691:     _splitpath( szName, szDrive, szDir, szFname, szExt );
                    692: 
                    693:     //
                    694:     // create a base file name excluding any possible path
                    695:     //
                    696:     wsprintf( buf, "%s%s", szFname, szExt );
                    697: 
                    698:     //
                    699:     // create a full path name to the file based on our current
                    700:     // working directory.  this is done so that we can check the
                    701:     // current directory before looking along the path env variable.
                    702:     //
                    703:     _fullpath( szFullPath, buf, sizeof(szFullPath) );
                    704: 
                    705:     //
                    706:     // split the path apart so the constituent parts can be used
                    707:     // by the next call to searchpath
                    708:     //
                    709:     _splitpath( szFullPath, szDrive, szDir, szFname, szExt );
                    710: 
                    711:     //
                    712:     // look in the current working directory for the file
                    713:     //
                    714:     rc = SearchPath( szDir, szFname, szExt, sizeof(buf), buf, &lpszFilePart );
                    715:     if (rc > 0) {
                    716:         //
                    717:         // found it so copy the filename and exit
                    718:         //
                    719:         strcpy( szName, buf );
                    720:         return TRUE;
                    721:     }
                    722: 
                    723:     //
                    724:     // now look along the path environment variable for the filename
                    725:     //
                    726:     rc = SearchPath( NULL, szFname, szExt, sizeof(buf), buf, &lpszFilePart );
                    727:     if (rc > 0) {
                    728:         //
                    729:         // found it so copy the filename and exit
                    730:         //
                    731:         strcpy( szName, buf );
                    732:         return TRUE;
                    733:     }
                    734: 
                    735:     //
                    736:     // could not file the file anywhere so create a base filename
                    737:     // and return
                    738:     //
                    739:     wsprintf( szName, "%s%s", szFname, szExt );
                    740:     return FALSE;
                    741: }
                    742: 
                    743: HANDLE
                    744: FindDebugInfoFile( LPSTR FileName, LPSTR SymbolPath, LPSTR DebugFilePath )
                    745: 
                    746: /*++
                    747: 
                    748: Routine Description:
                    749: 
                    750:     Locates a .DBG file based on the FileName and the SymbolPath.
                    751: 
                    752: Arguments:
                    753: 
                    754:     FileName         - base EXE/DLL file name
                    755:     SymbolPath       - path to search for the .DBG file
                    756:     DebugFilePath    - buffer for .DBG file name
                    757: 
                    758: Return Value:
                    759: 
                    760:     not NULL   - a valid handle to a .DBG file
                    761:     NULL       - could not find the .DBG file
                    762: 
                    763: --*/
                    764: 
                    765: {
                    766:     HANDLE FileHandle;
                    767:     LPSTR s, BaseName, Extension;
                    768:     LPSTR Start, End;
                    769:     UCHAR DirectoryPath[ MAX_PATH ];
                    770: 
                    771:     BaseName = strcpy( DebugFilePath, FileName );
                    772:     BaseName += strlen( BaseName );
                    773:     while (BaseName > DebugFilePath) {
                    774:         if (*--BaseName == '\\' || *BaseName == '/' || *BaseName == ':') {
                    775:             BaseName += 1;
                    776:             break;
                    777:             }
                    778:         }
                    779:     if (!(Extension = strrchr( BaseName, '.' ))) {
                    780:         Extension = strchr( BaseName, '\0' );
                    781:         }
                    782:     strcpy( Extension, ".DBG" );
                    783:     s = BaseName;
                    784:     if (s > DebugFilePath) {
                    785:         s -= 1;
                    786:         }
                    787: 
                    788:     while (TRUE) {
                    789:         FileHandle = CreateFile( DebugFilePath,
                    790:                                  GENERIC_READ,
                    791:                                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                    792:                                  NULL,
                    793:                                  OPEN_EXISTING,
                    794:                                  0,
                    795:                                  NULL
                    796:                                );
                    797:         if (FileHandle != INVALID_HANDLE_VALUE) {
                    798:             return FileHandle;
                    799:             }
                    800: 
                    801:         while (s > DebugFilePath) {
                    802:             if (*--s == '\\' || *s == '/' || *s == ':') {
                    803:                 break;
                    804:                 }
                    805:             }
                    806: 
                    807:         if (s == DebugFilePath) {
                    808:             break;
                    809:             }
                    810: 
                    811:         strcpy( s, "\\Symbols\\" );
                    812:         strcat( s, BaseName );
                    813:         }
                    814: 
                    815:     Start = SymbolPath;
                    816:     while (Start && *Start != '\0') {
                    817:         if (End = strchr( Start, ';' )) {
                    818:             strncpy( DirectoryPath, Start, End - Start );
                    819:             DirectoryPath[ End - Start ] = '\0';
                    820:             End += 1;
                    821:             }
                    822:         else {
                    823:             strcpy( DirectoryPath, Start );
                    824:             }
                    825: 
                    826:         if (SearchTreeForFile( DirectoryPath, BaseName, DebugFilePath )) {
                    827:             FileHandle = CreateFile( DebugFilePath,
                    828:                                      GENERIC_READ,
                    829:                                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                    830:                                      NULL,
                    831:                                      OPEN_EXISTING,
                    832:                                      0,
                    833:                                      NULL
                    834:                                    );
                    835:             if (FileHandle != INVALID_HANDLE_VALUE) {
                    836:                 return FileHandle;
                    837:                 }
                    838:             }
                    839: 
                    840:         Start = End;
                    841:         }
                    842: 
                    843:     return NULL;
                    844: }
                    845: 
                    846: #define MAX_DEPTH 32
                    847: 
                    848: BOOL
                    849: SearchTreeForFile(
                    850:     LPSTR RootPath,
                    851:     PCHAR InputPathName,
                    852:     PCHAR OutputPathBuffer
                    853:     )
                    854: 
                    855: /*++
                    856: 
                    857: Routine Description:
                    858: 
                    859:     Searches down the path(RootPath) for a file(InputPathName).
                    860: 
                    861: Arguments:
                    862: 
                    863:     RootPath         - path to search down
                    864:     InputPathName    - file name to look for
                    865:     OutputPathBuffer - buffer for .DBG file name
                    866: 
                    867: Return Value:
                    868: 
                    869:     TRUE       - file found
                    870:     FALSE      - could not find the .DBG file
                    871: 
                    872: --*/
                    873: 
                    874: {
                    875:     PCHAR FileName;
                    876:     PUCHAR Prefix = "";
                    877:     CHAR PathBuffer[ MAX_PATH ];
                    878:     ULONG Depth;
                    879:     PCHAR PathTail[ MAX_DEPTH ];
                    880:     PCHAR FindHandle[ MAX_DEPTH ];
                    881:     LPWIN32_FIND_DATA FindFileData;
                    882:     UCHAR FindFileBuffer[ MAX_PATH + sizeof( WIN32_FIND_DATA ) ];
                    883:     BOOL Result;
                    884: 
                    885:     strcpy( PathBuffer, RootPath );
                    886:     FileName = InputPathName;
                    887:     while (*InputPathName) {
                    888:         if (*InputPathName == ':' || *InputPathName == '\\' || *InputPathName == '/') {
                    889:             FileName = ++InputPathName;
                    890:             }
                    891:         else {
                    892:             InputPathName++;
                    893:             }
                    894:         }
                    895:     FindFileData = (LPWIN32_FIND_DATA)FindFileBuffer;
                    896:     Depth = 0;
                    897:     Result = FALSE;
                    898:     while (TRUE) {
                    899: startDirectorySearch:
                    900:         PathTail[ Depth ] = strchr( PathBuffer, '\0' );
                    901:         if (PathTail[ Depth ] > PathBuffer && PathTail[ Depth ][ -1 ] != '\\') {
                    902:             *(PathTail[ Depth ])++ = '\\';
                    903:             }
                    904: 
                    905:         strcpy( PathTail[ Depth ], "*.*" );
                    906:         FindHandle[ Depth ] = FindFirstFile( PathBuffer, FindFileData );
                    907:         if (FindHandle[ Depth ] != INVALID_HANDLE_VALUE) {
                    908:             do {
                    909:                 if (FindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    910:                     if (strcmp( FindFileData->cFileName, "." ) &&
                    911:                         strcmp( FindFileData->cFileName, ".." ) &&
                    912:                         Depth < MAX_DEPTH
                    913:                        ) {
                    914:                         sprintf( PathTail[ Depth ], "%s\\", FindFileData->cFileName );
                    915:                         Depth++;
                    916:                         goto startDirectorySearch;
                    917:                         }
                    918:                     }
                    919:                 else
                    920:                 if (!stricmp( FindFileData->cFileName, FileName )) {
                    921:                     strcpy( PathTail[ Depth ], FindFileData->cFileName );
                    922:                     strcpy( OutputPathBuffer, PathBuffer );
                    923:                     Result = TRUE;
                    924:                     }
                    925: 
                    926: restartDirectorySearch:
                    927:                 if (Result) {
                    928:                     break;
                    929:                     }
                    930:                 }
                    931:             while (FindNextFile( FindHandle[ Depth ], FindFileData ));
                    932:             FindClose( FindHandle[ Depth ] );
                    933: 
                    934:             if (Depth == 0) {
                    935:                 break;
                    936:                 }
                    937: 
                    938:             Depth--;
                    939:             goto restartDirectorySearch;
                    940:             }
                    941:         }
                    942: 
                    943:     return Result;
                    944: }
                    945: 
                    946: PMODULEINFO
                    947: AllocMi( PDEBUGPACKET dp )
                    948: 
                    949: /*++
                    950: 
                    951: Routine Description:
                    952: 
                    953:     Allocate a module information structure and link it in the
                    954:     list of modules for this debugee.
                    955: 
                    956: Arguments:
                    957: 
                    958:     dp               - debug packet
                    959: 
                    960: Return Value:
                    961: 
                    962:     pointer to module information structure
                    963: 
                    964: --*/
                    965: 
                    966: {
                    967:     PMODULEINFO mi;
                    968: 
                    969:     mi = (PMODULEINFO) malloc( sizeof(MODULEINFO) );
                    970:     if (mi == NULL) {
                    971:         return NULL;
                    972:     }
                    973:     memset( mi, 0, sizeof(MODULEINFO) );
                    974: 
                    975:     if (dp->miHead == NULL) {
                    976:         dp->miHead = dp->miTail = mi;
                    977:     }
                    978:     else {
                    979:         dp->miTail->next = mi;
                    980:         dp->miTail = mi;
                    981:     }
                    982: 
                    983:     return mi;
                    984: }

unix.superglobalmegacorp.com

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