|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: alloc.cpp
//
// Contents: Cert Server debug implementation
//
//---------------------------------------------------------------------------
#include "pch.cpp"
#pragma hdrstop
#include <assert.h>
#define __dwFILE__ __dwFILE_CERTCLIB_ALLOC_CPP__
#if DBG_CERTSRV
#undef FormatMessageW
#undef LocalAlloc
#undef LocalReAlloc
#undef LocalFree
#undef CoTaskMemAlloc
#undef CoTaskMemRealloc
#undef CoTaskMemFree
#undef StringFromCLSID
#undef StringFromIID
#undef SysAllocString
#undef SysReAllocString
#undef SysAllocStringLen
#undef SysReAllocStringLen
#undef SysFreeString
#undef SysAllocStringByteLen
#undef PropVariantClear
#undef VariantClear
#undef VariantChangeType
#undef VariantChangeTypeEx
DWORD g_MemTrack = 0;
#define MTF_UNREGISTERED 0x00000002
#define MTF_ALLOCTRACE 0x00000004
#define MTF_FREETRACE 0x00000008
#define MTF_STACKTRACE 0x00000010
typedef struct _RMALLOC { LONG cAlloc; LONG cAllocTotal; } RMALLOC;
RMALLOC g_armAlloc[CSM_MAX];
#define C_BP_FRAME 16
#define C_BACK_TRACE_CHUNK 100
#define C_MEM_HEADER_CHUNK 100
typedef struct _BACKTRACE { LONG cAlloc; // count of outstanding allocations
LONG cAllocTotal; // count of total allocations
LONG cbAlloc; // size of outstanding allocations
LONG cbAllocTotal; // size of total allocations
ULONG apCaller[C_BP_FRAME]; // stack trace
} BACKTRACE;
typedef struct _MEMHEADER { DWORD iBackTrace; // backtrace index
VOID const *pvMemory; // Pointer to memory block allocated
LONG cbMemory; // Size of memory block allocated
DWORD Flags; // Allocator flags
} MEMHEADER;
// critical section around myRegister APIs since they
// operate on global data structures
CRITICAL_SECTION g_critsecRegisterMemory; BOOL g_fRegisterMemoryCritSecInit = FALSE;
VOID RegisterMemoryEnterCriticalSection(VOID) { HRESULT hr; __try { if (!g_fRegisterMemoryCritSecInit) { InitializeCriticalSection(&g_critsecRegisterMemory); g_fRegisterMemoryCritSecInit = TRUE; } EnterCriticalSection(&g_critsecRegisterMemory); } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } }
VOID RegisterMemoryLeaveCriticalSection(VOID) { if (g_fRegisterMemoryCritSecInit) { LeaveCriticalSection(&g_critsecRegisterMemory); } }
BACKTRACE *g_rgbt = NULL; DWORD g_cbtMax = 0; DWORD g_cbt = 0;
MEMHEADER *g_rgmh = NULL; DWORD g_cmhMax = 0; DWORD g_cmh = 0;
MEMHEADER * AllocMemHeader() { if (g_cmh >= g_cmhMax) { DWORD cb = (C_MEM_HEADER_CHUNK + g_cmhMax) * sizeof(g_rgmh[0]); MEMHEADER *rgmhT;
if (NULL == g_rgmh) { rgmhT = (MEMHEADER *) LocalAlloc(LMEM_FIXED, cb); } else { rgmhT = (MEMHEADER *) LocalReAlloc(g_rgmh, cb, LMEM_MOVEABLE); } if (NULL == rgmhT) { DBGPRINT(( DBG_SS_CERTLIB, "Error allocating memtrack header\n")); return(NULL); } g_rgmh = rgmhT; g_cmhMax += C_MEM_HEADER_CHUNK; } return(&g_rgmh[g_cmh++]); }
MEMHEADER * LookupMemHeader( IN VOID const *pv) { MEMHEADER *pmh; MEMHEADER *pmhEnd;
pmh = g_rgmh; pmhEnd = &g_rgmh[g_cmh];
while (pmh < pmhEnd) { if (pv == pmh->pvMemory) { return(pmh); } pmh++; } return(NULL); }
VOID FreeMemHeader( IN MEMHEADER *pmh) { MEMHEADER *pmhLast;
assert(1 <= g_cmh); pmhLast = &g_rgmh[g_cmh - 1];
*pmh = *pmhLast; g_cmh--; }
BACKTRACE * AllocBackTrace( OUT DWORD *pibt) { if (g_cbt >= g_cbtMax) { DWORD cb = (C_BACK_TRACE_CHUNK + g_cbtMax) * sizeof(g_rgbt[0]); BACKTRACE *rgbtT;
if (NULL == g_rgbt) { rgbtT = (BACKTRACE *) LocalAlloc(LMEM_FIXED, cb); } else { rgbtT = (BACKTRACE *) LocalReAlloc(g_rgbt, cb, LMEM_MOVEABLE); DBGPRINT(( DBG_SS_CERTLIB, "Realloc'd memtrack backtrace from %x to %x\n", g_rgbt, rgbtT)); } if (NULL == rgbtT) { DBGPRINT(( DBG_SS_CERTLIB, "Error allocating memtrack backtrace\n")); return(NULL); } g_rgbt = rgbtT; g_cbtMax += C_BACK_TRACE_CHUNK; } *pibt = g_cbt + 1; return(&g_rgbt[g_cbt++]); }
BACKTRACE * LookupBackTrace( IN BACKTRACE *pbtIn, OUT DWORD *pibt) { BACKTRACE *pbt; BACKTRACE *pbtEnd;
pbt = g_rgbt; pbtEnd = &g_rgbt[g_cbt];
while (pbt < pbtEnd) { if (0 == memcmp(pbt->apCaller, pbtIn->apCaller, sizeof(pbt->apCaller))) { *pibt = SAFE_SUBTRACT_POINTERS(pbt, g_rgbt) + 1; return(pbt); } pbt++; } return(NULL); }
BACKTRACE * BackTraceFromIndex( IN DWORD ibt) { BACKTRACE *pbt = NULL;
if (0 == ibt) { DBGPRINT((DBG_SS_CERTLIB, "BackTraceFromIndex(0)\n")); } else if (g_cbt < ibt) { DBGPRINT(( DBG_SS_CERTLIB, "BackTraceFromIndex(%u) -- out of range\n", ibt)); } else { pbt = &g_rgbt[ibt - 1]; } return(pbt); }
VOID ReadEnvironmentFlags(VOID) { HRESULT hr; DWORD MemTrack; DWORD cb; DWORD dwDisposition; DWORD dwType; HKEY hkey = NULL; char *pszEnvVar;
pszEnvVar = getenv(szCERTSRV_MEMTRACK); if (NULL != pszEnvVar) { g_MemTrack = (DWORD) strtol(pszEnvVar, NULL, 16); } else { hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, wszREGKEYCONFIGPATH, 0, KEY_READ, &hkey); if (S_OK == hr) { cb = sizeof(MemTrack); hr = RegQueryValueEx( hkey, wszREGCERTSRVMEMTRACK, 0, &dwType, (BYTE *) &MemTrack, &cb); if (S_OK == hr && REG_DWORD == dwType && sizeof(MemTrack) == cb) { g_MemTrack = MemTrack; } } }
//error:
if (NULL != hkey) { RegCloseKey(hkey); } }
VOID CaptureStackBackTrace( EXCEPTION_POINTERS *pep, ULONG cSkip, ULONG cFrames, ULONG *aeip) { ZeroMemory(aeip, cFrames * sizeof(aeip[0]));
#if i386 == 1
ULONG ieip, *pebp; ULONG *pebpMax = (ULONG *) MAXLONG; // 2 * 1024 * 1024 * 1024; // 2 gig - 1
ULONG *pebpMin = (ULONG *) (64 * 1024); // 64k
if (pep == NULL) { ieip = 0; cSkip++; // always skip current frame
pebp = ((ULONG *) &pep) - 2; } else { ieip = 1; assert(cSkip == 0); aeip[0] = pep->ContextRecord->Eip; pebp = (ULONG *) pep->ContextRecord->Ebp; } if (pebp >= pebpMin && pebp < pebpMax) { __try { for ( ; ieip < cSkip + cFrames; ieip++) { if (ieip >= cSkip) { aeip[ieip - cSkip] = *(pebp + 1); // save an eip
}
ULONG *pebpNext = (ULONG *) *pebp; if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1 || pebpNext >= pebp + (256 * 1024) / sizeof(pebp[0])) { break; } pebp = pebpNext; } } __except(EXCEPTION_EXECUTE_HANDLER) { ; } } #endif // i386 == 1
}
WCHAR const * wszAllocator( IN DWORD Flags) { WCHAR const *pwsz;
switch (Flags) { case CSM_LOCALALLOC: pwsz = L"LocalAlloc"; break; case CSM_COTASKALLOC: pwsz = L"CoTaskMemAlloc"; break; case CSM_SYSALLOC: pwsz = L"SysAllocString"; break; case CSM_MALLOC: pwsz = L"malloc"; break; case CSM_NEW: pwsz = L"new"; break; case CSM_NEW | CSM_GLOBALDESTRUCTOR: pwsz = L"new-global"; break; default: pwsz = L"???"; break; } return(pwsz); }
WCHAR const * wszFreeer( IN DWORD Flags) { WCHAR const *pwsz;
switch (Flags) { case CSM_LOCALALLOC: pwsz = L"LocalFree"; break; case CSM_COTASKALLOC: pwsz = L"CoTaskMemFree"; break; case CSM_SYSALLOC: pwsz = L"SysFreeString"; break; case CSM_MALLOC: pwsz = L"free"; break; case CSM_NEW: pwsz = L"delete"; break; case CSM_NEW | CSM_GLOBALDESTRUCTOR: pwsz = L"delete-global"; break; default: pwsz = L"???"; break; } return(pwsz); }
VOID DumpMemBlock( IN WCHAR const *pwsz, IN VOID const *pvMemory, IN DWORD cbMemory, IN DWORD Flags, IN DWORD ibt, OPTIONAL IN BACKTRACE const *pbt) { DBGPRINT(( DBG_SS_CERTLIB, "%ws%wspv=%-6x cb=%-4x f=%x(%ws) pbt[%d]=%x:\n", pwsz, L'\0' != *pwsz? L": " : L"", pvMemory, cbMemory, Flags, wszAllocator(Flags), ibt, pbt));
if (NULL != pbt && DbgIsSSActive(DBG_SS_CERTLIB)) { DBGPRINT((MAXDWORD, "%d: ", ibt));
for (int i = 0; i < ARRAYSIZE(pbt->apCaller); i++) { if (NULL == pbt->apCaller[i]) { break; } DBGPRINT((MAXDWORD, "ln %x;", pbt->apCaller[i])); } DBGPRINT((MAXDWORD, "\n")); } }
VOID myRegisterMemDump() { MEMHEADER *pmh; MEMHEADER *pmhEnd; LONG cTotal; LONG cbTotal;
cTotal = 0; cbTotal = 0;
RegisterMemoryEnterCriticalSection();
__try { pmh = g_rgmh; pmhEnd = &g_rgmh[g_cmh];
while (pmh < pmhEnd) { if (0 == (CSM_GLOBALDESTRUCTOR & pmh->Flags) || (MTF_ALLOCTRACE & g_MemTrack)) { if (0 == cTotal) { if (DbgIsSSActive(DBG_SS_CERTLIB)) { DBGPRINT((MAXDWORD, "\n")); } DBGPRINT((DBG_SS_CERTLIB, "Allocated Memory Blocks:\n")); } cTotal++; cbTotal += pmh->cbMemory;
DumpMemBlock( L"", pmh->pvMemory, pmh->cbMemory, pmh->Flags, pmh->iBackTrace, BackTraceFromIndex(pmh->iBackTrace)); } pmh++; } if (0 != cTotal) { DBGPRINT((DBG_SS_CERTLIB, "Total: c=%x cb=%x\n\n", cTotal, cbTotal)); } } __except(EXCEPTION_EXECUTE_HANDLER) { }
RegisterMemoryLeaveCriticalSection(); }
VOID * _VariantMemory( IN PROPVARIANT const *pvar, OUT DWORD *pFlags, OPTIONAL OUT DWORD *pcb) { VOID *pv = NULL; DWORD cb = 0; BOOL fString = FALSE;
*pFlags = CSM_COTASKALLOC; if (NULL != pcb) { *pcb = 0; } switch (pvar->vt) { case VT_BSTR: pv = pvar->bstrVal; fString = TRUE; *pFlags = CSM_SYSALLOC; break;
case VT_BYREF | VT_BSTR: pv = *pvar->pbstrVal; fString = TRUE; *pFlags = CSM_SYSALLOC; break;
case VT_LPWSTR: pv = pvar->pwszVal; fString = TRUE; break;
case VT_BLOB: pv = pvar->blob.pBlobData; cb = pvar->blob.cbSize; break; } if (NULL != pcb) { if (fString) { cb = (wcslen((WCHAR const *) pv) + 1) * sizeof(WCHAR); } *pcb = cb; } return(pv); }
VOID myRegisterMemAlloc( IN VOID const *pv, IN LONG cb, IN DWORD Flags) { BACKTRACE bt; MEMHEADER *pmh; BACKTRACE *pbt;
if (CSM_VARIANT == Flags) { pv = _VariantMemory((PROPVARIANT const *) pv, &Flags, (DWORD *) &cb); if (NULL == pv) { return; // nothing to register
} } RegisterMemoryEnterCriticalSection();
__try { static BOOL s_fFirst = TRUE;
if (s_fFirst) { ReadEnvironmentFlags(); s_fFirst = FALSE; } if (0 != g_MemTrack) { // Do not register NULL as an allocation
CSASSERT(NULL != pv);
// see if we already have a reference to this memory
pmh = LookupMemHeader(pv); if (NULL != pmh) { DBGPRINT(( DBG_SS_CERTLIB, "Memory Leak: Tracked memory address reused. Previously allocated:\n")); DumpMemBlock( L"Memory leak", pv, pmh->cbMemory, pmh->Flags, pmh->iBackTrace, BackTraceFromIndex(pmh->iBackTrace));
CSASSERT(!"Tracked memory address reused"); FreeMemHeader(pmh); }
pmh = AllocMemHeader(); if (NULL != pmh) { DWORD ibt;
CaptureStackBackTrace(NULL, 0, C_BP_FRAME, bt.apCaller);
pbt = LookupBackTrace(&bt, &ibt); if (NULL != pbt) { pbt->cAlloc++; pbt->cAllocTotal++; pbt->cbAlloc += cb; pbt->cbAllocTotal += cb; } else { pbt = AllocBackTrace(&ibt); if (NULL != pbt) { pbt->cAlloc = 1; pbt->cAllocTotal = 1; pbt->cbAlloc = cb; pbt->cbAllocTotal = cb; CopyMemory(pbt->apCaller, bt.apCaller, sizeof(pbt->apCaller)); } } if (NULL != pbt) { pmh->iBackTrace = ibt; pmh->pvMemory = pv; pmh->cbMemory = cb; pmh->Flags = Flags;
CSASSERT(ARRAYSIZE(g_armAlloc) > Flags); g_armAlloc[Flags].cAlloc++; g_armAlloc[Flags].cAllocTotal++; if (MTF_ALLOCTRACE & g_MemTrack) { DBGPRINT(( DBG_SS_CERTLIB, "Alloc: pmh=%x: pv=%x cb=%x f=%x(%ws) -- pbt[%d]=%x: c=%x, cb=%x\n", pmh, pmh->pvMemory, pmh->cbMemory, pmh->Flags, wszAllocator(pmh->Flags), SAFE_SUBTRACT_POINTERS(pbt, g_rgbt), pbt, pbt->cAlloc, pbt->cbAlloc)); if (MTF_STACKTRACE & g_MemTrack) { DumpMemBlock( L"Alloc Trace memory block", pv, pmh->cbMemory, // cbMemory
pmh->Flags, // Flags
pmh->iBackTrace, // ibt
pbt); } } } else { FreeMemHeader(pmh); } } // if no problem allocating pmh
} // if g_MemTrack
} __except(EXCEPTION_EXECUTE_HANDLER) { }
RegisterMemoryLeaveCriticalSection(); }
VOID myRegisterMemFree( IN VOID const *pv, IN DWORD Flags) { MEMHEADER *pmh;
if (CSM_VARIANT == Flags) { pv = _VariantMemory((PROPVARIANT const *) pv, &Flags, NULL); if (NULL == pv) { return; // nothing to register
} } RegisterMemoryEnterCriticalSection(); CSASSERT(CSM_MAX > (~CSM_GLOBALDESTRUCTOR & Flags));
__try { pmh = LookupMemHeader(pv); if (NULL != pmh) { BACKTRACE *pbt = BackTraceFromIndex(pmh->iBackTrace);
if (CSM_GLOBALDESTRUCTOR & Flags) { if ((CSM_GLOBALDESTRUCTOR | pmh->Flags) != Flags) { BACKTRACE bt;
CaptureStackBackTrace(NULL, 0, C_BP_FRAME, bt.apCaller); DumpMemBlock( L"Wrong memory allocator for global destructor", pv, MAXDWORD, // cbMemory
MAXDWORD, // Flags
MAXDWORD, // ibt
&bt); CSASSERT(!"Wrong memory allocator for global destructor"); } else { pmh->Flags |= CSM_GLOBALDESTRUCTOR; } } else { g_armAlloc[Flags].cAlloc--;
pbt->cAlloc--; pbt->cbAlloc -= pmh->cbMemory;
if (CSM_GLOBALDESTRUCTOR & pmh->Flags) { Flags |= CSM_GLOBALDESTRUCTOR; } if (pmh->Flags != Flags) { DBGPRINT(( DBG_SS_CERTLIB, "Wrong memory allocator: Freed with %ws, Allocated by %ws\n", wszFreeer(Flags), wszAllocator(pmh->Flags))); DumpMemBlock( L"Wrong memory allocator", pv, pmh->cbMemory, pmh->Flags, pmh->iBackTrace, BackTraceFromIndex(pmh->iBackTrace)); CSASSERT(pmh->Flags == Flags); } else if (MTF_FREETRACE & g_MemTrack) { DBGPRINT(( DBG_SS_CERTLIB, "Free: pmh=%x: pv=%x cb=%x f=%x(%ws) -- pbt[%d]=%x: c=%x, cb=%x\n", pmh, pv, pmh->cbMemory, pmh->Flags, wszAllocator(pmh->Flags), pmh->iBackTrace, pbt, pbt->cAlloc, pbt->cbAlloc)); if (MTF_STACKTRACE & g_MemTrack) { BACKTRACE bt;
CaptureStackBackTrace(NULL, 0, C_BP_FRAME, bt.apCaller); DumpMemBlock( L"Free Trace memory block(alloc)", pv, pmh->cbMemory, // cbMemory
pmh->Flags, // Flags
pmh->iBackTrace, // ibt
pbt); DumpMemBlock( L"Free Trace memory block(free)", pv, pmh->cbMemory, // cbMemory
pmh->Flags, // Flags
MAXDWORD, // ibt
&bt); } } FreeMemHeader(pmh); } } else if (MTF_UNREGISTERED & g_MemTrack) { BACKTRACE bt;
CaptureStackBackTrace(NULL, 0, C_BP_FRAME, bt.apCaller); DumpMemBlock( L"Unregistered memory block", pv, MAXDWORD, // cbMemory
MAXDWORD, // Flags
MAXDWORD, // ibt
&bt); CSASSERT(!"Unregistered memory block"); } } __except(EXCEPTION_EXECUTE_HANDLER) { }
RegisterMemoryLeaveCriticalSection(); }
DWORD myFormatMessageW( IN DWORD dwFlags, IN LPCVOID lpSource, IN DWORD dwMessageId, IN DWORD dwLanguageId, OUT LPWSTR lpBuffer, IN DWORD nSize, IN va_list *Arguments) { DWORD cwc;
cwc = FormatMessage( dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments); if (cwc != 0 && (FORMAT_MESSAGE_ALLOCATE_BUFFER & dwFlags)) { myRegisterMemAlloc( *(WCHAR **) lpBuffer, (cwc + 1) * sizeof(WCHAR), CSM_LOCALALLOC); } return(cwc); }
HLOCAL myLocalAlloc( IN UINT uFlags, IN UINT uBytes) { HLOCAL hMem;
// one of these should always be specified (see LocalAlloc specification)
assert((LMEM_FIXED == (uFlags & LMEM_FIXED)) || (LMEM_MOVEABLE == (uFlags & LMEM_MOVEABLE)) );
hMem = LocalAlloc(uFlags, uBytes); if (NULL != hMem) { myRegisterMemAlloc(hMem, uBytes, CSM_LOCALALLOC); } return(hMem); }
HLOCAL myLocalReAlloc( IN HLOCAL hMem, IN UINT uBytes, IN UINT uFlags) { HLOCAL hMemNew;
// if realloc called without MOVEABLE flag, realloc can't relocate allocation
assert(LMEM_MOVEABLE == (uFlags & LMEM_MOVEABLE));
hMemNew = LocalReAlloc(hMem, uBytes, uFlags); if (NULL != hMemNew) { myRegisterMemFree(hMem, CSM_LOCALALLOC); myRegisterMemAlloc(hMemNew, uBytes, CSM_LOCALALLOC); }
return(hMemNew); }
HLOCAL myLocalFree( IN HLOCAL hMem) { myRegisterMemFree(hMem, CSM_LOCALALLOC); return(LocalFree(hMem)); }
VOID * myCoTaskMemAlloc( IN ULONG cb) { VOID *pv;
pv = CoTaskMemAlloc(cb); if (NULL != pv) { myRegisterMemAlloc(pv, cb, CSM_COTASKALLOC); } return(pv); }
VOID * myCoTaskMemRealloc( IN VOID *pv, IN ULONG cb) { VOID *pvNew;
pvNew = CoTaskMemRealloc(pv, cb); if (NULL != pvNew) { myRegisterMemFree(pv, CSM_COTASKALLOC); myRegisterMemAlloc(pvNew, cb, CSM_COTASKALLOC); } return(pvNew); }
VOID myCoTaskMemFree( IN VOID *pv) { myRegisterMemFree(pv, CSM_COTASKALLOC); CoTaskMemFree(pv); }
HRESULT myStringFromCLSID( IN REFCLSID rclsid, OUT LPOLESTR FAR *ppwsz) { HRESULT hr;
hr = StringFromCLSID(rclsid, ppwsz); _JumpIfError(hr, error, "StringFromCLSID");
if (NULL != *ppwsz) { myRegisterMemAlloc( *ppwsz, (wcslen(*ppwsz) + 1) * sizeof(WCHAR), CSM_COTASKALLOC); }
error: return(hr); }
HRESULT myStringFromIID( IN REFIID rclsid, OUT LPOLESTR FAR *ppwsz) { HRESULT hr;
hr = StringFromIID(rclsid, ppwsz); _JumpIfError(hr, error, "StringFromIID");
if (NULL != *ppwsz) { myRegisterMemAlloc( *ppwsz, (wcslen(*ppwsz) + 1) * sizeof(WCHAR), CSM_COTASKALLOC); }
error: return(hr); }
BSTR mySysAllocString( IN const OLECHAR *pwszIn) { BSTR str;
str = SysAllocString(pwszIn); if (NULL != str) { myRegisterMemAlloc(str, (wcslen(pwszIn) + 1) * sizeof(WCHAR), CSM_SYSALLOC); } return(str); }
INT mySysReAllocString( IN OUT BSTR *pstr, IN const OLECHAR *pwszIn) { BSTR str = *pstr; INT i;
i = SysReAllocString(pstr, pwszIn); if (i) { myRegisterMemFree(str, CSM_SYSALLOC); myRegisterMemAlloc(*pstr, (wcslen(pwszIn) + 1) * sizeof(WCHAR), CSM_SYSALLOC); } return(i); }
BSTR mySysAllocStringLen( IN const OLECHAR *pwcIn, IN UINT cwc) { BSTR str;
str = SysAllocStringLen(pwcIn, cwc); if (NULL != str) { myRegisterMemAlloc(str, cwc * sizeof(WCHAR), CSM_SYSALLOC); } return(str); }
INT mySysReAllocStringLen( IN OUT BSTR *pstr, IN const OLECHAR *pwcIn, IN UINT cwc) { BSTR str = *pstr; INT i;
i = SysReAllocStringLen(pstr, pwcIn, cwc); if (i) { myRegisterMemFree(str, CSM_SYSALLOC); myRegisterMemAlloc(*pstr, cwc * sizeof(WCHAR), CSM_SYSALLOC); } return(i); }
VOID mySysFreeString( IN BSTR str) { if (NULL != str) { myRegisterMemFree(str, CSM_SYSALLOC); } SysFreeString(str); }
BSTR mySysAllocStringByteLen( LPCSTR pszIn, UINT cb) { BSTR str;
str = SysAllocStringByteLen(pszIn, cb); if (NULL != str) { myRegisterMemAlloc(str, cb, CSM_SYSALLOC); } return(str); }
VOID _RegisterVariantMemAlloc( IN PROPVARIANT *pvar) { VOID *pv; DWORD Flags; DWORD cb; pv = _VariantMemory(pvar, &Flags, &cb); if (NULL != pv) { myRegisterMemAlloc(pv, cb, Flags); } }
VOID _RegisterVariantMemFree( IN PROPVARIANT *pvar) { VOID *pv; DWORD Flags; pv = _VariantMemory(pvar, &Flags, NULL); if (NULL != pv) { myRegisterMemFree(pv, Flags); } }
HRESULT myPropVariantClear( IN PROPVARIANT *pvar) { _RegisterVariantMemFree(pvar); return(PropVariantClear(pvar)); }
HRESULT myVariantClear( IN VARIANTARG *pvar) { _RegisterVariantMemFree((PROPVARIANT *) pvar); return(VariantClear(pvar)); }
HRESULT myVariantChangeType( OUT VARIANTARG *pvarDest, IN VARIANTARG *pvarSrc, IN unsigned short wFlags, IN VARTYPE vt) { HRESULT hr;
// if converting in-place, memory will be freed by the API call
if (pvarDest == pvarSrc) { _RegisterVariantMemFree((PROPVARIANT *) pvarSrc); } hr = VariantChangeType(pvarDest, pvarSrc, wFlags, vt); _RegisterVariantMemAlloc((PROPVARIANT *) pvarDest); return(hr); }
HRESULT myVariantChangeTypeEx( OUT VARIANTARG *pvarDest, IN VARIANTARG *pvarSrc, IN LCID lcid, IN unsigned short wFlags, IN VARTYPE vt) { HRESULT hr;
// if converting in-place, memory will be freed by the API call
if (pvarDest == pvarSrc) { _RegisterVariantMemFree((PROPVARIANT *) pvarSrc); } hr = VariantChangeTypeEx(pvarDest, pvarSrc, lcid, wFlags, vt); _RegisterVariantMemAlloc((PROPVARIANT *) pvarDest); return(hr); }
VOID * myNew( IN size_t size) { VOID *pv; pv = LocalAlloc(LMEM_FIXED, size); if (NULL != pv) { myRegisterMemAlloc(pv, size, CSM_NEW); } return(pv); }
VOID myDelete( IN VOID *pv) { myRegisterMemFree(pv, CSM_NEW); LocalFree(pv); }
#endif // DBG_CERTSRV
|