1 #include "dbghelp_private.h"
2
__HeapAlloc(int heap,int flags,size_t size)3 void* __HeapAlloc(int heap, int flags, size_t size)
4 {
5 void * ret = malloc(size);
6 if(flags & HEAP_ZERO_MEMORY)
7 memset(ret, 0, size);
8 return ret;
9 }
10
__HeapReAlloc(int heap,DWORD d2,void * slab,SIZE_T newsize)11 void* __HeapReAlloc(int heap, DWORD d2, void *slab, SIZE_T newsize)
12 {
13 return realloc(slab, newsize);
14 }
15
lstrcpynW(WCHAR * lpString1,const WCHAR * lpString2,int iMaxLength)16 WCHAR* lstrcpynW(WCHAR* lpString1, const WCHAR* lpString2, int iMaxLength)
17 {
18 LPWSTR d = lpString1;
19 const WCHAR* s = lpString2;
20 UINT count = iMaxLength;
21
22 while ((count > 1) && *s)
23 {
24 count--;
25 *d++ = *s++;
26 }
27
28 if (count)
29 *d = 0;
30
31 return lpString1;
32 }
33
__RtlImageNtHeader(void * data)34 PIMAGE_NT_HEADERS __RtlImageNtHeader(void *data)
35 {
36 PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)data;
37 PIMAGE_NT_HEADERS NtHeaders;
38 PCHAR NtHeaderPtr;
39 if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
40 return NULL;
41 NtHeaderPtr = ((PCHAR)data) + DosHeader->e_lfanew;
42 NtHeaders = (PIMAGE_NT_HEADERS)NtHeaderPtr;
43 if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
44 return NULL;
45 return NtHeaders;
46 }
47
48 PIMAGE_SECTION_HEADER
__RtlImageRvaToSection(const IMAGE_NT_HEADERS * NtHeader,PVOID BaseAddress,ULONG Rva)49 __RtlImageRvaToSection(
50 const IMAGE_NT_HEADERS* NtHeader,
51 PVOID BaseAddress,
52 ULONG Rva)
53 {
54 PIMAGE_SECTION_HEADER Section;
55 ULONG Va;
56 ULONG Count;
57
58 Count = SWAPW(NtHeader->FileHeader.NumberOfSections);
59 Section = IMAGE_FIRST_SECTION(NtHeader);
60
61 while (Count--)
62 {
63 Va = SWAPD(Section->VirtualAddress);
64 if ((Va <= Rva) && (Rva < Va + SWAPD(Section->SizeOfRawData)))
65 return Section;
66 Section++;
67 }
68
69 return NULL;
70 }
71
72 PVOID
__RtlImageRvaToVa(const IMAGE_NT_HEADERS * NtHeader,PVOID BaseAddress,ULONG Rva,PIMAGE_SECTION_HEADER * SectionHeader)73 __RtlImageRvaToVa
74 (const IMAGE_NT_HEADERS* NtHeader,
75 PVOID BaseAddress,
76 ULONG Rva,
77 PIMAGE_SECTION_HEADER *SectionHeader)
78 {
79 PIMAGE_SECTION_HEADER Section = NULL;
80
81 if (SectionHeader)
82 Section = *SectionHeader;
83
84 if ((Section == NULL) ||
85 (Rva < SWAPD(Section->VirtualAddress)) ||
86 (Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->SizeOfRawData)))
87 {
88 Section = RtlImageRvaToSection(NtHeader, BaseAddress, Rva);
89 if (Section == NULL)
90 return NULL;
91
92 if (SectionHeader)
93 *SectionHeader = Section;
94 }
95
96 return (PVOID)((ULONG_PTR)BaseAddress + Rva +
97 (ULONG_PTR)SWAPD(Section->PointerToRawData) -
98 (ULONG_PTR)SWAPD(Section->VirtualAddress));
99 }
100
101 PVOID
__RtlImageDirectoryEntryToData(PVOID BaseAddress,BOOLEAN MappedAsImage,USHORT Directory,PULONG Size)102 __RtlImageDirectoryEntryToData(
103 PVOID BaseAddress,
104 BOOLEAN MappedAsImage,
105 USHORT Directory,
106 PULONG Size)
107 {
108 PIMAGE_NT_HEADERS NtHeader;
109 ULONG Va;
110
111 /* Magic flag for non-mapped images. */
112 if ((ULONG_PTR)BaseAddress & 1)
113 {
114 BaseAddress = (PVOID)((ULONG_PTR)BaseAddress & ~1);
115 MappedAsImage = FALSE;
116 }
117
118 NtHeader = RtlImageNtHeader(BaseAddress);
119 if (NtHeader == NULL)
120 return NULL;
121
122 if (Directory >= SWAPD(NtHeader->OptionalHeader.NumberOfRvaAndSizes))
123 return NULL;
124
125 Va = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress);
126 if (Va == 0)
127 return NULL;
128
129 *Size = SWAPD(NtHeader->OptionalHeader.DataDirectory[Directory].Size);
130
131 if (MappedAsImage || Va < SWAPD(NtHeader->OptionalHeader.SizeOfHeaders))
132 return (PVOID)((ULONG_PTR)BaseAddress + Va);
133
134 /* Image mapped as ordinary file, we must find raw pointer */
135 return RtlImageRvaToVa(NtHeader, BaseAddress, Va, NULL);
136 }
137
__GetFileSizeEx(HANDLE file,PLARGE_INTEGER fsize)138 BOOL __GetFileSizeEx(HANDLE file, PLARGE_INTEGER fsize)
139 {
140 if (fseek((FILE*)file, 0, 2) == -1)
141 return FALSE;
142 fsize->QuadPart = ftell((FILE*)file);
143 return TRUE;
144 }
145
__CloseHandle(HANDLE handle)146 BOOL __CloseHandle(HANDLE handle)
147 {
148 fclose(handle);
149 return TRUE;
150 }
151
__CreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)152 HANDLE __CreateFileW(
153 LPCWSTR lpFileName,
154 DWORD dwDesiredAccess,
155 DWORD dwShareMode,
156 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
157 DWORD dwCreationDisposition,
158 DWORD dwFlagsAndAttributes,
159 HANDLE hTemplateFile)
160 {
161 char buf[MAX_PATH];
162 HANDLE res;
163
164 WideCharToMultiByte(CP_ACP, 0, lpFileName, -1, buf, MAX_PATH, NULL, NULL);
165 res = CreateFileA(buf, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
166 return res;
167 }
168
__ReadFile(HANDLE file,PVOID buffer,DWORD len,PDWORD outlen,PVOID overlap)169 BOOL __ReadFile(HANDLE file, PVOID buffer, DWORD len, PDWORD outlen, PVOID overlap)
170 {
171 size_t read;
172
173 assert(overlap == NULL);
174
175 read = fread(buffer, 1, len, file);
176
177 if (ferror(file) != 0)
178 return FALSE;
179
180 *outlen = (DWORD)read;
181 return TRUE;
182 }
183
__SetFilePointer(HANDLE file,LONG low,PLONG high,DWORD move)184 DWORD __SetFilePointer(HANDLE file,LONG low, PLONG high, DWORD move)
185 {
186 assert(move == FILE_BEGIN);
187 assert(high == NULL);
188
189 if (fseek(file, low, SEEK_SET))
190 return INVALID_SET_FILE_POINTER;
191 return low;
192 }
193
__MapViewOfFile(HANDLE file,DWORD d1,DWORD d2,DWORD d3,SIZE_T s)194 void* __MapViewOfFile(HANDLE file,DWORD d1,DWORD d2,DWORD d3,SIZE_T s)
195 {
196 FILE *f = (FILE*)file;
197 LARGE_INTEGER size;
198 char *result;
199
200 if (file == INVALID_HANDLE_VALUE)
201 return NULL;
202
203 if (!GetFileSizeEx(file, &size))
204 return NULL;
205
206 if (fseek(f, 0, 0) == -1)
207 return NULL;
208
209 result = malloc(size.LowPart);
210 if (fread(result, 1, size.LowPart, f) != size.LowPart)
211 {
212 free(result);
213 return NULL;
214 }
215
216 return result;
217 }
218
__UnmapViewOfFile(const void * data)219 BOOL __UnmapViewOfFile(const void* data)
220 {
221 free((void *)data);
222 return TRUE;
223 }
224
__lstrcpynA(LPSTR d,LPCSTR s,int c)225 LPSTR __lstrcpynA(LPSTR d,LPCSTR s,int c)
226 {
227 LPSTR r = d;
228 while(*s && c)
229 {
230 *d++ = *s++;
231 c--;
232 }
233 return r;
234 }
235
236 /* From Wine implementation over their unicode library */
237 INT
__WideCharToMultiByte(UINT page,DWORD flags,LPCWSTR src,INT srclen,LPSTR dst,INT dstlen,LPCSTR defchar,BOOL * used)238 __WideCharToMultiByte(UINT page, DWORD flags, LPCWSTR src, INT srclen,
239 LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
240 {
241 int i;
242
243 if (!src || !srclen || (!dst && dstlen))
244 {
245 SetLastError( ERROR_INVALID_PARAMETER );
246 return 0;
247 }
248
249 if (srclen < 0) srclen = strlenW(src) + 1;
250
251 if(!dstlen)
252 return srclen;
253
254 for(i=0; i<srclen && i<dstlen; i++)
255 dst[i] = src[i] & 0xFF;
256
257 if (used) *used = FALSE;
258
259 return i;
260 }
261
262 INT
__MultiByteToWideChar(UINT page,DWORD flags,LPCSTR src,INT srclen,LPWSTR dst,INT dstlen)263 __MultiByteToWideChar(UINT page, DWORD flags, LPCSTR src, INT srclen,
264 LPWSTR dst, INT dstlen )
265 {
266 int i;
267
268 if (!src || !srclen || (!dst && dstlen))
269 {
270 SetLastError( ERROR_INVALID_PARAMETER );
271 return 0;
272 }
273
274 if (srclen < 0) srclen = strlen(src) + 1;
275
276 if(!dstlen)
277 return srclen;
278
279 for(i=0; i<srclen && i<dstlen; i++)
280 dst[i] = src[i];
281
282 return i;
283 }
284
285 /* In our case, the provided file path is the one we are looking for */
__FindExecutableImageExW(PCWSTR file,PCWSTR path,PWSTR out_buffer,PFIND_EXE_FILE_CALLBACKW x,PVOID y)286 HANDLE __FindExecutableImageExW(PCWSTR file, PCWSTR path, PWSTR out_buffer, PFIND_EXE_FILE_CALLBACKW x, PVOID y)
287 {
288 HANDLE ret = CreateFileW(file, 0, 0, NULL, 0, 0, NULL);
289 if(ret)
290 memcpy(out_buffer, file, (strlenW(file) + 1)*sizeof(WCHAR));
291
292 return ret;
293 }
294
295 /* printf with temp buffer allocation */
wine_dbg_sprintf(const char * format,...)296 const char *wine_dbg_sprintf( const char *format, ... )
297 {
298 static const int max_size = 200;
299 static char buffer[256];
300 char *ret;
301 int len;
302 va_list valist;
303
304 va_start(valist, format);
305 ret = buffer;
306 len = vsnprintf( ret, max_size, format, valist );
307 if (len == -1 || len >= max_size) ret[max_size-1] = 0;
308 va_end(valist);
309 return ret;
310 }
311
312 /* default implementation of wine_dbgstr_an */
wine_dbgstr_an(const char * str,int n)313 const char *wine_dbgstr_an( const char *str, int n )
314 {
315 static const char hex[16] = "0123456789abcdef";
316 char *dst, *res;
317 size_t size;
318 static char buffer[256];
319
320 if (!((ULONG_PTR)str >> 16))
321 {
322 if (!str) return "(null)";
323 res = buffer;
324 sprintf( res, "#%04x", LOWORD(str) );
325 return res;
326 }
327 if (n == -1) n = strlen(str);
328 if (n < 0) n = 0;
329 size = 10 + min( 300, n * 4 );
330 dst = res = buffer;
331 *dst++ = '"';
332 while (n-- > 0 && dst <= res + size - 9)
333 {
334 unsigned char c = *str++;
335 switch (c)
336 {
337 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
338 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
339 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
340 case '"': *dst++ = '\\'; *dst++ = '"'; break;
341 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
342 default:
343 if (c >= ' ' && c <= 126)
344 *dst++ = c;
345 else
346 {
347 *dst++ = '\\';
348 *dst++ = 'x';
349 *dst++ = hex[(c >> 4) & 0x0f];
350 *dst++ = hex[c & 0x0f];
351 }
352 }
353 }
354 *dst++ = '"';
355 if (n > 0)
356 {
357 *dst++ = '.';
358 *dst++ = '.';
359 *dst++ = '.';
360 }
361 *dst++ = 0;
362 return res;
363 }
364
365
366 /* default implementation of wine_dbgstr_wn */
wine_dbgstr_wn(const WCHAR * str,int n)367 const char *wine_dbgstr_wn( const WCHAR *str, int n )
368 {
369 char *dst, *res;
370 size_t size;
371 static char buffer[256];
372
373 if (!((ULONG_PTR)str >> 16))
374 {
375 if (!str) return "(null)";
376 res = buffer;
377 sprintf( res, "#%04x", LOWORD(str) );
378 return res;
379 }
380 if (n == -1)
381 {
382 const WCHAR *end = str;
383 while (*end) end++;
384 n = end - str;
385 }
386 if (n < 0) n = 0;
387 size = 12 + min( 300, n * 5 );
388 dst = res = buffer;
389 *dst++ = 'L';
390 *dst++ = '"';
391 while (n-- > 0 && dst <= res + size - 10)
392 {
393 WCHAR c = *str++;
394 switch (c)
395 {
396 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
397 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
398 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
399 case '"': *dst++ = '\\'; *dst++ = '"'; break;
400 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
401 default:
402 if (c >= ' ' && c <= 126)
403 *dst++ = c;
404 else
405 {
406 *dst++ = '\\';
407 sprintf(dst,"%04x",c);
408 dst+=4;
409 }
410 }
411 }
412 *dst++ = '"';
413 if (n > 0)
414 {
415 *dst++ = '.';
416 *dst++ = '.';
417 *dst++ = '.';
418 }
419 *dst++ = 0;
420 return res;
421 }
422
__IsWow64Process(HANDLE Process,BOOL * is_wow64)423 BOOL __IsWow64Process(HANDLE Process, BOOL* is_wow64)
424 {
425 *is_wow64 = FALSE;
426 return TRUE;
427 }
428
429 /* from sdk/lib/rtl/crc2.c */
430 /* This work is based off of rtl.c in Wine.
431 * Please give credit where credit is due:
432 *
433 * Copyright 2003 Thomas Mertes
434 * Crc32 code Copyright 1986 Gary S. Brown (Public domain)
435 */
436
437 /* CRC polynomial 0xedb88320 */
438 static const ULONG CrcTable[256] =
439 {
440 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
441 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
442 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
443 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
444 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
445 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
446 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
447 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
448 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
449 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
450 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
451 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
452 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
453 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
454 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
455 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
456 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
457 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
458 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
459 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
460 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
461 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
462 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
463 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
464 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
465 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
466 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
467 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
468 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
469 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
470 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
471 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
472 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
473 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
474 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
475 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
476 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
477 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
478 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
479 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
480 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
481 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
482 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
483 };
484
485 /*********************************************************************
486 * RtlComputeCrc32 [NTDLL.@]
487 *
488 * Calculate the CRC32 checksum of a block of bytes
489 *
490 * PARAMS
491 * Initial [I] Initial CRC value
492 * Data [I] Data block
493 * Length [I] Length of the byte block
494 *
495 * RETURNS
496 * The cumulative CRC32 of Initial and Length bytes of the Data block.
497 *
498 * @implemented
499 */
500 ULONG
__RtlComputeCrc32(ULONG Initial,const UCHAR * Data,ULONG Length)501 __RtlComputeCrc32(ULONG Initial, const UCHAR *Data, ULONG Length)
502 {
503 ULONG CrcValue = ~Initial;
504
505 while (Length > 0)
506 {
507 CrcValue = CrcTable[(CrcValue ^ *Data) & 0xff] ^ (CrcValue >> 8);
508 Data++;
509 Length--;
510 }
511 return ~CrcValue;
512 }
513