ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dbghelp.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.