445 lines
13 KiB
C++
445 lines
13 KiB
C++
//+---------------------------------------------------------------------
|
|
//
|
|
// File: misc.cxx
|
|
//
|
|
// Contents: Useful OLE helper and debugging functions
|
|
//
|
|
//----------------------------------------------------------------------
|
|
|
|
extern "C" {
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <basetyps.h>
|
|
|
|
#include "dswarn.h"
|
|
#include "oledsdbg.h"
|
|
}
|
|
|
|
#if (defined(BUILD_FOR_NT40))
|
|
typedef unsigned long HRESULT;
|
|
#endif
|
|
|
|
|
|
|
|
static HRESULT ADsDebugOutHRESULT(DWORD dwFlags, HRESULT r);
|
|
|
|
#if DBG == 1
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: PrintHRESULT
|
|
//
|
|
// Synopsis: Outputs the name of the SCODE and a carriage return
|
|
// to the debugging device.
|
|
//
|
|
// Arguments: [dwFlags] -- Flags to ADsDebugOut.
|
|
// [scode] -- The status code to report.
|
|
//
|
|
// Notes: This function disappears in retail builds.
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDAPI
|
|
PrintHRESULT(DWORD dwFlags, HRESULT hr)
|
|
{
|
|
ADsDebugOut((dwFlags | DEB_NOCOMPNAME, " "));
|
|
ADsDebugOutHRESULT(dwFlags | DEB_NOCOMPNAME, hr);
|
|
ADsDebugOut((dwFlags | DEB_NOCOMPNAME, "\n"));
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: ADsDebugOutHRESULT
|
|
//
|
|
// Synopsis: Outputs the name of the SCODE to the debugging device.
|
|
//
|
|
// Arguments: [dwFlags] -- Flags to ADsDebugOut.
|
|
// [scode] -- The status code to report.
|
|
//
|
|
// Notes: This function disappears in retail builds.
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
static HRESULT
|
|
ADsDebugOutHRESULT(DWORD dwFlags, HRESULT r)
|
|
{
|
|
LPWSTR lpstr;
|
|
|
|
#define CASE_SCODE(sc) \
|
|
case sc: lpstr = (LPWSTR)L#sc; break;
|
|
|
|
switch (r) {
|
|
/* SCODE's defined in SCODE.H */
|
|
CASE_SCODE(S_OK)
|
|
CASE_SCODE(S_FALSE)
|
|
CASE_SCODE(OLE_S_USEREG)
|
|
CASE_SCODE(OLE_S_STATIC)
|
|
CASE_SCODE(OLE_S_MAC_CLIPFORMAT)
|
|
CASE_SCODE(DRAGDROP_S_DROP)
|
|
CASE_SCODE(DRAGDROP_S_USEDEFAULTCURSORS)
|
|
CASE_SCODE(DRAGDROP_S_CANCEL)
|
|
CASE_SCODE(DATA_S_SAMEFORMATETC)
|
|
CASE_SCODE(VIEW_S_ALREADY_FROZEN)
|
|
CASE_SCODE(CACHE_S_FORMATETC_NOTSUPPORTED)
|
|
CASE_SCODE(CACHE_S_SAMECACHE)
|
|
CASE_SCODE(CACHE_S_SOMECACHES_NOTUPDATED)
|
|
CASE_SCODE(OLEOBJ_S_INVALIDVERB)
|
|
CASE_SCODE(OLEOBJ_S_CANNOT_DOVERB_NOW)
|
|
CASE_SCODE(OLEOBJ_S_INVALIDHWND)
|
|
CASE_SCODE(INPLACE_S_TRUNCATED)
|
|
CASE_SCODE(CONVERT10_S_NO_PRESENTATION)
|
|
CASE_SCODE(MK_S_REDUCED_TO_SELF)
|
|
CASE_SCODE(MK_S_ME)
|
|
CASE_SCODE(MK_S_HIM)
|
|
CASE_SCODE(MK_S_US)
|
|
CASE_SCODE(MK_S_MONIKERALREADYREGISTERED)
|
|
CASE_SCODE(STG_S_CONVERTED)
|
|
|
|
CASE_SCODE(E_UNEXPECTED)
|
|
CASE_SCODE(E_NOTIMPL)
|
|
CASE_SCODE(E_OUTOFMEMORY)
|
|
CASE_SCODE(E_INVALIDARG)
|
|
CASE_SCODE(E_NOINTERFACE)
|
|
CASE_SCODE(E_POINTER)
|
|
CASE_SCODE(E_HANDLE)
|
|
CASE_SCODE(E_ABORT)
|
|
CASE_SCODE(E_FAIL)
|
|
CASE_SCODE(E_ACCESSDENIED)
|
|
|
|
/* SCODE's defined in DVOBJ.H */
|
|
// CASE_SCODE(DATA_E_FORMATETC)
|
|
// same as DATA_E_FORMATETC CASE_SCODE(DV_E_FORMATETC)
|
|
CASE_SCODE(VIEW_E_DRAW)
|
|
// same as VIEW_E_DRAW CASE_SCODE(E_DRAW)
|
|
CASE_SCODE(CACHE_E_NOCACHE_UPDATED)
|
|
|
|
/* SCODE's defined in OLE2.H */
|
|
CASE_SCODE(OLE_E_OLEVERB)
|
|
CASE_SCODE(OLE_E_ADVF)
|
|
CASE_SCODE(OLE_E_ENUM_NOMORE)
|
|
CASE_SCODE(OLE_E_ADVISENOTSUPPORTED)
|
|
CASE_SCODE(OLE_E_NOCONNECTION)
|
|
CASE_SCODE(OLE_E_NOTRUNNING)
|
|
CASE_SCODE(OLE_E_NOCACHE)
|
|
CASE_SCODE(OLE_E_BLANK)
|
|
CASE_SCODE(OLE_E_CLASSDIFF)
|
|
CASE_SCODE(OLE_E_CANT_GETMONIKER)
|
|
CASE_SCODE(OLE_E_CANT_BINDTOSOURCE)
|
|
CASE_SCODE(OLE_E_STATIC)
|
|
CASE_SCODE(OLE_E_PROMPTSAVECANCELLED)
|
|
CASE_SCODE(OLE_E_INVALIDRECT)
|
|
CASE_SCODE(OLE_E_WRONGCOMPOBJ)
|
|
CASE_SCODE(OLE_E_INVALIDHWND)
|
|
CASE_SCODE(DV_E_DVTARGETDEVICE)
|
|
CASE_SCODE(DV_E_STGMEDIUM)
|
|
CASE_SCODE(DV_E_STATDATA)
|
|
CASE_SCODE(DV_E_LINDEX)
|
|
CASE_SCODE(DV_E_TYMED)
|
|
CASE_SCODE(DV_E_CLIPFORMAT)
|
|
CASE_SCODE(DV_E_DVASPECT)
|
|
CASE_SCODE(DV_E_DVTARGETDEVICE_SIZE)
|
|
CASE_SCODE(DV_E_NOIVIEWOBJECT)
|
|
CASE_SCODE(CONVERT10_E_OLESTREAM_GET)
|
|
CASE_SCODE(CONVERT10_E_OLESTREAM_PUT)
|
|
CASE_SCODE(CONVERT10_E_OLESTREAM_FMT)
|
|
CASE_SCODE(CONVERT10_E_OLESTREAM_BITMAP_TO_DIB)
|
|
CASE_SCODE(CONVERT10_E_STG_FMT)
|
|
CASE_SCODE(CONVERT10_E_STG_NO_STD_STREAM)
|
|
CASE_SCODE(CONVERT10_E_STG_DIB_TO_BITMAP)
|
|
CASE_SCODE(CLIPBRD_E_CANT_OPEN)
|
|
CASE_SCODE(CLIPBRD_E_CANT_EMPTY)
|
|
CASE_SCODE(CLIPBRD_E_CANT_SET)
|
|
CASE_SCODE(CLIPBRD_E_BAD_DATA)
|
|
CASE_SCODE(CLIPBRD_E_CANT_CLOSE)
|
|
CASE_SCODE(DRAGDROP_E_NOTREGISTERED)
|
|
CASE_SCODE(DRAGDROP_E_ALREADYREGISTERED)
|
|
CASE_SCODE(DRAGDROP_E_INVALIDHWND)
|
|
CASE_SCODE(OLEOBJ_E_NOVERBS)
|
|
CASE_SCODE(INPLACE_E_NOTUNDOABLE)
|
|
CASE_SCODE(INPLACE_E_NOTOOLSPACE)
|
|
|
|
/* SCODE's defined in STORAGE.H */
|
|
CASE_SCODE(STG_E_INVALIDFUNCTION)
|
|
CASE_SCODE(STG_E_FILENOTFOUND)
|
|
CASE_SCODE(STG_E_PATHNOTFOUND)
|
|
CASE_SCODE(STG_E_TOOMANYOPENFILES)
|
|
CASE_SCODE(STG_E_ACCESSDENIED)
|
|
CASE_SCODE(STG_E_INVALIDHANDLE)
|
|
CASE_SCODE(STG_E_INSUFFICIENTMEMORY)
|
|
CASE_SCODE(STG_E_INVALIDPOINTER)
|
|
CASE_SCODE(STG_E_NOMOREFILES)
|
|
CASE_SCODE(STG_E_DISKISWRITEPROTECTED)
|
|
CASE_SCODE(STG_E_SEEKERROR)
|
|
CASE_SCODE(STG_E_WRITEFAULT)
|
|
CASE_SCODE(STG_E_READFAULT)
|
|
CASE_SCODE(STG_E_LOCKVIOLATION)
|
|
CASE_SCODE(STG_E_FILEALREADYEXISTS)
|
|
CASE_SCODE(STG_E_INVALIDPARAMETER)
|
|
CASE_SCODE(STG_E_MEDIUMFULL)
|
|
CASE_SCODE(STG_E_ABNORMALAPIEXIT)
|
|
CASE_SCODE(STG_E_INVALIDHEADER)
|
|
CASE_SCODE(STG_E_INVALIDNAME)
|
|
CASE_SCODE(STG_E_UNKNOWN)
|
|
CASE_SCODE(STG_E_UNIMPLEMENTEDFUNCTION)
|
|
CASE_SCODE(STG_E_INVALIDFLAG)
|
|
CASE_SCODE(STG_E_INUSE)
|
|
CASE_SCODE(STG_E_NOTCURRENT)
|
|
CASE_SCODE(STG_E_REVERTED)
|
|
CASE_SCODE(STG_E_CANTSAVE)
|
|
CASE_SCODE(STG_E_OLDFORMAT)
|
|
CASE_SCODE(STG_E_OLDDLL)
|
|
CASE_SCODE(STG_E_SHAREREQUIRED)
|
|
|
|
/* SCODE's defined in COMPOBJ.H */
|
|
CASE_SCODE(CO_E_NOTINITIALIZED)
|
|
CASE_SCODE(CO_E_ALREADYINITIALIZED)
|
|
CASE_SCODE(CO_E_CANTDETERMINECLASS)
|
|
CASE_SCODE(CO_E_CLASSSTRING)
|
|
CASE_SCODE(CO_E_IIDSTRING)
|
|
CASE_SCODE(CO_E_APPNOTFOUND)
|
|
CASE_SCODE(CO_E_APPSINGLEUSE)
|
|
CASE_SCODE(CO_E_ERRORINAPP)
|
|
CASE_SCODE(CO_E_DLLNOTFOUND)
|
|
CASE_SCODE(CO_E_ERRORINDLL)
|
|
CASE_SCODE(CO_E_WRONGOSFORAPP)
|
|
CASE_SCODE(CO_E_OBJNOTREG)
|
|
CASE_SCODE(CO_E_OBJISREG)
|
|
CASE_SCODE(CO_E_OBJNOTCONNECTED)
|
|
CASE_SCODE(CO_E_APPDIDNTREG)
|
|
CASE_SCODE(CLASS_E_NOAGGREGATION)
|
|
CASE_SCODE(REGDB_E_READREGDB)
|
|
CASE_SCODE(REGDB_E_WRITEREGDB)
|
|
CASE_SCODE(REGDB_E_KEYMISSING)
|
|
CASE_SCODE(REGDB_E_INVALIDVALUE)
|
|
CASE_SCODE(REGDB_E_CLASSNOTREG)
|
|
CASE_SCODE(REGDB_E_IIDNOTREG)
|
|
CASE_SCODE(RPC_E_CALL_REJECTED)
|
|
CASE_SCODE(RPC_E_CALL_CANCELED)
|
|
CASE_SCODE(RPC_E_CANTPOST_INSENDCALL)
|
|
CASE_SCODE(RPC_E_CANTCALLOUT_INASYNCCALL)
|
|
CASE_SCODE(RPC_E_CANTCALLOUT_INEXTERNALCALL)
|
|
CASE_SCODE(RPC_E_CONNECTION_TERMINATED)
|
|
#if defined(NO_NTOLEBUGS)
|
|
CASE_SCODE(RPC_E_SERVER_DIED)
|
|
#endif // NO_NTOLEBUGS
|
|
CASE_SCODE(RPC_E_CLIENT_DIED)
|
|
CASE_SCODE(RPC_E_INVALID_DATAPACKET)
|
|
CASE_SCODE(RPC_E_CANTTRANSMIT_CALL)
|
|
CASE_SCODE(RPC_E_CLIENT_CANTMARSHAL_DATA)
|
|
CASE_SCODE(RPC_E_CLIENT_CANTUNMARSHAL_DATA)
|
|
CASE_SCODE(RPC_E_SERVER_CANTMARSHAL_DATA)
|
|
CASE_SCODE(RPC_E_SERVER_CANTUNMARSHAL_DATA)
|
|
CASE_SCODE(RPC_E_INVALID_DATA)
|
|
CASE_SCODE(RPC_E_INVALID_PARAMETER)
|
|
CASE_SCODE(RPC_E_UNEXPECTED)
|
|
|
|
/* SCODE's defined in MONIKER.H */
|
|
CASE_SCODE(MK_E_CONNECTMANUALLY)
|
|
CASE_SCODE(MK_E_EXCEEDEDDEADLINE)
|
|
CASE_SCODE(MK_E_NEEDGENERIC)
|
|
CASE_SCODE(MK_E_UNAVAILABLE)
|
|
CASE_SCODE(MK_E_SYNTAX)
|
|
CASE_SCODE(MK_E_NOOBJECT)
|
|
CASE_SCODE(MK_E_INVALIDEXTENSION)
|
|
CASE_SCODE(MK_E_INTERMEDIATEINTERFACENOTSUPPORTED)
|
|
CASE_SCODE(MK_E_NOTBINDABLE)
|
|
CASE_SCODE(MK_E_NOTBOUND)
|
|
CASE_SCODE(MK_E_CANTOPENFILE)
|
|
CASE_SCODE(MK_E_MUSTBOTHERUSER)
|
|
CASE_SCODE(MK_E_NOINVERSE)
|
|
CASE_SCODE(MK_E_NOSTORAGE)
|
|
#if defined(NO_NTOLEBUGS)
|
|
CASE_SCODE(MK_S_MONIKERALREADYREGISTERED)
|
|
#endif //NO_NTOLEBUGS
|
|
|
|
|
|
// Dispatch error codes
|
|
CASE_SCODE(DISP_E_MEMBERNOTFOUND)
|
|
|
|
default:
|
|
ADsDebugOut((dwFlags, "<UNKNOWN SCODE 0x%lx>", r));
|
|
return r;
|
|
}
|
|
|
|
#undef CASE_SCODE
|
|
|
|
ADsDebugOut((dwFlags, "<%ws (0x%lx)>", lpstr, r));
|
|
return r;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: BreakOnFailed
|
|
//
|
|
// Synopsis: Function called when CheckAndReturnResult or CheckResult
|
|
// examines a failure code. Set a breakpoint on this function
|
|
// to break on failures.
|
|
//
|
|
// History: 5-18-94 adams Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
static void
|
|
BreakOnFailed(void)
|
|
{
|
|
int x;
|
|
x = 1;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: CheckAndReturnResult
|
|
//
|
|
// Synopsis: Issues a warning if the HRESULT indicates failure,
|
|
// and asserts if the HRESULT is not a permitted success code.
|
|
//
|
|
// Arguments: [hr] -- the HRESULT to be checked.
|
|
// [lpstrFile] -- the file where the HRESULT is being checked.
|
|
// [line] -- the line in the file where the HRESULT is
|
|
// being checked.
|
|
// [cSuccess] -- the number of permitted non-zero success codes.
|
|
// [...] -- list of success codes.
|
|
//
|
|
// Returns: The return value is exactly the HRESULT passed in.
|
|
//
|
|
// History: 1-06-94 adams Created.
|
|
// 5-24-94 adams Added call to BreakOnFailed.
|
|
//
|
|
// Notes: This function should not be used directly. Use
|
|
// the SRETURN and RRETURN macros instead.
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDAPI
|
|
CheckAndReturnResult(
|
|
HRESULT hr,
|
|
LPSTR lpstrFile,
|
|
UINT line,
|
|
int cSuccess,
|
|
...)
|
|
{
|
|
BOOL fOKReturnCode;
|
|
va_list va;
|
|
int i;
|
|
HRESULT hrSuccess;
|
|
|
|
//
|
|
// Check if code is an error or permitted success.
|
|
//
|
|
|
|
fOKReturnCode = (FAILED(hr) || hr == S_OK || hr == S_FALSE ||
|
|
cSuccess == -1);
|
|
if (!fOKReturnCode && cSuccess > 0)
|
|
{
|
|
va_start(va, cSuccess);
|
|
for (i = 0; i < cSuccess; i++)
|
|
{
|
|
hrSuccess = va_arg(va, HRESULT);
|
|
ADsAssert(SUCCEEDED(hrSuccess));
|
|
if (hr == hrSuccess)
|
|
{
|
|
fOKReturnCode = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
va_end(va);
|
|
}
|
|
|
|
//
|
|
// Assert on non-permitted success code.
|
|
//
|
|
|
|
if (!fOKReturnCode)
|
|
{
|
|
/* ADsDebugOut((
|
|
DEB_ERROR,
|
|
"ERROR: %s:%d returned bad success code",
|
|
lpstrFile,
|
|
line)); */
|
|
|
|
// (void) PrintHRESULT(DEB_ERROR | DEB_NOCOMPNAME, hr);
|
|
|
|
//
|
|
// I've removed the Assert but we should enable this
|
|
// to monitor all functions that are returning S_FALSE
|
|
// As far as possible, functions should not return
|
|
// S_FALSE except for the Next function of an Enumerator
|
|
// object.
|
|
|
|
// ADsAssert(0 && "An unpermitted success code was returned.");
|
|
}
|
|
|
|
//
|
|
// Warn on error result.
|
|
//
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ADsDebugOut((
|
|
DEB_IWARN,
|
|
"WARNING: %s:%d returning",
|
|
lpstrFile,
|
|
line));
|
|
|
|
PrintHRESULT(DEB_IWARN | DEB_NOCOMPNAME, hr);
|
|
|
|
BreakOnFailed();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: CheckResult
|
|
//
|
|
// Synopsis: Issues a warning if the HRESULT indicates failure
|
|
//
|
|
// Arguments: [hr] -- the HRESULT to be checked
|
|
// [lpstrFile] -- the file where the HRESULT is being checked
|
|
// [line] -- the line in the file where the HRESULT is being checked
|
|
//
|
|
//
|
|
// History: 1-06-94 adams Error printed only on FAILURE, not also
|
|
// on non-zero success.
|
|
// 5-24-94 adams Added call to BreakOnFailed.
|
|
//
|
|
// Notes: This function should not be used directly. The RRETURN
|
|
// macro is provided for convenience.
|
|
//
|
|
//----------------------------------------------------------------
|
|
|
|
STDAPI_(void)
|
|
CheckResult(HRESULT hr, LPSTR lpstrFile, UINT line)
|
|
{
|
|
if (FAILED(hr))
|
|
{
|
|
ADsDebugOut((DEB_IWARN, "WARNING: "));
|
|
ADsDebugOutHRESULT(DEB_IWARN | DEB_NOCOMPNAME, hr);
|
|
ADsDebugOut((
|
|
DEB_IWARN | DEB_NOCOMPNAME,
|
|
" occurred at %s:%d.\n",
|
|
lpstrFile,
|
|
line));
|
|
|
|
BreakOnFailed();
|
|
}
|
|
}
|
|
|
|
|
|
#endif // DBG == 1
|