xref: /reactos/dll/win32/dbghelp/compat.c (revision 01fbf25d)
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