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