windows-nt/Source/XPSP1/NT/ds/security/services/ca/certclib/alloc.cpp
2020-09-26 16:20:57 +08:00

1222 lines
22 KiB
C++

//+--------------------------------------------------------------------------
//
// 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