MAPIDBG.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:64k
源码类别:
Windows编程
开发平台:
Visual C++
- /*
- * MAPIDBG.C
- *
- * MAPI Debugging Utilities
- *
- * Copyright (C) 1986-1996 Microsoft Corporation. All rights reserved.
- */
- #ifdef DEBUG
- #pragma warning(disable:4100) /* unreferenced formal parameter */
- #pragma warning(disable:4127) /* conditional expression is constant */
- #pragma warning(disable:4201) /* nameless struct/union */
- #pragma warning(disable:4206) /* translation unit is empty */
- #pragma warning(disable:4209) /* benign typedef redefinition */
- #pragma warning(disable:4214) /* bit field types other than int */
- #pragma warning(disable:4001) /* single line comments */
- #pragma warning(disable:4050) /* different code attributes */
- #ifdef _MAC
- #define INC_OLE2
- #include <windows.h>
- #include <macname1.h>
- #include <macosmenus.h>
- #include <stdio.h>
- #include <mapiprof.h>
- #define GetPrivateProfileIntA MAPIGetPrivateProfileInt
- #elif defined(WIN16) || defined(_WIN32)
- #pragma warning(disable:4115) /* named type definition in parentheses */
- #include <windows.h>
- #include <mapiwin.h>
- #ifdef _WIN32
- #pragma warning(disable:4001) /* single line comments */
- #pragma warning(disable:4115) /* named type definition in parentheses */
- #pragma warning (disable:4514) /* unreferenced inline function */
- #include <objerror.h>
- #endif
- #else
- #include <stdio.h>
- void __far __pascal OutputDebugString(char __far *);
- #define wvsprintf vsprintf
- #define wsprintf sprintf
- #endif /* _MAC */
- #ifdef DOS
- #define lstrcpyA strcpy
- #define lstrlenA strlen
- #define lstrcatA strcat
- #define wvsprintfA wvsprintf
- #define wsprintfA wsprintf
- #define OutputDebugStringA OutputDebugString
- #endif
- #include <mapidbg.h>
- #include <mapidefs.h>
- #include <mapitags.h>
- #include <mapicode.h>
- #include <stdarg.h>
- #include <string.h>
- #include <time.h>
- #ifdef _MAC
- #include <macname2.h>
- #endif
- #if defined(DBCS) && defined(DOS)
- #include <gapidos.h>
- #endif
- #if defined(DEBUG) && defined(_WINNT)
- #include <lmcons.h>
- #include <lmalert.h>
- #endif
- /* Patch/Hack for 16bit, optimized builds.
- *
- * memcpy with a size of 0 bytes causes a
- * crash.
- */
- #ifndef __MEMCPY_H_
- #define __MEMCPY_H_
- #if defined(WIN16) && !defined(DEBUG)
- #define MemCopy(_dst,_src,_cb) do
- {
- size_t __cb = (size_t)(_cb);
- if (__cb)
- memcpy(_dst,_src,__cb);
- } while (FALSE)
- #else
- #define MemCopy(_dst,_src,_cb) memcpy(_dst,_src,(size_t)(_cb))
- #endif
- #endif
- #if (defined(WIN16) || defined(DOS)) && !defined(NO_BASED_DEBUG)
- #define BASED_DEBUG __based(__segname("DEBUG_DATA"))
- #else
- #define BASED_DEBUG
- #endif
- #if defined(WIN16)
- #define BASED_CODE __based(__segname("_CODE"))
- #else
- #define BASED_CODE
- #endif
- #if defined(WIN16) || defined(_WIN32)
- static BOOL fTraceEnabled = -1;
- static BOOL fUseEventLog = -1;
- static BOOL fAssertLeaks = -1;
- #if defined(_WIN32) && !defined(_MAC)
- BOOL fInhibitTrapThread = 2;
- #endif
- static char szKeyTraceEnabled[] = "DebugTrace";
- static char szKeyInhibitTrapThread[] = "TrapOnSameThread";
- static char szKeyEventLog[] = "EventLog";
- static char szKeyUseVirtual[] = "VirtualMemory";
- static char szKeyAssertLeaks[] = "AssertLeaks";
- static char szKeyCheckOften[] = "CheckHeapOften";
- static char szKeyFillRandom[] = "MemoryFillRandom";
- static char szSectionDebug[] = "General";
- static char szDebugIni[] = "MAPIDBG.INI";
- #endif
- #ifndef VTABLE_FILL
- #ifdef _MAC
- #define VTABLE_FILL NULL,
- #else
- #define VTABLE_FILL
- #endif
- #endif
- #if defined(DEBUG) && defined(_WINNT)
- typedef BOOL (WINAPI *ReportEventFN)(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCTSTR *, LPVOID);
- typedef HANDLE (WINAPI *RegisterEventSourceAFN)(LPCTSTR, LPCTSTR);
- ReportEventFN pfnReportEvent = NULL;
- RegisterEventSourceAFN pfnRegisterEventSourceA = NULL;
- #endif
- #ifdef WIN16
- #pragma code_seg("Debug")
- #endif
- #if defined( _WINNT)
- /*++
- Routine Description:
- This routine returns if the service specified is running interactively
- (not invoked by the service controller).
- Arguments:
- None
- Return Value:
- BOOL - TRUE if the service is an EXE.
- Note:
- --*/
- BOOL WINAPI IsDBGServiceAnExe( VOID )
- {
- HANDLE hProcessToken = NULL;
- DWORD groupLength = 50;
- PTOKEN_GROUPS groupInfo = (PTOKEN_GROUPS)LocalAlloc(0, groupLength);
- SID_IDENTIFIER_AUTHORITY siaNt = SECURITY_NT_AUTHORITY;
- PSID InteractiveSid = NULL;
- PSID ServiceSid = NULL;
- DWORD i;
- // Start with assumption that process is an EXE, not a Service.
- BOOL fExe = TRUE;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken))
- goto ret;
- if (groupInfo == NULL)
- goto ret;
- if (!GetTokenInformation(hProcessToken, TokenGroups, groupInfo,
- groupLength, &groupLength))
- {
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- goto ret;
- LocalFree(groupInfo);
- groupInfo = NULL;
- groupInfo = (PTOKEN_GROUPS)LocalAlloc(0, groupLength);
- if (groupInfo == NULL)
- goto ret;
- if (!GetTokenInformation(hProcessToken, TokenGroups, groupInfo,
- groupLength, &groupLength))
- {
- goto ret;
- }
- }
- //
- // We now know the groups associated with this token. We want to look to see if
- // the interactive group is active in the token, and if so, we know that
- // this is an interactive process.
- //
- // We also look for the "service" SID, and if it's present, we know we're a service.
- //
- // The service SID will be present iff the service is running in a
- // user account (and was invoked by the service controller).
- //
- if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_INTERACTIVE_RID, 0, 0,
- 0, 0, 0, 0, 0, &InteractiveSid))
- {
- goto ret;
- }
- if (!AllocateAndInitializeSid(&siaNt, 1, SECURITY_SERVICE_RID, 0, 0, 0,
- 0, 0, 0, 0, &ServiceSid))
- {
- goto ret;
- }
- for (i = 0; i < groupInfo->GroupCount ; i += 1)
- {
- SID_AND_ATTRIBUTES sanda = groupInfo->Groups[i];
- PSID Sid = sanda.Sid;
- //
- // Check to see if the group we're looking at is one of
- // the 2 groups we're interested in.
- //
- if (EqualSid(Sid, InteractiveSid))
- {
- //
- // This process has the Interactive SID in its
- // token. This means that the process is running as
- // an EXE.
- //
- goto ret;
- }
- else if (EqualSid(Sid, ServiceSid))
- {
- //
- // This process has the Service SID in its
- // token. This means that the process is running as
- // a service running in a user account.
- //
- fExe = FALSE;
- goto ret;
- }
- }
- //
- // Neither Interactive or Service was present in the current users token,
- // This implies that the process is running as a service, most likely
- // running as LocalSystem.
- //
- fExe = FALSE;
- ret:
- if (InteractiveSid)
- FreeSid(InteractiveSid);
- if (ServiceSid)
- FreeSid(ServiceSid);
- if (groupInfo)
- LocalFree(groupInfo);
- if (hProcessToken)
- CloseHandle(hProcessToken);
- return(fExe);
- }
- #endif
- /* LogIt */
- #ifndef _MAC
- void LogIt(LPSTR plpcText, BOOL fUseAlert)
- {
- #if defined(DEBUG) && defined(_WINNT)
- LPSTR llpcStr[2];
- static HANDLE hEventSource = NULL;
- if (pfnRegisterEventSourceA == NULL)
- {
- /* This handle is not important as the lib will be freed on exit (and it's debug only) */
- HINSTANCE lhLib = LoadLibraryA("advapi32.dll");
- if (!lhLib)
- return;
- pfnRegisterEventSourceA = (RegisterEventSourceAFN) GetProcAddress(lhLib, "RegisterEventSourceA");
- pfnReportEvent = (ReportEventFN) GetProcAddress(lhLib, "ReportEventA");
- if (!pfnRegisterEventSourceA || !pfnReportEvent)
- return;
- }
- if (!hEventSource)
- hEventSource = pfnRegisterEventSourceA(NULL, "MAPIDebug");
- llpcStr[0] = "MAPI Debug Log";
- llpcStr[1] = plpcText;
- pfnReportEvent(hEventSource, /* handle of event source */
- EVENTLOG_ERROR_TYPE, /* event type */
- 0, /* event category */
- 0, /* event ID */
- NULL, /* current user's SID */
- 2, /* strings in lpszStrings */
- 0, /* no bytes of raw data */
- llpcStr, /* array of error strings */
- NULL); /* no raw data */
- /* Now we generate an Alert! */
- /* This code is adapted from PierreC's stuff, and NEEDS TO BE UNICODE!!!! */
- if (fUseAlert)
- {
- #define MAX_LINE 256
- typedef NET_API_STATUS (WINAPI *NAREFN)(TCHAR *, ADMIN_OTHER_INFO *, ULONG, TCHAR *);
- BYTE rgb[sizeof(ADMIN_OTHER_INFO) + (sizeof(WCHAR) * MAX_LINE)];
- ADMIN_OTHER_INFO * poi = (ADMIN_OTHER_INFO *) rgb;
- WCHAR * pch = (WCHAR *) (rgb + sizeof(ADMIN_OTHER_INFO));
- NET_API_STATUS nas;
- static NAREFN fnNetAlertRaiseEx = NULL;
- /* Resolve function here, never free library as it's debug only */
- if (!fnNetAlertRaiseEx)
- {
- HINSTANCE lhLib = LoadLibrary("NETAPI32.DLL");
- if (lhLib)
- fnNetAlertRaiseEx = (NAREFN) GetProcAddress(lhLib, "NetAlertRaiseEx");
- }
- if (fnNetAlertRaiseEx)
- {
- poi->alrtad_errcode = (DWORD) -1;
- poi->alrtad_numstrings = 1;
- if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plpcText, -1, pch, MAX_LINE))
- {
- nas = fnNetAlertRaiseEx(
- (TCHAR *) L"ADMIN",
- poi,
- sizeof(ADMIN_OTHER_INFO) + ((lstrlenW(pch) + 1) * sizeof(WCHAR)),
- (TCHAR *) L"MAPI Assert");
- }
- }
- }
- #endif /* DEBUG && NT */
- }
- #endif /* !_MAC */
- /* DebugOutputFn ------------------------------------------------------------ */
- char BASED_CODE szCR[] = "r";
- void DebugOutputFn(char *psz)
- {
- #if defined(_MAC)
- OutputDebugString(psz);
- #else
- #if defined(WIN16) || defined(_WIN32)
- if (fTraceEnabled == -1)
- {
- fTraceEnabled = GetPrivateProfileIntA(szSectionDebug, szKeyTraceEnabled,
- 0, szDebugIni);
- fUseEventLog = GetPrivateProfileIntA(szSectionDebug, szKeyEventLog,
- 0, szDebugIni);
- }
- if (!fTraceEnabled)
- return;
- if (fUseEventLog)
- #else
- if (FALSE)
- #endif
- LogIt(psz, FALSE);
- #ifdef WIN16
- OutputDebugString(psz);
- OutputDebugString(szCR);
- #else
- OutputDebugStringA(psz);
- OutputDebugStringA(szCR);
- #endif
- #endif /* _MAC */
- }
- /* DebugTrapFn -------------------------------------------------------------- */
- #if defined(_WIN32) && !defined(_MAC)
- typedef struct {
- char * sz1;
- char * sz2;
- UINT rgf;
- int iResult;
- } MBContext;
- DWORD WINAPI MessageBoxFnThreadMain(MBContext *pmbc)
- {
- if (fUseEventLog)
- {
- LogIt(pmbc->sz1, TRUE);
- pmbc->iResult = IDIGNORE;
- }
- else
- pmbc->iResult = MessageBoxA(NULL, pmbc->sz1, pmbc->sz2,
- pmbc->rgf | MB_SETFOREGROUND);
- return(0);
- }
- int MessageBoxFn(char *sz1, char *sz2, UINT rgf)
- {
- HANDLE hThread;
- DWORD dwThreadId;
- MBContext mbc;
- mbc.sz1 = sz1;
- mbc.sz2 = sz2;
- mbc.rgf = rgf;
- mbc.iResult = IDRETRY;
- #if defined(_WIN32) && !defined(_MAC)
- if (fInhibitTrapThread == 2)
- fInhibitTrapThread = GetPrivateProfileIntA(szSectionDebug,
- szKeyInhibitTrapThread, 0, szDebugIni);
- #endif
- if (fInhibitTrapThread)
- {
- MessageBoxFnThreadMain(&mbc);
- }
- else
- {
- hThread = CreateThread(NULL, 0,
- (PTHREAD_START_ROUTINE)MessageBoxFnThreadMain, &mbc, 0, &dwThreadId);
- if (hThread != NULL) {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- }
- }
- return(mbc.iResult);
- }
- #else
- #define MessageBoxFn(sz1, sz2, rgf) MessageBoxA(NULL, sz1, sz2, rgf)
- #endif
- int EXPORTDBG __cdecl DebugTrapFn(int fFatal, char *pszFile, int iLine, char *pszFormat, ...)
- {
- char sz[512];
- va_list vl;
- #if defined(WIN16) || defined(_WIN32)
- int id;
- #endif
- #if defined(_WIN32) && !defined(_MAC)
- static int iServiceFlag = -1;
- #endif
- lstrcpyA(sz, "++++ MAPI Debug Trap (");
- _strdate(sz + lstrlenA(sz));
- lstrcatA(sz, " ");
- _strtime(sz + lstrlenA(sz));
- lstrcatA(sz, ")n");
- DebugOutputFn(sz);
- va_start(vl, pszFormat);
- wvsprintfA(sz, pszFormat, vl);
- va_end(vl);
- wsprintfA(sz + lstrlenA(sz), "n[File %s, Line %d]nn", pszFile, iLine);
- DebugOutputFn(sz);
- #if defined(DOS)
- _asm { int 3 }
- #endif
- #if defined(WIN16) || defined(_WIN32)
- /* Hold down control key to prevent MessageBox */
- if ( GetAsyncKeyState(VK_CONTROL) >= 0 )
- {
- UINT uiFlags = MB_ABORTRETRYIGNORE;
- if (fFatal)
- uiFlags |= MB_DEFBUTTON1;
- else
- uiFlags |= MB_DEFBUTTON3;
- #ifdef WIN16
- uiFlags |= MB_ICONEXCLAMATION | MB_SYSTEMMODAL;
- #else
- uiFlags |= MB_ICONSTOP | MB_TASKMODAL;
- #endif
- #if defined(_WIN32) && !defined(_MAC)
- if (iServiceFlag == -1)
- {
- DWORD dwVersion = GetVersion();
- if (dwVersion & 0x80000000)
- {
- if (LOBYTE(LOWORD(dwVersion)) < 4)
- {
- // NT 3.51
- iServiceFlag = 0x00040000;
- }
- else
- {
- // NT 4.0+
- iServiceFlag = 0x00200000;
- }
- }
- else
- // not NT, skip this
- iServiceFlag = 0;
- }
- if (!IsDBGServiceAnExe())
- uiFlags |= (UINT) iServiceFlag;
- #endif
- id = MessageBoxFn(sz, "MAPI Debug Trap", uiFlags);
- if (id == IDABORT)
- *((LPBYTE)NULL) = 0;
- else if (id == IDRETRY)
- DebugBreak();
- }
- #endif
- return(0);
- }
- /* DebugTraceFn ------------------------------------------------------------- */
- int EXPORTDBG __cdecl DebugTraceFn(char *pszFormat, ...)
- {
- char sz[768];
- int fAutoLF = 0;
- va_list vl;
- if (*pszFormat == '~') {
- pszFormat += 1;
- fAutoLF = 1;
- }
- va_start(vl, pszFormat);
- wvsprintfA(sz, pszFormat, vl);
- va_end(vl);
- #ifndef _MAC
- if (fAutoLF)
- lstrcatA(sz, "n");
- #endif
- DebugOutputFn(sz);
- return(0);
- }
- /* DebugTraceProblemsFn */
- void EXPORTDBG __cdecl DebugTraceProblemsFn(LPSTR sz, LPVOID pv)
- {
- LPSPropProblemArray pprobs = (LPSPropProblemArray)pv;
- SPropProblem * pprob = pprobs->aProblem;
- int cprob = (int)pprobs->cProblem;
- DebugTraceFn("%s: SetProps problemn", sz);
- while (cprob--)
- {
- DebugTraceFn("Property %s (index %ld): failed with %sn",
- SzDecodeUlPropTagFn(pprob->ulPropTag),
- pprob->ulIndex,
- SzDecodeScodeFn(pprob->scode));
- }
- }
- /* SCODE & PropTag decoding ------------------------------------------------- */
- typedef struct
- {
- char * psz;
- unsigned long ulPropTag;
- } PT;
- typedef struct
- {
- char * psz;
- SCODE sc;
- } SC;
- #define Pt(_ptag) {#_ptag, _ptag}
- #define Sc(_sc) {#_sc, _sc}
- #if !defined(DOS)
- static PT BASED_DEBUG rgpt[] = {
- #include "_tags.h"
- /*
- * Property types
- */
- Pt(PR_NULL),
- Pt(PT_UNSPECIFIED),
- Pt(PT_NULL),
- Pt(PT_I2),
- Pt(PT_LONG),
- Pt(PT_R4),
- Pt(PT_DOUBLE),
- Pt(PT_CURRENCY),
- Pt(PT_APPTIME),
- Pt(PT_ERROR),
- Pt(PT_BOOLEAN),
- Pt(PT_OBJECT),
- Pt(PT_I8),
- Pt(PT_STRING8),
- Pt(PT_UNICODE),
- Pt(PT_SYSTIME),
- Pt(PT_CLSID),
- Pt(PT_BINARY),
- Pt(PT_TSTRING),
- Pt(PT_MV_I2),
- Pt(PT_MV_LONG),
- Pt(PT_MV_R4),
- Pt(PT_MV_DOUBLE),
- Pt(PT_MV_CURRENCY),
- Pt(PT_MV_APPTIME),
- Pt(PT_MV_SYSTIME),
- Pt(PT_MV_STRING8),
- Pt(PT_MV_BINARY),
- Pt(PT_MV_UNICODE),
- Pt(PT_MV_CLSID),
- Pt(PT_MV_I8)
- };
- #define cpt (sizeof(rgpt) / sizeof(PT))
- static SC BASED_DEBUG rgsc[] = {
- /* FACILITY_NULL error codes from OLE */
- Sc(S_OK),
- Sc(S_FALSE),
- Sc(E_UNEXPECTED),
- Sc(E_NOTIMPL),
- Sc(E_OUTOFMEMORY),
- Sc(E_INVALIDARG),
- Sc(E_NOINTERFACE),
- Sc(E_POINTER),
- Sc(E_HANDLE),
- Sc(E_ABORT),
- Sc(E_FAIL),
- Sc(E_ACCESSDENIED),
- /* MAPI error codes from MAPICODE.H */
- #include "_scode.h"
- };
- #define csc (sizeof(rgsc) / sizeof(SC))
- #endif
- char * EXPORTDBG __cdecl
- SzDecodeScodeFn(SCODE sc)
- {
- static char rgch[64];
- #if !defined(DOS)
- int isc;
- for (isc = 0; isc < csc; ++isc)
- if (sc == rgsc[isc].sc)
- return rgsc[isc].psz;
- #endif
- wsprintfA (rgch, "%08lX", sc);
- return rgch;
- }
- char * EXPORTDBG __cdecl
- SzDecodeUlPropTypeFn(unsigned long ulPropType)
- {
- static char rgch[8];
- switch (ulPropType)
- {
- case PT_UNSPECIFIED: return("PT_UNSPECIFIED"); break;
- case PT_NULL: return("PT_NULL"); break;
- case PT_I2: return("PT_I2"); break;
- case PT_LONG: return("PT_LONG"); break;
- case PT_R4: return("PT_R4"); break;
- case PT_DOUBLE: return("PT_DOUBLE"); break;
- case PT_CURRENCY: return("PT_CURRENCY"); break;
- case PT_APPTIME: return("PT_APPTIME"); break;
- case PT_ERROR: return("PT_ERROR"); break;
- case PT_BOOLEAN: return("PT_BOOLEAN"); break;
- case PT_OBJECT: return("PT_OBJECT"); break;
- case PT_I8: return("PT_I8"); break;
- case PT_STRING8: return("PT_STRING8"); break;
- case PT_UNICODE: return("PT_UNICODE"); break;
- case PT_SYSTIME: return("PT_SYSTIME"); break;
- case PT_CLSID: return("PT_CLSID"); break;
- case PT_BINARY: return("PT_BINARY"); break;
- }
- wsprintfA(rgch, "0x%04lX", ulPropType);
- return rgch;
- }
- char * EXPORTDBG __cdecl
- SzDecodeUlPropTagFn(unsigned long ulPropTag)
- {
- static char rgch[64];
- #if !defined(DOS)
- int ipt;
- for (ipt = 0; ipt < cpt; ++ipt)
- if (ulPropTag == rgpt[ipt].ulPropTag)
- return rgpt[ipt].psz;
- #endif
- wsprintfA(rgch, "PROP_TAG(%s, 0x%04lX)",
- SzDecodeUlPropType(PROP_TYPE(ulPropTag)),
- PROP_ID(ulPropTag));
- return rgch;
- }
- SCODE EXPORTDBG __cdecl
- ScodeFromSzFn(char *psz)
- {
- #if !defined(DOS)
- int isc;
- for (isc = 0; isc < csc; ++isc)
- {
- if (lstrcmpA(psz, rgsc[isc].psz) == 0)
- {
- return rgsc[isc].sc;
- }
- }
- #endif
- return 0;
- }
- unsigned long EXPORTDBG __cdecl
- UlPropTagFromSzFn(char *psz)
- {
- #if !defined(DOS)
- int ipt;
- for (ipt = 0; ipt < cpt; ++ipt)
- {
- if (lstrcmpA(psz, rgpt[ipt].psz) == 0)
- {
- return rgpt[ipt].ulPropTag;
- }
- }
- #endif
- return 0;
- }
- /* ScCheckScFn -------------------------------------------------------------- */
- #if !defined(DOS)
- SCODE EXPORTDBG __cdecl ScCheckScFn( SCODE sc,
- SCODE * lpscLegal,
- char * lpszMethod,
- char * lpszFile,
- int iLine)
- {
- BOOL fIsQueryInterface = (lpscLegal == IUnknown_QueryInterface_Scodes);
- if (sc == S_OK)
- return(sc);
- while( *lpscLegal != S_OK && sc != *lpscLegal )
- {
- lpscLegal++;
- }
- if ( *lpscLegal == S_OK )
- {
- SCODE *lpscNextCommon = Common_Scodes;
- /* see if this is a common scode */
- if ( !fIsQueryInterface )
- while( *lpscNextCommon != S_OK &&
- sc != *lpscNextCommon )
- {
- lpscNextCommon++;
- }
- /* this is an illegal error or an RPC error */
- if ( (*lpscNextCommon == S_OK || fIsQueryInterface) &&
- ( SCODE_FACILITY(sc) != FACILITY_RPC) )
- {
- DebugTrace( "Unrecognized scode %s from %snt in file %s line %dn",
- SzDecodeScode( sc ), lpszMethod, lpszFile, iLine);
- }
- }
- return(sc);
- }
- #endif
- /* SCODE lists -------------------------------------------------------------- */
- #if !defined(DOS)
- #define STANDARD_OPENENTRY_SCODES
- E_NOINTERFACE,
- MAPI_E_NOT_FOUND
- SCODE BASED_DEBUG Common_Scodes[] =
- {
- MAPI_E_BAD_CHARWIDTH,
- MAPI_E_CALL_FAILED,
- MAPI_E_INVALID_ENTRYID,
- MAPI_E_INVALID_OBJECT,
- MAPI_E_INVALID_PARAMETER,
- MAPI_E_NO_ACCESS,
- MAPI_E_NO_SUPPORT,
- MAPI_E_NOT_ENOUGH_MEMORY,
- MAPI_E_UNKNOWN_FLAGS,
- S_OK
- };
- SCODE BASED_DEBUG MAPILogon_Scodes[] =
- {
- MAPI_E_NOT_INITIALIZED,
- MAPI_E_LOGON_FAILED,
- S_OK
- };
- SCODE BASED_DEBUG MAPIAllocateBuffer_Scodes[] =
- {
- MAPI_E_NOT_INITIALIZED,
- S_OK
- };
- SCODE BASED_DEBUG MAPIAllocateMore_Scodes[] =
- {
- MAPI_E_NOT_INITIALIZED,
- S_OK
- };
- SCODE BASED_DEBUG MAPIFreeBuffer_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IUnknown_QueryInterface_Scodes[] =
- {
- E_INVALIDARG,
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IUnknown_GetLastError_Scodes[] =
- {
- MAPI_E_EXTENDED_ERROR,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_CopyTo_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- MAPI_E_INVALID_TYPE,
- MAPI_E_FOLDER_CYCLE,
- MAPI_E_DECLINE_COPY,
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_CopyProps_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- MAPI_W_PARTIAL_COMPLETION,
- MAPI_E_INVALID_TYPE,
- MAPI_E_FOLDER_CYCLE,
- MAPI_E_DECLINE_COPY,
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_DeleteProps_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- MAPI_E_INVALID_TYPE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_GetIDsFromNames_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- MAPI_E_TABLE_TOO_BIG,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_GetLastError_Scodes[] =
- {
- MAPI_E_EXTENDED_ERROR,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_GetNamesFromIDs_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_GetPropList_Scodes[] =
- {
- MAPI_W_ERRORS_RETURNED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_GetProps_Scodes[] =
- {
- MAPI_E_NOT_FOUND,
- MAPI_E_OBJECT_DELETED,
- MAPI_W_ERRORS_RETURNED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_OpenProperty_Scodes[] =
- {
- MAPI_E_INTERFACE_NOT_SUPPORTED,
- MAPI_E_NOT_FOUND,
- MAPI_E_OBJECT_DELETED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_SetProps_Scodes[] =
- {
- MAPI_E_COMPUTED,
- MAPI_E_UNEXPECTED_TYPE,
- MAPI_E_INVALID_TYPE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIProp_SaveChanges_Scodes[] =
- {
- MAPI_E_NOT_ENOUGH_DISK,
- MAPI_E_OBJECT_CHANGED,
- MAPI_E_OBJECT_DELETED,
- S_OK
- };
- SCODE BASED_DEBUG IStream_Read_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Write_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Seek_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_SetSize_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Tell_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_LockRegion_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_UnlockRegion_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Clone_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_CopyTo_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Revert_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Stat_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IStream_Commit_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_GetLastError_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_Advise_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_Unadvise_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_GetStatus_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_SetColumns_Scodes[] =
- {
- MAPI_E_BUSY,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_QueryColumns_Scodes[] =
- {
- MAPI_E_BUSY,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_GetRowCount_Scodes[] =
- {
- MAPI_E_BUSY,
- MAPI_W_APPROX_COUNT,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_SeekRow_Scodes[] =
- {
- MAPI_E_INVALID_BOOKMARK,
- MAPI_E_UNABLE_TO_COMPLETE,
- MAPI_W_POSITION_CHANGED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_SeekRowApprox_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_QueryPosition_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_FindRow_Scodes[] =
- {
- MAPI_E_INVALID_BOOKMARK,
- MAPI_E_NOT_FOUND,
- MAPI_W_POSITION_CHANGED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_Restrict_Scodes[] =
- {
- MAPI_E_BUSY,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_CreateBookmark_Scodes[] =
- {
- MAPI_E_UNABLE_TO_COMPLETE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_FreeBookmark_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_SortTable_Scodes[] =
- {
- MAPI_E_TOO_COMPLEX,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_QuerySortOrder_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_QueryRows_Scodes[] =
- {
- MAPI_E_INVALID_BOOKMARK,
- MAPI_W_POSITION_CHANGED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_Abort_Scodes[] =
- {
- MAPI_E_UNABLE_TO_ABORT,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_ExpandRow_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_CollapseRow_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_WaitForCompletion_Scodes[] =
- {
- MAPI_E_TIMEOUT,
- S_OK
- };
- SCODE BASED_DEBUG IMAPITable_GetCollapseState_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPITable_SetCollapseState_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_LogOff_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_Release_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_GetLastError_Scodes[] =
- {
- MAPI_E_EXTENDED_ERROR,
- S_OK
- };
- SCODE BASED_DEBUG IMAPISession_GetMsgStoresTable_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_GetStatusTable_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_OpenMsgStore_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_OpenAddressBook_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_OpenEntry_Scodes[] =
- {
- STANDARD_OPENENTRY_SCODES,
- S_OK
- };
- SCODE BASED_DEBUG IMAPISession_OpenProfileSection_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_Advise_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_Unadvise_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_CompareEntryIDs_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_MessageOptions_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_QueryDefaultMessageOpt_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_EnumAdrTypes_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPISession_QueryIdentity_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_OpenEntry_Scodes[] =
- {
- STANDARD_OPENENTRY_SCODES,
- MAPI_E_SUBMITTED,
- S_OK
- };
- SCODE BASED_DEBUG IMsgStore_SetReceiveFolder_Scodes[] =
- {
- MAPI_E_BAD_CHARWIDTH,
- MAPI_E_NOT_FOUND,
- S_OK
- };
- SCODE BASED_DEBUG IMsgStore_GetReceiveFolder_Scodes[] =
- {
- MAPI_E_BAD_CHARWIDTH,
- S_OK
- };
- SCODE BASED_DEBUG IMsgStore_GetReceiveFolderTable_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_StoreLogoff_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_Advise_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_Unadvise_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_CompareEntryIDs_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMsgStore_GetOutgoingQueue_Scodes[] = {
- MAPI_E_NO_SUPPORT,
- S_OK};
- SCODE BASED_DEBUG IMsgStore_SetLockState_Scodes[] = {
- MAPI_E_NO_SUPPORT,
- MAPI_E_NOT_FOUND,
- S_OK};
- SCODE BASED_DEBUG IMsgStore_FinishedMsg_Scodes[] = {
- MAPI_E_NO_SUPPORT,
- S_OK};
- SCODE BASED_DEBUG IMsgStore_AbortSubmit_Scodes[] = {
- MAPI_E_UNABLE_TO_ABORT,
- MAPI_E_NOT_IN_QUEUE,
- S_OK};
- SCODE BASED_DEBUG IMsgStore_NotifyNewMail_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPIFolder_GetContentsTable_Scodes[] =
- {
- MAPI_E_OBJECT_DELETED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_GetHierarchyTable_Scodes[] =
- {
- MAPI_E_OBJECT_DELETED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_SaveContentsSort_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_OpenEntry_Scodes[] =
- {
- STANDARD_OPENENTRY_SCODES,
- MAPI_E_SUBMITTED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_CreateMessage_Scodes[] =
- {
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_CopyMessages_Scodes[] =
- {
- E_NOINTERFACE,
- MAPI_E_SUBMITTED,
- MAPI_E_DECLINE_COPY,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_DeleteMessages_Scodes[] =
- {
- MAPI_E_SUBMITTED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_CreateFolder_Scodes[] =
- {
- E_NOINTERFACE,
- MAPI_E_COLLISION,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_CopyFolder_Scodes[] =
- {
- E_NOINTERFACE,
- MAPI_E_COLLISION,
- MAPI_E_FOLDER_CYCLE,
- MAPI_E_DECLINE_COPY,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_DeleteFolder_Scodes[] =
- {
- MAPI_E_HAS_FOLDERS,
- MAPI_E_HAS_MESSAGES,
- MAPI_E_SUBMITTED,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_SetSearchCriteria_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_GetSearchCriteria_Scodes[] =
- {
- MAPI_E_NOT_INITIALIZED,
- MAPI_E_CORRUPT_STORE,
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_SetReadFlags_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_GetMessageStatus_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_SetMessageStatus_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMAPIFolder_EmptyFolder_Scodes[] =
- {
- MAPI_E_SUBMITTED,
- S_OK
- };
- SCODE BASED_DEBUG IMessage_GetAttachmentTable_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMessage_OpenAttach_Scodes[] =
- {
- MAPI_E_NOT_FOUND,
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IMessage_CreateAttach_Scodes[] =
- {
- E_NOINTERFACE,
- S_OK
- };
- SCODE BASED_DEBUG IMessage_DeleteAttach_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMessage_GetRecipientTable_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IMessage_ModifyRecipients_Scodes[] =
- {
- MAPI_E_NOT_FOUND,
- S_OK
- };
- SCODE BASED_DEBUG IMessage_SubmitMessage_Scodes[] =
- {
- MAPI_E_NO_RECIPIENTS,
- MAPI_E_NON_STANDARD,
- S_OK
- };
- SCODE BASED_DEBUG IMessage_SetReadFlag_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IAttach_SaveChanges_Scodes[] =
- {
- S_OK
- };
- SCODE BASED_DEBUG IAddrBook_OpenEntry_Scodes[] =
- {
- STANDARD_OPENENTRY_SCODES,
- S_OK
- };
- SCODE BASED_DEBUG IAddrBook_CompareEntryIDs_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_CreateOneOff_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_ResolveName_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_Address_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_Details_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_RecipOptions_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_QueryDefaultRecipOpt_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IAddrBook_ButtonPress_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IABContainer_GetContentsTable_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IABContainer_GetHierarchyTable_Scodes[] = {S_OK};
- SCODE BASED_DEBUG INotifObj_ChangeEvMask_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPIStatus_ChangePassword_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPIStatus_FlushQueues_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPIStatus_SettingsDialog_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMAPIStatus_ValidateState_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPILogon_Scodes[] = {
- MAPI_E_LOGON_FAILED,
- S_OK};
- SCODE BASED_DEBUG SMAPI_MAPILogoff_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIFreeBuffer_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPISendMail_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPISendDocuments_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIFindNext_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIReadMail_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPISaveMail_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIDeleteMail_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIAddress_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIResolveName_Scodes[] = {S_OK};
- SCODE BASED_DEBUG SMAPI_MAPIDetails_Scodes[] = {S_OK};
- SCODE BASED_DEBUG IMSProvider_Logon_Scodes[] = {
- MAPI_E_UNCONFIGURED,
- MAPI_E_FAILONEPROVIDER,
- MAPI_E_STRING_TOO_LONG,
- MAPI_E_LOGON_FAILED,
- MAPI_E_CORRUPT_STORE,
- MAPI_E_USER_CANCEL,
- S_OK};
- SCODE BASED_DEBUG IMSProvider_Deinit_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSProvider_Shutdown_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSProvider_Init_Scodes[] = {
- MAPI_E_VERSION,
- S_OK};
- SCODE BASED_DEBUG IMSProvider_SpoolerLogon_Scodes[] = {
- MAPI_E_LOGON_FAILED,
- S_OK};
- SCODE BASED_DEBUG IMSLogon_OpenEntry_Scodes[] =
- {
- STANDARD_OPENENTRY_SCODES,
- S_OK
- };
- SCODE BASED_DEBUG IMSLogon_OpenStatusEntry_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSLogon_CompareEntryIDs_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSLogon_Advise_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSLogon_Unadvise_Scodes[] = {
- S_OK};
- SCODE BASED_DEBUG IMSLogon_Logoff_Scodes[] = {
- S_OK};
- #endif
- /* DBGMEM ------------------------------------------------------------------- */
- #undef INTERFACE
- #define INTERFACE struct _DBGMEM
- DECLARE_INTERFACE(DBGMEM_)
- {
- BEGIN_INTERFACE
- STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
- STDMETHOD_(ULONG,AddRef) (THIS) PURE;
- STDMETHOD_(ULONG,Release) (THIS) PURE;
- STDMETHOD_(void FAR*, Alloc) (THIS_ ULONG cb) PURE;
- STDMETHOD_(void FAR*, Realloc) (THIS_ void FAR* pv, ULONG cb) PURE;
- STDMETHOD_(void, Free) (THIS_ void FAR* pv) PURE;
- STDMETHOD_(ULONG, GetSize) (THIS_ void FAR* pv) PURE;
- STDMETHOD_(int, DidAlloc) (THIS_ void FAR* pv) PURE;
- STDMETHOD_(void, HeapMinimize) (THIS) PURE;
- };
- extern DBGMEM_Vtbl vtblDBGMEM;
- typedef struct _DBGMEM DBGMEM, FAR *PDBGMEM;
- typedef struct _BLK BLK, *PBLK;
- typedef struct _BLK UNALIGNED * PUABLK;
- typedef struct _BLKTAIL BLKTAIL, *PBLKTAIL;
- struct _DBGMEM {
- DBGMEM_Vtbl * lpVtbl;
- ULONG cRef;
- LPMALLOC pmalloc;
- char szSubsys[16];
- ULONG ulAllocNum;
- ULONG ulAllocAt;
- ULONG ulFailureAt;
- BOOL fCheckOften;
- BOOL fUnleakable;
- ULONG cbVirtual;
- BOOL fFillRandom;
- int cbExtra;
- int cbTail;
- PBLK pblkHead;
- #if defined(_WIN32) && defined(_X86_)
- CRITICAL_SECTION cs;
- #endif
- };
- #define NCALLERS 12
- struct _BLK {
- PDBGMEM pdbgmem; /* pointer to the allocator */
- PBLK pblkNext; /* next link in chain of allocated blocks */
- PBLK pblkPrev; /* prev link in chain of allocated blocks */
- ULONG ulAllocNum; /* internal allocation number */
- BOOL fUnleakable; /* TRUE if leak code should ignore block */
- #if defined(_WIN32) && defined(_X86_)
- FARPROC pfnCallers[NCALLERS];
- #endif
- PBLKTAIL pblktail; /* pointer to block tail */
- };
- struct _BLKTAIL {
- PBLK pblk; /* pointer back to beginning of the block */
- };
- #define PblkToPv(pblk) ((LPVOID)((PBLK)(pblk) + 1))
- #define PvToPblk(pblk) ((PBLK)(pv) - 1)
- #define PblkClientSize(pblk) ((ULONG)((char *)(pblk)->pblktail - (char *)PblkToPv(pblk)))
- #define PblkAllocSize(pblk) (PblkClientSize(pblk) + sizeof(BLK) + (pblk)->pdbgmem->cbTail)
- #if defined(_WIN32) && defined(_X86_)
- #define DBGMEM_EnterCriticalSection(pdbgmem)
- EnterCriticalSection(&(pdbgmem)->cs)
- #define DBGMEM_LeaveCriticalSection(pdbgmem)
- LeaveCriticalSection(&(pdbgmem)->cs)
- #else
- #define DBGMEM_EnterCriticalSection(pdbgmem)
- #define DBGMEM_LeaveCriticalSection(pdbgmem)
- #endif
- #define INITGUID
- #include <initguid.h>
- DEFINE_OLEGUID(DBGMEM_IID_IUnknown, 0x00000000L, 0, 0);
- DEFINE_OLEGUID(DBGMEM_IID_IMalloc, 0x00000002L, 0, 0);
- DEFINE_OLEGUID(DBGMEM_IID_IBaseMalloc, 0x000203FFL, 0, 0);
- /* Forward Declarations ----------------------------------------------------- */
- BOOL DBGMEM_ValidatePblk(PDBGMEM pdbgmem, PBLK pblk, char ** pszReason);
- BOOL DBGMEM_ValidatePv(PDBGMEM pdbgmem, void * pv, char * pszFunc);
- STDMETHODIMP_(void) DBGMEM_Free(PDBGMEM pdbgmem, void * pv);
- /* Call Stack (_WIN32) ------------------------------------------------------- */
- #if defined(_WIN32) && defined(_X86_)
- #ifdef _WIN95
- #define dwStackLimit 0x00400000 /* 4MB for Windows 95 */
- #else
- #define dwStackLimit 0x00010000 /* 64KB for NT */
- #endif
- void EXPORTDBG __cdecl GetCallStack(DWORD *pdwCaller, int cSkip, int cFind)
- {
- DWORD * pdwStack;
- DWORD * pdwStackPrev = (DWORD *)0;
- DWORD dwCaller;
- __asm mov pdwStack, ebp
- memset(pdwCaller, 0, cFind * sizeof(DWORD));
- while (cSkip + cFind > 0)
- {
- pdwStack = (DWORD *)*pdwStack;
- if ( pdwStack <= (DWORD *)dwStackLimit
- || pdwStackPrev >= pdwStack
- || IsBadReadPtr(pdwStack, 2 * sizeof(DWORD)))
- break;
- dwCaller = *(pdwStack + 1);
- if (dwCaller <= dwStackLimit)
- break;
- else if (cSkip > 0)
- cSkip -= 1;
- else
- {
- *pdwCaller++ = dwCaller;
- cFind -= 1;
- pdwStackPrev = pdwStack;
- }
- }
- }
- #endif
- /* Virtual Memory Support (_WIN32) ------------------------------------------- */
- #if defined(_WIN32) && (defined(_X86_) || defined(_PPC_) || defined(_MIPS_))
- #define PAGE_SIZE 4096
- #define PvToVMBase(pv) ((void *)((ULONG)pv & 0xFFFF0000))
- BOOL VMValidatePvEx(void *pv, ULONG cbCluster)
- {
- void * pvBase;
- BYTE * pb;
- pvBase = PvToVMBase(pv);
- pb = (BYTE *)pvBase + sizeof(ULONG);
- while (pb < (BYTE *)pv) {
- if (*pb++ != 0xAD) {
- TrapSz1("VMValidatePvEx(pv=%08lX): Block leader has been overwritten", pv);
- return(FALSE);
- }
- }
- if (cbCluster != 1)
- {
- ULONG cb = *((ULONG *)pvBase);
- ULONG cbPad = 0;
- if (cb % cbCluster)
- cbPad = (cbCluster - (cb % cbCluster));
- if (cbPad)
- {
- BYTE *pbMac;
- pb = (BYTE *)pv + cb;
- pbMac = pb + cbPad;
- while (pb < pbMac)
- {
- if (*pb++ != 0xBC)
- {
- TrapSz1("VMValidatePvEx(pv=%08lX): Block trailer has been "
- "overwritten", pv);
- return(FALSE);
- }
- }
- }
- }
- return(TRUE);
- }
- void * EXPORTDBG __cdecl VMAlloc(ULONG cb)
- {
- return VMAllocEx(cb, 1);
- }
- void * EXPORTDBG __cdecl VMAllocEx(ULONG cb, ULONG cbCluster)
- {
- ULONG cbAlloc;
- void * pvR;
- void * pvC;
- ULONG cbPad = 0;
- // a cluster size of 0 means don't use the virtual allocator.
- AssertSz(cbCluster != 0, "Cluster size is zero.");
- if (cb > 0x100000)
- return(0);
- if (cb % cbCluster)
- cbPad = (cbCluster - (cb % cbCluster));
- cbAlloc = sizeof(ULONG) + cb + cbPad + PAGE_SIZE - 1;
- cbAlloc -= cbAlloc % PAGE_SIZE;
- cbAlloc += PAGE_SIZE;
- pvR = VirtualAlloc(0, cbAlloc, MEM_RESERVE, PAGE_NOACCESS);
- if (pvR == 0)
- return(0);
- pvC = VirtualAlloc(pvR, cbAlloc - PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
- if (pvC != pvR)
- {
- VirtualFree(pvR, 0, MEM_RELEASE);
- return(0);
- }
- *(ULONG *)pvC = cb;
- memset((BYTE *)pvC + sizeof(ULONG), 0xAD,
- (UINT) cbAlloc - cb - cbPad - sizeof(ULONG) - PAGE_SIZE);
- if (cbPad)
- memset((BYTE *)pvC + cbAlloc - PAGE_SIZE - cbPad, 0xBC,
- (UINT) cbPad);
- return((BYTE *)pvC + (cbAlloc - cb - cbPad - PAGE_SIZE));
- }
- void EXPORTDBG __cdecl VMFree(void *pv)
- {
- VMFreeEx(pv, 1);
- }
- void EXPORTDBG __cdecl VMFreeEx(void *pv, ULONG cbCluster)
- {
- VMValidatePvEx(pv, cbCluster);
- if (!VirtualFree(PvToVMBase(pv), 0, MEM_RELEASE))
- TrapSz2("VMFreeEx(pv=%08lX): VirtualFree failed (%08lX)",
- pv, GetLastError());
- }
- void * EXPORTDBG __cdecl VMRealloc(void *pv, ULONG cb)
- {
- return VMReallocEx(pv, cb, 1);
- }
- void * EXPORTDBG __cdecl VMReallocEx(void *pv, ULONG cb, ULONG cbCluster)
- {
- void * pvNew = 0;
- ULONG cbCopy;
- VMValidatePvEx(pv, cbCluster);
- cbCopy = *(ULONG *)PvToVMBase(pv);
- if (cbCopy > cb)
- cbCopy = cb;
- pvNew = VMAllocEx(cb, cbCluster);
- if (pvNew)
- {
- MemCopy(pvNew, pv, cbCopy);
- VMFreeEx(pv, cbCluster);
- }
- return(pvNew);
- }
- ULONG EXPORTDBG __cdecl VMGetSize(void *pv)
- {
- return VMGetSizeEx(pv, 1);
- }
- ULONG EXPORTDBG __cdecl VMGetSizeEx(void *pv, ULONG cbCluster)
- {
- return(*(ULONG *)PvToVMBase(pv));
- }
- #endif
- /* Virtual Memory Support (WIN16) ------------------------------------------- */
- #ifdef WIN16
- #define PvToVMBase(pv) ((void *)((ULONG)pv & 0xFFFF0000))
- BOOL VMValidatePvEx(void *pv, ULONG cbCluster)
- {
- void * pvBase;
- BYTE * pb;
- pvBase = PvToVMBase(pv);
- pb = (BYTE *)pvBase + sizeof(ULONG);
- while (pb < (BYTE *)pv) {
- if (*pb++ != 0xAD) {
- TrapSz1("VMValidatePvEx(pv=%08lX): Block leader has been overwritten", pv);
- return(FALSE);
- }
- }
- if (cbCluster != 1)
- {
- ULONG cb = *((ULONG *)pvBase);
- ULONG cbPad = 0;
- if (cb % cbCluster)
- cbPad = (cbCluster - (cb % cbCluster));
- if (cbPad)
- {
- BYTE *pbMac;
- pb = (BYTE *)pv + cb;
- pbMac = pb + cbPad;
- while (pb < pbMac)
- {
- if (*pb++ != 0xBC)
- {
- TrapSz1("VMValidatePvEx(pv=%08lX): Block trailer has been "
- "overwritten", pv);
- return(FALSE);
- }
- }
- }
- }
- return(TRUE);
- }
- BOOL VMValidatePv(void *pv)
- {
- return VMValidatePvEx(pv, 1);
- }
- void * EXPORTDBG __cdecl VMAlloc(ULONG cb)
- {
- return VMAllocEx(cb, 1);
- }
- void * EXPORTDBG __cdecl VMAllocEx(ULONG cb, ULONG cbCluster)
- {
- HGLOBAL hGlobal;
- ULONG cbAlloc;
- ULONG cbAllocFromSys;
- void * pvAlloc;
- ULONG cbPad = 0;
- if (cb > 0x10000 - sizeof(ULONG))
- return(0);
- if (cb % cbCluster)
- cbPad = (cbCluster - (cb % cbCluster));
- cbAlloc = sizeof(ULONG) + cb + cbPad;
- if (cbAlloc > 0x10000)
- return(0);
- #ifdef SIMPLE_MAPI
- hGlobal = GlobalAlloc(GPTR | GMEM_SHARE, cbAlloc);
- #else
- hGlobal = GlobalAlloc(GPTR, cbAlloc);
- #endif
- if (hGlobal == 0)
- return(0);
- cbAllocFromSys = GlobalSize(hGlobal);
- Assert(cbAllocFromSys >= cbAlloc);
- cbAlloc = cbAllocFromSys;
- pvAlloc = GlobalLock(hGlobal);
- if (pvAlloc == 0) {
- GlobalFree(hGlobal);
- return(0);
- }
- Assert(((ULONG)pvAlloc & 0x0000FFFF) == 0);
- *(ULONG *)pvAlloc = cb;
- memset((BYTE *)pvAlloc + sizeof(ULONG), 0xAD,
- (size_t)(cbAlloc - cb - cbPad - sizeof(ULONG)));
- if (cbPad)
- memset((BYTE *)pvAlloc + cbAlloc - cbPad, 0xBC, (size_t) cbPad);
- return((BYTE *)pvAlloc + (cbAlloc - cb - cbPad));
- }
- void EXPORTDBG __cdecl VMFree(void *pv)
- {
- VMFreeEx(pv, 1);
- }
- void EXPORTDBG __cdecl VMFreeEx(void *pv, ULONG cbCluster)
- {
- if (VMValidatePvEx(pv, cbCluster))
- {
- HGLOBAL hGlobal;
- ULONG cb = *(ULONG *)PvToVMBase(pv);
- memset(pv, 0xFE, (size_t)cb);
- hGlobal = (HGLOBAL)((ULONG)pv >> 16);
- GlobalFree(hGlobal);
- }
- }
- void * EXPORTDBG __cdecl VMRealloc(void *pv, ULONG cb)
- {
- return VMReallocEx(pv, cb, 1);
- }
- void * EXPORTDBG __cdecl VMReallocEx(void *pv, ULONG cb, ULONG cbCluster)
- {
- void * pvNew = 0;
- ULONG cbCopy;
- if (VMValidatePvEx(pv, cbCluster)) {
- cbCopy = *(ULONG *)PvToVMBase(pv);
- if (cbCopy > cb)
- cbCopy = cb;
- pvNew = VMAllocEx(cb, cbCluster);
- if (pvNew) {
- MemCopy(pvNew, pv, (size_t)cbCopy);
- VMFreeEx(pv, cbCluster);
- }
- }
- return(pvNew);
- }
- ULONG EXPORTDBG __cdecl VMGetSize(void *pv)
- {
- return VMGetSizeEx(pv, 1);
- }
- ULONG EXPORTDBG __cdecl VMGetSizeEx(void *pv, ULONG ulCluster)
- {
- if (VMValidatePvEx(pv, ulCluster))
- return(*(ULONG *)PvToVMBase(pv));
- return(0);
- }
- #endif
- /* Virtual Memory Support (Others) ------------------------------------------ */
- /*
- * The VM Allocators do not currently work on:
- * ALPHA
- * MAC
- */
- #if defined(MAC) || defined(_ALPHA_)
- #define VMAlloc(cb) 0
- #define VMAllocEx(cb, ul) 0
- #define VMRealloc(pv, cb) 0
- #define VMReallocEx(pv, cb, ul) 0
- #define VMFree(pv)
- #define VMFreeEx(pv, ul)
- #define VMGetSize(pv) 0
- #define VMGetSizeEx(pv, ul) 0
- #endif
- /* PblkEnqueue / PblkDequeue ------------------------------------------------ */
- void PblkEnqueue(PBLK pblk)
- {
- pblk->pblkNext = pblk->pdbgmem->pblkHead;
- pblk->pblkPrev = 0;
- pblk->pdbgmem->pblkHead = pblk;
- if (pblk->pblkNext)
- pblk->pblkNext->pblkPrev = pblk;
- }
- void PblkDequeue(PBLK pblk)
- {
- if (pblk->pblkNext)
- pblk->pblkNext->pblkPrev = pblk->pblkPrev;
- if (pblk->pblkPrev)
- pblk->pblkPrev->pblkNext = pblk->pblkNext;
- else
- pblk->pdbgmem->pblkHead = pblk->pblkNext;
- }
- /* QueryInterface/AddRef/Release -------------------------------------------- */
- STDMETHODIMP DBGMEM_QueryInterface(PDBGMEM pdbgmem, REFIID riid, LPVOID FAR* ppvObj)
- {
- if (memcmp(riid, &DBGMEM_IID_IBaseMalloc, sizeof(IID)) == 0) {
- pdbgmem->pmalloc->lpVtbl->AddRef(pdbgmem->pmalloc);
- *ppvObj = pdbgmem->pmalloc;
- return(0);
- }
- if (memcmp(riid, &DBGMEM_IID_IMalloc, sizeof(IID)) == 0 ||
- memcmp(riid, &DBGMEM_IID_IUnknown, sizeof(IID)) == 0) {
- ++pdbgmem->cRef;
- *ppvObj = pdbgmem;
- return(0);
- }
- *ppvObj = NULL; /* OLE requires zeroing [out] parameter */
- return(ResultFromScode(E_NOINTERFACE));
- }
- STDMETHODIMP_(ULONG) DBGMEM_AddRef(PDBGMEM pdbgmem)
- {
- ULONG cRef;
- DBGMEM_EnterCriticalSection(pdbgmem);
- cRef = ++pdbgmem->cRef;
- DBGMEM_LeaveCriticalSection(pdbgmem);
- return(cRef);
- }
- STDMETHODIMP_(ULONG) DBGMEM_Release(PDBGMEM pdbgmem)
- {
- ULONG cRef;
- LPMALLOC pmalloc;
- DBGMEM_EnterCriticalSection(pdbgmem);
- cRef = --pdbgmem->cRef;
- DBGMEM_LeaveCriticalSection(pdbgmem);
- if (cRef == 0) {
- DBGMEM_CheckMemFn(pdbgmem, TRUE);
- pmalloc = pdbgmem->pmalloc;
- pdbgmem->lpVtbl = 0;
- #if defined(_WIN32) && defined(_X86_)
- DeleteCriticalSection(&pdbgmem->cs);
- #endif
- pmalloc->lpVtbl->Free(pmalloc, pdbgmem);
- pmalloc->lpVtbl->Release(pmalloc);
- }
- return(cRef);
- }
- /* IMalloc::Alloc ----------------------------------------------------------- */
- STDMETHODIMP_(void FAR *) DBGMEM_Alloc(PDBGMEM pdbgmem, ULONG cb)
- {
- PBLK pblk;
- ULONG cbAlloc;
- LPVOID pvAlloc = 0;
- BYTE bFill = 0xFA;
- DBGMEM_EnterCriticalSection(pdbgmem);
- if (pdbgmem->fCheckOften)
- DBGMEM_CheckMemFn(pdbgmem, FALSE);
- cbAlloc = sizeof(BLK) + cb + pdbgmem->cbTail;
- if (pdbgmem->ulFailureAt != 0)
- {
- if (pdbgmem->ulFailureAt != pdbgmem->ulAllocAt)
- ++pdbgmem->ulAllocAt;
- else
- cbAlloc = 0;
- }
- if (cbAlloc < cb)
- pblk = 0;
- else if (pdbgmem->cbVirtual)
- pblk = VMAllocEx(cbAlloc, pdbgmem->cbVirtual);
- else
- pblk = (PBLK)pdbgmem->pmalloc->lpVtbl->Alloc(pdbgmem->pmalloc, cbAlloc);
- if (pblk) {
- pblk->pdbgmem = pdbgmem;
- pblk->ulAllocNum = ++pdbgmem->ulAllocNum;
- pblk->fUnleakable = FALSE;
- pblk->pblktail = (PBLKTAIL)((char *)pblk + sizeof(BLK) + cb);
- if (!pdbgmem->cbVirtual)
- *((PUABLK UNALIGNED * )
- &((struct _BLKTAIL UNALIGNED *) pblk->pblktail)->pblk) = pblk;
- PblkEnqueue(pblk);
- #if defined(_WIN32) && defined(_X86_)
- GetCallStack((DWORD *)pblk->pfnCallers, 0, NCALLERS);
- #endif
- if (pdbgmem->fCheckOften)
- DBGMEM_CheckMemFn(pdbgmem, FALSE);
- pvAlloc = PblkToPv(pblk);
- if (pdbgmem->fFillRandom)
- bFill = (BYTE)pblk->ulAllocNum;
- memset(pvAlloc, bFill, (size_t)cb);
- if (pdbgmem->cbExtra)
- memset(pblk->pblktail + 1, 0xAE, pdbgmem->cbExtra * sizeof(ULONG));
- }
- DBGMEM_LeaveCriticalSection(pdbgmem);
- return(pvAlloc);
- }
- /* IMalloc::Realloc --------------------------------------------------------- */
- STDMETHODIMP_(void FAR *) DBGMEM_Realloc(PDBGMEM pdbgmem, void FAR* pv, ULONG cb)
- {
- ULONG cbAlloc;
- LPVOID pvAlloc = 0;
- BYTE bFill = 0xFA;
- DBGMEM_EnterCriticalSection(pdbgmem);
- if (pdbgmem->fCheckOften)
- DBGMEM_CheckMemFn(pdbgmem, FALSE);
- if (pv == 0) {
- TrapSz1("DBGMEM_Realloc(pv=NULL,cb=%ld): IMalloc::Realloc is being used allocate a new memory block. Explicit use of IMalloc::Alloc is preferred.", cb);
- pvAlloc = DBGMEM_Alloc(pdbgmem, cb);
- } else if (cb == 0) {
- TrapSz1("DBGMEM_Realloc(pv=%08lX,cb=0): IMalloc::Realloc is being used to free a memory block. Explicit use of IMalloc::Free is preferred.", pv);
- DBGMEM_Free(pdbgmem, pv);
- pvAlloc = 0;
- } else if (DBGMEM_ValidatePv(pdbgmem, pv, "DBGMEM_Realloc")) {
- PBLK pblk = PvToPblk(pv);
- ULONG cbOld = PblkClientSize(pblk);
- PBLK pblkNew;
- PblkDequeue(pblk);
- cbAlloc = sizeof(BLK) + cb + pdbgmem->cbTail;
- if (pdbgmem->ulFailureAt != 0)
- {
- if (pdbgmem->ulFailureAt != pdbgmem->ulAllocAt)
- ++pdbgmem->ulAllocAt;
- else
- cbAlloc = 0;
- }
- if (cbAlloc < cb)
- pblkNew = 0;
- else if (pdbgmem->cbVirtual)
- pblkNew = (PBLK)VMReallocEx(pblk, cbAlloc, pdbgmem->cbVirtual);
- else
- pblkNew = (PBLK)pdbgmem->pmalloc->lpVtbl->Realloc(pdbgmem->pmalloc, pblk, cbAlloc);
- if (pblkNew == 0) {
- PblkEnqueue(pblk);
- pvAlloc = 0;
- } else {
- pblkNew->pblktail = (PBLKTAIL)((char *)pblkNew + sizeof(BLK) + cb);
- if (!pdbgmem->cbVirtual)
- *((PUABLK UNALIGNED * )
- &((struct _BLKTAIL UNALIGNED *) pblkNew->pblktail)->pblk) = pblkNew;
- PblkEnqueue(pblkNew);
- pvAlloc = PblkToPv(pblkNew);
- if (pdbgmem->fFillRandom)
- bFill = (BYTE)pblkNew->ulAllocNum;
- if (cb > cbOld)
- memset((char *)pvAlloc + cbOld, bFill, (size_t)(cb - cbOld));
- if (pdbgmem->cbExtra)
- memset(pblkNew->pblktail + 1, 0xAE, pdbgmem->cbExtra * sizeof(ULONG));
- }
- }
- DBGMEM_LeaveCriticalSection(pdbgmem);
- return(pvAlloc);
- }
- /* IMalloc::Free ------------------------------------------------------------ */
- STDMETHODIMP_(void) DBGMEM_Free(PDBGMEM pdbgmem, void FAR * pv)
- {
- DBGMEM_EnterCriticalSection(pdbgmem);
- if (pdbgmem->fCheckOften)
- DBGMEM_CheckMemFn(pdbgmem, FALSE);
- if (pv && DBGMEM_ValidatePv(pdbgmem, pv, "DBGMEM_Free")) {
- PBLK pblk = PvToPblk(pv);
- PblkDequeue(pblk);
- memset(pblk, 0xDC, (size_t)PblkAllocSize(pblk));
- if (pdbgmem->cbVirtual)
- VMFreeEx(pblk, pdbgmem->cbVirtual);
- else
- pdbgmem->pmalloc->lpVtbl->Free(pdbgmem->pmalloc, pblk);
- }
- DBGMEM_LeaveCriticalSection(pdbgmem);
- }
- /* IMalloc::GetSize --------------------------------------------------------- */
- STDMETHODIMP_(ULONG) DBGMEM_GetSize(PDBGMEM pdbgmem, void FAR * pv)
- {
- ULONG ulResult = (ULONG)(-1);
- DBGMEM_EnterCriticalSection(pdbgmem);
- if (pv == 0)
- TrapSz("Although technically not an error, I bet you didn't really want to pass a NULL pointer to IMalloc::GetSize, did you? I hope you can deal with a size of -1, because that's the offical answer. Good luck.");
- else if (DBGMEM_ValidatePv(pdbgmem, pv, "DBGMEM_GetSize"))
- ulResult = PblkClientSize(PvToPblk(pv));
- DBGMEM_LeaveCriticalSection(pdbgmem);
- return(ulResult);
- }
- /* IMalloc::DidAlloc -------------------------------------------------------- */
- STDMETHODIMP_(int) DBGMEM_DidAlloc(PDBGMEM pdbgmem, void FAR * pv)
- {
- PBLK pblk;
- char * pszReason;
- int iResult = 0;
- DBGMEM_EnterCriticalSection(pdbgmem);
- for (pblk = pdbgmem->pblkHead; pblk; pblk = pblk->pblkNext)
- {
- AssertSz2(DBGMEM_ValidatePblk(pdbgmem,pblk,&pszReason)==TRUE,
- "Block header (pblk=%08lX) is invalidn%s",
- pblk, pszReason);
- if (PblkToPv(pblk) == pv) {
- iResult = 1;
- break;
- }
- }
- DBGMEM_LeaveCriticalSection(pdbgmem);
- return(iResult);
- }
- /* IMalloc::HeapMinimize ---------------------------------------------------- */
- STDMETHODIMP_(void) DBGMEM_HeapMinimize(PDBGMEM pdbgmem)
- {
- pdbgmem->pmalloc->lpVtbl->HeapMinimize(pdbgmem->pmalloc);
- }
- /* DBGMEM_ValidatePblk ------------------------------------------------------ */
- BOOL DBGMEM_ValidatePblk(PDBGMEM pdbgmem, PBLK pblk, char ** pszReason)
- {
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (IsBadWritePtr(pblk, sizeof(BLK))) {
- *pszReason = "Block header cannot be written to";
- goto err;
- }
- #endif
- if (pblk->pdbgmem != pdbgmem) {
- *pszReason = "Block header does not have correct pointer back to allocator";
- goto err;
- }
- if (pblk->pblkNext) {
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (IsBadWritePtr(pblk->pblkNext, sizeof(BLK))) {
- *pszReason = "Block header has invalid next link pointer";
- goto err;
- }
- #endif
- if (pblk->pblkNext->pblkPrev != pblk) {
- *pszReason = "Block header points to a next block which doesn't point back to it";
- goto err;
- }
- }
- if (pblk->pblkPrev) {
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (IsBadWritePtr(pblk->pblkPrev, sizeof(BLK))) {
- *pszReason = "Block header has invalid prev link pointer";
- goto err;
- }
- #endif
- if (pblk->pblkPrev->pblkNext != pblk) {
- *pszReason = "Block header points to a prev block which doesn't point back to it";
- goto err;
- }
- } else if (pdbgmem->pblkHead != pblk) {
- *pszReason = "Block header has a zero prev link but the allocator doesn't believe it is the first block";
- goto err;
- }
- if (pblk->ulAllocNum > pdbgmem->ulAllocNum) {
- *pszReason = "Block header has an invalid internal allocation number";
- goto err;
- }
- if (!pdbgmem->cbVirtual) {
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (IsBadWritePtr(pblk->pblktail, pdbgmem->cbTail)) {
- *pszReason = "Block header has invalid pblktail pointer";
- goto err;
- }
- #endif
- if (*((PUABLK UNALIGNED * )
- &((struct _BLKTAIL UNALIGNED *) pblk->pblktail)->pblk) != pblk) {
- *pszReason = "Block trailer does not point back to the block header";
- goto err;
- }
- }
- if (pdbgmem->cbExtra) {
- ULONG UNALIGNED * pul = (ULONG UNALIGNED *)(pblk->pblktail + 1);
- int n = pdbgmem->cbExtra;
- for (; --n >= 0; ++pul)
- if (*pul != 0xAEAEAEAE) {
- *pszReason = "Block trailer spiddle-zone has been overwritten";
- goto err;
- }
- }
- return(TRUE);
- err:
- return(FALSE);
- }
- /* DBGMEM_ValidatePv -------------------------------------------------------- */
- BOOL DBGMEM_ValidatePv(PDBGMEM pdbgmem, void * pv, char * pszFunc)
- {
- char * pszReason;
- if (DBGMEM_DidAlloc(pdbgmem, pv) == 0) {
- TrapSz3("DBGMEM_ValidatePv(subsys=%s,pv=%08lX) [via %s]nDetected a memory block which was not allocated by this allocator",
- pdbgmem->szSubsys, pv, pszFunc);
- return(FALSE);
- }
- if (DBGMEM_ValidatePblk(pdbgmem,PvToPblk(pv),&pszReason))
- return(TRUE);
- TrapSz4("DBGMEM_ValidatePv(%s,pv=%08lX) [via %s]n%s",
- pdbgmem->szSubsys, pv, pszFunc, pszReason);
- return(FALSE);
- }
- /* DBGMEM_ReportLeak -------------------------------------------------------- */
- #if defined(_WIN32) && defined(_X86_)
- void EXPORTDBG __cdecl DBGMEM_LeakHook(FARPROC pfn)
- {
- /* Dummy function so that you can set a breakpoint with command */
- /* "ln ecx;g", in order to get the debugger to print out the name */
- /* of the function which allocated the leaked memory block */
- }
- #endif
- void DBGMEM_ReportLeak(PDBGMEM pdbgmem, PBLK pblk)
- {
- int i = 0;
- DebugTrace("%s Memory Leak: @%08lX, allocation #%ld, size %ldn",
- pdbgmem->szSubsys, PblkToPv(pblk), pblk->ulAllocNum, PblkClientSize(pblk));
- #if defined(_WIN32) && defined(_X86_)
- for (i = 0; i < NCALLERS && pblk->pfnCallers[i] != 0; i++) {
- DebugTrace("[%d] %08lX ", i, pblk->pfnCallers[i]);
- DBGMEM_LeakHook(pblk->pfnCallers[i]);
- }
- DebugTrace("n");
- #endif
- }
- /* DBGMEM_NoLeakDetectFn ---------------------------------------------------- */
- void EXPORTDBG __cdecl DBGMEM_NoLeakDetectFn(void * pmalloc, void *pv)
- {
- PDBGMEM pdbgmem = (PDBGMEM)pmalloc;
- DBGMEM_EnterCriticalSection(pdbgmem);
- if (pv == 0)
- pdbgmem->fUnleakable = TRUE;
- else if (DBGMEM_ValidatePv(pdbgmem, pv, "DBGMEM_NoLeakDetectFn"))
- PvToPblk(pv)->fUnleakable = TRUE;
- DBGMEM_LeaveCriticalSection(pdbgmem);
- }
- /* DBGMEM_SetFailureAtFn ---------------------------------------------------- */
- void EXPORTDBG __cdecl DBGMEM_SetFailureAtFn(void * pmalloc, ULONG ulFailureAt)
- {
- PDBGMEM pdbgmem = (PDBGMEM)pmalloc;
- DBGMEM_EnterCriticalSection(pdbgmem);
- pdbgmem->ulFailureAt = ulFailureAt;
- DBGMEM_LeaveCriticalSection(pdbgmem);
- }
- /* DBGMEM_CheckMemFn -------------------------------------------------------- */
- void EXPORTDBG __cdecl DBGMEM_CheckMemFn(void * pmalloc, BOOL fReportOrphans)
- {
- PDBGMEM pdbgmem = (PDBGMEM)pmalloc;
- PBLK pblk;
- int cLeaks = 0;
- DBGMEM_EnterCriticalSection(pdbgmem);
- for (pblk = pdbgmem->pblkHead; pblk; pblk = pblk->pblkNext) {
- if (!DBGMEM_ValidatePv(pdbgmem, PblkToPv(pblk), "DBGMEM_CheckMemFn"))
- break;
- if (fReportOrphans && !pdbgmem->fUnleakable && !pblk->fUnleakable) {
- DBGMEM_ReportLeak(pdbgmem, pblk);
- cLeaks += 1;
- }
- }
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (fAssertLeaks == -1)
- {
- fAssertLeaks = GetPrivateProfileIntA(szSectionDebug, szKeyAssertLeaks,
- 0, szDebugIni);
- }
- #endif
- if (cLeaks > 0)
- {
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- if (fAssertLeaks)
- {
- TrapSz3("DBGMEM detected %d memory leak%s in subsystem %s",
- cLeaks, cLeaks == 1 ? "" : "s", pdbgmem->szSubsys);
- }
- else
- {
- TraceSz3("DBGMEM detected %d memory leak%s in subsystem %s",
- cLeaks, cLeaks == 1 ? "" : "s", pdbgmem->szSubsys);
- }
- #else
- TraceSz3("DBGMEM detected %d memory leak%s in subsystem %s",
- cLeaks, cLeaks == 1 ? "" : "s", pdbgmem->szSubsys);
- #endif
- }
- DBGMEM_LeaveCriticalSection(pdbgmem);
- }
- /* vtblDBGMEM --------------------------------------------------------------- */
- DBGMEM_Vtbl BASED_DEBUG vtblDBGMEM =
- {
- VTABLE_FILL
- DBGMEM_QueryInterface,
- DBGMEM_AddRef,
- DBGMEM_Release,
- DBGMEM_Alloc,
- DBGMEM_Realloc,
- DBGMEM_Free,
- DBGMEM_GetSize,
- DBGMEM_DidAlloc,
- DBGMEM_HeapMinimize
- };
- /* DBGMEM_EncapsulateFn ----------------------------------------------------- */
- void * EXPORTDBG __cdecl DBGMEM_EncapsulateFn(void * pvmalloc, char *pszSubsys, BOOL fCheckOften)
- {
- LPMALLOC pmalloc = (LPMALLOC)pvmalloc;
- PDBGMEM pdbgmem;
- LPMALLOC pmallocBase;
- ULONG cbVirtual = 0;
- BOOL fFillRandom = FALSE;
- HRESULT hr;
- hr = pmalloc->lpVtbl->QueryInterface(pmalloc, &DBGMEM_IID_IBaseMalloc, &pmallocBase);
- if (hr) {
- pmallocBase = pmalloc;
- pmallocBase->lpVtbl->AddRef(pmallocBase);
- }
- pdbgmem = (PDBGMEM)pmallocBase->lpVtbl->Alloc(pmallocBase, sizeof(DBGMEM));
- if (pdbgmem == 0) {
- TrapSz("DBGMEM: Failed trying to allocate memory for the first time!n");
- return(pmallocBase);
- }
- #if defined(WIN16) || (defined(_WIN32) && defined(_X86_))
- cbVirtual = GetPrivateProfileIntA(szSectionDebug, szKeyUseVirtual, 0,
- szDebugIni);
- if (cbVirtual != 0 && cbVirtual != 1 && cbVirtual != 4)
- cbVirtual = 1;
- if (cbVirtual)
- DebugTrace("DBGMEM: Subsystem '%s' using virtual memory allocator -"
- " align %d.n", pszSubsys, cbVirtual);
- if (!fCheckOften)
- fCheckOften = GetPrivateProfileIntA(szSectionDebug, szKeyCheckOften, 0,
- szDebugIni);
- fFillRandom = GetPrivateProfileIntA(szSectionDebug, szKeyFillRandom, 0,
- szDebugIni);
- #endif
- memset(pdbgmem, 0, sizeof(DBGMEM));
- pdbgmem->lpVtbl = &vtblDBGMEM;
- pdbgmem->cRef = 1;
- pdbgmem->pmalloc = pmallocBase;
- pdbgmem->fCheckOften = fCheckOften;
- pdbgmem->fUnleakable = FALSE;
- pdbgmem->cbVirtual = cbVirtual;
- pdbgmem->fFillRandom = fFillRandom;
- pdbgmem->cbExtra = 0;
- pdbgmem->ulAllocAt = 1L;
- pdbgmem->ulFailureAt = 0L;
- if (pdbgmem->cbVirtual)
- pdbgmem->cbTail = 0;
- else
- pdbgmem->cbTail = sizeof(BLKTAIL) + pdbgmem->cbExtra * sizeof(ULONG);
- lstrcpyn(pdbgmem->szSubsys, pszSubsys, sizeof(pdbgmem->szSubsys));
- #if defined(_WIN32) && defined(_X86_)
- InitializeCriticalSection(&pdbgmem->cs);
- #endif
- return(pdbgmem);
- }
- /* DBGMEM_ShutdownFn -------------------------------------------------------- */
- void EXPORTDBG __cdecl DBGMEM_ShutdownFn(void *pvmalloc)
- {
- LPMALLOC pmalloc = (LPMALLOC)pvmalloc;
- PDBGMEM pdbgmem = (PDBGMEM)pvmalloc;
- LPMALLOC pmallocBase;
- HRESULT hr;
- hr = pmalloc->lpVtbl->QueryInterface(pmalloc, &DBGMEM_IID_IBaseMalloc, &pmallocBase);
- if (hr == 0) {
- pmallocBase->lpVtbl->Release(pmallocBase);
- if (pdbgmem->cRef != 1) {
- TrapSz2("DBGMEM_Shutdown: Expected a cRef of 1; instead have %ld for %s",
- pdbgmem->cRef, pdbgmem->szSubsys);
- pdbgmem->cRef = 1;
- }
- }
- pmalloc->lpVtbl->Release(pmalloc);
- }
- /* -------------------------------------------------------------------------- */
- #endif