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.

262 lines
7.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1994, Microsoft Corporation.
  4. //
  5. // File: util.cxx
  6. //
  7. // Contents: global utilities and data for Content Index Test 'Q'
  8. //
  9. // History: 27-Dec-94 dlee Created from pieces of Q
  10. // 18-Jan-95 t-colinb Added suppport for COMMAND_GETLASTQUERY_FAILED
  11. // 02-Mar-95 t-colinb Removed unnecessary IMPLEMENT_UNWIND
  12. //
  13. //----------------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include <dberror.hxx> // for IsCIError function
  17. #include <vqdebug.hxx>
  18. //+---------------------------------------------------------------------------
  19. //
  20. // Function: OpenFileFromPath
  21. //
  22. // Synopsis: Searches the current path for the specified file and
  23. // opens it for reading.
  24. //
  25. // Arguments: [wcsFile] -- filename to open
  26. //
  27. // History: 17-Jun-94 t-jeffc Created
  28. //
  29. //----------------------------------------------------------------------------
  30. FILE * OpenFileFromPath( WCHAR const * wcsFile )
  31. {
  32. unsigned int cwcPath = 256;
  33. XArray<WCHAR> wcsPath( cwcPath );
  34. WCHAR * wcsFilePart;
  35. for( ;; )
  36. {
  37. DWORD rc = SearchPath( NULL,
  38. wcsFile,
  39. NULL,
  40. cwcPath,
  41. wcsPath.GetPointer(),
  42. &wcsFilePart );
  43. if( rc == 0 )
  44. return NULL;
  45. else if( rc >= cwcPath )
  46. {
  47. delete [] wcsPath.Acquire();
  48. cwcPath = rc + 1;
  49. wcsPath.Init( cwcPath );
  50. }
  51. else
  52. break;
  53. }
  54. return _wfopen( wcsPath.GetPointer(), L"r" );
  55. }
  56. //-----------------------------------------------------------------------------
  57. //
  58. // Function: GetOleDBErrorInfo
  59. //
  60. // Synopsis: Retrieves the secondary error from Ole DB error object
  61. //
  62. // Arguments: [pErrSrc] - Pointer to object that posted the error.
  63. // [riid] - Interface that posted the error.
  64. // [lcid] - Locale in which the text is desired.
  65. // [pErrorInfo] - Pointer to memory where ERRORINFO should be.
  66. // [ppIErrorInfo] - Holds the returning IErrorInfo. Caller should
  67. // release this.
  68. //
  69. // Notes: The caller should use the contents of *ppIErrorInfo only if the return
  70. // is >= 0 (SUCCEEDED(return value)) AND *ppIErrorInfo is not NULL.
  71. //
  72. // History: 05 May 1997 KrishnaN Created
  73. //
  74. //-----------------------------------------------------------------------------
  75. SCODE GetOleDBErrorInfo(IUnknown *pErrSrc,
  76. REFIID riid,
  77. LCID lcid,
  78. unsigned eDesiredDetail,
  79. ERRORINFO *pErrorInfo,
  80. IErrorInfo **ppIErrorInfo)
  81. {
  82. if (0 == pErrSrc || 0 == pErrorInfo || 0 == ppIErrorInfo)
  83. return E_INVALIDARG;
  84. *ppIErrorInfo = 0;
  85. SCODE sc = S_OK;
  86. XInterface<ISupportErrorInfo> xSupportErrorInfo;
  87. sc = pErrSrc->QueryInterface(IID_ISupportErrorInfo, xSupportErrorInfo.GetQIPointer());
  88. if (FAILED(sc))
  89. return sc;
  90. sc = xSupportErrorInfo->InterfaceSupportsErrorInfo(riid);
  91. if (FAILED(sc))
  92. return sc;
  93. //
  94. // Get the current error object. Return if none exists.
  95. //
  96. XInterface<IErrorInfo> xErrorInfo;
  97. sc = GetErrorInfo(0, (IErrorInfo **)xErrorInfo.GetQIPointer());
  98. if ( 0 == xErrorInfo.GetPointer() )
  99. return sc;
  100. //
  101. // Get the IErrorRecord interface and get the count of errors.
  102. //
  103. XInterface<IErrorRecords> xErrorRecords;
  104. sc = xErrorInfo->QueryInterface(IID_IErrorRecords, xErrorRecords.GetQIPointer());
  105. if (FAILED(sc))
  106. return sc;
  107. ULONG cErrRecords;
  108. sc = xErrorRecords->GetRecordCount(&cErrRecords);
  109. if (0 == cErrRecords)
  110. return sc;
  111. //
  112. // We will first look for what the user desires.
  113. // If we can't find what they desire, then we
  114. // return the closest we can.
  115. //
  116. ULONG ulRecord = 0;
  117. long i; // This has to be signed to keep the loop test simple
  118. switch (eDesiredDetail)
  119. {
  120. case eMostGeneric:
  121. ulRecord = 0;
  122. break;
  123. case eDontCare:
  124. case eMostDetailed:
  125. ulRecord = cErrRecords - 1;
  126. break;
  127. case eMostDetailedOleDBError:
  128. // Find the last (starting from 0) non-CI error
  129. ulRecord = cErrRecords - 1;
  130. for (i = (long) cErrRecords - 1; i >= 0 ; i--)
  131. {
  132. xErrorRecords->GetBasicErrorInfo(i, pErrorInfo);
  133. // if it not a CI error, it is a Ole DB error
  134. if (!IsCIError(pErrorInfo->hrError))
  135. {
  136. ulRecord = i;
  137. break;
  138. }
  139. }
  140. break;
  141. case eMostDetailedCIError:
  142. // Find the last (starting from 0) non-CI error
  143. ulRecord = cErrRecords - 1;
  144. for (i = (long) cErrRecords - 1; i >= 0 ; i--)
  145. {
  146. xErrorRecords->GetBasicErrorInfo(i, pErrorInfo);
  147. if (IsCIError(pErrorInfo->hrError))
  148. {
  149. ulRecord = i;
  150. break;
  151. }
  152. }
  153. break;
  154. case eMostGenericOleDBError:
  155. // Find the first (starting from 0) non-CI error
  156. ulRecord = 0;
  157. for (i = 0; i < (long)cErrRecords; i++)
  158. {
  159. xErrorRecords->GetBasicErrorInfo(i, pErrorInfo);
  160. // if it not a CI error, it is a Ole DB error
  161. if (!IsCIError(pErrorInfo->hrError))
  162. {
  163. ulRecord = i;
  164. break;
  165. }
  166. }
  167. break;
  168. case eMostGenericCIError:
  169. // Find the first (starting from 0) non-CI error
  170. ulRecord = 0;
  171. for (i = 0; i < (long)cErrRecords; i++)
  172. {
  173. xErrorRecords->GetBasicErrorInfo(i, pErrorInfo);
  174. // if it not a CI error, it is a Ole DB error
  175. if (IsCIError(pErrorInfo->hrError))
  176. {
  177. ulRecord = i;
  178. break;
  179. }
  180. }
  181. break;
  182. default:
  183. Win4Assert(!"Unrecognized error detail option!");
  184. ulRecord = 0;
  185. break;
  186. }
  187. // Get basic error information
  188. Win4Assert( ulRecord < cErrRecords );
  189. sc = xErrorRecords->GetBasicErrorInfo(ulRecord, pErrorInfo);
  190. Win4Assert(sc != DB_E_BADRECORDNUM);
  191. sc = xErrorRecords->GetErrorInfo(ulRecord, lcid, ppIErrorInfo);
  192. Win4Assert(sc != DB_E_BADRECORDNUM);
  193. #if CIDBG
  194. //
  195. // Get error description and source through the IErrorInfo
  196. // interface pointer on a particular record.
  197. //
  198. BSTR bstrErrorDescription = 0;
  199. BSTR bstrErrorSource = 0;
  200. (*ppIErrorInfo)->GetDescription(&bstrErrorDescription);
  201. (*ppIErrorInfo)->GetSource(&bstrErrorSource);
  202. //
  203. // At this point we could call GetCustomErrorObject and query for additional
  204. // interfaces to determine what else happened. Currently no custom errors are
  205. // supported, so nothing to do.
  206. //
  207. if (bstrErrorSource && bstrErrorDescription)
  208. {
  209. WCHAR wszBuff[1024];
  210. swprintf(wszBuff, L"HRESULT: %lx, Minor Code: %lu, Source: %ws\nDescription: %ws\n",
  211. pErrorInfo->hrError, pErrorInfo->dwMinor, bstrErrorSource, bstrErrorDescription);
  212. vqDebugOut((DEB_IERROR, "%ws", wszBuff));
  213. }
  214. //
  215. // Free the resources
  216. //
  217. SysFreeString(bstrErrorDescription);
  218. SysFreeString(bstrErrorSource);
  219. #endif // CIDBG
  220. return sc;
  221. }