21339b7ac3f57add184ef6f805468255b0a06873
[reactos.git] / reactos / lib / rossym / fromfile.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: lib/rossym/fromfile.c
5 * PURPOSE: Creating rossym info from a file
6 *
7 * PROGRAMMERS: Ge van Geldorp (gvg@reactos.com)
8 */
9
10 #define NTOSAPI
11 #include <ntddk.h>
12 #include <reactos/rossym.h>
13 #include "rossympriv.h"
14 #include <ntimage.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 BOOLEAN
20 RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo)
21 {
22 IMAGE_DOS_HEADER DosHeader;
23 IMAGE_NT_HEADERS NtHeaders;
24 PIMAGE_SECTION_HEADER SectionHeaders, SectionHeader;
25 unsigned SectionIndex;
26 char SectionName[IMAGE_SIZEOF_SHORT_NAME];
27 ROSSYM_HEADER RosSymHeader;
28
29 /* Load DOS header */
30 if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER)))
31 {
32 DPRINT1("Failed to read DOS header\n");
33 return FALSE;
34 }
35 if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader))
36 {
37 DPRINT1("Image doesn't have a valid DOS header\n");
38 return FALSE;
39 }
40
41 /* Load NT headers */
42 if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew))
43 {
44 DPRINT1("Failed seeking to NT headers\n");
45 return FALSE;
46 }
47 if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS)))
48 {
49 DPRINT1("Failed to read NT headers\n");
50 return FALSE;
51 }
52 if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders))
53 {
54 DPRINT1("Image doesn't have a valid PE header\n");
55 return FALSE;
56 }
57
58 /* Load section headers */
59 if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) -
60 (char *) &NtHeaders + DosHeader.e_lfanew))
61 {
62 DPRINT1("Failed seeking to section headers\n");
63 return FALSE;
64 }
65 SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections
66 * sizeof(IMAGE_SECTION_HEADER));
67 if (NULL == SectionHeaders)
68 {
69 DPRINT1("Failed to allocate memory for %u section headers\n",
70 NtHeaders.FileHeader.NumberOfSections);
71 return FALSE;
72 }
73 if (! RosSymReadFile(FileContext, SectionHeaders,
74 NtHeaders.FileHeader.NumberOfSections
75 * sizeof(IMAGE_SECTION_HEADER)))
76 {
77 RosSymFreeMem(SectionHeaders);
78 DPRINT1("Failed to read section headers\n");
79 return FALSE;
80 }
81
82 /* Search for the section header */
83 strncpy(SectionName, ROSSYM_SECTION_NAME, IMAGE_SIZEOF_SHORT_NAME);
84 SectionHeader = SectionHeaders;
85 for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; SectionIndex++)
86 {
87 if (0 == memcmp(SectionName, SectionHeader->Name, IMAGE_SIZEOF_SHORT_NAME))
88 {
89 break;
90 }
91 SectionHeader++;
92 }
93 if (NtHeaders.FileHeader.NumberOfSections <= SectionIndex)
94 {
95 RosSymFreeMem(SectionHeaders);
96 DPRINT("No %s section found\n", ROSSYM_SECTION_NAME);
97 return FALSE;
98 }
99
100 /* Load rossym header */
101 if (! RosSymSeekFile(FileContext, SectionHeader->PointerToRawData))
102 {
103 RosSymFreeMem(SectionHeaders);
104 DPRINT1("Failed seeking to section data\n");
105 return FALSE;
106 }
107 RosSymFreeMem(SectionHeaders);
108 if (! RosSymReadFile(FileContext, &RosSymHeader, sizeof(ROSSYM_HEADER)))
109 {
110 DPRINT1("Failed to read rossym header\n");
111 return FALSE;
112 }
113 if (RosSymHeader.SymbolsOffset < sizeof(ROSSYM_HEADER)
114 || RosSymHeader.StringsOffset < RosSymHeader.SymbolsOffset + RosSymHeader.SymbolsLength
115 || 0 != (RosSymHeader.SymbolsLength % sizeof(ROSSYM_ENTRY)))
116 {
117 DPRINT1("Invalid ROSSYM_HEADER\n");
118 return FALSE;
119 }
120
121 *RosSymInfo = RosSymAllocMem(sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER)
122 + RosSymHeader.StringsOffset + RosSymHeader.StringsLength + 1);
123 if (NULL == *RosSymInfo)
124 {
125 DPRINT1("Failed to allocate memory for rossym\n");
126 return FALSE;
127 }
128 (*RosSymInfo)->Symbols = (PROSSYM_ENTRY)((char *) *RosSymInfo + sizeof(ROSSYM_INFO)
129 - sizeof(ROSSYM_HEADER) + RosSymHeader.SymbolsOffset);
130 (*RosSymInfo)->SymbolsCount = RosSymHeader.SymbolsLength / sizeof(ROSSYM_ENTRY);
131 (*RosSymInfo)->Strings = (PCHAR) *RosSymInfo + sizeof(ROSSYM_INFO) - sizeof(ROSSYM_HEADER)
132 + RosSymHeader.StringsOffset;
133 (*RosSymInfo)->StringsLength = RosSymHeader.StringsLength;
134 if (! RosSymReadFile(FileContext, *RosSymInfo + 1,
135 RosSymHeader.StringsOffset + RosSymHeader.StringsLength
136 - sizeof(ROSSYM_HEADER)))
137 {
138 DPRINT1("Failed to read rossym headers\n");
139 return FALSE;
140 }
141 /* Make sure the last string is null terminated, we allocated an extra byte for that */
142 (*RosSymInfo)->Strings[(*RosSymInfo)->StringsLength] = '\0';
143
144 return TRUE;
145 }
146
147 /* EOF */