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