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.

510 lines
12 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2002
  5. //
  6. // File: ceerror.cpp
  7. //
  8. // Contents: Cert Server error wrapper routines
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include "celib.h"
  14. #include <assert.h>
  15. #include <ntdsbmsg.h>
  16. #include <delayimp.h>
  17. #include <wininet.h>
  18. #define CERTLIB_12BITERRORMASK 0x00000fff
  19. #define CERTLIB_WIN32ERRORMASK 0x0000ffff
  20. //+--------------------------------------------------------------------------
  21. // Jet errors:
  22. #define HRESULT_FROM_JETWARNING(jerr) \
  23. (ERROR_SEVERITY_WARNING | (FACILITY_NTDSB << 16) | jerr)
  24. #define HRESULT_FROM_JETERROR(jerr) \
  25. (ERROR_SEVERITY_ERROR | (FACILITY_NTDSB << 16) | -jerr)
  26. #define JETERROR_FROM_HRESULT(hr) \
  27. (-(LONG) (CERTLIB_WIN32ERRORMASK & (hr)))
  28. #define ISJETERROR(hr) \
  29. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) ~CERTLIB_WIN32ERRORMASK)
  30. #define ISJETHRESULT(hr) \
  31. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  32. (FACILITY_NTDSB << 16)))
  33. #define wszJETERRORPREFIX L"ESE"
  34. //+--------------------------------------------------------------------------
  35. // Setup API errors:
  36. #define ISSETUPHRESULT(hr) \
  37. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  38. APPLICATION_ERROR_MASK | \
  39. (FACILITY_NULL << 16)))
  40. #define wszSETUPERRORPREFIX L"INF"
  41. //+--------------------------------------------------------------------------
  42. // Win32 errors:
  43. #define ISWIN32ERROR(hr) \
  44. ((~CERTLIB_WIN32ERRORMASK & (hr)) == 0)
  45. #define ISWIN32HRESULT(hr) \
  46. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_WARNING | \
  47. (FACILITY_WIN32 << 16)))
  48. #define WIN32ERROR_FROM_HRESULT(hr) \
  49. (CERTLIB_WIN32ERRORMASK & (hr))
  50. #define wszWIN32ERRORPREFIX L"WIN32"
  51. //+--------------------------------------------------------------------------
  52. // Http errors:
  53. #define ISHTTPERROR(hr) \
  54. ((HRESULT) HTTP_STATUS_FIRST <= (hr) && (HRESULT) HTTP_STATUS_LAST >= (hr))
  55. #define ISHTTPHRESULT(hr) \
  56. (ISWIN32HRESULT(hr) && ISHTTPERROR(WIN32ERROR_FROM_HRESULT(hr)))
  57. #define wszHTTPERRORPREFIX L"HTTP"
  58. //+--------------------------------------------------------------------------
  59. // Delayload errors:
  60. #define DELAYLOAD_FROM_WIN32(hr) VcppException(ERROR_SEVERITY_ERROR, (hr))
  61. #define WIN32ERROR_FROM_DELAYLOAD(hr) (CERTLIB_WIN32ERRORMASK & (hr))
  62. #define ISDELAYLOADHRESULTFACILITY(hr) \
  63. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  64. (FACILITY_VISUALCPP << 16)))
  65. // E_DELAYLOAD_MOD_NOT_FOUND 0xc06d007e
  66. #define E_DELAYLOAD_MOD_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_MOD_NOT_FOUND)
  67. // E_DELAYLOAD_PROC_NOT_FOUND 0xc06d007f
  68. #define E_DELAYLOAD_PROC_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_PROC_NOT_FOUND)
  69. #define ISDELAYLOADHRESULT(hr) \
  70. ((HRESULT) E_DELAYLOAD_MOD_NOT_FOUND == (hr) || \
  71. (HRESULT) E_DELAYLOAD_PROC_NOT_FOUND == (hr) || \
  72. HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) == (hr) || \
  73. HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND) == (hr))
  74. //+--------------------------------------------------------------------------
  75. // ASN encoding errors:
  76. #define ISOSSERROR(hr) \
  77. ((~CERTLIB_12BITERRORMASK & (hr)) == CRYPT_E_OSS_ERROR)
  78. #define OSSERROR_FROM_HRESULT(hr) \
  79. (CERTLIB_12BITERRORMASK & (hr))
  80. #define wszOSSERRORPREFIX L"ASN"
  81. HRESULT
  82. ceJetHResult(
  83. IN HRESULT hr)
  84. {
  85. if (S_OK != hr)
  86. {
  87. if (SUCCEEDED(hr))
  88. {
  89. #if 0
  90. hr = HRESULT_FROM_JETWARNING(hr);
  91. #else
  92. if (S_FALSE != hr)
  93. {
  94. _PrintError(hr, "JetHResult: mapping to S_FALSE");
  95. }
  96. assert(S_FALSE == hr);
  97. hr = S_FALSE;
  98. #endif
  99. }
  100. else if (ISJETERROR(hr))
  101. {
  102. hr = HRESULT_FROM_JETERROR(hr);
  103. }
  104. }
  105. assert(S_OK == hr || S_FALSE == hr || FAILED(hr));
  106. return(hr);
  107. }
  108. HRESULT
  109. ceHExceptionCode(
  110. IN EXCEPTION_POINTERS const *pep)
  111. {
  112. HRESULT hr = pep->ExceptionRecord->ExceptionCode;
  113. #if (0 == i386)
  114. if ((HRESULT) STATUS_DATATYPE_MISALIGNMENT == hr)
  115. {
  116. hr = CERTSRV_E_ALIGNMENT_FAULT;
  117. }
  118. #endif
  119. return(ceHError(hr));
  120. }
  121. BOOL
  122. ceIsDelayLoadHResult(
  123. IN HRESULT hr)
  124. {
  125. return(ISDELAYLOADHRESULT(hr));
  126. }
  127. #define wszCOLONSPACE L": "
  128. WCHAR const *
  129. ceHResultToStringEx(
  130. IN OUT WCHAR *awchr,
  131. IN HRESULT hr,
  132. IN BOOL fRaw)
  133. {
  134. HRESULT hrd;
  135. WCHAR const *pwszType;
  136. hrd = hr;
  137. pwszType = L"";
  138. if (ISJETERROR(hr))
  139. {
  140. pwszType = wszJETERRORPREFIX wszCOLONSPACE;
  141. }
  142. else if (ISJETHRESULT(hr))
  143. {
  144. hrd = JETERROR_FROM_HRESULT(hr);
  145. pwszType = wszJETERRORPREFIX wszCOLONSPACE;
  146. }
  147. else if (ISOSSERROR(hr))
  148. {
  149. hrd = OSSERROR_FROM_HRESULT(hr);
  150. pwszType = wszOSSERRORPREFIX wszCOLONSPACE;
  151. }
  152. else if (ISHTTPHRESULT(hr) || ISHTTPERROR(hr))
  153. {
  154. hrd = WIN32ERROR_FROM_HRESULT(hr);
  155. pwszType = wszWIN32ERRORPREFIX L"/" wszHTTPERRORPREFIX wszCOLONSPACE;
  156. }
  157. else if (ISWIN32HRESULT(hr) || ISWIN32ERROR(hr))
  158. {
  159. hrd = WIN32ERROR_FROM_HRESULT(hr);
  160. pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
  161. }
  162. else if (ISDELAYLOADHRESULTFACILITY(hr))
  163. {
  164. hrd = WIN32ERROR_FROM_DELAYLOAD(hr);
  165. pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
  166. }
  167. else if (ISSETUPHRESULT(hr))
  168. {
  169. pwszType = wszSETUPERRORPREFIX wszCOLONSPACE;
  170. }
  171. if (fRaw)
  172. {
  173. pwszType = L"";
  174. }
  175. _snwprintf(
  176. awchr,
  177. cwcHRESULTSTRING,
  178. L"0x%x (%ws%d)",
  179. hr,
  180. pwszType,
  181. hrd);
  182. return(awchr);
  183. }
  184. WCHAR const *
  185. ceHResultToString(
  186. IN OUT WCHAR *awchr,
  187. IN HRESULT hr)
  188. {
  189. return(ceHResultToStringEx(awchr, hr, FALSE));
  190. }
  191. WCHAR const *
  192. ceHResultToStringRaw(
  193. IN OUT WCHAR *awchr,
  194. IN HRESULT hr)
  195. {
  196. return(ceHResultToStringEx(awchr, hr, TRUE));
  197. }
  198. static HMODULE s_hMod = NULL;
  199. static DWORD s_idsUnexpected = 0;
  200. static DWORD s_idsUnknownErrorCode = 0; // L"Error %ws %ws"
  201. VOID
  202. ceInitErrorMessageText(
  203. IN HMODULE hMod,
  204. IN DWORD idsUnexpected,
  205. IN DWORD idsUnknownErrorCode) // L"Error %ws %ws"
  206. {
  207. s_hMod = hMod;
  208. s_idsUnexpected = idsUnexpected;
  209. s_idsUnknownErrorCode = idsUnknownErrorCode;
  210. }
  211. DWORD
  212. errFormatMessage(
  213. IN HMODULE hMod,
  214. IN HRESULT hr,
  215. OUT WCHAR const **ppwszOut,
  216. OPTIONAL IN WCHAR const * const *ppwszArgs)
  217. {
  218. DWORD dwFlags;
  219. dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER;
  220. if (NULL == hMod)
  221. {
  222. dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
  223. }
  224. else
  225. {
  226. dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  227. }
  228. if (NULL == ppwszArgs || NULL == ppwszArgs[0])
  229. {
  230. dwFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
  231. }
  232. else
  233. {
  234. dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
  235. }
  236. return(FormatMessage(
  237. dwFlags,
  238. hMod,
  239. hr,
  240. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  241. (WCHAR *) ppwszOut,
  242. 1,
  243. (va_list *) ppwszArgs));
  244. }
  245. // Alloc and return error message string
  246. WCHAR const *
  247. ceGetErrorMessageText(
  248. IN HRESULT hr,
  249. IN BOOL fHResultString)
  250. {
  251. return(ceGetErrorMessageTextEx(hr, fHResultString, NULL));
  252. }
  253. WCHAR const *
  254. ceGetErrorMessageText1(
  255. IN HRESULT hr,
  256. IN BOOL fHResultString,
  257. IN OPTIONAL WCHAR const *pwszInsertionText)
  258. {
  259. WCHAR const *apwszInsertionText[2];
  260. WCHAR const * const *papwsz = NULL;
  261. if (NULL != pwszInsertionText)
  262. {
  263. apwszInsertionText[0] = pwszInsertionText;
  264. apwszInsertionText[1] = NULL;
  265. papwsz = apwszInsertionText;
  266. }
  267. return(ceGetErrorMessageTextEx(hr, fHResultString, papwsz));
  268. }
  269. WCHAR const *
  270. ceGetErrorMessageTextEx(
  271. IN HRESULT hr,
  272. IN BOOL fHResultString,
  273. IN OPTIONAL WCHAR const * const *papwszInsertionText)
  274. {
  275. WCHAR const *pwszRet = NULL;
  276. WCHAR const *pwszRetStatic = NULL;
  277. WCHAR *pwszMsgT;
  278. WCHAR awchr[cwcHRESULTSTRING];
  279. DWORD cwc;
  280. DWORD cwcCopy;
  281. DWORD cwcUnexpected;
  282. WCHAR const *pwszUnexpected = NULL;
  283. WCHAR wszEmpty[] = L"";
  284. HMODULE hMod1 = NULL;
  285. HMODULE hMod2 = NULL;
  286. if (E_UNEXPECTED == hr)
  287. {
  288. pwszUnexpected = L"Unexpected method call sequence.";
  289. }
  290. #if (0 == i386)
  291. else if (STATUS_DATATYPE_MISALIGNMENT == hr)
  292. {
  293. pwszUnexpected = L"Possible data alignment fault.";
  294. }
  295. #endif
  296. if (NULL == pwszUnexpected)
  297. {
  298. pwszUnexpected = wszEmpty;
  299. }
  300. cwcUnexpected = wcslen(pwszUnexpected);
  301. cwc = errFormatMessage(NULL, hr, &pwszRet, papwszInsertionText);
  302. if (0 == cwc && ISDELAYLOADHRESULTFACILITY(hr))
  303. {
  304. cwc = errFormatMessage(
  305. NULL,
  306. WIN32ERROR_FROM_DELAYLOAD(hr),
  307. &pwszRet,
  308. papwszInsertionText);
  309. }
  310. if (0 == cwc)
  311. {
  312. hMod1 = LoadLibrary(L"ntdsbmsg.dll");
  313. if (NULL != hMod1)
  314. {
  315. HRESULT hrEDB = hr;
  316. HRESULT hrFormat;
  317. BOOL fFirst = TRUE;
  318. while (TRUE)
  319. {
  320. cwc = errFormatMessage(hMod1, hrEDB, &pwszRet, papwszInsertionText);
  321. if (0 == cwc && FAILED(hrEDB) && fFirst)
  322. {
  323. hrFormat = ceHLastError();
  324. if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
  325. {
  326. hrEDB = ceJetHResult(hrEDB);
  327. if (hrEDB != hr)
  328. {
  329. fFirst = FALSE;
  330. continue;
  331. }
  332. }
  333. }
  334. break;
  335. }
  336. }
  337. }
  338. if (0 == cwc)
  339. {
  340. HMODULE hModT = GetModuleHandle(L"wininet.dll");
  341. if (NULL != hModT)
  342. {
  343. HRESULT hrHttp = hr;
  344. HRESULT hrFormat;
  345. BOOL fFirst = TRUE;
  346. while (TRUE)
  347. {
  348. cwc = errFormatMessage(hModT, hrHttp, &pwszRet, papwszInsertionText);
  349. if (0 == cwc && ISWIN32HRESULT(hrHttp) && fFirst)
  350. {
  351. hrFormat = ceHLastError();
  352. if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
  353. {
  354. hrHttp = WIN32ERROR_FROM_HRESULT(hrHttp);
  355. if (hrHttp != hr)
  356. {
  357. fFirst = FALSE;
  358. continue;
  359. }
  360. }
  361. }
  362. break;
  363. }
  364. }
  365. }
  366. if (0 == cwc)
  367. {
  368. hMod2 = LoadLibrary(L"cdosys.dll");
  369. if (NULL != hMod2)
  370. {
  371. cwc = errFormatMessage(hMod2, hr, &pwszRet, papwszInsertionText);
  372. }
  373. }
  374. if (0 == cwc) // couldn't find error, use default & error code
  375. {
  376. fHResultString = TRUE;
  377. }
  378. awchr[0] = L'\0';
  379. if (fHResultString)
  380. {
  381. ceHResultToString(awchr, hr);
  382. }
  383. if (0 == cwc)
  384. {
  385. pwszRetStatic = L"Error";
  386. pwszRet = pwszRetStatic;
  387. }
  388. // strip trailing \r\n
  389. cwcCopy = wcslen(pwszRet);
  390. if (2 <= cwcCopy &&
  391. L'\r' == pwszRet[cwcCopy - 2] &&
  392. L'\n' == pwszRet[cwcCopy - 1])
  393. {
  394. cwcCopy -= 2;
  395. }
  396. cwc = cwcCopy + 1 + cwcUnexpected + 1 + wcslen(awchr) + 1;
  397. pwszMsgT = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  398. if (NULL == pwszMsgT)
  399. {
  400. _JumpError(E_OUTOFMEMORY, error, "LocalAlloc");
  401. }
  402. CopyMemory(pwszMsgT, pwszRet, cwcCopy * sizeof(WCHAR));
  403. pwszMsgT[cwcCopy] = L'\0';
  404. if (0 != cwcUnexpected)
  405. {
  406. wcscat(pwszMsgT, L" ");
  407. wcscat(pwszMsgT, pwszUnexpected);
  408. }
  409. if (fHResultString)
  410. {
  411. wcscat(pwszMsgT, L" ");
  412. wcscat(pwszMsgT, awchr);
  413. }
  414. assert(wcslen(pwszMsgT) < cwc);
  415. if (NULL != pwszRet && pwszRetStatic != pwszRet)
  416. {
  417. LocalFree(const_cast<WCHAR *>(pwszRet));
  418. }
  419. pwszRet = pwszMsgT;
  420. error:
  421. if (NULL != hMod1)
  422. {
  423. FreeLibrary(hMod1);
  424. }
  425. if (NULL != hMod2)
  426. {
  427. FreeLibrary(hMod2);
  428. }
  429. return(pwszRet);
  430. }