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