[PSDK]
[reactos.git] / reactos / dll / win32 / dbghelp / compat.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include "dbghelp_private.h"
4
5 void* __HeapAlloc(int heap, int flags, size_t size)
6 {
7 void * ret = malloc(size);
8 if(flags & HEAP_ZERO_MEMORY)
9 memset(ret, 0, size);
10 return ret;
11 }
12
13 void* __HeapReAlloc(int heap, DWORD d2, void *slab, SIZE_T newsize)
14 {
15 return realloc(slab, newsize);
16 }
17
18 WCHAR* lstrcpynW(WCHAR* lpString1, const WCHAR* lpString2, int iMaxLength)
19 {
20 LPWSTR d = lpString1;
21 const WCHAR* s = lpString2;
22 UINT count = iMaxLength;
23
24 while ((count > 1) && *s)
25 {
26 count--;
27 *d++ = *s++;
28 }
29
30 if (count)
31 *d = 0;
32
33 return lpString1;
34 }
35
36 PIMAGE_NT_HEADERS __RtlImageNtHeader(void *data)
37 {
38 PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)data;
39 PIMAGE_NT_HEADERS NtHeaders;
40 PCHAR NtHeaderPtr;
41 if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
42 return NULL;
43 NtHeaderPtr = ((PCHAR)data) + DosHeader->e_lfanew;
44 NtHeaders = (PIMAGE_NT_HEADERS)NtHeaderPtr;
45 if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
46 return NULL;
47 return NtHeaders;
48 }
49
50 PIMAGE_SECTION_HEADER
51 __RtlImageRvaToSection(
52 const IMAGE_NT_HEADERS* NtHeader,
53 PVOID BaseAddress,
54 ULONG Rva)
55 {
56 PIMAGE_SECTION_HEADER Section;
57 ULONG Va;
58 ULONG Count;
59
60 Count = SWAPW(NtHeader->FileHeader.NumberOfSections);
61 Section = IMAGE_FIRST_SECTION(NtHeader);
62
63 while (Count--)
64 {
65 Va = SWAPD(Section->VirtualAddress);
66 if ((Va <= Rva) &&
67 (Rva < Va + SWAPD(Section->Misc.VirtualSize)))
68 return Section;
69 Section++;
70 }
71 return NULL;
72 }
73
74 PVOID
75 __RtlImageRvaToVa
76 (const IMAGE_NT_HEADERS* NtHeader,
77 PVOID BaseAddress,
78 ULONG Rva,
79 PIMAGE_SECTION_HEADER *SectionHeader)
80 {
81 PIMAGE_SECTION_HEADER Section = NULL;
82
83 if (SectionHeader)
84 Section = *SectionHeader;
85
86 if ((Section == NULL) ||
87 (Rva < SWAPD(Section->VirtualAddress)) ||
88 (Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->Misc.VirtualSize)))
89 {
90 Section = RtlImageRvaToSection (NtHeader, BaseAddress, Rva);
91 if (Section == NULL)
92 return NULL;
93
94 if (SectionHeader)
95 *SectionHeader = Section;
96 }
97
98 return (PVOID)((ULONG_PTR)BaseAddress +
99 Rva +
100 SWAPD(Section->PointerToRawData) -
101 (ULONG_PTR)SWAPD(Section->VirtualAddress));
102 }
103
104 PVOID
105 __RtlImageDirectoryEntryToData(
106 PVOID BaseAddress,
107 BOOLEAN MappedAsImage,
108 USHORT Directory,
109 PULONG Size)
110 {
111 PIMAGE_NT_HEADERS NtHeader;
112 ULONG Va;
113
114 /* Magic flag for non-mapped images. */
115 if ((ULONG_PTR)BaseAddress & 1)
116 {
117 BaseAddress = (PVOID)((ULONG_PTR)BaseAddress & ~1);
118 MappedAsImage = FALSE;
119 }
120
121 NtHeader = RtlImageNtHeader(BaseAddress);
122 if (NtHeader == NULL)
123 return NULL;
124
125 if (Directory >= SWAPD(NtHeader->OptionalHeader.NumberOfRvaAndSizes))
126 return NULL;
127
128 Va = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress);
129 if (Va == 0)
130 return NULL;
131
132 *Size = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].Size);
133
134 if (MappedAsImage || Va < SWAPD(NtHeader->OptionalHeader.SizeOfHeaders))
135 return (PVOID)((ULONG_PTR)BaseAddress + Va);
136
137 /* image mapped as ordinary file, we must find raw pointer */
138 return RtlImageRvaToVa(NtHeader, BaseAddress, Va, NULL);
139 }
140
141 BOOL __GetFileSizeEx(HANDLE file, PLARGE_INTEGER fsize)
142 {
143 if (fseek((FILE*)file, 0, 2) == -1)
144 return FALSE;
145 fsize->QuadPart = ftell((FILE*)file);
146 return TRUE;
147 }
148
149 BOOL __CloseHandle(HANDLE handle)
150 {
151 fclose(handle);
152 return TRUE;
153 }
154
155 HANDLE __CreateFileW(
156 LPCWSTR lpFileName,
157 DWORD dwDesiredAccess,
158 DWORD dwShareMode,
159 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
160 DWORD dwCreationDisposition,
161 DWORD dwFlagsAndAttributes,
162 HANDLE hTemplateFile)
163 {
164 char buf[MAX_PATH];
165 HANDLE res;
166
167 WideCharToMultiByte(CP_ACP, 0, lpFileName, -1, buf, MAX_PATH, NULL, NULL);
168 res = CreateFileA(buf, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
169 return res;
170 }
171
172 void* __MapViewOfFile(HANDLE file,DWORD d1,DWORD d2,DWORD d3,SIZE_T s)
173 {
174 FILE *f = (FILE*)file;
175 LARGE_INTEGER size;
176 char *result;
177
178 if (file == INVALID_HANDLE_VALUE)
179 return NULL;
180
181 if (!GetFileSizeEx(file, &size))
182 return NULL;
183
184 if (fseek(f, 0, 0) == -1)
185 return NULL;
186
187 result = malloc(size.LowPart);
188 if (fread(result, 1, size.LowPart, f) != size.LowPart)
189 {
190 free(result);
191 return NULL;
192 }
193
194 return result;
195 }
196
197 BOOL __UnmapViewOfFile(const void* data)
198 {
199 free((void *)data);
200 return TRUE;
201 }
202
203 LPSTR __lstrcpynA(LPSTR d,LPCSTR s,int c)
204 {
205 LPSTR r = d;
206 while(*s && c)
207 {
208 *d++ = *s++;
209 c--;
210 }
211 return r;
212 }
213
214 /* From Wine implementation over their unicode library */
215 INT
216 __WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src, INT srclen,
217 LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
218 {
219 int i;
220
221 if (!src || !srclen || (!dst && dstlen))
222 {
223 SetLastError( ERROR_INVALID_PARAMETER );
224 return 0;
225 }
226
227 if (srclen < 0) srclen = strlenW(src) + 1;
228
229 if(!dstlen)
230 return srclen;
231
232 for(i=0; i<srclen && i<dstlen; i++)
233 dst[i] = src[i] & 0xFF;
234
235 if (used) *used = FALSE;
236
237 return i;
238 }
239
240 INT
241 __MultiByteToWideChar(UINT page, DWORD flags, LPCSTR src, INT srclen,
242 LPWSTR dst, INT dstlen )
243 {
244 int i;
245
246 if (!src || !srclen || (!dst && dstlen))
247 {
248 SetLastError( ERROR_INVALID_PARAMETER );
249 return 0;
250 }
251
252 if (srclen < 0) srclen = strlen(src) + 1;
253
254 if(!dstlen)
255 return srclen;
256
257 for(i=0; i<srclen && i<dstlen; i++)
258 dst[i] = src[i];
259
260 return i;
261 }
262
263 /* In our case, the provided file path is the one we are looking for */
264 HANDLE __FindExecutableImageExW(PCWSTR file, PCWSTR path, PWSTR out_buffer, PFIND_EXE_FILE_CALLBACKW x, PVOID y)
265 {
266 HANDLE ret = CreateFileW(file, 0, 0, NULL, 0, 0, NULL);
267 if(ret)
268 memcpy(out_buffer, file, (strlenW(file) + 1)*sizeof(WCHAR));
269
270 return ret;
271 }
272
273 /* printf with temp buffer allocation */
274 const char *wine_dbg_sprintf( const char *format, ... )
275 {
276 static const int max_size = 200;
277 static char buffer[256];
278 char *ret;
279 int len;
280 va_list valist;
281
282 va_start(valist, format);
283 ret = buffer;
284 len = vsnprintf( ret, max_size, format, valist );
285 if (len == -1 || len >= max_size) ret[max_size-1] = 0;
286 va_end(valist);
287 return ret;
288 }
289
290 /* default implementation of wine_dbgstr_an */
291 const char *wine_dbgstr_an( const char *str, int n )
292 {
293 static const char hex[16] = "0123456789abcdef";
294 char *dst, *res;
295 size_t size;
296 char buffer[256];
297
298 if (!((ULONG_PTR)str >> 16))
299 {
300 if (!str) return "(null)";
301 res = buffer;
302 sprintf( res, "#%04x", LOWORD(str) );
303 return res;
304 }
305 if (n == -1) n = strlen(str);
306 if (n < 0) n = 0;
307 size = 10 + min( 300, n * 4 );
308 dst = res = buffer;
309 *dst++ = '"';
310 while (n-- > 0 && dst <= res + size - 9)
311 {
312 unsigned char c = *str++;
313 switch (c)
314 {
315 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
316 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
317 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
318 case '"': *dst++ = '\\'; *dst++ = '"'; break;
319 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
320 default:
321 if (c >= ' ' && c <= 126)
322 *dst++ = c;
323 else
324 {
325 *dst++ = '\\';
326 *dst++ = 'x';
327 *dst++ = hex[(c >> 4) & 0x0f];
328 *dst++ = hex[c & 0x0f];
329 }
330 }
331 }
332 *dst++ = '"';
333 if (n > 0)
334 {
335 *dst++ = '.';
336 *dst++ = '.';
337 *dst++ = '.';
338 }
339 *dst++ = 0;
340 return res;
341 }
342
343
344 /* default implementation of wine_dbgstr_wn */
345 const char *wine_dbgstr_wn( const WCHAR *str, int n )
346 {
347 char *dst, *res;
348 size_t size;
349 static char buffer[256];
350
351 if (!((ULONG_PTR)str >> 16))
352 {
353 if (!str) return "(null)";
354 res = buffer;
355 sprintf( res, "#%04x", LOWORD(str) );
356 return res;
357 }
358 if (n == -1)
359 {
360 const WCHAR *end = str;
361 while (*end) end++;
362 n = end - str;
363 }
364 if (n < 0) n = 0;
365 size = 12 + min( 300, n * 5 );
366 dst = res = buffer;
367 *dst++ = 'L';
368 *dst++ = '"';
369 while (n-- > 0 && dst <= res + size - 10)
370 {
371 WCHAR c = *str++;
372 switch (c)
373 {
374 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
375 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
376 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
377 case '"': *dst++ = '\\'; *dst++ = '"'; break;
378 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
379 default:
380 if (c >= ' ' && c <= 126)
381 *dst++ = c;
382 else
383 {
384 *dst++ = '\\';
385 sprintf(dst,"%04x",c);
386 dst+=4;
387 }
388 }
389 }
390 *dst++ = '"';
391 if (n > 0)
392 {
393 *dst++ = '.';
394 *dst++ = '.';
395 *dst++ = '.';
396 }
397 *dst++ = 0;
398 return res;
399 }