xref: /reactos/sdk/lib/rossym/fromfile.c (revision 5140a990)
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 #include <ntdef.h>
11 #include <reactos/rossym.h>
12 #include "rossympriv.h"
13 #include <ntimage.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 */
147