|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.