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.

590 lines
10 KiB

  1. #include "StdAfx.h"
  2. #include "Error.h"
  3. #include <ComDef.h>
  4. using namespace _com_util;
  5. #define COUNT_OF(a) (sizeof(a) / sizeof(a[0]))
  6. namespace Error_cpp
  7. {
  8. IErrorInfoPtr __stdcall AdmtCreateErrorInfo(const CLSID& clsid, const IID& iid, const _com_error& ce, LPCTSTR pszDescription);
  9. // AdmtSetErrorImpl Method
  10. inline HRESULT __stdcall AdmtSetErrorImpl(const CLSID& clsid, const IID& iid, const _com_error& ce, LPCTSTR pszDescription)
  11. {
  12. SetErrorInfo(0, AdmtCreateErrorInfo(clsid, iid, ce, pszDescription));
  13. return ce.Error();
  14. }
  15. // AdmtThrowErrorImpl Method
  16. inline void __stdcall AdmtThrowErrorImpl(const CLSID& clsid, const IID& iid, const _com_error& ce, LPCTSTR pszDescription)
  17. {
  18. IErrorInfoPtr spErrorInfo = AdmtCreateErrorInfo(clsid, iid, ce, pszDescription);
  19. if (spErrorInfo)
  20. {
  21. _com_raise_error(ce.Error(), spErrorInfo.Detach());
  22. }
  23. else
  24. {
  25. _com_raise_error(ce.Error());
  26. }
  27. }
  28. }
  29. using namespace Error_cpp;
  30. //---------------------------------------------------------------------------
  31. // Error Methods
  32. //---------------------------------------------------------------------------
  33. // AdmtSetError Methods -------------------------------------------------
  34. HRESULT __cdecl AdmtSetError(const CLSID& clsid, const IID& iid, _com_error ce, UINT uId, ...)
  35. {
  36. _TCHAR szFormat[512];
  37. _TCHAR szDescription[1024];
  38. if (LoadString(_Module.GetResourceInstance(), uId, szFormat, 512))
  39. {
  40. va_list args;
  41. va_start(args, uId);
  42. _vsntprintf(szDescription, COUNT_OF(szDescription), szFormat, args);
  43. va_end(args);
  44. }
  45. else
  46. {
  47. szDescription[0] = _T('\0');
  48. }
  49. return AdmtSetErrorImpl(clsid, iid, ce, szDescription);
  50. }
  51. HRESULT __cdecl AdmtSetError(const CLSID& clsid, const IID& iid, _com_error ce, LPCTSTR pszFormat, ...)
  52. {
  53. _TCHAR szDescription[1024];
  54. if (pszFormat)
  55. {
  56. va_list args;
  57. va_start(args, pszFormat);
  58. _vsntprintf(szDescription, COUNT_OF(szDescription), pszFormat, args);
  59. va_end(args);
  60. }
  61. else
  62. {
  63. szDescription[0] = _T('\0');
  64. }
  65. return AdmtSetErrorImpl(clsid, iid, ce, szDescription);
  66. }
  67. // AdmtThrowError Methods -----------------------------------------------
  68. void __cdecl AdmtThrowError(const CLSID& clsid, const IID& iid, _com_error ce, UINT uId, ...)
  69. {
  70. _TCHAR szFormat[512];
  71. _TCHAR szDescription[1024];
  72. if (LoadString(_Module.GetResourceInstance(), uId, szFormat, 512))
  73. {
  74. va_list args;
  75. va_start(args, uId);
  76. _vsntprintf(szDescription, COUNT_OF(szDescription), szFormat, args);
  77. va_end(args);
  78. }
  79. else
  80. {
  81. szDescription[0] = _T('\0');
  82. }
  83. AdmtThrowErrorImpl(clsid, iid, ce, szDescription);
  84. }
  85. void __cdecl AdmtThrowError(const CLSID& clsid, const IID& iid, _com_error ce, LPCTSTR pszFormat, ...)
  86. {
  87. _TCHAR szDescription[1024];
  88. if (pszFormat)
  89. {
  90. va_list args;
  91. va_start(args, pszFormat);
  92. _vsntprintf(szDescription, COUNT_OF(szDescription), pszFormat, args);
  93. va_end(args);
  94. }
  95. else
  96. {
  97. szDescription[0] = _T('\0');
  98. }
  99. AdmtThrowErrorImpl(clsid, iid, ce, szDescription);
  100. }
  101. // Implementation -----------------------------------------------------------
  102. namespace Error_cpp
  103. {
  104. // AdmtCreateErrorInfo Method
  105. IErrorInfoPtr __stdcall AdmtCreateErrorInfo(const CLSID& clsid, const IID& iid, const _com_error& ce, LPCTSTR pszDescription)
  106. {
  107. ICreateErrorInfoPtr spCreateErrorInfo;
  108. CreateErrorInfo(&spCreateErrorInfo);
  109. if (spCreateErrorInfo)
  110. {
  111. IErrorInfoPtr spErrorInfo = ce.ErrorInfo();
  112. if (spErrorInfo == NULL)
  113. {
  114. GetErrorInfo(0, &spErrorInfo);
  115. }
  116. // source
  117. if (IsEqualCLSID(clsid, GUID_NULL) == FALSE)
  118. {
  119. LPOLESTR pszProgId;
  120. if (ProgIDFromCLSID(clsid, &pszProgId) == S_OK)
  121. {
  122. spCreateErrorInfo->SetSource(pszProgId);
  123. CoTaskMemFree(pszProgId);
  124. }
  125. else
  126. {
  127. spCreateErrorInfo->SetSource(L"");
  128. }
  129. }
  130. else if (spErrorInfo)
  131. {
  132. BSTR bstrSource;
  133. spErrorInfo->GetSource(&bstrSource);
  134. spCreateErrorInfo->SetSource(bstrSource);
  135. SysFreeString(bstrSource);
  136. }
  137. else
  138. {
  139. spCreateErrorInfo->SetSource(L"");
  140. }
  141. // GUID
  142. if (IsEqualIID(iid, GUID_NULL) == FALSE)
  143. {
  144. spCreateErrorInfo->SetGUID(iid);
  145. }
  146. else if (spErrorInfo)
  147. {
  148. GUID guid;
  149. spErrorInfo->GetGUID(&guid);
  150. spCreateErrorInfo->SetGUID(guid);
  151. }
  152. else
  153. {
  154. spCreateErrorInfo->SetGUID(GUID_NULL);
  155. }
  156. // description
  157. _bstr_t strDescription = pszDescription;
  158. if (spErrorInfo)
  159. {
  160. BSTR bstrSource;
  161. spErrorInfo->GetSource(&bstrSource);
  162. if (SysStringLen(bstrSource) > 0)
  163. {
  164. if (strDescription.length() > 0)
  165. {
  166. strDescription += _T(" : ");
  167. }
  168. strDescription += bstrSource;
  169. }
  170. SysFreeString(bstrSource);
  171. BSTR bstrDescription;
  172. spErrorInfo->GetDescription(&bstrDescription);
  173. if (SysStringLen(bstrDescription) > 0)
  174. {
  175. if (strDescription.length() > 0)
  176. {
  177. strDescription += _T(" ");
  178. }
  179. strDescription += bstrDescription;
  180. }
  181. else
  182. {
  183. LPCTSTR pszErrorMessage = ce.ErrorMessage();
  184. if (pszErrorMessage)
  185. {
  186. if (strDescription.length() > 0)
  187. {
  188. strDescription += _T(" : ");
  189. }
  190. strDescription += pszErrorMessage;
  191. }
  192. }
  193. SysFreeString(bstrDescription);
  194. }
  195. else
  196. {
  197. LPCTSTR pszErrorMessage = ce.ErrorMessage();
  198. if (pszErrorMessage)
  199. {
  200. if (strDescription.length() > 0)
  201. {
  202. strDescription += _T(" ");
  203. }
  204. strDescription += pszErrorMessage;
  205. }
  206. }
  207. spCreateErrorInfo->SetDescription(strDescription);
  208. // help file
  209. if (spErrorInfo)
  210. {
  211. BSTR bstrHelpFile;
  212. spErrorInfo->GetHelpFile(&bstrHelpFile);
  213. spCreateErrorInfo->SetHelpFile(bstrHelpFile);
  214. SysFreeString(bstrHelpFile);
  215. }
  216. else
  217. {
  218. spCreateErrorInfo->SetHelpFile(L"");
  219. }
  220. // help context
  221. DWORD dwHelpContext = 0;
  222. if (spErrorInfo)
  223. {
  224. spErrorInfo->GetHelpContext(&dwHelpContext);
  225. }
  226. spCreateErrorInfo->SetHelpContext(dwHelpContext);
  227. }
  228. return IErrorInfoPtr(spCreateErrorInfo);
  229. }
  230. } // namespace Error_cpp
  231. /*
  232. _bstr_t __stdcall FormatResult(HRESULT hr);
  233. _bstr_t __cdecl FormatError(_com_error ce, UINT uId, ...)
  234. {
  235. _bstr_t bstrDescription;
  236. try
  237. {
  238. _TCHAR szFormat[1024];
  239. if (LoadString(_Module.GetResourceInstance(), uId, szFormat, 1024))
  240. {
  241. _TCHAR szDescription[1024];
  242. va_list args;
  243. va_start(args, uId);
  244. _vsntprintf(szDescription, COUNT_OF(szDescription), szFormat, args);
  245. va_end(args);
  246. bstrDescription = szDescription;
  247. }
  248. _bstr_t bstrSource = ce.Source();
  249. if (bstrSource.length() > 0)
  250. {
  251. if (bstrDescription.length() > 0)
  252. {
  253. bstrDescription += _T(" : ");
  254. }
  255. bstrDescription += bstrSource;
  256. }
  257. _bstr_t bstrOldDescription = ce.Description();
  258. if (bstrOldDescription.length() > 0)
  259. {
  260. if (bstrDescription.length() > 0)
  261. {
  262. bstrDescription += _T(" ");
  263. }
  264. bstrDescription += bstrOldDescription;
  265. }
  266. _bstr_t bstrResult = FormatResult(ce.Error());
  267. if (bstrResult.length() > 0)
  268. {
  269. if (bstrDescription.length() > 0)
  270. {
  271. bstrDescription += _T(" : ");
  272. }
  273. bstrDescription += bstrResult;
  274. }
  275. }
  276. catch (...)
  277. {
  278. ;
  279. }
  280. return bstrDescription;
  281. }
  282. _bstr_t __cdecl FormatError(_com_error ce, LPCTSTR pszFormat, ...)
  283. {
  284. _bstr_t bstrDescription;
  285. try
  286. {
  287. if (pszFormat)
  288. {
  289. _TCHAR szDescription[1024];
  290. va_list args;
  291. va_start(args, pszFormat);
  292. _vsntprintf(szDescription, COUNT_OF(szDescription), pszFormat, args);
  293. va_end(args);
  294. bstrDescription = szDescription;
  295. }
  296. _bstr_t bstrSource = ce.Source();
  297. if (bstrSource.length() > 0)
  298. {
  299. if (bstrDescription.length() > 0)
  300. {
  301. bstrDescription += _T(" : ");
  302. }
  303. bstrDescription += bstrSource;
  304. }
  305. _bstr_t bstrOldDescription = ce.Description();
  306. if (bstrOldDescription.length() > 0)
  307. {
  308. if (bstrDescription.length() > 0)
  309. {
  310. bstrDescription += _T(" ");
  311. }
  312. bstrDescription += bstrOldDescription;
  313. }
  314. _bstr_t bstrResult = FormatResult(ce.Error());
  315. if (bstrResult.length() > 0)
  316. {
  317. if (bstrDescription.length() > 0)
  318. {
  319. bstrDescription += _T(" : ");
  320. }
  321. bstrDescription += bstrResult;
  322. }
  323. }
  324. catch (...)
  325. {
  326. ;
  327. }
  328. return bstrDescription;
  329. }
  330. _bstr_t __stdcall FormatResult(HRESULT hr)
  331. {
  332. _bstr_t bstrError;
  333. LPTSTR pszError = NULL;
  334. try
  335. {
  336. switch (HRESULT_FACILITY(hr))
  337. {
  338. // case FACILITY_NULL: // 0
  339. // case FACILITY_RPC: // 1
  340. // case FACILITY_DISPATCH: // 2
  341. // case FACILITY_STORAGE: // 3
  342. // case FACILITY_ITF: // 4
  343. // {
  344. // HMODULE hModule = LoadLibrary(_T("MSDAERR.dll"));
  345. // if (hModule)
  346. // {
  347. // FormatMessage(
  348. // FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
  349. // hModule,
  350. // hr,
  351. // 0,
  352. // (LPTSTR)&pszError,
  353. // 0,
  354. // NULL
  355. // );
  356. // FreeLibrary(hModule);
  357. // }
  358. // break;
  359. // }
  360. case FACILITY_WIN32: // 7
  361. {
  362. FormatMessage(
  363. FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
  364. NULL,
  365. hr,
  366. 0,
  367. (LPTSTR)&pszError,
  368. 0,
  369. NULL
  370. );
  371. break;
  372. }
  373. // case FACILITY_WINDOWS: // 8
  374. // case FACILITY_SSPI: // 9
  375. // case FACILITY_SECURITY: // 9
  376. // case FACILITY_CONTROL: // 10
  377. // {
  378. // HMODULE hModule = LoadLibrary(_T("MSADER15.dll"));
  379. // if (hModule)
  380. // {
  381. // FormatMessage(
  382. // FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
  383. // hModule,
  384. // hr,
  385. // 0,
  386. // (LPTSTR)&pszError,
  387. // 0,
  388. // NULL
  389. // );
  390. // FreeLibrary(hModule);
  391. // }
  392. // break;
  393. // }
  394. // case FACILITY_CERT: // 11
  395. // case FACILITY_INTERNET: // 12
  396. // case FACILITY_MEDIASERVER: // 13
  397. case FACILITY_MSMQ: // 14
  398. {
  399. HMODULE hModule = LoadLibrary(_T("MQUTIL.dll"));
  400. if (hModule)
  401. {
  402. FormatMessage(
  403. FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
  404. hModule,
  405. hr,
  406. 0,
  407. (LPTSTR)&pszError,
  408. 0,
  409. NULL
  410. );
  411. FreeLibrary(hModule);
  412. }
  413. break;
  414. }
  415. // case FACILITY_SETUPAPI: // 15
  416. // case FACILITY_SCARD: // 16
  417. // case FACILITY_COMPLUS: // 17
  418. // case FACILITY_AAF: // 18
  419. // case FACILITY_URT: // 19
  420. // case FACILITY_ACS: // 20
  421. default:
  422. {
  423. FormatMessage(
  424. FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
  425. NULL,
  426. hr,
  427. 0,
  428. (LPTSTR)&pszError,
  429. 0,
  430. NULL
  431. );
  432. break;
  433. }
  434. }
  435. if (pszError)
  436. {
  437. size_t cch = _tcslen(pszError);
  438. if ((cch > 1) && (pszError[cch - 1] == _T('\n')))
  439. {
  440. pszError[cch - 1] = 0;
  441. if (pszError[cch - 2] == _T('\r'))
  442. {
  443. pszError[cch - 2] = 0;
  444. }
  445. }
  446. bstrError = pszError;
  447. }
  448. else
  449. {
  450. _TCHAR szError[32];
  451. _stprintf(szError, _T("Unknown error 0x%08lX."), hr);
  452. bstrError = szError;
  453. }
  454. }
  455. catch (...)
  456. {
  457. ;
  458. }
  459. if (pszError)
  460. {
  461. LocalFree((HLOCAL)pszError);
  462. }
  463. return bstrError;
  464. }
  465. */