Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendbghelp.c
Go to the documentation of this file.
00001 /* 00002 * File dbghelp.c - generic routines (process) for dbghelp DLL 00003 * 00004 * Copyright (C) 2004, Eric Pouech 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include "dbghelp_private.h" 00024 #include "winerror.h" 00025 #include "psapi.h" 00026 #include "wine/debug.h" 00027 #include "wdbgexts.h" 00028 #include "winnls.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); 00031 00032 /* TODO 00033 * - support for symbols' types is still partly missing 00034 * + C++ support 00035 * + we should store the underlying type for an enum in the symt_enum struct 00036 * + for enums, we store the names & values (associated to the enum type), 00037 * but those values are not directly usable from a debugger (that's why, I 00038 * assume, that we have also to define constants for enum values, as 00039 * Codeview does BTW. 00040 * + SymEnumTypes should only return *user* defined types (UDT, typedefs...) not 00041 * all the types stored/used in the modules (like char*) 00042 * - SymGetLine{Next|Prev} don't work as expected (they don't seem to work across 00043 * functions, and even across function blocks...). Basically, for *Next* to work 00044 * it requires an address after the prolog of the func (the base address of the 00045 * func doesn't work) 00046 * - most options (dbghelp_options) are not used (loading lines...) 00047 * - in symbol lookup by name, we don't use RE everywhere we should. Moreover, when 00048 * we're supposed to use RE, it doesn't make use of our hash tables. Therefore, 00049 * we could use hash if name isn't a RE, and fall back to a full search when we 00050 * get a full RE 00051 * - msc: 00052 * + we should add parameters' types to the function's signature 00053 * while processing a function's parameters 00054 * + add support for function-less labels (as MSC seems to define them) 00055 * + C++ management 00056 * - stabs: 00057 * + when, in a same module, the same definition is used in several compilation 00058 * units, we get several definitions of the same object (especially 00059 * struct/union). we should find a way not to duplicate them 00060 * + in some cases (dlls/user/dialog16.c DIALOG_GetControl16), the same static 00061 * global variable is defined several times (at different scopes). We are 00062 * getting several of those while looking for a unique symbol. Part of the 00063 * issue is that we don't give a scope to a static variable inside a function 00064 * + C++ management 00065 */ 00066 00067 unsigned dbghelp_options = SYMOPT_UNDNAME; 00068 HANDLE hMsvcrt = NULL; 00069 00070 /*********************************************************************** 00071 * DllMain (DEBUGHLP.@) 00072 */ 00073 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 00074 { 00075 switch (fdwReason) 00076 { 00077 case DLL_PROCESS_ATTACH: break; 00078 case DLL_PROCESS_DETACH: 00079 if (hMsvcrt) FreeLibrary(hMsvcrt); 00080 break; 00081 case DLL_THREAD_ATTACH: break; 00082 case DLL_THREAD_DETACH: break; 00083 default: break; 00084 } 00085 return TRUE; 00086 } 00087 00088 static struct process* process_first /* = NULL */; 00089 00090 /****************************************************************** 00091 * process_find_by_handle 00092 * 00093 */ 00094 struct process* process_find_by_handle(HANDLE hProcess) 00095 { 00096 struct process* p; 00097 00098 for (p = process_first; p && p->handle != hProcess; p = p->next); 00099 if (!p) SetLastError(ERROR_INVALID_HANDLE); 00100 return p; 00101 } 00102 00103 /****************************************************************** 00104 * validate_addr64 (internal) 00105 * 00106 */ 00107 BOOL validate_addr64(DWORD64 addr) 00108 { 00109 if (sizeof(void*) == sizeof(int) && (addr >> 32)) 00110 { 00111 FIXME("Unsupported address %s\n", wine_dbgstr_longlong(addr)); 00112 SetLastError(ERROR_INVALID_PARAMETER); 00113 return FALSE; 00114 } 00115 return TRUE; 00116 } 00117 00118 /****************************************************************** 00119 * fetch_buffer 00120 * 00121 * Ensures process' internal buffer is large enough. 00122 */ 00123 void* fetch_buffer(struct process* pcs, unsigned size) 00124 { 00125 if (size > pcs->buffer_size) 00126 { 00127 if (pcs->buffer) 00128 pcs->buffer = HeapReAlloc(GetProcessHeap(), 0, pcs->buffer, size); 00129 else 00130 pcs->buffer = HeapAlloc(GetProcessHeap(), 0, size); 00131 pcs->buffer_size = (pcs->buffer) ? size : 0; 00132 } 00133 return pcs->buffer; 00134 } 00135 00136 const char* wine_dbgstr_addr(const ADDRESS64* addr) 00137 { 00138 if (!addr) return "(null)"; 00139 switch (addr->Mode) 00140 { 00141 case AddrModeFlat: 00142 return wine_dbg_sprintf("flat<%s>", wine_dbgstr_longlong(addr->Offset)); 00143 case AddrMode1616: 00144 return wine_dbg_sprintf("1616<%04x:%04x>", addr->Segment, (DWORD)addr->Offset); 00145 case AddrMode1632: 00146 return wine_dbg_sprintf("1632<%04x:%08x>", addr->Segment, (DWORD)addr->Offset); 00147 case AddrModeReal: 00148 return wine_dbg_sprintf("real<%04x:%04x>", addr->Segment, (DWORD)addr->Offset); 00149 default: 00150 return "unknown"; 00151 } 00152 } 00153 00154 extern struct cpu cpu_i386, cpu_x86_64, cpu_ppc, cpu_sparc, cpu_arm; 00155 00156 static struct cpu* dbghelp_cpus[] = {&cpu_i386, &cpu_x86_64, &cpu_ppc, &cpu_sparc, &cpu_arm, NULL}; 00157 struct cpu* dbghelp_current_cpu = 00158 #if defined(__i386__) 00159 &cpu_i386 00160 #elif defined(__x86_64__) 00161 &cpu_x86_64 00162 #elif defined(__powerpc__) 00163 &cpu_ppc 00164 #elif defined(__sparc__) 00165 &cpu_sparc 00166 #elif defined(__arm__) 00167 &cpu_arm 00168 #else 00169 #error define support for your CPU 00170 #endif 00171 ; 00172 00173 struct cpu* cpu_find(DWORD machine) 00174 { 00175 struct cpu** cpu; 00176 00177 for (cpu = dbghelp_cpus ; *cpu; cpu++) 00178 { 00179 if (cpu[0]->machine == machine) return cpu[0]; 00180 } 00181 return NULL; 00182 } 00183 00184 /****************************************************************** 00185 * SymSetSearchPathW (DBGHELP.@) 00186 * 00187 */ 00188 BOOL WINAPI SymSetSearchPathW(HANDLE hProcess, PCWSTR searchPath) 00189 { 00190 struct process* pcs = process_find_by_handle(hProcess); 00191 00192 if (!pcs) return FALSE; 00193 if (!searchPath) return FALSE; 00194 00195 HeapFree(GetProcessHeap(), 0, pcs->search_path); 00196 pcs->search_path = lstrcpyW(HeapAlloc(GetProcessHeap(), 0, 00197 (lstrlenW(searchPath) + 1) * sizeof(WCHAR)), 00198 searchPath); 00199 return TRUE; 00200 } 00201 00202 /****************************************************************** 00203 * SymSetSearchPath (DBGHELP.@) 00204 * 00205 */ 00206 BOOL WINAPI SymSetSearchPath(HANDLE hProcess, PCSTR searchPath) 00207 { 00208 BOOL ret = FALSE; 00209 unsigned len; 00210 WCHAR* sp; 00211 00212 len = MultiByteToWideChar(CP_ACP, 0, searchPath, -1, NULL, 0); 00213 if ((sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) 00214 { 00215 MultiByteToWideChar(CP_ACP, 0, searchPath, -1, sp, len); 00216 00217 ret = SymSetSearchPathW(hProcess, sp); 00218 HeapFree(GetProcessHeap(), 0, sp); 00219 } 00220 return ret; 00221 } 00222 00223 /*********************************************************************** 00224 * SymGetSearchPathW (DBGHELP.@) 00225 */ 00226 BOOL WINAPI SymGetSearchPathW(HANDLE hProcess, PWSTR szSearchPath, 00227 DWORD SearchPathLength) 00228 { 00229 struct process* pcs = process_find_by_handle(hProcess); 00230 if (!pcs) return FALSE; 00231 00232 lstrcpynW(szSearchPath, pcs->search_path, SearchPathLength); 00233 return TRUE; 00234 } 00235 00236 /*********************************************************************** 00237 * SymGetSearchPath (DBGHELP.@) 00238 */ 00239 BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath, 00240 DWORD SearchPathLength) 00241 { 00242 WCHAR* buffer = HeapAlloc(GetProcessHeap(), 0, SearchPathLength * sizeof(WCHAR)); 00243 BOOL ret = FALSE; 00244 00245 if (buffer) 00246 { 00247 ret = SymGetSearchPathW(hProcess, buffer, SearchPathLength); 00248 if (ret) 00249 WideCharToMultiByte(CP_ACP, 0, buffer, SearchPathLength, 00250 szSearchPath, SearchPathLength, NULL, NULL); 00251 HeapFree(GetProcessHeap(), 0, buffer); 00252 } 00253 return ret; 00254 } 00255 00256 /****************************************************************** 00257 * invade_process 00258 * 00259 * SymInitialize helper: loads in dbghelp all known (and loaded modules) 00260 * this assumes that hProcess is a handle on a valid process 00261 */ 00262 static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user) 00263 { 00264 WCHAR tmp[MAX_PATH]; 00265 HANDLE hProcess = user; 00266 00267 if (!GetModuleFileNameExW(hProcess, (HMODULE)(DWORD_PTR)base, 00268 tmp, sizeof(tmp) / sizeof(WCHAR))) 00269 lstrcpynW(tmp, name, sizeof(tmp) / sizeof(WCHAR)); 00270 00271 SymLoadModuleExW(hProcess, 0, tmp, name, base, size, NULL, 0); 00272 return TRUE; 00273 } 00274 00275 /****************************************************************** 00276 * check_live_target 00277 * 00278 */ 00279 static BOOL check_live_target(struct process* pcs) 00280 { 00281 if (!GetProcessId(pcs->handle)) return FALSE; 00282 if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE; 00283 if (!elf_read_wine_loader_dbg_info(pcs)) 00284 macho_read_wine_loader_dbg_info(pcs); 00285 return TRUE; 00286 } 00287 00288 /****************************************************************** 00289 * SymInitializeW (DBGHELP.@) 00290 * 00291 * The initialisation of a dbghelp's context. 00292 * Note that hProcess doesn't need to be a valid process handle (except 00293 * when fInvadeProcess is TRUE). 00294 * Since, we're also allow to load ELF (pure) libraries and Wine ELF libraries 00295 * containing PE (and NE) module(s), here's how we handle it: 00296 * - we load every module (ELF, NE, PE) passed in SymLoadModule 00297 * - in fInvadeProcess (in SymInitialize) is TRUE, we set up what is called ELF 00298 * synchronization: hProcess should be a valid process handle, and we hook 00299 * ourselves on hProcess's loaded ELF-modules, and keep this list in sync with 00300 * our internal ELF modules representation (loading / unloading). This way, 00301 * we'll pair every loaded builtin PE module with its ELF counterpart (and 00302 * access its debug information). 00303 * - if fInvadeProcess (in SymInitialize) is FALSE, we check anyway if the 00304 * hProcess refers to a running process. We use some heuristics here, so YMMV. 00305 * If we detect a live target, then we get the same handling as if 00306 * fInvadeProcess is TRUE (except that the modules are not loaded). Otherwise, 00307 * we won't be able to make the peering between a builtin PE module and its ELF 00308 * counterpart. Hence we won't be able to provide the requested debug 00309 * information. We'll however be able to load native PE modules (and their 00310 * debug information) without any trouble. 00311 * Note also that this scheme can be intertwined with the deferred loading 00312 * mechanism (ie only load the debug information when we actually need it). 00313 */ 00314 BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess) 00315 { 00316 struct process* pcs; 00317 00318 TRACE("(%p %s %u)\n", hProcess, debugstr_w(UserSearchPath), fInvadeProcess); 00319 00320 if (process_find_by_handle(hProcess)){ 00321 WARN("the symbols for this process have already been initialized!\n"); 00322 00323 /* MSDN says to only call this function once unless SymCleanup() has been called since the last call. 00324 It also says to call SymRefreshModuleList() instead if you just want the module list refreshed. 00325 Native still returns TRUE even if the process has already been initialized. */ 00326 return TRUE; 00327 } 00328 00329 pcs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pcs)); 00330 if (!pcs) return FALSE; 00331 00332 pcs->handle = hProcess; 00333 00334 if (UserSearchPath) 00335 { 00336 pcs->search_path = lstrcpyW(HeapAlloc(GetProcessHeap(), 0, 00337 (lstrlenW(UserSearchPath) + 1) * sizeof(WCHAR)), 00338 UserSearchPath); 00339 } 00340 else 00341 { 00342 unsigned size; 00343 unsigned len; 00344 static const WCHAR sym_path[] = {'_','N','T','_','S','Y','M','B','O','L','_','P','A','T','H',0}; 00345 static const WCHAR alt_sym_path[] = {'_','N','T','_','A','L','T','E','R','N','A','T','E','_','S','Y','M','B','O','L','_','P','A','T','H',0}; 00346 00347 pcs->search_path = HeapAlloc(GetProcessHeap(), 0, (len = MAX_PATH) * sizeof(WCHAR)); 00348 while ((size = GetCurrentDirectoryW(len, pcs->search_path)) >= len) 00349 pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (len *= 2) * sizeof(WCHAR)); 00350 pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1) * sizeof(WCHAR)); 00351 00352 len = GetEnvironmentVariableW(sym_path, NULL, 0); 00353 if (len) 00354 { 00355 pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR)); 00356 pcs->search_path[size] = ';'; 00357 GetEnvironmentVariableW(sym_path, pcs->search_path + size + 1, len); 00358 size += 1 + len; 00359 } 00360 len = GetEnvironmentVariableW(alt_sym_path, NULL, 0); 00361 if (len) 00362 { 00363 pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR)); 00364 pcs->search_path[size] = ';'; 00365 GetEnvironmentVariableW(alt_sym_path, pcs->search_path + size + 1, len); 00366 } 00367 } 00368 00369 pcs->lmodules = NULL; 00370 pcs->dbg_hdr_addr = 0; 00371 pcs->next = process_first; 00372 process_first = pcs; 00373 00374 if (check_live_target(pcs)) 00375 { 00376 if (fInvadeProcess) 00377 EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess); 00378 elf_synchronize_module_list(pcs); 00379 macho_synchronize_module_list(pcs); 00380 } 00381 else if (fInvadeProcess) 00382 { 00383 SymCleanup(hProcess); 00384 SetLastError(ERROR_INVALID_PARAMETER); 00385 return FALSE; 00386 } 00387 00388 return TRUE; 00389 } 00390 00391 /****************************************************************** 00392 * SymInitialize (DBGHELP.@) 00393 * 00394 * 00395 */ 00396 BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess) 00397 { 00398 WCHAR* sp = NULL; 00399 BOOL ret; 00400 00401 if (UserSearchPath) 00402 { 00403 unsigned len; 00404 00405 len = MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, NULL, 0); 00406 sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00407 MultiByteToWideChar(CP_ACP, 0, UserSearchPath, -1, sp, len); 00408 } 00409 00410 ret = SymInitializeW(hProcess, sp, fInvadeProcess); 00411 HeapFree(GetProcessHeap(), 0, sp); 00412 return ret; 00413 } 00414 00415 /****************************************************************** 00416 * SymCleanup (DBGHELP.@) 00417 * 00418 */ 00419 BOOL WINAPI SymCleanup(HANDLE hProcess) 00420 { 00421 struct process** ppcs; 00422 struct process* next; 00423 00424 for (ppcs = &process_first; *ppcs; ppcs = &(*ppcs)->next) 00425 { 00426 if ((*ppcs)->handle == hProcess) 00427 { 00428 while ((*ppcs)->lmodules) module_remove(*ppcs, (*ppcs)->lmodules); 00429 00430 HeapFree(GetProcessHeap(), 0, (*ppcs)->search_path); 00431 next = (*ppcs)->next; 00432 HeapFree(GetProcessHeap(), 0, *ppcs); 00433 *ppcs = next; 00434 return TRUE; 00435 } 00436 } 00437 00438 ERR("this process has not had SymInitialize() called for it!\n"); 00439 return FALSE; 00440 } 00441 00442 /****************************************************************** 00443 * SymSetOptions (DBGHELP.@) 00444 * 00445 */ 00446 DWORD WINAPI SymSetOptions(DWORD opts) 00447 { 00448 struct process* pcs; 00449 00450 for (pcs = process_first; pcs; pcs = pcs->next) 00451 { 00452 pcs_callback(pcs, CBA_SET_OPTIONS, &opts); 00453 } 00454 return dbghelp_options = opts; 00455 } 00456 00457 /****************************************************************** 00458 * SymGetOptions (DBGHELP.@) 00459 * 00460 */ 00461 DWORD WINAPI SymGetOptions(void) 00462 { 00463 return dbghelp_options; 00464 } 00465 00466 /****************************************************************** 00467 * SymSetParentWindow (DBGHELP.@) 00468 * 00469 */ 00470 BOOL WINAPI SymSetParentWindow(HWND hwnd) 00471 { 00472 /* Save hwnd so it can be used as parent window */ 00473 FIXME("(%p): stub\n", hwnd); 00474 return TRUE; 00475 } 00476 00477 /****************************************************************** 00478 * SymSetContext (DBGHELP.@) 00479 * 00480 */ 00481 BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, 00482 PIMAGEHLP_CONTEXT Context) 00483 { 00484 struct process* pcs = process_find_by_handle(hProcess); 00485 if (!pcs) return FALSE; 00486 00487 if (pcs->ctx_frame.ReturnOffset == StackFrame->ReturnOffset && 00488 pcs->ctx_frame.FrameOffset == StackFrame->FrameOffset && 00489 pcs->ctx_frame.StackOffset == StackFrame->StackOffset) 00490 { 00491 TRACE("Setting same frame {rtn=%s frm=%s stk=%s}\n", 00492 wine_dbgstr_longlong(pcs->ctx_frame.ReturnOffset), 00493 wine_dbgstr_longlong(pcs->ctx_frame.FrameOffset), 00494 wine_dbgstr_longlong(pcs->ctx_frame.StackOffset)); 00495 pcs->ctx_frame.InstructionOffset = StackFrame->InstructionOffset; 00496 SetLastError(ERROR_ACCESS_DENIED); /* latest MSDN says ERROR_SUCCESS */ 00497 return FALSE; 00498 } 00499 00500 pcs->ctx_frame = *StackFrame; 00501 /* MSDN states that Context is not (no longer?) used */ 00502 return TRUE; 00503 } 00504 00505 /****************************************************************** 00506 * reg_cb64to32 (internal) 00507 * 00508 * Registered callback for converting information from 64 bit to 32 bit 00509 */ 00510 static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user) 00511 { 00512 struct process* pcs = process_find_by_handle(hProcess); 00513 void* data32; 00514 IMAGEHLP_DEFERRED_SYMBOL_LOAD64* idsl64; 00515 IMAGEHLP_DEFERRED_SYMBOL_LOAD idsl; 00516 00517 if (!pcs) return FALSE; 00518 switch (action) 00519 { 00520 case CBA_DEBUG_INFO: 00521 case CBA_DEFERRED_SYMBOL_LOAD_CANCEL: 00522 case CBA_SET_OPTIONS: 00523 case CBA_SYMBOLS_UNLOADED: 00524 data32 = (void*)(DWORD_PTR)data; 00525 break; 00526 case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE: 00527 case CBA_DEFERRED_SYMBOL_LOAD_FAILURE: 00528 case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL: 00529 case CBA_DEFERRED_SYMBOL_LOAD_START: 00530 idsl64 = (IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)(DWORD_PTR)data; 00531 if (!validate_addr64(idsl64->BaseOfImage)) 00532 return FALSE; 00533 idsl.SizeOfStruct = sizeof(idsl); 00534 idsl.BaseOfImage = (DWORD)idsl64->BaseOfImage; 00535 idsl.CheckSum = idsl64->CheckSum; 00536 idsl.TimeDateStamp = idsl64->TimeDateStamp; 00537 memcpy(idsl.FileName, idsl64->FileName, sizeof(idsl.FileName)); 00538 idsl.Reparse = idsl64->Reparse; 00539 data32 = &idsl; 00540 break; 00541 case CBA_DUPLICATE_SYMBOL: 00542 case CBA_EVENT: 00543 case CBA_READ_MEMORY: 00544 default: 00545 FIXME("No mapping for action %u\n", action); 00546 return FALSE; 00547 } 00548 return pcs->reg_cb32(hProcess, action, data32, (PVOID)(DWORD_PTR)user); 00549 } 00550 00551 /****************************************************************** 00552 * pcs_callback (internal) 00553 */ 00554 BOOL pcs_callback(const struct process* pcs, ULONG action, void* data) 00555 { 00556 IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl; 00557 00558 TRACE("%p %u %p\n", pcs, action, data); 00559 00560 if (!pcs->reg_cb) return FALSE; 00561 if (!pcs->reg_is_unicode) 00562 { 00563 IMAGEHLP_DEFERRED_SYMBOL_LOADW64* idslW; 00564 00565 switch (action) 00566 { 00567 case CBA_DEBUG_INFO: 00568 case CBA_DEFERRED_SYMBOL_LOAD_CANCEL: 00569 case CBA_SET_OPTIONS: 00570 case CBA_SYMBOLS_UNLOADED: 00571 break; 00572 case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE: 00573 case CBA_DEFERRED_SYMBOL_LOAD_FAILURE: 00574 case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL: 00575 case CBA_DEFERRED_SYMBOL_LOAD_START: 00576 idslW = data; 00577 idsl.SizeOfStruct = sizeof(idsl); 00578 idsl.BaseOfImage = idslW->BaseOfImage; 00579 idsl.CheckSum = idslW->CheckSum; 00580 idsl.TimeDateStamp = idslW->TimeDateStamp; 00581 WideCharToMultiByte(CP_ACP, 0, idslW->FileName, -1, 00582 idsl.FileName, sizeof(idsl.FileName), NULL, NULL); 00583 idsl.Reparse = idslW->Reparse; 00584 data = &idsl; 00585 break; 00586 case CBA_DUPLICATE_SYMBOL: 00587 case CBA_EVENT: 00588 case CBA_READ_MEMORY: 00589 default: 00590 FIXME("No mapping for action %u\n", action); 00591 return FALSE; 00592 } 00593 } 00594 return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user); 00595 } 00596 00597 /****************************************************************** 00598 * sym_register_cb 00599 * 00600 * Helper for registering a callback. 00601 */ 00602 static BOOL sym_register_cb(HANDLE hProcess, 00603 PSYMBOL_REGISTERED_CALLBACK64 cb, 00604 PSYMBOL_REGISTERED_CALLBACK cb32, 00605 DWORD64 user, BOOL unicode) 00606 { 00607 struct process* pcs = process_find_by_handle(hProcess); 00608 00609 if (!pcs) return FALSE; 00610 pcs->reg_cb = cb; 00611 pcs->reg_cb32 = cb32; 00612 pcs->reg_is_unicode = unicode; 00613 pcs->reg_user = user; 00614 00615 return TRUE; 00616 } 00617 00618 /*********************************************************************** 00619 * SymRegisterCallback (DBGHELP.@) 00620 */ 00621 BOOL WINAPI SymRegisterCallback(HANDLE hProcess, 00622 PSYMBOL_REGISTERED_CALLBACK CallbackFunction, 00623 PVOID UserContext) 00624 { 00625 TRACE("(%p, %p, %p)\n", 00626 hProcess, CallbackFunction, UserContext); 00627 return sym_register_cb(hProcess, reg_cb64to32, CallbackFunction, (DWORD_PTR)UserContext, FALSE); 00628 } 00629 00630 /*********************************************************************** 00631 * SymRegisterCallback64 (DBGHELP.@) 00632 */ 00633 BOOL WINAPI SymRegisterCallback64(HANDLE hProcess, 00634 PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, 00635 ULONG64 UserContext) 00636 { 00637 TRACE("(%p, %p, %s)\n", 00638 hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext)); 00639 return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, FALSE); 00640 } 00641 00642 /*********************************************************************** 00643 * SymRegisterCallbackW64 (DBGHELP.@) 00644 */ 00645 BOOL WINAPI SymRegisterCallbackW64(HANDLE hProcess, 00646 PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, 00647 ULONG64 UserContext) 00648 { 00649 TRACE("(%p, %p, %s)\n", 00650 hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext)); 00651 return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, TRUE); 00652 } 00653 00654 /* This is imagehlp version not dbghelp !! */ 00655 static API_VERSION api_version = { 4, 0, 2, 0 }; 00656 00657 /*********************************************************************** 00658 * ImagehlpApiVersion (DBGHELP.@) 00659 */ 00660 LPAPI_VERSION WINAPI ImagehlpApiVersion(VOID) 00661 { 00662 return &api_version; 00663 } 00664 00665 /*********************************************************************** 00666 * ImagehlpApiVersionEx (DBGHELP.@) 00667 */ 00668 LPAPI_VERSION WINAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion) 00669 { 00670 if (!AppVersion) return NULL; 00671 00672 AppVersion->MajorVersion = api_version.MajorVersion; 00673 AppVersion->MinorVersion = api_version.MinorVersion; 00674 AppVersion->Revision = api_version.Revision; 00675 AppVersion->Reserved = api_version.Reserved; 00676 00677 return AppVersion; 00678 } 00679 00680 /****************************************************************** 00681 * ExtensionApiVersion (DBGHELP.@) 00682 */ 00683 LPEXT_API_VERSION WINAPI ExtensionApiVersion(void) 00684 { 00685 static EXT_API_VERSION eav = {5, 5, 5, 0}; 00686 return &eav; 00687 } 00688 00689 /****************************************************************** 00690 * WinDbgExtensionDllInit (DBGHELP.@) 00691 */ 00692 void WINAPI WinDbgExtensionDllInit(PWINDBG_EXTENSION_APIS lpExtensionApis, 00693 unsigned short major, unsigned short minor) 00694 { 00695 } Generated on Sun May 27 2012 04:23:20 for ReactOS by
1.7.6.1
|