|
|
1.1 root 1: /*++
2:
3:
4: Copyright (c) 1992 Microsoft Corporation
5:
6: Module Name:
7:
8: file.c
9:
10: Abstract:
11:
12: This module handles all file i/o for SYMCVT. This includes the
13: mapping of all files and establishing all file pointers for the
14: mapped file(s).
15:
16: Author:
17:
18: Wesley A. Witt (wesw) 19-April-1993
19:
20: Environment:
21:
22: Win32, User Mode
23:
24: --*/
25:
26: #include <windows.h>
27: #include <stdlib.h>
28: #include <string.h>
29: #include <stdio.h>
30:
31: #include "symcvt.h"
32:
33:
34: static BOOL CalculateOutputFilePointers( PIMAGEPOINTERS pi, PIMAGEPOINTERS po );
35: static BOOL CalculateInputFilePointers( PIMAGEPOINTERS p );
36:
37:
38:
39: BOOL
40: MapInputFile (
41: PPOINTERS p,
42: HANDLE hFile,
43: char * fname
44: )
45: /*++
46:
47: Routine Description:
48:
49: Maps the input file specified by the fname argument and saves the
50: file handle & file pointer in the POINTERS structure.
51:
52:
53: Arguments:
54:
55: p - Supplies pointer to a POINTERS structure (see cofftocv.h)
56: hFile - OPTIONAL Supplies handle for file if already open
57: fname - Supplies ascii string for the file name
58:
59: Return Value:
60:
61: TRUE - file mapped ok
62: FALSE - file could not be mapped
63:
64: --*/
65:
66: {
67: BOOL rVal = TRUE;
68: DWORD lwFsize;
69:
70: memset( p, 0, sizeof(POINTERS) );
71:
72: strcpy( p->iptrs.szName, fname );
73:
74: if (hFile != NULL) {
75:
76: p->iptrs.hFile = hFile;
77:
78: } else {
79:
80: p->iptrs.hFile = CreateFile( p->iptrs.szName,
81: GENERIC_READ,
82: FILE_SHARE_READ | FILE_SHARE_WRITE,
83: NULL,
84: OPEN_EXISTING,
85: 0,
86: NULL );
87: }
88:
89: if (p->iptrs.hFile == INVALID_HANDLE_VALUE) {
90:
91: rVal = FALSE;
92:
93: } else {
94:
95: p->iptrs.fsize = GetFileSize( p->iptrs.hFile, NULL );
96: if (lwFsize == 0xffffffff) {
97: ;
98: }
99: p->iptrs.hMap = CreateFileMapping( p->iptrs.hFile,
100: NULL,
101: PAGE_READONLY,
102: 0,
103: 0,
104: NULL
105: );
106:
107: if (p->iptrs.hMap == INVALID_HANDLE_VALUE) {
108:
109: p->iptrs.hMap = NULL;
110: rVal = FALSE;
111:
112: } else {
113:
114: p->iptrs.fptr = MapViewOfFile( p->iptrs.hMap,
115: FILE_MAP_READ,
116: 0, 0, 0 );
117: if (p->iptrs.fptr == NULL) {
118: CloseHandle( p->iptrs.hMap );
119: p->iptrs.hMap = NULL;
120: rVal = FALSE;
121: }
122: }
123: }
124:
125: if (!hFile && p->iptrs.hFile != INVALID_HANDLE_VALUE) {
126: CloseHandle(p->iptrs.hFile);
127: p->iptrs.hFile = NULL;
128: }
129:
130: return rVal;
131: } /* MapInputFile() */
132:
133:
134:
135: BOOL
136: UnMapInputFile (
137: PPOINTERS p
138: )
139: /*++
140:
141: Routine Description:
142:
143: Unmaps the input file specified by the fname argument and then
144: closes the file.
145:
146:
147: Arguments:
148:
149: p - pointer to a POINTERS structure (see cofftocv.h)
150:
151: Return Value:
152:
153: TRUE - file mapped ok
154: FALSE - file could not be mapped
155:
156: --*/
157:
158: {
159: if ( p->iptrs.fptr ) {
160: UnmapViewOfFile( p->iptrs.fptr );
161: p->iptrs.fptr = NULL;
162: }
163: if ( p->iptrs.hMap ) {
164: CloseHandle( p->iptrs.hMap );
165: p->iptrs.hMap = NULL;
166: }
167: if (p->iptrs.hFile != NULL) {
168: CloseHandle( p->iptrs.hFile );
169: p->iptrs.hFile = NULL;
170: }
171: return TRUE;
172: } /* UnMapInputFile() */
173:
174:
175: BOOL
176: FillInSeparateImagePointers(
177: PIMAGEPOINTERS p
178: )
179: /*++
180:
181: Routine Description:
182:
183: This routine will go through the exe file and fill in the
184: pointers needed relative to the separate debug information files
185:
186: Arguments:
187:
188: p - Supplies the structure to fill in
189:
190: Return Value:
191:
192: TRUE if successful and FALSE otherwise.
193:
194: --*/
195:
196: {
197: int li;
198: int numDebugDirs;
199: PIMAGE_DEBUG_DIRECTORY pDebugDir;
200: PIMAGE_COFF_SYMBOLS_HEADER pCoffHdr;
201:
202: p->sectionHdrs = (PIMAGE_SECTION_HEADER)
203: (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER));
204:
205: numDebugDirs = p->sepHdr->DebugDirectorySize/sizeof(IMAGE_DEBUG_DIRECTORY);
206:
207: if (numDebugDirs == 0) {
208: return FALSE;
209: }
210:
211: /*
212: * For each debug directory, determine the debug directory type
213: * and cache any information about them.
214: */
215:
216: pDebugDir = (PIMAGE_DEBUG_DIRECTORY)
217: (p->fptr + sizeof(IMAGE_SEPARATE_DEBUG_HEADER) +
218: p->sepHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
219: p->sepHdr->ExportedNamesSize);
220:
221: for (li=0; li<numDebugDirs; li++, pDebugDir++) {
222: if (((int) pDebugDir->Type) > p->cDebugDir) {
223: p->cDebugDir += 10;
224: p->rgDebugDir = realloc((char *) p->rgDebugDir,
225: p->cDebugDir * sizeof(p->rgDebugDir[0]));
226: memset(&p->rgDebugDir[p->cDebugDir-10], 0,
227: 10*sizeof(p->rgDebugDir[0]));
228: }
229:
230: p->rgDebugDir[pDebugDir->Type] = pDebugDir;
231: }
232:
233: if (p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF] != NULL) {
234: pCoffHdr = (PIMAGE_COFF_SYMBOLS_HEADER) (p->fptr +
235: p->rgDebugDir[IMAGE_DEBUG_TYPE_COFF]->PointerToRawData);
236: p->AllSymbols = (PIMAGE_SYMBOL)
237: ((char *) pCoffHdr + pCoffHdr->LvaToFirstSymbol);
238: p->stringTable = pCoffHdr->NumberOfSymbols * IMAGE_SIZEOF_SYMBOL +
239: (char *) p->AllSymbols;
240: p->numberOfSymbols = pCoffHdr->NumberOfSymbols;
241: }
242: p->numberOfSections = p->sepHdr->NumberOfSections;
243:
244: return TRUE;
245: } /* FillInSeparateImagePointers() */
246:
247:
248:
249: BOOL
250: CalculateNtImagePointers(
251: PIMAGEPOINTERS p
252: )
253: /*++
254:
255: Routine Description:
256:
257: This function reads an NT image and its associated COFF headers
258: and file pointers and build a set of pointers into the mapped image.
259: The pointers are all relative to the image's mapped file pointer
260: and allow direct access to the necessary data.
261:
262: Arguments:
263:
264: p - pointer to a IMAGEPOINTERS structure (see cofftocv.h)
265:
266: Return Value:
267:
268: TRUE - pointers were created
269: FALSE - pointers could not be created
270:
271: --*/
272: {
273: PIMAGE_DEBUG_DIRECTORY debugDir;
274: PIMAGE_SECTION_HEADER sh;
275: DWORD i, li, rva, numDebugDirs;
276: PIMAGE_FILE_HEADER pFileHdr;
277: PIMAGE_OPTIONAL_HEADER pOptHdr;
278: DWORD offDebugInfo;
279:
280: try {
281: /*
282: * Based on wheither or not we find the dos (MZ) header
283: * at the beginning of the file, attempt to get a pointer
284: * to where the PE header is suppose to be.
285: */
286:
287: p->dosHdr = (PIMAGE_DOS_HEADER) p->fptr;
288: if (p->dosHdr->e_magic == IMAGE_DOS_SIGNATURE) {
289: p->ntHdr = (PIMAGE_NT_HEADERS)
290: ((DWORD)p->dosHdr->e_lfanew + p->fptr);
291: } else if (p->dosHdr->e_magic == IMAGE_SEPARATE_DEBUG_SIGNATURE) {
292: p->sepHdr = (PIMAGE_SEPARATE_DEBUG_HEADER) p->fptr;
293: p->dosHdr = NULL;
294: return FillInSeparateImagePointers(p);
295: } else {
296: p->ntHdr = (PIMAGE_NT_HEADERS) p->fptr;
297: p->dosHdr = NULL;
298: }
299:
300: /*
301: * What comes next must be a PE header. If not then pop out
302: */
303:
304: if (p->ntHdr->Signature != IMAGE_NT_SIGNATURE) {
305: return FALSE;
306: }
307:
308: /*
309: * We did find a PE header so start setting pointers to various
310: * structures in the exe file.
311: */
312:
313: pFileHdr = p->fileHdr = &p->ntHdr->FileHeader;
314: pOptHdr = p->optHdr = &p->ntHdr->OptionalHeader;
315:
316: if (!(pFileHdr->Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {
317: return FALSE;
318: }
319:
320: /*
321: * If they exists then get a pointer to the symbol table and
322: * the string table
323: */
324:
325: if (pFileHdr->PointerToSymbolTable) {
326: p->AllSymbols = (PIMAGE_SYMBOL) (pFileHdr->PointerToSymbolTable +
327: p->fptr);
328: p->stringTable = pFileHdr->PointerToSymbolTable + p->fptr +
329: (IMAGE_SIZEOF_SYMBOL * pFileHdr->NumberOfSymbols);
330: p->numberOfSymbols = pFileHdr->NumberOfSymbols;
331: }
332: p->numberOfSections = pFileHdr->NumberOfSections;
333:
334: /*
335: * Locate the debug directory
336: */
337:
338: rva =
339: pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
340:
341: numDebugDirs =
342: pOptHdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size /
343: sizeof(IMAGE_DEBUG_DIRECTORY);
344:
345: if (numDebugDirs == 0) {
346: return FALSE;
347: }
348:
349: sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
350:
351: /*
352: * Find the section the debug directory is in.
353: */
354:
355: for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
356: if (rva >= sh->VirtualAddress &&
357: rva < sh->VirtualAddress+sh->SizeOfRawData) {
358: break;
359: }
360: }
361:
362: /*
363: * For each debug directory, determine the debug directory
364: * type and cache any information about them.
365: */
366:
367: debugDir = (PIMAGE_DEBUG_DIRECTORY) ( rva - sh->VirtualAddress +
368: sh->PointerToRawData +
369: p->fptr );
370: for (li=0; li<numDebugDirs; li++, debugDir++) {
371: if (((int) debugDir->Type) > p->cDebugDir) {
372: p->cDebugDir += 10;
373: p->rgDebugDir = realloc((char *) p->rgDebugDir,
374: p->cDebugDir * sizeof(p->rgDebugDir[0]));
375: memset(&p->rgDebugDir[p->cDebugDir-10], 0,
376: 10*sizeof(p->rgDebugDir[0]));
377: }
378: p->rgDebugDir[debugDir->Type] = debugDir;
379: offDebugInfo = debugDir->AddressOfRawData;
380: }
381:
382: /*
383: * Check to see if the debug information is mapped and if
384: * there is a section called .debug
385: */
386:
387: sh = p->sectionHdrs = IMAGE_FIRST_SECTION( p->ntHdr );
388: for (i=0; i<pFileHdr->NumberOfSections; i++, sh++) {
389: if ((offDebugInfo >= sh->VirtualAddress) &&
390: (offDebugInfo < sh->VirtualAddress+sh->SizeOfRawData)) {
391: p->debugSection = sh;
392: break;
393: }
394: }
395: return TRUE;
396: } except (EXCEPTION_EXECUTE_HANDLER) {
397: return FALSE;
398: }
399: } /* CalcuateNtImagePointers() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.