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) && (Rva < Va + SWAPD(Section->SizeOfRawData))) 65 return Section; 66 Section++; 67 } 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->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 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 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 146 BOOL __CloseHandle(HANDLE handle) 147 { 148 fclose(handle); 149 return TRUE; 150 } 151 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 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 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 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 219 BOOL __UnmapViewOfFile(const void* data) 220 { 221 free((void *)data); 222 return TRUE; 223 } 224 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 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 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 */ 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 */ 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 */ 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 */ 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 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 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