Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
9.8 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMI OLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // Error Routines
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #ifndef __ERROR_H__
  10. #define __ERROR_H__
  11. #include "headers.h"
  12. #include "classfac.h"
  13. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  14. // Forward declarations ------------------------------------------------------
  15. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  16. class CErrorLookup;
  17. typedef CErrorLookup* PCERRORLOOKUP;
  18. class CImpIWMIErrorInfo;
  19. typedef CImpIWMIErrorInfo* PIMPIWMIERRORINFO;
  20. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  21. //----------------------------------------------------------------------------
  22. // MACROS AND INLINE FUNCTIONS
  23. //----------------------------------------------------------------------------
  24. // The following macro takes the Data1 element of a guid and looks at the lower
  25. // byte. Taking this value and a particular base value that would will yield a
  26. // number between 1 and 32, we can determine what bit in the DWORD to set on.
  27. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  28. #define PBIT(p1, base) (DWORD)(1 << (((p1) & 0x000000FF) & ~(base)))
  29. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  30. const DWORD ERR_STATIC_STRING = 0x08000000; // NOTE: High Byte is reserved by IDENTIFIER_SDK_MASK
  31. const DWORD INITIAL_SIZE_FOR_ERRORSTUFF = 32;
  32. const DWORD INCREMENT_BY_FOR_ERRORSTUFF = 16;
  33. typedef struct tagERRORSTUFF
  34. {
  35. DWORD dwDynamicId; // Identification number for a set of errors
  36. UINT uStringId; // String id for standard error
  37. LONG lNative; // Native Error value
  38. HRESULT hr; // HRESULT
  39. WORD wLineNumber; // Batch/Procedue Line number
  40. WCHAR* pwszServer; // Server name
  41. WCHAR* pwszProcedure; // Procedure name
  42. WCHAR * pwszMessage;
  43. } ERRORSTUFF, *PERRORSTUFF;
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  45. //
  46. // Class that maintains error data until we generate error records via IErrorRecords::AddErrorRecord
  47. //
  48. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  49. class CErrorData : public CFlexArray
  50. {
  51. private:
  52. WORD m_wStatus;
  53. public:
  54. CErrorData();
  55. ~CErrorData();
  56. WORD WGetStatus(WORD w) const { return m_wStatus & w; }
  57. void SetStatus(WORD w) { m_wStatus |= w; }
  58. void ClearStatus(WORD w) { m_wStatus &= ~w; }
  59. inline void GetLastError(PERRORSTUFF *ppErrorStuff) { assert(Size() > 0); *ppErrorStuff = (PERRORSTUFF) GetAt(Size()-1);}
  60. STDMETHODIMP InsertError( ULONG iInsert, // IN | index to insert the error
  61. UINT uStringId, // IN | string ID for error
  62. LONG lNative = 0 ); // IN | native error code
  63. void PeekError( DWORD *pdwStdError, // OUT | standard WMI error number (optional)
  64. LONG *plNativeError ); // OUT | native error number from WMI Server
  65. STDMETHODIMP PostStandardError( UINT uStringId, // IN | string ID for error
  66. HRESULT hrErr = S_OK, // IN | hresult to associate
  67. LONG lNative = 0 ); // IN | native eror code
  68. STDMETHODIMP PostWMIError( UINT uStringId, // IN | string ID for error
  69. LONG lNative, // IN | native error code
  70. WORD wLineNumber, // IN | batch/procedure line number
  71. LPCWSTR pwszError, // IN | error message
  72. LPCWSTR pwszServer, // IN | server name or NULL
  73. LPCWSTR pwszProcedure, // IN | procedure name or NULL
  74. HRESULT hrErr = S_OK // IN | associated hresult
  75. );
  76. inline STDMETHODIMP PostWinError(UINT uStringId){ return PostStandardError(uStringId, S_OK, (LONG)::GetLastError()); }
  77. ULONG RemoveError( LONG lNativeError );
  78. void XferErrors(CErrorData* pCError);
  79. enum EErrStatus {
  80. ERR_STATUS_OK = 0x0000,
  81. ERR_STATUS_OOM = 0x0001, // Out-of-memory error occurred
  82. ERR_STATUS_KEEP = 0x0002, };
  83. ULONG SetPosError(HRESULT rc);
  84. void FreeErrors();
  85. };
  86. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  87. class CImpISupportErrorInfo : public ISupportErrorInfo
  88. {
  89. private:
  90. ULONG m_cRef;
  91. IUnknown* m_pUnkOuter;
  92. GUID** m_rgpErrInt;
  93. ULONG m_cpErrInt;
  94. ULONG m_cAllocGuid; // Number of allocate GUIDs
  95. public:
  96. CImpISupportErrorInfo( IUnknown* pUnkOuter );
  97. ~CImpISupportErrorInfo();
  98. STDMETHODIMP_(ULONG) AddRef(void);
  99. STDMETHODIMP_(ULONG) Release(void);
  100. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  101. STDMETHODIMP InterfaceSupportsErrorInfo(REFIID riid);
  102. HRESULT AddInterfaceID(REFIID riid);
  103. };
  104. typedef CImpISupportErrorInfo* PIMPISUPPORTERRORINFO;
  105. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  106. class CImpIErrorLookup : public IErrorLookup
  107. {
  108. private:
  109. ULONG m_cRef;
  110. PCERRORLOOKUP m_pCErrorLookup;
  111. public:
  112. CImpIErrorLookup(PCERRORLOOKUP pCErrorLookup){
  113. DEBUGCODE(m_cRef = 0L);
  114. m_pCErrorLookup = pCErrorLookup;
  115. }
  116. ~CImpIErrorLookup() {}
  117. STDMETHODIMP_(ULONG) AddRef(void);
  118. STDMETHODIMP_(ULONG) Release(void);
  119. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  120. STDMETHODIMP GetErrorDescription(HRESULT hrError, DWORD dwLookupId, DISPPARAMS* pdispparams, LCID lcid, BSTR* ppwszSource, BSTR* ppwszDescription);
  121. STDMETHODIMP GetHelpInfo(HRESULT hrError, DWORD dwMinor, LCID lcid, BSTR* ppwszHelpFile, DWORD* pdwHelpContext);
  122. STDMETHODIMP ReleaseErrors(const DWORD dwDynamicErrorId);
  123. };
  124. typedef CImpIErrorLookup* PIMPIERRORLOOKUP;
  125. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  126. class CErrorLookup : public CBaseObj
  127. {
  128. friend class CImpIErrorLookup;
  129. protected:
  130. CImpIErrorLookup m_IErrorLookup;
  131. public:
  132. CErrorLookup(LPUNKNOWN pUnkOuter);
  133. ~CErrorLookup(void) {}
  134. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  135. STDMETHODIMP_(ULONG) AddRef(void);
  136. STDMETHODIMP_(ULONG) Release(void);
  137. };
  138. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  139. //
  140. // Routines to maintain the internal posting, viewing and removal of error information.
  141. //
  142. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  143. class CError
  144. {
  145. private:
  146. ERRORINFO m_ErrorInfo;
  147. PERRORSTUFF* m_prgErrorDex;
  148. CCriticalSection* m_pcsErrors;
  149. ULONG m_cErrors;
  150. ULONG m_cErrorsUsed;
  151. ULONG m_ulNext;
  152. DWORD m_dwId;
  153. CFlexArray* m_pWMIErrorInfoCollection;
  154. private:
  155. HRESULT GetErrorInterfaces(IErrorInfo** ppIErrorInfo, IErrorRecords** ppIErrorRecords);
  156. public:
  157. CError();
  158. ~CError();
  159. HRESULT FInit();
  160. HRESULT FindFreeDex(ULONG* pulDex);
  161. inline static void ClearErrorInfo(void) { SetErrorInfo(0, NULL); }
  162. inline int Size() { return m_pWMIErrorInfoCollection->Size(); }
  163. inline void SetAt(int n, void *p) { m_pWMIErrorInfoCollection->SetAt(n,p); }
  164. inline HRESULT AddToCollection(CImpIWMIErrorInfo* pWMIErrorInfo);
  165. inline void RemoveFromCollection(ULONG hObjCollection);
  166. HRESULT GetErrorDescription(ULONG ulDex, BSTR* ppwszDescription);
  167. void RemoveErrors(DWORD dwDynamicId);
  168. void FreeErrors();
  169. HRESULT PostError(HRESULT hrErr, const IID* piid, DWORD dwIds, DISPPARAMS* pdispparams);
  170. HRESULT PostErrorMessage(HRESULT hrErr, const IID* piid, UINT uStringId, LPCWSTR pwszMessage);
  171. HRESULT PostHResult(HRESULT hrErr, const IID* piid);
  172. HRESULT PostWMIErrors( HRESULT hrErr, const IID* piid, CErrorData* pErrData);
  173. };
  174. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. class CImpIWMIErrorInfo
  176. {
  177. private:
  178. ULONG m_cRef;
  179. PERRORSTUFF m_pErrStuff;
  180. ULONG m_hObjCollection;
  181. public:
  182. CImpIWMIErrorInfo(PERRORSTUFF pErrStuff);
  183. ~CImpIWMIErrorInfo();
  184. inline HRESULT FInit();
  185. PERRORSTUFF GetErrorStuff(void) const { return m_pErrStuff; }
  186. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  187. STDMETHODIMP_(ULONG) AddRef(void);
  188. STDMETHODIMP_(ULONG) Release(void);
  189. STDMETHODIMP GetWMIInfo(BSTR* pbstrWMIInfo, LONG* plNativeError);
  190. };
  191. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. inline HRESULT CError::AddToCollection( CImpIWMIErrorInfo* pWMIErrorInfo )
  193. {
  194. CAutoBlock Crit(m_pcsErrors);
  195. HRESULT hr = m_pWMIErrorInfoCollection->Add(pWMIErrorInfo);
  196. return hr;
  197. };
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. inline void CError::RemoveFromCollection(ULONG hObjCollection)
  200. {
  201. CAutoBlock Crit(m_pcsErrors);
  202. m_pWMIErrorInfoCollection->RemoveAt(hObjCollection);
  203. }
  204. extern CError * g_pCError;
  205. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  206. inline HRESULT CImpIWMIErrorInfo::FInit()
  207. {
  208. // For Abnormal Termination, add self to Collection
  209. if( g_pCError ){
  210. return g_pCError->AddToCollection(this);
  211. }
  212. return -1;
  213. }
  214. #endif