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.

772 lines
20 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: error.cpp
  7. //
  8. // Contents: Cert Server error wrapper routines
  9. //
  10. //---------------------------------------------------------------------------
  11. #include <pch.cpp>
  12. #pragma hdrstop
  13. #include <assert.h>
  14. #include <ntdsbmsg.h>
  15. #include <delayimp.h>
  16. #include <wininet.h>
  17. #include "resource.h"
  18. #define __dwFILE__ __dwFILE_CERTCLIB_ERROR_CPP__
  19. #define DBG_CERTSRV_DEBUG_PRINT
  20. #define CERTLIB_12BITERRORMASK 0x00000fff
  21. #define CERTLIB_WIN32ERRORMASK 0x0000ffff
  22. //+--------------------------------------------------------------------------
  23. // Jet errors:
  24. #define HRESULT_FROM_JETWARNING(jerr) \
  25. (ERROR_SEVERITY_WARNING | (FACILITY_NTDSB << 16) | jerr)
  26. #define HRESULT_FROM_JETERROR(jerr) \
  27. (ERROR_SEVERITY_ERROR | (FACILITY_NTDSB << 16) | -jerr)
  28. #define JETERROR_FROM_HRESULT(hr) \
  29. (-(LONG) (CERTLIB_WIN32ERRORMASK & (hr)))
  30. #define ISJETERROR(hr) \
  31. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) ~CERTLIB_WIN32ERRORMASK)
  32. #define ISJETHRESULT(hr) \
  33. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  34. (FACILITY_NTDSB << 16)))
  35. #define wszJETERRORPREFIX L"ESE"
  36. //+--------------------------------------------------------------------------
  37. // Setup API errors:
  38. #define ISSETUPHRESULT(hr) \
  39. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  40. APPLICATION_ERROR_MASK | \
  41. (FACILITY_NULL << 16)))
  42. #define wszSETUPERRORPREFIX L"INF"
  43. //+--------------------------------------------------------------------------
  44. // Win32 errors:
  45. #define ISWIN32ERROR(hr) \
  46. ((~CERTLIB_WIN32ERRORMASK & (hr)) == 0)
  47. #define ISWIN32HRESULT(hr) \
  48. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_WARNING | \
  49. (FACILITY_WIN32 << 16)))
  50. #define WIN32ERROR_FROM_HRESULT(hr) \
  51. (CERTLIB_WIN32ERRORMASK & (hr))
  52. #define wszWIN32ERRORPREFIX L"WIN32"
  53. //+--------------------------------------------------------------------------
  54. // Http errors:
  55. #define ISHTTPERROR(hr) \
  56. ((HRESULT) HTTP_STATUS_FIRST <= (hr) && (HRESULT) HTTP_STATUS_LAST >= (hr))
  57. #define ISHTTPHRESULT(hr) \
  58. (ISWIN32HRESULT(hr) && ISHTTPERROR(WIN32ERROR_FROM_HRESULT(hr)))
  59. #define wszHTTPERRORPREFIX L"HTTP"
  60. //+--------------------------------------------------------------------------
  61. // Delayload errors:
  62. #define DELAYLOAD_FROM_WIN32(hr) VcppException(ERROR_SEVERITY_ERROR, (hr))
  63. #define WIN32ERROR_FROM_DELAYLOAD(hr) (CERTLIB_WIN32ERRORMASK & (hr))
  64. #define ISDELAYLOADHRESULTFACILITY(hr) \
  65. ((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
  66. (FACILITY_VISUALCPP << 16)))
  67. // E_DELAYLOAD_MOD_NOT_FOUND 0xc06d007e
  68. #define E_DELAYLOAD_MOD_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_MOD_NOT_FOUND)
  69. // E_DELAYLOAD_PROC_NOT_FOUND 0xc06d007f
  70. #define E_DELAYLOAD_PROC_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_PROC_NOT_FOUND)
  71. #define ISDELAYLOADHRESULT(hr) \
  72. ((HRESULT) E_DELAYLOAD_MOD_NOT_FOUND == (hr) || \
  73. (HRESULT) E_DELAYLOAD_PROC_NOT_FOUND == (hr) || \
  74. HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) == (hr) || \
  75. HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND) == (hr))
  76. //+--------------------------------------------------------------------------
  77. // ASN encoding errors:
  78. #define ISOSSERROR(hr) \
  79. ((~CERTLIB_12BITERRORMASK & (hr)) == CRYPT_E_OSS_ERROR)
  80. #define OSSERROR_FROM_HRESULT(hr) \
  81. (CERTLIB_12BITERRORMASK & (hr))
  82. #define wszOSSERRORPREFIX L"ASN"
  83. HRESULT
  84. myJetHResult(
  85. IN HRESULT hr)
  86. {
  87. #if DBG_CERTSRV
  88. HRESULT hrIn = hr;
  89. #endif
  90. if (S_OK != hr)
  91. {
  92. if (SUCCEEDED(hr))
  93. {
  94. #if 0
  95. hr = HRESULT_FROM_JETWARNING(hr);
  96. #else
  97. if (S_FALSE != hr)
  98. {
  99. _PrintError(hr, "JetHResult: mapping to S_FALSE");
  100. }
  101. CSASSERT(S_FALSE == hr);
  102. hr = S_FALSE;
  103. #endif
  104. }
  105. else if (ISJETERROR(hr))
  106. {
  107. hr = HRESULT_FROM_JETERROR(hr);
  108. }
  109. }
  110. #if DBG_CERTSRV
  111. if (S_OK != hrIn || S_OK != hr)
  112. {
  113. DBGPRINT((
  114. DBG_SS_CERTLIBI,
  115. "myJetHResult(%x (%d)) --> %x (%d)\n",
  116. hrIn,
  117. hrIn,
  118. hr,
  119. hr));
  120. }
  121. #endif
  122. CSASSERT(S_OK == hr || S_FALSE == hr || FAILED(hr));
  123. return(hr);
  124. }
  125. HRESULT
  126. myHExceptionCode(
  127. IN EXCEPTION_POINTERS const *pep)
  128. {
  129. HRESULT hr = pep->ExceptionRecord->ExceptionCode;
  130. #if (0 == i386)
  131. if ((HRESULT) STATUS_DATATYPE_MISALIGNMENT == hr)
  132. {
  133. hr = CERTSRV_E_ALIGNMENT_FAULT;
  134. }
  135. #endif
  136. return(myHError(hr));
  137. }
  138. #ifdef DBG_CERTSRV_DEBUG_PRINT
  139. VOID
  140. myCaptureStackBackTrace(
  141. EXCEPTION_POINTERS const *pep,
  142. ULONG cSkip,
  143. ULONG cFrames,
  144. ULONG *aeip)
  145. {
  146. ZeroMemory(aeip, cFrames * sizeof(aeip[0]));
  147. #if i386 == 1
  148. ULONG ieip, *pebp;
  149. ULONG *pebpMax = (ULONG *) MAXLONG; // 2 * 1024 * 1024 * 1024; // 2 gig - 1
  150. ULONG *pebpMin = (ULONG *) (64 * 1024); // 64k
  151. if (pep == NULL)
  152. {
  153. ieip = 0;
  154. cSkip++; // always skip current frame
  155. pebp = ((ULONG *) &pep) - 2;
  156. }
  157. else
  158. {
  159. ieip = 1;
  160. assert(cSkip == 0);
  161. aeip[0] = pep->ContextRecord->Eip;
  162. pebp = (ULONG *) pep->ContextRecord->Ebp;
  163. }
  164. if (pebp >= pebpMin && pebp < pebpMax)
  165. {
  166. __try
  167. {
  168. for ( ; ieip < cSkip + cFrames; ieip++)
  169. {
  170. if (ieip >= cSkip)
  171. {
  172. aeip[ieip - cSkip] = *(pebp + 1); // save an eip
  173. }
  174. ULONG *pebpNext = (ULONG *) *pebp;
  175. if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1)
  176. {
  177. break;
  178. }
  179. pebp = pebpNext;
  180. }
  181. }
  182. __except(EXCEPTION_EXECUTE_HANDLER)
  183. {
  184. ;
  185. }
  186. }
  187. #endif // i386 == 1
  188. }
  189. #endif // ifdef DBG_CERTSRV_DEBUG_PRINT
  190. FNLOGEXCEPTION *s_pfnLogException = NULL;
  191. VOID
  192. myLogExceptionInit(
  193. OPTIONAL IN FNLOGEXCEPTION *pfnLogException)
  194. {
  195. s_pfnLogException = pfnLogException;
  196. }
  197. HRESULT
  198. myHExceptionCodePrint(
  199. IN EXCEPTION_POINTERS const *pep,
  200. OPTIONAL IN char const *pszFile,
  201. IN DWORD dwFile,
  202. IN DWORD dwLine)
  203. {
  204. HRESULT hr;
  205. #ifdef DBG_CERTSRV_DEBUG_PRINT
  206. if (DbgIsSSActive(DBG_SS_ERROR) &&
  207. (!myIsDelayLoadHResult(pep->ExceptionRecord->ExceptionCode) ||
  208. DbgIsSSActive(DBG_SS_MODLOAD)))
  209. {
  210. WCHAR awc[35 + 3 * cwcDWORDSPRINTF];
  211. ULONG aeip[16];
  212. wsprintf(
  213. awc,
  214. L"0x%x @ 0x%p",
  215. pep->ExceptionRecord->ExceptionFlags,
  216. pep->ExceptionRecord->ExceptionAddress);
  217. if (NULL == pszFile)
  218. {
  219. CSPrintErrorLineFileData(
  220. awc,
  221. __MAKELINEFILE__(dwFile, dwLine),
  222. pep->ExceptionRecord->ExceptionCode);
  223. }
  224. else
  225. {
  226. CSPrintError(
  227. "Exception",
  228. awc,
  229. pszFile,
  230. dwLine,
  231. pep->ExceptionRecord->ExceptionCode,
  232. S_OK);
  233. }
  234. myCaptureStackBackTrace(pep, 0, ARRAYSIZE(aeip), aeip);
  235. for (int i = 0; i < ARRAYSIZE(aeip); i++)
  236. {
  237. if (0 == aeip[i])
  238. {
  239. break;
  240. }
  241. DbgPrintf(MAXDWORD, "ln %x;", aeip[i]);
  242. }
  243. if (0 < i)
  244. {
  245. DbgPrintf(MAXDWORD, "\n");
  246. }
  247. }
  248. #endif // DBG_CERTSRV_DEBUG_PRINT
  249. hr = myHExceptionCode(pep);
  250. if (NULL != s_pfnLogException)
  251. {
  252. (*s_pfnLogException)(hr, pep, pszFile, dwFile, dwLine);
  253. }
  254. return(hr);
  255. }
  256. BOOL
  257. myIsDelayLoadHResult(
  258. IN HRESULT hr)
  259. {
  260. return(ISDELAYLOADHRESULT(hr));
  261. }
  262. #define wszCOLONSPACE L": "
  263. WCHAR const *
  264. myHResultToStringEx(
  265. IN OUT WCHAR *awchr,
  266. IN HRESULT hr,
  267. IN BOOL fRaw)
  268. {
  269. HRESULT hrd;
  270. WCHAR const *pwszType;
  271. LONG cwc;
  272. hrd = hr;
  273. pwszType = L"";
  274. if (ISJETERROR(hr))
  275. {
  276. pwszType = wszJETERRORPREFIX wszCOLONSPACE;
  277. }
  278. else if (ISJETHRESULT(hr))
  279. {
  280. hrd = JETERROR_FROM_HRESULT(hr);
  281. pwszType = wszJETERRORPREFIX wszCOLONSPACE;
  282. }
  283. else if (ISOSSERROR(hr))
  284. {
  285. hrd = OSSERROR_FROM_HRESULT(hr);
  286. pwszType = wszOSSERRORPREFIX wszCOLONSPACE;
  287. }
  288. else if (ISHTTPHRESULT(hr) || ISHTTPERROR(hr))
  289. {
  290. hrd = WIN32ERROR_FROM_HRESULT(hr);
  291. pwszType = wszWIN32ERRORPREFIX L"/" wszHTTPERRORPREFIX wszCOLONSPACE;
  292. }
  293. else if (ISWIN32HRESULT(hr) || ISWIN32ERROR(hr))
  294. {
  295. hrd = WIN32ERROR_FROM_HRESULT(hr);
  296. pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
  297. }
  298. else if (ISDELAYLOADHRESULTFACILITY(hr))
  299. {
  300. hrd = WIN32ERROR_FROM_DELAYLOAD(hr);
  301. pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
  302. }
  303. else if (ISSETUPHRESULT(hr))
  304. {
  305. pwszType = wszSETUPERRORPREFIX wszCOLONSPACE;
  306. }
  307. if (fRaw)
  308. {
  309. pwszType = L"";
  310. }
  311. cwc = _snwprintf(
  312. awchr,
  313. cwcHRESULTSTRING,
  314. L"0x%x (%ws%d)",
  315. hr,
  316. pwszType,
  317. hrd);
  318. if (0 > cwc || cwcHRESULTSTRING <= cwc)
  319. {
  320. awchr[cwcHRESULTSTRING - 1] = L'\0';
  321. }
  322. return(awchr);
  323. }
  324. WCHAR const *
  325. myHResultToString(
  326. IN OUT WCHAR *awchr,
  327. IN HRESULT hr)
  328. {
  329. return(myHResultToStringEx(awchr, hr, FALSE));
  330. }
  331. WCHAR const *
  332. myHResultToStringRaw(
  333. IN OUT WCHAR *awchr,
  334. IN HRESULT hr)
  335. {
  336. return(myHResultToStringEx(awchr, hr, TRUE));
  337. }
  338. typedef struct _ERRORMAP
  339. {
  340. HRESULT hr;
  341. UINT idMessage;
  342. } ERRORMAP;
  343. ERRORMAP g_aSetup[] = {
  344. { ERROR_EXPECTED_SECTION_NAME, IDS_SETUP_ERROR_EXPECTED_SECTION_NAME, },
  345. { ERROR_BAD_SECTION_NAME_LINE, IDS_SETUP_ERROR_BAD_SECTION_NAME_LINE, },
  346. { ERROR_SECTION_NAME_TOO_LONG, IDS_SETUP_ERROR_SECTION_NAME_TOO_LONG, },
  347. { ERROR_GENERAL_SYNTAX, IDS_SETUP_ERROR_GENERAL_SYNTAX, },
  348. { ERROR_WRONG_INF_STYLE, IDS_SETUP_ERROR_WRONG_INF_STYLE, },
  349. { ERROR_SECTION_NOT_FOUND, IDS_SETUP_ERROR_SECTION_NOT_FOUND, },
  350. { ERROR_LINE_NOT_FOUND, IDS_SETUP_ERROR_LINE_NOT_FOUND, },
  351. };
  352. ERRORMAP s_aHttp[] =
  353. {
  354. { HTTP_STATUS_CONTINUE, IDS_HTTP_STATUS_CONTINUE },
  355. { HTTP_STATUS_SWITCH_PROTOCOLS, IDS_HTTP_STATUS_SWITCH_PROTOCOLS },
  356. { HTTP_STATUS_OK, IDS_HTTP_STATUS_OK },
  357. { HTTP_STATUS_CREATED, IDS_HTTP_STATUS_CREATED },
  358. { HTTP_STATUS_ACCEPTED, IDS_HTTP_STATUS_ACCEPTED },
  359. { HTTP_STATUS_PARTIAL, IDS_HTTP_STATUS_PARTIAL },
  360. { HTTP_STATUS_NO_CONTENT, IDS_HTTP_STATUS_NO_CONTENT },
  361. { HTTP_STATUS_RESET_CONTENT, IDS_HTTP_STATUS_RESET_CONTENT },
  362. { HTTP_STATUS_PARTIAL_CONTENT, IDS_HTTP_STATUS_PARTIAL_CONTENT },
  363. { HTTP_STATUS_AMBIGUOUS, IDS_HTTP_STATUS_AMBIGUOUS },
  364. { HTTP_STATUS_MOVED, IDS_HTTP_STATUS_MOVED },
  365. { HTTP_STATUS_REDIRECT, IDS_HTTP_STATUS_REDIRECT },
  366. { HTTP_STATUS_REDIRECT_METHOD, IDS_HTTP_STATUS_REDIRECT_METHOD },
  367. { HTTP_STATUS_NOT_MODIFIED, IDS_HTTP_STATUS_NOT_MODIFIED },
  368. { HTTP_STATUS_USE_PROXY, IDS_HTTP_STATUS_USE_PROXY },
  369. { HTTP_STATUS_REDIRECT_KEEP_VERB, IDS_HTTP_STATUS_REDIRECT_KEEP_VERB },
  370. { HTTP_STATUS_BAD_REQUEST, IDS_HTTP_STATUS_BAD_REQUEST },
  371. { HTTP_STATUS_DENIED, IDS_HTTP_STATUS_DENIED },
  372. { HTTP_STATUS_PAYMENT_REQ, IDS_HTTP_STATUS_PAYMENT_REQ },
  373. { HTTP_STATUS_FORBIDDEN, IDS_HTTP_STATUS_FORBIDDEN },
  374. { HTTP_STATUS_NOT_FOUND, IDS_HTTP_STATUS_NOT_FOUND },
  375. { HTTP_STATUS_BAD_METHOD, IDS_HTTP_STATUS_BAD_METHOD },
  376. { HTTP_STATUS_NONE_ACCEPTABLE, IDS_HTTP_STATUS_NONE_ACCEPTABLE },
  377. { HTTP_STATUS_PROXY_AUTH_REQ, IDS_HTTP_STATUS_PROXY_AUTH_REQ },
  378. { HTTP_STATUS_REQUEST_TIMEOUT, IDS_HTTP_STATUS_REQUEST_TIMEOUT },
  379. { HTTP_STATUS_CONFLICT, IDS_HTTP_STATUS_CONFLICT },
  380. { HTTP_STATUS_GONE, IDS_HTTP_STATUS_GONE },
  381. { HTTP_STATUS_LENGTH_REQUIRED, IDS_HTTP_STATUS_LENGTH_REQUIRED },
  382. { HTTP_STATUS_PRECOND_FAILED, IDS_HTTP_STATUS_PRECOND_FAILED },
  383. { HTTP_STATUS_REQUEST_TOO_LARGE, IDS_HTTP_STATUS_REQUEST_TOO_LARGE },
  384. { HTTP_STATUS_URI_TOO_LONG, IDS_HTTP_STATUS_URI_TOO_LONG },
  385. { HTTP_STATUS_UNSUPPORTED_MEDIA, IDS_HTTP_STATUS_UNSUPPORTED_MEDIA },
  386. { HTTP_STATUS_RETRY_WITH, IDS_HTTP_STATUS_RETRY_WITH },
  387. { HTTP_STATUS_SERVER_ERROR, IDS_HTTP_STATUS_SERVER_ERROR },
  388. { HTTP_STATUS_NOT_SUPPORTED, IDS_HTTP_STATUS_NOT_SUPPORTED },
  389. { HTTP_STATUS_BAD_GATEWAY, IDS_HTTP_STATUS_BAD_GATEWAY },
  390. { HTTP_STATUS_SERVICE_UNAVAIL, IDS_HTTP_STATUS_SERVICE_UNAVAIL },
  391. { HTTP_STATUS_GATEWAY_TIMEOUT, IDS_HTTP_STATUS_GATEWAY_TIMEOUT },
  392. { HTTP_STATUS_VERSION_NOT_SUP, IDS_HTTP_STATUS_VERSION_NOT_SUP },
  393. };
  394. DWORD
  395. errLoadStaticMessage(
  396. IN HRESULT hr,
  397. IN ERRORMAP const *pmap,
  398. IN DWORD cmap,
  399. OUT WCHAR const **ppwszOut)
  400. {
  401. DWORD cwc = 0;
  402. ERRORMAP const *pmapEnd;
  403. for (pmapEnd = &pmap[cmap]; pmap < pmapEnd; pmap++)
  404. {
  405. if (hr == pmap->hr)
  406. {
  407. *ppwszOut = myLoadResourceString(pmap->idMessage);
  408. if (NULL != *ppwszOut)
  409. {
  410. cwc = wcslen(*ppwszOut);
  411. }
  412. break;
  413. }
  414. }
  415. //error:
  416. return(cwc);
  417. }
  418. DWORD
  419. errFormatMessage(
  420. IN HMODULE hMod,
  421. IN HRESULT hr,
  422. OUT WCHAR const **ppwszOut,
  423. OPTIONAL IN WCHAR const * const *ppwszArgs)
  424. {
  425. DWORD dwFlags;
  426. dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER;
  427. if (NULL == hMod)
  428. {
  429. dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
  430. }
  431. else
  432. {
  433. dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  434. }
  435. if (NULL == ppwszArgs || NULL == ppwszArgs[0])
  436. {
  437. dwFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
  438. }
  439. else
  440. {
  441. dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
  442. }
  443. return(FormatMessage(
  444. dwFlags,
  445. hMod,
  446. hr,
  447. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  448. (WCHAR *) ppwszOut,
  449. 1,
  450. (va_list *) ppwszArgs));
  451. }
  452. // Alloc and return error message string
  453. WCHAR const *
  454. myGetErrorMessageText(
  455. IN HRESULT hr,
  456. IN BOOL fHResultString)
  457. {
  458. return(myGetErrorMessageTextEx(hr, fHResultString, NULL));
  459. }
  460. WCHAR const *
  461. myGetErrorMessageText1(
  462. IN HRESULT hr,
  463. IN BOOL fHResultString,
  464. IN OPTIONAL WCHAR const *pwszInsertionText)
  465. {
  466. WCHAR const *apwszInsertionText[2];
  467. WCHAR const * const *papwsz = NULL;
  468. if (NULL != pwszInsertionText)
  469. {
  470. apwszInsertionText[0] = pwszInsertionText;
  471. apwszInsertionText[1] = NULL;
  472. papwsz = apwszInsertionText;
  473. }
  474. return(myGetErrorMessageTextEx(hr, fHResultString, papwsz));
  475. }
  476. WCHAR const *
  477. myGetErrorMessageTextEx(
  478. IN HRESULT hr,
  479. IN BOOL fHResultString,
  480. IN OPTIONAL WCHAR const * const *papwszInsertionText)
  481. {
  482. static WCHAR s_wszUnknownDefault[] = L"Error";
  483. WCHAR const *pwszRet = NULL;
  484. WCHAR const *pwszRetStatic = NULL;
  485. WCHAR *pwszMsgT;
  486. WCHAR awchr[cwcHRESULTSTRING];
  487. DWORD cwc;
  488. DWORD cwcCopy;
  489. DWORD cwcUnexpected;
  490. WCHAR const *pwszUnexpected = NULL;
  491. WCHAR wszEmpty[] = L"";
  492. HMODULE hMod1 = NULL;
  493. HMODULE hMod2 = NULL;
  494. if (E_UNEXPECTED == hr)
  495. {
  496. pwszUnexpected = myLoadResourceString(IDS_E_UNEXPECTED); // L"Unexpected method call sequence."
  497. }
  498. #if (0 == i386)
  499. else if (STATUS_DATATYPE_MISALIGNMENT == hr)
  500. {
  501. pwszUnexpected = myLoadResourceString(IDS_E_DATA_MISALIGNMENT); // L"Possible data alignment fault."
  502. }
  503. #endif
  504. if (NULL == pwszUnexpected)
  505. {
  506. HRESULT hrHttp = hr;
  507. if (ISWIN32HRESULT(hrHttp))
  508. {
  509. hrHttp = WIN32ERROR_FROM_HRESULT(hrHttp);
  510. }
  511. if (ISHTTPERROR(hrHttp))
  512. {
  513. cwc = errLoadStaticMessage(
  514. hrHttp,
  515. s_aHttp,
  516. ARRAYSIZE(s_aHttp),
  517. &pwszUnexpected);
  518. }
  519. }
  520. if (NULL == pwszUnexpected)
  521. {
  522. pwszUnexpected = wszEmpty;
  523. }
  524. cwcUnexpected = wcslen(pwszUnexpected);
  525. cwc = errFormatMessage(NULL, hr, &pwszRet, papwszInsertionText);
  526. if (0 == cwc && ISDELAYLOADHRESULTFACILITY(hr))
  527. {
  528. cwc = errFormatMessage(
  529. NULL,
  530. WIN32ERROR_FROM_DELAYLOAD(hr),
  531. &pwszRet,
  532. papwszInsertionText);
  533. }
  534. if (0 == cwc && ISSETUPHRESULT(hr))
  535. {
  536. cwc = errLoadStaticMessage(
  537. hr,
  538. g_aSetup,
  539. ARRAYSIZE(g_aSetup),
  540. &pwszRetStatic);
  541. pwszRet = pwszRetStatic;
  542. }
  543. if (0 == cwc)
  544. {
  545. hMod1 = LoadLibrary(L"ntdsbmsg.dll");
  546. if (NULL != hMod1)
  547. {
  548. HRESULT hrEDB = hr;
  549. HRESULT hrFormat;
  550. BOOL fFirst = TRUE;
  551. while (TRUE)
  552. {
  553. cwc = errFormatMessage(hMod1, hrEDB, &pwszRet, papwszInsertionText);
  554. if (0 == cwc && FAILED(hrEDB) && fFirst)
  555. {
  556. hrFormat = myHLastError();
  557. if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
  558. {
  559. hrEDB = myJetHResult(hrEDB);
  560. if (hrEDB != hr)
  561. {
  562. fFirst = FALSE;
  563. continue;
  564. }
  565. }
  566. }
  567. break;
  568. }
  569. }
  570. }
  571. if (0 == cwc)
  572. {
  573. HMODULE hModT = GetModuleHandle(L"wininet.dll");
  574. if (NULL != hModT)
  575. {
  576. HRESULT hrHttp = hr;
  577. HRESULT hrFormat;
  578. BOOL fFirst = TRUE;
  579. while (TRUE)
  580. {
  581. cwc = errFormatMessage(hModT, hrHttp, &pwszRet, papwszInsertionText);
  582. if (0 == cwc && ISWIN32HRESULT(hrHttp) && fFirst)
  583. {
  584. hrFormat = myHLastError();
  585. if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
  586. {
  587. hrHttp = WIN32ERROR_FROM_HRESULT(hrHttp);
  588. if (hrHttp != hr)
  589. {
  590. fFirst = FALSE;
  591. continue;
  592. }
  593. }
  594. }
  595. break;
  596. }
  597. }
  598. }
  599. if (0 == cwc)
  600. {
  601. hMod2 = LoadLibrary(L"cdosys.dll");
  602. if (NULL != hMod2)
  603. {
  604. cwc = errFormatMessage(hMod2, hr, &pwszRet, papwszInsertionText);
  605. }
  606. }
  607. if (0 == cwc) // couldn't find error, use default & error code
  608. {
  609. fHResultString = TRUE;
  610. }
  611. awchr[0] = L'\0';
  612. if (fHResultString)
  613. {
  614. myHResultToString(awchr, hr);
  615. }
  616. if (0 == cwc)
  617. {
  618. pwszRetStatic = myLoadResourceString(IDS_UNKNOWN_ERROR_CODE); // L"Error"
  619. if (NULL == pwszRetStatic)
  620. {
  621. pwszRetStatic = s_wszUnknownDefault;
  622. }
  623. pwszRet = pwszRetStatic;
  624. }
  625. // strip trailing \r\n
  626. cwcCopy = wcslen(pwszRet);
  627. if (2 <= cwcCopy &&
  628. L'\r' == pwszRet[cwcCopy - 2] &&
  629. L'\n' == pwszRet[cwcCopy - 1])
  630. {
  631. cwcCopy -= 2;
  632. }
  633. cwc = cwcCopy + 1 + cwcUnexpected + 1 + wcslen(awchr) + 1;
  634. pwszMsgT = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
  635. if (NULL == pwszMsgT)
  636. {
  637. _JumpError(E_OUTOFMEMORY, error, "LocalAlloc");
  638. }
  639. CopyMemory(pwszMsgT, pwszRet, cwcCopy * sizeof(WCHAR));
  640. pwszMsgT[cwcCopy] = L'\0';
  641. if (0 != cwcUnexpected)
  642. {
  643. wcscat(pwszMsgT, L" ");
  644. wcscat(pwszMsgT, pwszUnexpected);
  645. }
  646. if (fHResultString)
  647. {
  648. wcscat(pwszMsgT, L" ");
  649. wcscat(pwszMsgT, awchr);
  650. }
  651. CSASSERT(wcslen(pwszMsgT) < cwc);
  652. if (NULL != pwszRet && pwszRetStatic != pwszRet)
  653. {
  654. LocalFree(const_cast<WCHAR *>(pwszRet));
  655. }
  656. pwszRet = pwszMsgT;
  657. error:
  658. if (NULL != hMod1)
  659. {
  660. FreeLibrary(hMod1);
  661. }
  662. if (NULL != hMod2)
  663. {
  664. FreeLibrary(hMod2);
  665. }
  666. return(pwszRet);
  667. }