windows-nt/Source/XPSP1/NT/shell/inc/dbgmem.cpp
2020-09-26 16:20:57 +08:00

112 lines
4.8 KiB
C++

#ifdef DEBUG
#include <dbgmem.h>
//EXTERN_C BOOL g_bUseNewLeakDetection;
BOOL g_bRegistered = FALSE;
HINSTANCE g_hinstDBG;
#define SHELLDBG "ShellDBG.DLL"
STDAPI_(void) _GetProcFromDLL(HMODULE* phmod, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc);
// the following are in olestuff.cpp
STDAPI_(void) _DebugMemLeak(UINT flag, LPCTSTR pszFile, UINT iLine);
STDAPI_(void) _add_to_memlist(HMODULE hmod, void *pv, UINT nSize, UINT nType, LPCSTR pszFile, const INT_PTR iLine);
STDAPI_(void) _remove_from_memlist(void *pv);
STDAPI_(void) _remove_from_thread_memlist(DWORD dwThreadId, LPVOID pv);
STDAPI_(void) _transfer_to_thread_memlist(DWORD dwThread, LPVOID pv);
STDAPI_(UINT) _mem_thread_message(void);
STDAPI_(void) _received_for_thread_memlist(DWORD dwFlags, void * pData);
STDAPI_(void) _register_intelli_dump(HMODULE hmod, const INTELLILEAKDUMPCBFUNCTIONS *pfns);
STDAPI_(void) MemLeakInit(UINT wFlags, LPCTSTR pszFile, UINT iLine);
STDAPI_(void) MemLeakTerminate(DWORD dwFlags);
// should be in olestuff.cpp of each dll
STDAPI_(void) DumpLeakedMemory(PLEAKMEMINFO pmeminfo);
STDAPI_(LPWSTR) GetLeakSymbolicName(PLEAKMEMINFO pmeminfo, LPWSTR pwszBuf, int cchBuf);
static const INTELLILEAKDUMPCBFUNCTIONS c_ildcbf = {
DumpLeakedMemory,
GetLeakSymbolicName
};
#define DELAY_LOAD_LEAK_VOID(_fn, _ord, _args, _nargs) \
void __stdcall _fn _args \
{ \
static void (__stdcall *_pfn##_fn) _args = NULL; \
if (g_bUseNewLeakDetection) \
{ \
if (!g_bRegistered) \
{ \
register_intelli_dump(HINST_THISDLL, &c_ildcbf); \
g_bRegistered = TRUE; \
} \
_GetProcFromDLL(&g_hinstDBG, SHELLDBG, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
} \
else \
_pfn##_fn = _##_fn; \
if (_pfn##_fn) \
_pfn##_fn _nargs; \
return; \
}
#define DELAY_LOAD_LEAK_FN(_ret, _fn, _ord, _args, _nargs, _err) \
_ret __stdcall _fn _args \
{ \
static _ret (__stdcall *_pfn##_fn) _args = NULL; \
if (g_bUseNewLeakDetection) \
{ \
if (!g_bRegistered) \
{ \
register_intelli_dump(HINST_THISDLL, &c_ildcbf); \
g_bRegistered = TRUE; \
} \
_GetProcFromDLL(&g_hinstDBG, SHELLDBG, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); \
} \
else \
_pfn##_fn = _##_fn; \
if (_pfn##_fn) \
return _pfn##_fn _nargs; \
return (_ret)_err; \
}
#define _MemLeakInit _DebugMemLeak // for delay load macro to work
DELAY_LOAD_LEAK_VOID(MemLeakInit, 2,
(UINT wFlags, LPCTSTR pszFile, UINT iLine),
(wFlags, pszFile, iLine))
// does nothing for now because MemLeakInit is called to terminate leak detection as well
STDAPI_(void) MemLeakTerminate(DWORD dwFlags)
{
}
DELAY_LOAD_LEAK_VOID(add_to_memlist, 3,
(HMODULE hmod, void *pv, UINT nSize, UINT nType, LPCSTR pszFile, const INT_PTR iLine),
(hmod, pv, nSize, nType, pszFile, iLine))
DELAY_LOAD_LEAK_FN(UINT, mem_thread_message, 4, (void), (), 0)
DELAY_LOAD_LEAK_VOID(received_for_thread_memlist, 5, (DWORD dwFlags, void *pData), (dwFlags, pData))
DELAY_LOAD_LEAK_VOID(remove_from_memlist, 6, (void *pv), (pv))
DELAY_LOAD_LEAK_VOID(remove_from_thread_memlist, 7, (DWORD dwThreadId, LPVOID pv), (dwThreadId, pv))
DELAY_LOAD_LEAK_VOID(transfer_to_thread_memlist, 8, (DWORD dwThreadId, LPVOID pv), (dwThreadId, pv))
//DELAY_LOAD_LEAK_VOID(register_intelli_dump, 9, (HMODULE hmod, const INTELLILEAKDUMPCBFUNCTIONS *pfns), (hmod, pfns))
void register_intelli_dump(HMODULE hmod, const INTELLILEAKDUMPCBFUNCTIONS *pfns)
{
static void (__stdcall *pfnregister_intelli_dump)(HMODULE hmod, const INTELLILEAKDUMPCBFUNCTIONS *pfns) = NULL;
if (!pfnregister_intelli_dump)
{
if (g_bUseNewLeakDetection)
_GetProcFromDLL(&g_hinstDBG, SHELLDBG, (FARPROC*)&pfnregister_intelli_dump, (LPCSTR)9);
else
pfnregister_intelli_dump = _register_intelli_dump;
}
if (pfnregister_intelli_dump)
pfnregister_intelli_dump(hmod, pfns);
}
#endif //DEBUG