Leaked source code of windows server 2003
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.

273 lines
11 KiB

  1. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Microsoft Windows, Copyright (C) Microsoft Corporation, 2000
  3. File: Error.h
  4. Content: Global error reporting facilities.
  5. History: 11-15-99 dsie created
  6. ------------------------------------------------------------------------------*/
  7. #ifndef _INCLUDE_ERROR_H
  8. #define _INCLUDE_ERROR_H
  9. #include "CAPICOM.h"
  10. #include "Resource.h"
  11. #include "Debug.h"
  12. ////////////////////
  13. //
  14. // typedefs
  15. //
  16. typedef struct capicom_error_map
  17. {
  18. CAPICOM_ERROR_CODE ErrorCode;
  19. DWORD ErrorStringId;
  20. } CAPICOM_ERROR_MAP;
  21. #ifndef ARRAYSIZE
  22. #define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0]))
  23. #endif
  24. //
  25. // Error code to error string ID map.
  26. //
  27. static CAPICOM_ERROR_MAP CapicomErrorMap[] =
  28. {
  29. {CAPICOM_E_ENCODE_INVALID_TYPE, IDS_CAPICOM_E_ENCODE_INVALID_TYPE},
  30. {CAPICOM_E_EKU_INVALID_OID, IDS_CAPICOM_E_EKU_INVALID_OID},
  31. {CAPICOM_E_EKU_OID_NOT_INITIALIZED, IDS_CAPICOM_E_EKU_OID_NOT_INITIALIZED},
  32. {CAPICOM_E_CERTIFICATE_NOT_INITIALIZED, IDS_CAPICOM_E_CERTIFICATE_NOT_INITIALIZED},
  33. {CAPICOM_E_CERTIFICATE_NO_PRIVATE_KEY, IDS_CAPICOM_E_CERTIFICATE_NO_PRIVATE_KEY},
  34. {CAPICOM_E_CHAIN_NOT_BUILT, IDS_CAPICOM_E_CHAIN_NOT_BUILT},
  35. {CAPICOM_E_STORE_NOT_OPENED, IDS_CAPICOM_E_STORE_NOT_OPENED},
  36. {CAPICOM_E_STORE_EMPTY, IDS_CAPICOM_E_STORE_EMPTY},
  37. {CAPICOM_E_STORE_INVALID_OPEN_MODE, IDS_CAPICOM_E_STORE_INVALID_OPEN_MODE},
  38. {CAPICOM_E_STORE_INVALID_SAVE_AS_TYPE, IDS_CAPICOM_E_STORE_INVALID_SAVE_AS_TYPE},
  39. {CAPICOM_E_ATTRIBUTE_NAME_NOT_INITIALIZED, IDS_CAPICOM_E_ATTRIBUTE_NAME_NOT_INITIALIZED},
  40. {CAPICOM_E_ATTRIBUTE_VALUE_NOT_INITIALIZED, IDS_CAPICOM_E_ATTRIBUTE_VALUE_NOT_INITIALIZED},
  41. {CAPICOM_E_ATTRIBUTE_INVALID_NAME, IDS_CAPICOM_E_ATTRIBUTE_INVALID_NAME},
  42. {CAPICOM_E_ATTRIBUTE_INVALID_VALUE, IDS_CAPICOM_E_ATTRIBUTE_INVALID_VALUE},
  43. {CAPICOM_E_SIGNER_NOT_INITIALIZED, IDS_CAPICOM_E_SIGNER_NOT_INITIALIZED},
  44. {CAPICOM_E_SIGNER_NOT_FOUND, IDS_CAPICOM_E_SIGNER_NOT_FOUND},
  45. {CAPICOM_E_SIGNER_NO_CHAIN, IDS_CAPICOM_E_SIGNER_NO_CHAIN}, // v2.0
  46. {CAPICOM_E_SIGNER_INVALID_USAGE, IDS_CAPICOM_E_SIGNER_INVALID_USAGE}, // v2.0
  47. {CAPICOM_E_SIGN_NOT_INITIALIZED, IDS_CAPICOM_E_SIGN_NOT_INITIALIZED},
  48. {CAPICOM_E_SIGN_INVALID_TYPE, IDS_CAPICOM_E_SIGN_INVALID_TYPE},
  49. {CAPICOM_E_SIGN_NOT_SIGNED, IDS_CAPICOM_E_SIGN_NOT_SIGNED},
  50. {CAPICOM_E_INVALID_ALGORITHM, IDS_CAPICOM_E_INVALID_ALGORITHM},
  51. {CAPICOM_E_INVALID_KEY_LENGTH, IDS_CAPICOM_E_INVALID_KEY_LENGTH},
  52. {CAPICOM_E_ENVELOP_NOT_INITIALIZED, IDS_CAPICOM_E_ENVELOP_NOT_INITIALIZED},
  53. {CAPICOM_E_ENVELOP_INVALID_TYPE, IDS_CAPICOM_E_ENVELOP_INVALID_TYPE},
  54. {CAPICOM_E_ENVELOP_NO_RECIPIENT, IDS_CAPICOM_E_ENVELOP_NO_RECIPIENT},
  55. {CAPICOM_E_ENVELOP_RECIPIENT_NOT_FOUND, IDS_CAPICOM_E_ENVELOP_RECIPIENT_NOT_FOUND},
  56. {CAPICOM_E_ENCRYPT_NOT_INITIALIZED, IDS_CAPICOM_E_ENCRYPT_NOT_INITIALIZED},
  57. {CAPICOM_E_ENCRYPT_INVALID_TYPE, IDS_CAPICOM_E_ENCRYPT_INVALID_TYPE},
  58. {CAPICOM_E_ENCRYPT_NO_SECRET, IDS_CAPICOM_E_ENCRYPT_NO_SECRET},
  59. {CAPICOM_E_NOT_SUPPORTED, IDS_CAPICOM_E_NOT_SUPPORTED},
  60. {CAPICOM_E_UI_DISABLED, IDS_CAPICOM_E_UI_DISABLED},
  61. {CAPICOM_E_CANCELLED, IDS_CAPICOM_E_CANCELLED},
  62. {CAPICOM_E_NOT_ALLOWED, IDS_CAPICOM_E_NOT_ALLOWED}, // v2.0
  63. {CAPICOM_E_OUT_OF_RESOURCE, IDS_CAPICOM_E_OUT_OF_RESOURCE}, // v2.0
  64. {CAPICOM_E_INTERNAL, IDS_CAPICOM_E_INTERNAL},
  65. {CAPICOM_E_UNKNOWN, IDS_CAPICOM_E_UNKNOWN},
  66. //
  67. // CAPICOM v2.0
  68. //
  69. {CAPICOM_E_PRIVATE_KEY_NOT_INITIALIZED, IDS_CAPICOM_E_PRIVATE_KEY_NOT_INITIALIZED},
  70. {CAPICOM_E_PRIVATE_KEY_NOT_EXPORTABLE, IDS_CAPICOM_E_PRIVATE_KEY_NOT_EXPORTABLE},
  71. {CAPICOM_E_ENCODE_NOT_INITIALIZED, IDS_CAPICOM_E_ENCODE_NOT_INITIALIZED},
  72. {CAPICOM_E_EXTENSION_NOT_INITIALIZED, IDS_CAPICOM_E_EXTENSION_NOT_INITIALIZED},
  73. {CAPICOM_E_PROPERTY_NOT_INITIALIZED, IDS_CAPICOM_E_PROPERTY_NOT_INITIALIZED},
  74. {CAPICOM_E_FIND_INVALID_TYPE, IDS_CAPICOM_E_FIND_INVALID_TYPE},
  75. {CAPICOM_E_FIND_INVALID_PREDEFINED_POLICY, IDS_CAPICOM_E_FIND_INVALID_PREDEFINED_POLICY},
  76. {CAPICOM_E_CODE_NOT_INITIALIZED, IDS_CAPICOM_E_CODE_NOT_INITIALIZED},
  77. {CAPICOM_E_CODE_NOT_SIGNED, IDS_CAPICOM_E_CODE_NOT_SIGNED},
  78. {CAPICOM_E_CODE_DESCRIPTION_NOT_INITIALIZED, IDS_CAPICOM_E_CODE_DESCRIPTION_NOT_INITIALIZED},
  79. {CAPICOM_E_CODE_DESCRIPTION_URL_NOT_INITIALIZED, IDS_CAPICOM_E_CODE_DESCRIPTION_URL_NOT_INITIALIZED},
  80. {CAPICOM_E_CODE_INVALID_TIMESTAMP_URL, IDS_CAPICOM_E_CODE_INVALID_TIMESTAMP_URL},
  81. {CAPICOM_E_HASH_NO_DATA, IDS_CAPICOM_E_HASH_NO_DATA},
  82. {CAPICOM_E_INVALID_CONVERT_TYPE, IDS_CAPICOM_E_INVALID_CONVERT_TYPE},
  83. };
  84. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  85. ICAPICOMError:
  86. This is a template class that implements the ISupportErrorInfo interface. In
  87. addition, it also contains member functions that facilitate error reporting.
  88. To use it, simply derive your class from this class, and add ISupportErrorInfo
  89. entry into your COM map.
  90. ie.
  91. class ATL_NO_VTABLE CMyClass :
  92. ...
  93. public ICAPICOMError<CMyClass, &IID_IMyClass>,
  94. ...
  95. {
  96. ...
  97. BEGIN_COM_MAP(CMyClass)
  98. ...
  99. COM_INTERFACE_ENTRY(ISupportErrorInfo)
  100. ...
  101. END_COM_MAP()
  102. ...
  103. };
  104. ------------------------------------------------------------------------------*/
  105. template <class T, const IID * piid>
  106. class ATL_NO_VTABLE ICAPICOMError: public ISupportErrorInfo
  107. {
  108. public:
  109. STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
  110. {
  111. return (IsEqualGUID(riid, *piid)) ? S_OK : S_FALSE;
  112. }
  113. HRESULT ReportError(HRESULT hr)
  114. {
  115. HLOCAL pMsgBuf = NULL;
  116. DebugTrace("Entering ReportError(HRESULT).\n");
  117. //
  118. // If there's a system message associated with this error, report that.
  119. //
  120. if (::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  121. NULL,
  122. (DWORD) hr,
  123. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  124. (LPSTR) &pMsgBuf,
  125. 0,
  126. NULL))
  127. {
  128. //
  129. // Sanity check.
  130. //
  131. ATLASSERT(NULL != pMsgBuf);
  132. //
  133. // Report error and free the buffer.
  134. //
  135. if (pMsgBuf)
  136. {
  137. CComCoClass<T>::Error((LPSTR) pMsgBuf, *piid, hr);
  138. ::LocalFree(pMsgBuf);
  139. }
  140. }
  141. else
  142. {
  143. //
  144. // No, so try CAPICOM error.
  145. //
  146. ReportError((CAPICOM_ERROR_CODE) hr);
  147. }
  148. DebugTrace("Leaving ReportError(HRESULT).\n");
  149. return hr;
  150. }
  151. HRESULT ReportError(CAPICOM_ERROR_CODE CAPICOMError)
  152. {
  153. HRESULT hr = (HRESULT) CAPICOMError;
  154. DWORD ids = IDS_CAPICOM_E_UNKNOWN;
  155. DWORD cbMsg = 0;
  156. HLOCAL pMsgBuf = NULL;
  157. char szFormat[512] = {'\0'};
  158. DebugTrace("Entering ReportError(CAPICOM_ERROR_CODE).\n");
  159. //
  160. // Map to error string id.
  161. //
  162. for (DWORD i = 0; i < ARRAYSIZE(CapicomErrorMap); i++)
  163. {
  164. if (CapicomErrorMap[i].ErrorCode == CAPICOMError)
  165. {
  166. ids = CapicomErrorMap[i].ErrorStringId;
  167. break;
  168. }
  169. }
  170. //
  171. // Load error format string from resource.
  172. //
  173. if (::LoadStringA(_Module.GetModuleInstance(),
  174. ids,
  175. szFormat,
  176. ARRAYSIZE(szFormat)))
  177. {
  178. //
  179. // Format message into buffer.
  180. //
  181. if ('\0' != szFormat[0])
  182. {
  183. cbMsg = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  184. szFormat,
  185. 0,
  186. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  187. (LPSTR) &pMsgBuf,
  188. 0,
  189. NULL);
  190. }
  191. }
  192. else
  193. {
  194. //
  195. // well, try a general error string.
  196. //
  197. if (::LoadStringA(_Module.GetModuleInstance(),
  198. hr = CAPICOM_E_UNKNOWN,
  199. szFormat,
  200. ARRAYSIZE(szFormat)))
  201. {
  202. cbMsg = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  203. szFormat,
  204. 0,
  205. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  206. (LPSTR) &pMsgBuf,
  207. 0,
  208. NULL);
  209. }
  210. }
  211. //
  212. // If we are still unable to get a formatted error string, then
  213. // fablicate one ourselves (very unlikely).
  214. //
  215. if (0 == cbMsg)
  216. {
  217. pMsgBuf = (HLOCAL) ::LocalAlloc(LPTR, sizeof(szFormat));
  218. if (NULL != pMsgBuf)
  219. {
  220. ::lstrcpyA((LPSTR) pMsgBuf, "Unknown error.\n");
  221. }
  222. }
  223. //
  224. // Report error and free the buffer.
  225. //
  226. if (pMsgBuf)
  227. {
  228. CComCoClass<T>::Error((LPSTR) pMsgBuf, *piid, hr);
  229. ::LocalFree(pMsgBuf);
  230. }
  231. DebugTrace("Leaving ReportError(CAPICOM_ERROR_CODE).\n");
  232. return hr;
  233. }
  234. };
  235. #endif // __INCLUDE_ERROR_H