[SDK][CRT] Fix _ismbblead undefined error on MSVC
[reactos.git] / sdk / lib / crt / startup / pesect.c
1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7 //#include <windows.h>
8 #include <stdarg.h>
9 #include <windef.h>
10 #include <winbase.h>
11 #include <string.h>
12
13 #if defined (_WIN64) && defined (__ia64__)
14 #error FIXME: Unsupported __ImageBase implementation.
15 #else
16 #ifdef __GNUC__
17 /* Hack, for bug in ld. Will be removed soon. */
18 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
19 #endif
20 /* This symbol is defined by the linker. */
21 extern IMAGE_DOS_HEADER __ImageBase;
22 #endif
23
24 WINBOOL _ValidateImageBase (PBYTE);
25
26 WINBOOL
27 _ValidateImageBase (PBYTE pImageBase)
28 {
29 PIMAGE_DOS_HEADER pDOSHeader;
30 PIMAGE_NT_HEADERS pNTHeader;
31 PIMAGE_OPTIONAL_HEADER pOptHeader;
32
33 pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
34 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
35 return FALSE;
36 pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
37 if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
38 return FALSE;
39 pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
40 if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
41 return FALSE;
42 return TRUE;
43 }
44
45 PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
46
47 PIMAGE_SECTION_HEADER
48 _FindPESection (PBYTE pImageBase, DWORD_PTR rva)
49 {
50 PIMAGE_NT_HEADERS pNTHeader;
51 PIMAGE_SECTION_HEADER pSection;
52 unsigned int iSection;
53
54 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
55
56 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
57 iSection < pNTHeader->FileHeader.NumberOfSections;
58 ++iSection,++pSection)
59 {
60 if (rva >= pSection->VirtualAddress
61 && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
62 return pSection;
63 }
64 return NULL;
65 }
66
67 PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
68
69 PIMAGE_SECTION_HEADER
70 _FindPESectionByName (const char *pName)
71 {
72 PBYTE pImageBase;
73 PIMAGE_NT_HEADERS pNTHeader;
74 PIMAGE_SECTION_HEADER pSection;
75 unsigned int iSection;
76
77 /* Long names aren't supported. */
78 if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
79 return NULL;
80
81 pImageBase = (PBYTE) &__ImageBase;
82 if (! _ValidateImageBase (pImageBase))
83 return NULL;
84
85 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
86
87 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
88 iSection < pNTHeader->FileHeader.NumberOfSections;
89 ++iSection,++pSection)
90 {
91 if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
92 return pSection;
93 }
94 return NULL;
95 }
96
97 int __mingw_GetSectionCount (void);
98 PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
99
100 PIMAGE_SECTION_HEADER
101 __mingw_GetSectionForAddress (LPVOID p)
102 {
103 PBYTE pImageBase;
104 DWORD_PTR rva;
105
106 pImageBase = (PBYTE) &__ImageBase;
107 if (! _ValidateImageBase (pImageBase))
108 return NULL;
109
110 rva = (DWORD_PTR) (((PBYTE) p) - pImageBase);
111 return _FindPESection (pImageBase, rva);
112 }
113
114 int
115 __mingw_GetSectionCount (void)
116 {
117 PBYTE pImageBase;
118 PIMAGE_NT_HEADERS pNTHeader;
119
120 pImageBase = (PBYTE) &__ImageBase;
121 if (! _ValidateImageBase (pImageBase))
122 return 0;
123
124 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
125
126 return (int) pNTHeader->FileHeader.NumberOfSections;
127 }
128
129
130 PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
131
132 PIMAGE_SECTION_HEADER
133 _FindPESectionExec (size_t eNo)
134 {
135 PBYTE pImageBase;
136 PIMAGE_NT_HEADERS pNTHeader;
137 PIMAGE_SECTION_HEADER pSection;
138 unsigned int iSection;
139
140 pImageBase = (PBYTE) &__ImageBase;
141 if (! _ValidateImageBase (pImageBase))
142 return NULL;
143
144 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
145
146 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
147 iSection < pNTHeader->FileHeader.NumberOfSections;
148 ++iSection,++pSection)
149 {
150 if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
151 {
152 if (!eNo)
153 return pSection;
154 --eNo;
155 }
156 }
157 return NULL;
158 }
159
160 PBYTE _GetPEImageBase (void);
161
162 PBYTE
163 _GetPEImageBase (void)
164 {
165 PBYTE pImageBase;
166 pImageBase = (PBYTE) &__ImageBase;
167 if (! _ValidateImageBase (pImageBase))
168 return NULL;
169 return pImageBase;
170 }
171
172 WINBOOL _IsNonwritableInCurrentImage (PBYTE);
173
174 WINBOOL
175 _IsNonwritableInCurrentImage (PBYTE pTarget)
176 {
177 PBYTE pImageBase;
178 DWORD_PTR rvaTarget;
179 PIMAGE_SECTION_HEADER pSection;
180
181 pImageBase = (PBYTE) &__ImageBase;
182 if (! _ValidateImageBase (pImageBase))
183 return FALSE;
184 rvaTarget = pTarget - pImageBase;
185 pSection = _FindPESection (pImageBase, rvaTarget);
186 if (pSection == NULL)
187 return FALSE;
188 return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
189 }
190
191 const char *
192 __mingw_enum_import_library_names (int);
193
194 const char *
195 __mingw_enum_import_library_names (int i)
196 {
197 PBYTE pImageBase;
198 PIMAGE_NT_HEADERS pNTHeader;
199 PIMAGE_IMPORT_DESCRIPTOR importDesc;
200 PIMAGE_SECTION_HEADER pSection;
201 DWORD importsStartRVA;
202
203 pImageBase = (PBYTE) &__ImageBase;
204 if (! _ValidateImageBase (pImageBase))
205 return NULL;
206
207 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
208
209 importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
210 if (!importsStartRVA)
211 return NULL;
212
213 pSection = _FindPESection (pImageBase, importsStartRVA);
214 if (!pSection)
215 return NULL;
216
217 importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA);
218 if (!importDesc)
219 return NULL;
220
221 for (;;)
222 {
223 if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0)
224 break;
225
226 if (i <= 0)
227 return (char *) (pImageBase + importDesc->Name);
228 --i;
229 importDesc++;
230 }
231
232 return NULL;
233 }
234
235 HMODULE __mingw_get_msvcrt_handle(void);
236 HMODULE __mingw_get_msvcrt_handle(void)
237 {
238 static HANDLE msvcrt_handle;
239
240 if(!msvcrt_handle) {
241 const char *lib_name;
242 int i = 0;
243
244 while ((lib_name = __mingw_enum_import_library_names (i++))) {
245 if((lib_name[0] == 'm' || lib_name[0] == 'M')
246 && (lib_name[1] == 's' || lib_name[1] == 'S')
247 && (lib_name[2] == 'v' || lib_name[2] == 'V')
248 && (lib_name[3] == 'c' || lib_name[3] == 'C')
249 && (lib_name[4] == 'r' || lib_name[4] == 'R')
250 && (lib_name[5] == 't' || lib_name[5] == 'T' || ('0' <= lib_name[5] && lib_name[5] <= '9')))
251 break;
252 }
253
254 if(lib_name)
255 msvcrt_handle = GetModuleHandleA(lib_name);
256 if(!msvcrt_handle)
257 msvcrt_handle = LoadLibraryW(L"msvcrt.dll");
258 }
259
260 return msvcrt_handle;
261 }