windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/errinf.h
2020-09-26 16:20:57 +08:00

258 lines
9.8 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMI OLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// Error Routines
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __ERROR_H__
#define __ERROR_H__
#include "headers.h"
#include "classfac.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Forward declarations ------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////////////
class CErrorLookup;
typedef CErrorLookup* PCERRORLOOKUP;
class CImpIWMIErrorInfo;
typedef CImpIWMIErrorInfo* PIMPIWMIERRORINFO;
///////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
// MACROS AND INLINE FUNCTIONS
//----------------------------------------------------------------------------
// The following macro takes the Data1 element of a guid and looks at the lower
// byte. Taking this value and a particular base value that would will yield a
// number between 1 and 32, we can determine what bit in the DWORD to set on.
///////////////////////////////////////////////////////////////////////////////////////////////////////
#define PBIT(p1, base) (DWORD)(1 << (((p1) & 0x000000FF) & ~(base)))
///////////////////////////////////////////////////////////////////////////////////////////////////////
const DWORD ERR_STATIC_STRING = 0x08000000; // NOTE: High Byte is reserved by IDENTIFIER_SDK_MASK
const DWORD INITIAL_SIZE_FOR_ERRORSTUFF = 32;
const DWORD INCREMENT_BY_FOR_ERRORSTUFF = 16;
typedef struct tagERRORSTUFF
{
DWORD dwDynamicId; // Identification number for a set of errors
UINT uStringId; // String id for standard error
LONG lNative; // Native Error value
HRESULT hr; // HRESULT
WORD wLineNumber; // Batch/Procedue Line number
WCHAR* pwszServer; // Server name
WCHAR* pwszProcedure; // Procedure name
WCHAR * pwszMessage;
} ERRORSTUFF, *PERRORSTUFF;
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Class that maintains error data until we generate error records via IErrorRecords::AddErrorRecord
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
class CErrorData : public CFlexArray
{
private:
WORD m_wStatus;
public:
CErrorData();
~CErrorData();
WORD WGetStatus(WORD w) const { return m_wStatus & w; }
void SetStatus(WORD w) { m_wStatus |= w; }
void ClearStatus(WORD w) { m_wStatus &= ~w; }
inline void GetLastError(PERRORSTUFF *ppErrorStuff) { assert(Size() > 0); *ppErrorStuff = (PERRORSTUFF) GetAt(Size()-1);}
STDMETHODIMP InsertError( ULONG iInsert, // IN | index to insert the error
UINT uStringId, // IN | string ID for error
LONG lNative = 0 ); // IN | native error code
void PeekError( DWORD *pdwStdError, // OUT | standard WMI error number (optional)
LONG *plNativeError ); // OUT | native error number from WMI Server
STDMETHODIMP PostStandardError( UINT uStringId, // IN | string ID for error
HRESULT hrErr = S_OK, // IN | hresult to associate
LONG lNative = 0 ); // IN | native eror code
STDMETHODIMP PostWMIError( UINT uStringId, // IN | string ID for error
LONG lNative, // IN | native error code
WORD wLineNumber, // IN | batch/procedure line number
LPCWSTR pwszError, // IN | error message
LPCWSTR pwszServer, // IN | server name or NULL
LPCWSTR pwszProcedure, // IN | procedure name or NULL
HRESULT hrErr = S_OK // IN | associated hresult
);
inline STDMETHODIMP PostWinError(UINT uStringId){ return PostStandardError(uStringId, S_OK, (LONG)::GetLastError()); }
ULONG RemoveError( LONG lNativeError );
void XferErrors(CErrorData* pCError);
enum EErrStatus {
ERR_STATUS_OK = 0x0000,
ERR_STATUS_OOM = 0x0001, // Out-of-memory error occurred
ERR_STATUS_KEEP = 0x0002, };
ULONG SetPosError(HRESULT rc);
void FreeErrors();
};
///////////////////////////////////////////////////////////////////////////////////////////////////////
class CImpISupportErrorInfo : public ISupportErrorInfo
{
private:
ULONG m_cRef;
IUnknown* m_pUnkOuter;
GUID** m_rgpErrInt;
ULONG m_cpErrInt;
ULONG m_cAllocGuid; // Number of allocate GUIDs
public:
CImpISupportErrorInfo( IUnknown* pUnkOuter );
~CImpISupportErrorInfo();
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid);
HRESULT AddInterfaceID(REFIID riid);
};
typedef CImpISupportErrorInfo* PIMPISUPPORTERRORINFO;
///////////////////////////////////////////////////////////////////////////////////////////////////////
class CImpIErrorLookup : public IErrorLookup
{
private:
ULONG m_cRef;
PCERRORLOOKUP m_pCErrorLookup;
public:
CImpIErrorLookup(PCERRORLOOKUP pCErrorLookup){
DEBUGCODE(m_cRef = 0L);
m_pCErrorLookup = pCErrorLookup;
}
~CImpIErrorLookup() {}
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
STDMETHODIMP GetErrorDescription(HRESULT hrError, DWORD dwLookupId, DISPPARAMS* pdispparams, LCID lcid, BSTR* ppwszSource, BSTR* ppwszDescription);
STDMETHODIMP GetHelpInfo(HRESULT hrError, DWORD dwMinor, LCID lcid, BSTR* ppwszHelpFile, DWORD* pdwHelpContext);
STDMETHODIMP ReleaseErrors(const DWORD dwDynamicErrorId);
};
typedef CImpIErrorLookup* PIMPIERRORLOOKUP;
///////////////////////////////////////////////////////////////////////////////////////////////////////
class CErrorLookup : public CBaseObj
{
friend class CImpIErrorLookup;
protected:
CImpIErrorLookup m_IErrorLookup;
public:
CErrorLookup(LPUNKNOWN pUnkOuter);
~CErrorLookup(void) {}
STDMETHODIMP QueryInterface(REFIID, LPVOID *);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Routines to maintain the internal posting, viewing and removal of error information.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
class CError
{
private:
ERRORINFO m_ErrorInfo;
PERRORSTUFF* m_prgErrorDex;
CCriticalSection* m_pcsErrors;
ULONG m_cErrors;
ULONG m_cErrorsUsed;
ULONG m_ulNext;
DWORD m_dwId;
CFlexArray* m_pWMIErrorInfoCollection;
private:
HRESULT GetErrorInterfaces(IErrorInfo** ppIErrorInfo, IErrorRecords** ppIErrorRecords);
public:
CError();
~CError();
HRESULT FInit();
HRESULT FindFreeDex(ULONG* pulDex);
inline static void ClearErrorInfo(void) { SetErrorInfo(0, NULL); }
inline int Size() { return m_pWMIErrorInfoCollection->Size(); }
inline void SetAt(int n, void *p) { m_pWMIErrorInfoCollection->SetAt(n,p); }
inline HRESULT AddToCollection(CImpIWMIErrorInfo* pWMIErrorInfo);
inline void RemoveFromCollection(ULONG hObjCollection);
HRESULT GetErrorDescription(ULONG ulDex, BSTR* ppwszDescription);
void RemoveErrors(DWORD dwDynamicId);
void FreeErrors();
HRESULT PostError(HRESULT hrErr, const IID* piid, DWORD dwIds, DISPPARAMS* pdispparams);
HRESULT PostErrorMessage(HRESULT hrErr, const IID* piid, UINT uStringId, LPCWSTR pwszMessage);
HRESULT PostHResult(HRESULT hrErr, const IID* piid);
HRESULT PostWMIErrors( HRESULT hrErr, const IID* piid, CErrorData* pErrData);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
class CImpIWMIErrorInfo
{
private:
ULONG m_cRef;
PERRORSTUFF m_pErrStuff;
ULONG m_hObjCollection;
public:
CImpIWMIErrorInfo(PERRORSTUFF pErrStuff);
~CImpIWMIErrorInfo();
inline HRESULT FInit();
PERRORSTUFF GetErrorStuff(void) const { return m_pErrStuff; }
STDMETHODIMP QueryInterface(REFIID, LPVOID *);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetWMIInfo(BSTR* pbstrWMIInfo, LONG* plNativeError);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
inline HRESULT CError::AddToCollection( CImpIWMIErrorInfo* pWMIErrorInfo )
{
CAutoBlock Crit(m_pcsErrors);
HRESULT hr = m_pWMIErrorInfoCollection->Add(pWMIErrorInfo);
return hr;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////
inline void CError::RemoveFromCollection(ULONG hObjCollection)
{
CAutoBlock Crit(m_pcsErrors);
m_pWMIErrorInfoCollection->RemoveAt(hObjCollection);
}
extern CError * g_pCError;
////////////////////////////////////////////////////////////////////////////////////////////////////////
inline HRESULT CImpIWMIErrorInfo::FInit()
{
// For Abnormal Termination, add self to Collection
if( g_pCError ){
return g_pCError->AddToCollection(this);
}
return -1;
}
#endif