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.

410 lines
12 KiB

  1. //---------------------------------------------------------------------------
  2. // SetErrorInfo.cpp
  3. //
  4. // Copyright (c) 1996 Microsoft Corporation, All Rights Reserved
  5. // Developed by Sheridan Software Systems, Inc.
  6. //---------------------------------------------------------------------------
  7. #include "stdafx.h"
  8. #include "globals.h"
  9. #include "resource.h"
  10. #include <mbstring.h>
  11. // needed for ASSERTs and FAIL
  12. //
  13. SZTHISFILE
  14. #define MAX_STRING_BUFFLEN 512
  15. CVDResourceDLL::CVDResourceDLL(LCID lcid)
  16. {
  17. m_lcid = lcid;
  18. m_hinstance = 0;
  19. }
  20. CVDResourceDLL::~CVDResourceDLL()
  21. {
  22. if (m_hinstance)
  23. FreeLibrary(m_hinstance);
  24. }
  25. int CVDResourceDLL::LoadString(UINT uID, // resource identifier
  26. LPTSTR lpBuffer, // address of buffer for resource
  27. int nBufferMax) // size of buffer
  28. {
  29. lpBuffer[0] = 0; //initialize buffer
  30. if (!m_hinstance)
  31. {
  32. // Get this dll's full path
  33. TCHAR szDllName[MAX_PATH];
  34. GetModuleFileName(g_hinstance, szDllName, MAX_PATH);
  35. // Strip off filename/ext leaving dir path
  36. TBYTE * szDirectory = _mbsrchr((TBYTE*)szDllName, '\\');
  37. if (!szDirectory)
  38. szDirectory = _mbsrchr((TBYTE*)szDllName, ':');
  39. if (szDirectory)
  40. {
  41. szDirectory = _mbsinc(szDirectory);
  42. *szDirectory = 0;
  43. }
  44. // construct dll name from supplied lcid
  45. TCHAR szLang[4 * 2];
  46. szLang[0] = 0;
  47. GetLocaleInfo (m_lcid,
  48. LOCALE_SABBREVLANGNAME,
  49. szLang,
  50. 4 * 2);
  51. _mbscat((TBYTE*)szDllName, (TBYTE*)VD_DLL_PREFIX);
  52. _mbscat((TBYTE*)szDllName, (TBYTE*)szLang);
  53. _mbscat((TBYTE*)szDllName, (TBYTE*)".DLL");
  54. m_hinstance = LoadLibrary(szDllName);
  55. // if dll not found try english us dll which should always be there
  56. if (!m_hinstance && szDirectory)
  57. {
  58. *szDirectory = 0;
  59. _mbscat((TBYTE*)szDllName, (TBYTE*)VD_DLL_PREFIX);
  60. _mbscat((TBYTE*)szDllName, (TBYTE*)"ENU.DLL");
  61. m_hinstance = LoadLibrary(szDllName);
  62. ASSERT(m_hinstance, VD_ASSERTMSG_CANTFINDRESOURCEDLL);
  63. }
  64. }
  65. return m_hinstance ? ::LoadString(m_hinstance, uID, lpBuffer, nBufferMax) : 0;
  66. }
  67. //=--------------------------------------------------------------------------=
  68. // VDSetErrorInfo
  69. //=--------------------------------------------------------------------------=
  70. // Sets rich error info
  71. //
  72. // Parameters:
  73. // nErrStringResID - [in] The resource ID of the error string
  74. // riid - [in] The guid of the interface that will used in
  75. // the ICreateErrorInfo::SetGUID method
  76. // pResDLL - [in] A pointer to the CVDResourceDLL object
  77. // that keeps track of the resource DLL
  78. // for error strings
  79. //
  80. void VDSetErrorInfo(UINT nErrStringResID,
  81. REFIID riid,
  82. CVDResourceDLL * pResDLL)
  83. {
  84. ICreateErrorInfo *pCreateErrorInfo;
  85. HRESULT hr = CreateErrorInfo(&pCreateErrorInfo);
  86. if (SUCCEEDED(hr))
  87. {
  88. TCHAR buff[MAX_STRING_BUFFLEN];
  89. // set guid
  90. pCreateErrorInfo->SetGUID(riid);
  91. // load source string
  92. int nLen = pResDLL->LoadString(IDS_ERR_SOURCE,
  93. buff,
  94. MAX_STRING_BUFFLEN);
  95. if (nLen > 0)
  96. {
  97. BSTR bstr = BSTRFROMANSI(buff);
  98. if (bstr)
  99. {
  100. pCreateErrorInfo->SetSource(bstr);
  101. SysFreeString(bstr);
  102. }
  103. // load error description
  104. nLen = pResDLL->LoadString(nErrStringResID,
  105. buff,
  106. MAX_STRING_BUFFLEN);
  107. if (nLen > 0)
  108. {
  109. bstr = BSTRFROMANSI(buff);
  110. if (bstr)
  111. {
  112. pCreateErrorInfo->SetDescription(bstr);
  113. SysFreeString(bstr);
  114. }
  115. }
  116. IErrorInfo *pErrorInfo;
  117. hr = pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (LPVOID FAR*) &pErrorInfo);
  118. if (SUCCEEDED(hr))
  119. {
  120. SetErrorInfo(0, pErrorInfo);
  121. pErrorInfo->Release();
  122. }
  123. }
  124. pCreateErrorInfo->Release();
  125. }
  126. }
  127. //=--------------------------------------------------------------------------=
  128. // VDCheckErrorInfo
  129. //=--------------------------------------------------------------------------=
  130. // Checks if rich error info is already available, otherwise it supplies it
  131. //
  132. // Parameters:
  133. // nErrStringResID - [in] The resource ID of the error string
  134. // riid - [in] The guid of the interface that will used in
  135. // the ICreateErrorInfo::SetGUID method
  136. // punkSource - [in] The interface that generated the error.
  137. // (e.g. a call to ICursorFind)
  138. // riidSource - [in] The interface ID of the interface that
  139. // generated the error. If punkSource is not
  140. // NULL then this guid is passed into the
  141. // ISupportErrorInfo::InterfaceSupportsErrorInfo
  142. // method.
  143. // pResDLL - [in] A pointer to the CVDResourceDLL object
  144. // that keeps track of the resource DLL
  145. // for error strings
  146. //
  147. void VDCheckErrorInfo(UINT nErrStringResID,
  148. REFIID riid,
  149. LPUNKNOWN punkSource,
  150. REFIID riidSource,
  151. CVDResourceDLL * pResDLL)
  152. {
  153. if (punkSource)
  154. {
  155. // check if the ISupportErrorInfo interface is implemented
  156. ISupportErrorInfo * pSupportErrorInfo = NULL;
  157. HRESULT hr = punkSource->QueryInterface(IID_ISupportErrorInfo,
  158. (void**)&pSupportErrorInfo);
  159. if SUCCEEDED(hr)
  160. {
  161. // check if the interface that generated the error supports error info
  162. BOOL fInterfaceSupported = (S_OK == pSupportErrorInfo->InterfaceSupportsErrorInfo(riidSource));
  163. pSupportErrorInfo->Release();
  164. if (fInterfaceSupported)
  165. return; // rich error info has already been supplied so just return
  166. }
  167. }
  168. // rich error info wasn't supplied so set it ourselves
  169. VDSetErrorInfo(nErrStringResID, riid, pResDLL);
  170. }
  171. //=--------------------------------------------------------------------------=
  172. // VDGetErrorInfo
  173. //=--------------------------------------------------------------------------=
  174. // if available, gets rich error info from supplied interface
  175. //
  176. // Parameters:
  177. // punkSource - [in] The interface that generated the error.
  178. // (e.g. a call to ICursorFind)
  179. // riidSource - [in] The interface ID of the interface that
  180. // generated the error. If punkSource is not
  181. // NULL then this guid is passed into the
  182. // ISupportErrorInfo::InterfaceSupportsErrorInfo
  183. // method.
  184. // pbstrErrorDesc - [out] a pointer to memory in which to return
  185. // error description BSTR.
  186. //
  187. // Note - this function is no longer used, however it might be useful in
  188. // the future so it was not permanently removed.
  189. //
  190. /*
  191. HRESULT VDGetErrorInfo(LPUNKNOWN punkSource,
  192. REFIID riidSource,
  193. BSTR * pbstrErrorDesc)
  194. {
  195. ASSERT_POINTER(pbstrErrorDesc, BSTR)
  196. if (punkSource && pbstrErrorDesc)
  197. {
  198. // init out parameter
  199. *pbstrErrorDesc = NULL;
  200. // check if the ISupportErrorInfo interface is implemented
  201. ISupportErrorInfo * pSupportErrorInfo = NULL;
  202. HRESULT hr = punkSource->QueryInterface(IID_ISupportErrorInfo,
  203. (void**)&pSupportErrorInfo);
  204. if (SUCCEEDED(hr))
  205. {
  206. // check if the interface that generated the error supports error info
  207. BOOL fInterfaceSupported = (S_OK == pSupportErrorInfo->InterfaceSupportsErrorInfo(riidSource));
  208. pSupportErrorInfo->Release();
  209. if (fInterfaceSupported)
  210. {
  211. // get error info interface
  212. IErrorInfo * pErrorInfo = NULL;
  213. hr = GetErrorInfo(0, &pErrorInfo);
  214. if (hr == S_OK)
  215. {
  216. // get rich error info
  217. hr = pErrorInfo->GetDescription(pbstrErrorDesc);
  218. pErrorInfo->Release();
  219. return hr;
  220. }
  221. }
  222. }
  223. }
  224. return E_FAIL;
  225. }
  226. */
  227. //=--------------------------------------------------------------------------=
  228. // VDMapCursorHRtoRowsetHR
  229. //=--------------------------------------------------------------------------=
  230. // Translates an ICursor HRESULT to an IRowset HRESULT
  231. //
  232. // Parameters:
  233. // nErrStringResID - [in] ICursor HRESULT
  234. // nErrStringResID - [in] The resource ID of the error string
  235. // riid - [in] The guid of the interface that will used in
  236. // the ICreateErrorInfo::SetGUID method
  237. // punkSource - [in] The interface that generated the error.
  238. // (e.g. a call to ICursorFind)
  239. // riidSource - [in] The interface ID of the interface that
  240. // generated the error. If punkSource is not
  241. // NULL then this guid is passed into the
  242. // ISupportErrorInfo::InterfaceSupportsErrorInfo
  243. // method.
  244. // pResDLL - [in] A pointer to the CVDResourceDLL object
  245. // that keeps track of the resource DLL
  246. // for error strings
  247. //
  248. // Output:
  249. // HRESULT - Translated IRowset HRESULT
  250. //
  251. HRESULT VDMapCursorHRtoRowsetHR(HRESULT hr,
  252. UINT nErrStringResIDFailed,
  253. REFIID riid,
  254. LPUNKNOWN punkSource,
  255. REFIID riidSource,
  256. CVDResourceDLL * pResDLL)
  257. {
  258. switch (hr)
  259. {
  260. case CURSOR_DB_S_ENDOFCURSOR:
  261. hr = DB_S_ENDOFROWSET;
  262. break;
  263. case CURSOR_DB_E_BADBOOKMARK:
  264. VDCheckErrorInfo(IDS_ERR_BADBOOKMARK, riid, punkSource, riidSource, pResDLL);
  265. hr = DB_E_BADBOOKMARK;
  266. break;
  267. case CURSOR_DB_E_ROWDELETED:
  268. VDCheckErrorInfo(IDS_ERR_DELETEDROW, riid, punkSource, riidSource, pResDLL);
  269. hr = DB_E_DELETEDROW;
  270. break;
  271. case CURSOR_DB_E_BADFRACTION:
  272. VDCheckErrorInfo(IDS_ERR_BADFRACTION, riid, punkSource, riidSource, pResDLL);
  273. hr = DB_E_BADRATIO;
  274. break;
  275. case CURSOR_DB_E_UPDATEINPROGRESS:
  276. VDCheckErrorInfo(IDS_ERR_UPDATEINPROGRESS, riid, punkSource, riidSource, pResDLL);
  277. hr = E_FAIL;
  278. break;
  279. case E_OUTOFMEMORY:
  280. VDCheckErrorInfo((UINT)E_OUTOFMEMORY, riid, punkSource, riidSource, pResDLL);
  281. hr = E_OUTOFMEMORY;
  282. break;
  283. default:
  284. if FAILED(hr)
  285. {
  286. VDCheckErrorInfo(nErrStringResIDFailed, riid, punkSource, riidSource, pResDLL);
  287. hr = E_FAIL;
  288. }
  289. break;
  290. }
  291. return hr;
  292. }
  293. //=--------------------------------------------------------------------------=
  294. // VDMapRowsetHRtoCursorHR
  295. //=--------------------------------------------------------------------------=
  296. // Translates an IRowset HRESULT to an ICursor HRESULT
  297. //
  298. // Parameters:
  299. // hr - [in] IRowset HRESULT
  300. // nErrStringResID - [in] The resource ID of the error string
  301. // riid - [in] The guid of the interface that will used in
  302. // the ICreateErrorInfo::SetGUID method
  303. // punkSource - [in] The interface that generated the error.
  304. // (e.g. a call to IRowsetFind)
  305. // riidSource - [in] The interface ID of the interface that
  306. // generated the error. If punkSource is not
  307. // NULL then this guid is passed into the
  308. // ISupportErrorInfo::InterfaceSupportsErrorInfo
  309. // method.
  310. // pResDLL - [in] A pointer to the CVDResourceDLL object
  311. // that keeps track of the resource DLL
  312. // for error strings
  313. //
  314. // Output:
  315. // HRESULT - Translated ICursor HRESULT
  316. //
  317. HRESULT VDMapRowsetHRtoCursorHR(HRESULT hr,
  318. UINT nErrStringResIDFailed,
  319. REFIID riid,
  320. LPUNKNOWN punkSource,
  321. REFIID riidSource,
  322. CVDResourceDLL * pResDLL)
  323. {
  324. switch (hr)
  325. {
  326. case DB_S_ENDOFROWSET:
  327. hr = CURSOR_DB_S_ENDOFCURSOR;
  328. break;
  329. case DB_E_DELETEDROW:
  330. VDCheckErrorInfo(IDS_ERR_DELETEDROW, riid, punkSource, riidSource, pResDLL);
  331. hr = CURSOR_DB_E_ROWDELETED;
  332. break;
  333. case DB_E_BADBOOKMARK:
  334. VDCheckErrorInfo(IDS_ERR_BADBOOKMARK, riid, punkSource, riidSource, pResDLL);
  335. hr = CURSOR_DB_E_BADBOOKMARK;
  336. break;
  337. case DB_E_BADRATIO:
  338. VDCheckErrorInfo(IDS_ERR_BADFRACTION, riid, punkSource, riidSource, pResDLL);
  339. hr = CURSOR_DB_E_BADFRACTION;
  340. break;
  341. case E_OUTOFMEMORY:
  342. VDCheckErrorInfo((UINT)E_OUTOFMEMORY, riid, punkSource, riidSource, pResDLL);
  343. hr = E_OUTOFMEMORY;
  344. break;
  345. default:
  346. if FAILED(hr)
  347. {
  348. VDCheckErrorInfo(nErrStringResIDFailed, riid, punkSource, riidSource, pResDLL);
  349. hr = E_FAIL;
  350. }
  351. break;
  352. }
  353. return hr;
  354. }