source: trunk/src/kernel32/pefile.cpp@ 46

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

File size: 7.4 KB
Line 
1/*
2 * PE2LX PE utility functions
3 *
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 */
7#define INCL_BASE
8#include <os2.h>
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#ifdef __WATCOMC__
13#include <mem.h>
14#endif
15#include <win32type.h>
16#include <pefile.h>
17#include <misc.h>
18#include <winimage.h>
19
20//******************************************************************************
21//******************************************************************************
22char *UnicodeToFixedAsciiString(int length, WCHAR *NameString)
23{
24static char asciistring[256];
25int i;
26
27 if(length >= 255) length = 255;
28 for(i=0;i<length;i++) {
29 asciistring[i] = NameString[i] & 0xFF;
30 }
31 asciistring[length] = 0;
32 return(asciistring);
33}
34//******************************************************************************
35//******************************************************************************
36BOOL GetPEFileHeader (LPVOID lpFile, PIMAGE_FILE_HEADER pHeader)
37{
38 if(*(USHORT *)lpFile == IMAGE_DOS_SIGNATURE &&
39 *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
40 {
41 memcpy ((LPVOID)pHeader, PEHEADEROFF (lpFile), sizeof (IMAGE_FILE_HEADER));
42 return TRUE;
43 }
44 else return FALSE;
45}
46//******************************************************************************
47//******************************************************************************
48BOOL GetPEOptionalHeader (LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader)
49{
50 if(*(USHORT *)lpFile == IMAGE_DOS_SIGNATURE &&
51 *(DWORD *)PE_HEADER (lpFile) == IMAGE_NT_SIGNATURE)
52 {
53 memcpy ((LPVOID)pHeader, OPTHEADEROFF (lpFile), sizeof (IMAGE_OPTIONAL_HEADER));
54 return TRUE;
55 }
56 else return FALSE;
57}
58//******************************************************************************
59//******************************************************************************
60LPVOID ImageDirectoryOffset (LPVOID lpFile, DWORD dwIMAGE_DIRECTORY)
61{
62 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF (lpFile);
63 IMAGE_SECTION_HEADER sh;
64
65 if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
66 return NULL;
67
68 if(GetSectionHdrByRVA(lpFile, &sh, poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress) == FALSE)
69 {
70 return NULL;
71 }
72
73 return (LPVOID)(((ULONG)lpFile + (ULONG)(poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress -
74 sh.VirtualAddress) + (ULONG)sh.PointerToRawData));
75}
76//******************************************************************************
77//******************************************************************************
78BOOL GetSectionHdrByImageDir(LPVOID lpFile, DWORD dwIMAGE_DIRECTORY, PIMAGE_SECTION_HEADER pSect)
79{
80 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF (lpFile);
81
82 if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
83 return FALSE;
84
85 return GetSectionHdrByRVA(lpFile, pSect, poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress);
86}
87//******************************************************************************
88//******************************************************************************
89BOOL IsImportSection(LPVOID lpFile, PIMAGE_SECTION_HEADER psh)
90{
91 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF (lpFile);
92 int i = 0;
93 DWORD ImageDirVA;
94
95 ImageDirVA = poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
96
97 if(psh->VirtualAddress <= ImageDirVA &&
98 psh->VirtualAddress + max(psh->Misc.VirtualSize,psh->SizeOfRawData) > ImageDirVA &&
99 strcmp(psh->Name, ".idata") == 0)
100 {
101 return TRUE;
102 }
103 return FALSE;
104}
105//******************************************************************************
106//******************************************************************************
107BOOL GetSectionHdrByName (LPVOID lpFile, IMAGE_SECTION_HEADER *sh, char *szSection)
108{
109 PIMAGE_SECTION_HEADER psh;
110 int nSections = NR_SECTIONS (lpFile);
111 int i;
112
113 if((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (lpFile)) != NULL)
114 {
115 for(i=0; i<nSections; i++)
116 {
117 if(strcmp (psh->Name, szSection) == 0)
118 {
119 memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER));
120 return TRUE;
121 }
122 else psh++;
123 }
124 }
125 return FALSE;
126}
127//******************************************************************************
128//******************************************************************************
129BOOL GetSectionHdrByType (LPVOID lpFile, IMAGE_SECTION_HEADER *sh, int type)
130{
131 PIMAGE_SECTION_HEADER psh;
132 int nSections = NR_SECTIONS (lpFile);
133 int i;
134
135 if((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (lpFile)) != NULL)
136 {
137 for(i=0; i<nSections; i++)
138 {
139 if(psh->Characteristics & type)
140 {
141 memcpy ((LPVOID)sh, (LPVOID)psh, sizeof (IMAGE_SECTION_HEADER));
142 return TRUE;
143 }
144 else psh++;
145 }
146 }
147 return FALSE;
148}
149//******************************************************************************
150//******************************************************************************
151int GetNumberOfResources(LPVOID lpFile)
152{
153 PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;
154 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
155 int nCnt=0, i, j, id;
156 char *resname;
157
158 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY)ImageDirectoryOffset
159 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
160 return 0;
161
162 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
163
164 for (i=0; i<prdRoot->NumberOfNamedEntries+prdRoot->NumberOfIdEntries; i++)
165 {
166 prdType = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)prdRoot + (ULONG)prde->u2.OffsetToData);
167
168 if(i<prdRoot->NumberOfNamedEntries) {
169 //SvL: 30-10-'97, high bit is set, so clear to get real offset
170 prde->u1.Name &= ~0x80000000;
171 for(j=0;j<MAX_RES;j++) {
172 resname = UnicodeToFixedAsciiString(*(WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name), (WCHAR *)((ULONG)prdRoot + (ULONG)prde->u1.Name + sizeof(WCHAR))); // first word = string length
173 if(strcmp(resname, ResTypes[j]) == 0)
174 break;
175 }
176 if(j == MAX_RES) {
177 //SvL: 30-10-'97, not found = custom resource type (correct?)
178 id = NTRT_RCDATA;
179 }
180 else id = j;
181 }
182 else id = prde->u1.Id;
183
184 prdType = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)prdType ^ 0x80000000);
185
186 if(id == NTRT_STRING) {
187 //String tables can contain up to 16 individual resources!
188 nCnt += prdType->NumberOfNamedEntries*16 + prdType->NumberOfIdEntries*16;
189 }
190 else {
191 //Only icon groups are stored as resources in the LX file
192 //Icon groups contain one or more icons
193 if(id != NTRT_ICON)
194 nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
195 }
196 prde++;
197 }
198
199 return nCnt;
200}
201/** Get Section Header for the given RVA - returns boolean according to the result
202 *
203 * knut [Jul 22 1998 2:53am]
204 */
205BOOL GetSectionHdrByRVA (LPVOID lpFile, IMAGE_SECTION_HEADER *sh, ULONG rva)
206{
207 PIMAGE_SECTION_HEADER psh;
208 int nSections = NR_SECTIONS (lpFile);
209 int i;
210
211 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (lpFile)) != NULL)
212 {
213 for (i=0; i<nSections; i++)
214 {
215 if (rva >= psh->VirtualAddress && rva < psh->VirtualAddress + max(psh->Misc.VirtualSize,psh->SizeOfRawData))
216 {
217 memcpy (sh, psh, sizeof(IMAGE_SECTION_HEADER));
218 return TRUE;
219 }
220 else psh++;
221 }
222 }
223 return FALSE;
224}
225//******************************************************************************
226//******************************************************************************
Note: See TracBrowser for help on using the repository browser.