Bug 458256. Use LoadLibraryW instead of LoadLibrary (patch by DougT). r+sr=vlad
[wine-gecko.git] / tools / trace-malloc / lib / nsDebugHelpWin32.h
blobd8dc2989614394004287154baa5456f6b606d896
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * John Bandhauer <jband@netscape.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 /* Win32 x86 code for stack walking, symbol resolution, and function hooking */
41 #ifndef __nsDebugHelpWin32_h__
42 #define __nsDebugHelpWin32_h__
44 #if defined(_WIN32) && defined(_M_IX86)
45 #ifndef WIN32_LEAN_AND_MEAN
46 #define WIN32_LEAN_AND_MEAN
47 #endif
48 #include <windows.h>
49 #include <imagehlp.h>
50 #include <crtdbg.h>
51 #else
52 #error "nsDebugHelpWin32.h should only be included in Win32 x86 builds"
53 #endif
55 // XXX temporary hack...
56 //#include "hacky_defines.h"
59 /***************************************************************************/
60 // useful macros...
62 #define DHW_DECLARE_FUN_TYPE(retval_, conv_, typename_, args_) \
63 typedef retval_ ( conv_ * typename_ ) args_ ;
65 #ifdef DHW_IMPLEMENT_GLOBALS
66 #define DHW_DECLARE_FUN_GLOBAL(typename_, name_) typename_ dhw##name_
67 #else
68 #define DHW_DECLARE_FUN_GLOBAL(typename_, name_) extern typename_ dhw##name_
69 #endif
71 #define DHW_DECLARE_FUN_PROTO(retval_, conv_, name_, args_) \
72 retval_ conv_ name_ args_
74 #define DHW_DECLARE_FUN_STATIC_PROTO(retval_, name_, args_) \
75 static retval_ conv_ name_ args_
77 #define DHW_DECLARE_FUN_TYPE_AND_PROTO(name_, retval_, conv_, typename_, args_) \
78 DHW_DECLARE_FUN_TYPE(retval_, conv_, typename_, args_); \
79 DHW_DECLARE_FUN_PROTO(retval_, conv_, name_, args_)
81 #define DHW_DECLARE_FUN_TYPE_AND_STATIC_PROTO(name_, retval_, conv_, typename_, args_) \
82 DHW_DECLARE_FUN_TYPE(retval_, conv_, typename_, args_); \
83 DHW_DECLARE_FUN_STATIC_PROTO(retval_, conv_, name_, args_)
85 #define DHW_DECLARE_FUN_TYPE_AND_GLOBAL(typename_, name_, retval_, conv_, args_) \
86 DHW_DECLARE_FUN_TYPE(retval_, conv_, typename_, args_); \
87 DHW_DECLARE_FUN_GLOBAL(typename_, name_)
90 /**********************************************************/
91 // These are used to get 'original' function addresses from DHWImportHooker.
93 #define DHW_DECLARE_ORIGINAL(type_, name_, hooker_) \
94 type_ name_ = (type_) hooker_ . GetOriginalFunction()
96 #define DHW_DECLARE_ORIGINAL_PTR(type_, name_, hooker_) \
97 type_ name_ = (type_) hooker_ -> GetOriginalFunction()
99 #define DHW_ORIGINAL(type_, hooker_) \
100 ((type_) hooker_ . GetOriginalFunction())
102 #define DHW_ORIGINAL_PTR(type_, hooker_) \
103 ((type_) hooker_ -> GetOriginalFunction())
105 /***************************************************************************/
106 // Global declarations of entry points into ImgHelp functions
107 #if 0
108 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMINITIALIZEPROC, SymInitialize, \
109 BOOL, __stdcall, (HANDLE, LPSTR, BOOL));
111 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMSETOPTIONS, SymSetOptions, \
112 DWORD, __stdcall, (DWORD));
114 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMGETOPTIONS, SymGetOptions, \
115 DWORD, __stdcall, ());
117 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMGETMODULEINFO, SymGetModuleInfo, \
118 BOOL, __stdcall, (HANDLE, DWORD, PIMAGEHLP_MODULE));
120 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMGETSYMFROMADDRPROC, SymGetSymFromAddr, \
121 BOOL, __stdcall, (HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL));
123 #endif
125 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(ENUMERATELOADEDMODULES, EnumerateLoadedModules, \
126 BOOL, __stdcall, (HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID));
128 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(IMAGEDIRECTORYENTRYTODATA, ImageDirectoryEntryToData, \
129 PVOID, __stdcall, (PVOID, BOOL, USHORT, PULONG));
131 // We aren't using any of the below yet...
134 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMCLEANUPPROC, SymCleanup, \
135 BOOL, __stdcall, (HANDLE));
137 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(STACKWALKPROC, StackWalk, \
138 BOOL,
139 __stdcall,
140 (DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, \
141 PREAD_PROCESS_MEMORY_ROUTINE, \
142 PFUNCTION_TABLE_ACCESS_ROUTINE, \
143 PGET_MODULE_BASE_ROUTINE, \
144 PTRANSLATE_ADDRESS_ROUTINE));
146 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMFUNCTIONTABLEACCESSPROC, SymFunctionTableAccess, \
147 LPVOID, __stdcall, (HANDLE, DWORD));
149 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMGETMODULEBASEPROC, SymGetModuleBase, \
150 DWORD, __stdcall, (HANDLE, DWORD));
152 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMLOADMODULE, SymLoadModule, \
153 DWORD, __stdcall, (HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD));
155 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(UNDECORATESYMBOLNAME, _UnDecorateSymbolName, \
156 DWORD, __stdcall, (LPCSTR, LPSTR, DWORD, DWORD));
158 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMUNDNAME, SymUnDName, \
159 BOOL, __stdcall, (PIMAGEHLP_SYMBOL, LPSTR, DWORD));
161 DHW_DECLARE_FUN_TYPE_AND_GLOBAL(SYMGETLINEFROMADDR, SymGetLineFromAddr, \
162 BOOL, __stdcall, (HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE));
166 /***************************************************************************/
168 extern PRBool
169 dhwEnsureImageHlpInitialized();
171 /***************************************************************************/
173 DHW_DECLARE_FUN_TYPE(FARPROC, __stdcall, GETPROCADDRESS, (HMODULE, PCSTR));
175 class DHWImportHooker
177 public:
179 DHWImportHooker(const char* aModuleName,
180 const char* aFunctionName,
181 PROC aHook,
182 PRBool aExcludeOurModule = PR_FALSE);
184 ~DHWImportHooker();
186 PROC GetOriginalFunction() {return mOriginal;}
188 PRBool PatchAllModules();
189 PRBool PatchOneModule(HMODULE aModule, const char* name);
190 static PRBool ModuleLoaded(HMODULE aModule, DWORD flags);
193 // I think that these should be made not static members, but allocated
194 // things created in an explicit static 'init' method and cleaned up in
195 // an explicit static 'finish' method. This would allow the application
196 // to have proper lifetime control over all the hooks.
198 static DHWImportHooker &getLoadLibraryWHooker();
199 static DHWImportHooker &getLoadLibraryExWHooker();
200 static DHWImportHooker &getLoadLibraryAHooker();
201 static DHWImportHooker &getLoadLibraryExAHooker();
202 static DHWImportHooker &getGetProcAddressHooker();
204 static HMODULE WINAPI LoadLibraryA(PCSTR path);
206 private:
207 DHWImportHooker* mNext;
208 const char* mModuleName;
209 const char* mFunctionName;
210 PROC mOriginal;
211 PROC mHook;
212 HMODULE mIgnoreModule;
213 PRBool mHooking;
215 private:
216 static PRLock* gLock;
217 static DHWImportHooker* gHooks;
218 static GETPROCADDRESS gRealGetProcAddress;
220 static HMODULE WINAPI LoadLibraryW(PCWSTR path);
221 static HMODULE WINAPI LoadLibraryExW(PCWSTR path, HANDLE file, DWORD flags);
222 static HMODULE WINAPI LoadLibraryExA(PCSTR path, HANDLE file, DWORD flags);
224 static FARPROC WINAPI GetProcAddress(HMODULE aModule, PCSTR aFunctionName);
227 /***************************************************************************/
228 // This supports the _CrtSetAllocHook based hooking.
229 // This system sucks because you don't get to see the allocated pointer. I
230 // don't think it appropriate for nsTraceMalloc, but is useful as a means to make
231 // malloc fail for testing purposes.
232 #if 0 //comment out this stuff. not necessary
234 class DHWAllocationSizeDebugHook
236 public:
237 virtual PRBool AllocHook(size_t size) = 0;
238 virtual PRBool ReallocHook(size_t size, size_t sizeOld) = 0;
239 virtual PRBool FreeHook(size_t size) = 0;
242 extern PRBool dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook);
243 extern PRBool dhwClearAllocationSizeDebugHook();
245 /***************************************************************************/
246 #endif //0
248 #endif /* __nsDebugHelpWin32_h__ */