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.

302 lines
9.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. //
  5. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. // IBindResource.CPP CImplIBindRsrc interface implementation for
  8. // Session object
  9. //
  10. ///////////////////////////////////////////////////////////////////////////
  11. #include "headers.h"
  12. ///////////////////////////////////////////////////////////////////////////
  13. // Method of the IBindResource which binds the requested URL
  14. // S_OK Bind succeeded
  15. // DB_S_ERRORSOCCURRED Bind succeeded, but some bind flags
  16. // or properties were not satisfied
  17. // DB_E_NOAGGREGATION Aggregation not supported by the
  18. // object requested
  19. // DB_E_NOTFOUND Object requested as from URL not found
  20. // DB_E_OBJECTMISMATCH The object requested and the URL passed
  21. // does not match
  22. // DB_SEC_E_PERMISSIONDENIED User does not have permission for the
  23. // object requested
  24. // E_FAIL Other error ( WMI specifice errors)
  25. // E_INVALIDARG one or more arguments are not valid
  26. // E_NOINTERFACE The interface requested is not supported
  27. // E_UNEXPECTED unexpected error
  28. ///////////////////////////////////////////////////////////////////////////
  29. STDMETHODIMP CImplIBindRsrc::Bind( IUnknown * pUnkOuter,
  30. LPCOLESTR pwszURL,
  31. DBBINDURLFLAG dwBindURLFlags,
  32. REFGUID rguid,
  33. REFIID riid,
  34. IAuthenticate * pAuthenticate,
  35. DBIMPLICITSESSION * pImplSession,
  36. DBBINDURLSTATUS * pdwBindStatus,
  37. IUnknown ** ppUnk)
  38. {
  39. HRESULT hr = S_OK;
  40. BSTR strUrl;
  41. CSetStructuredExceptionHandler seh;
  42. TRY_BLOCK;
  43. //=========================================================================================
  44. // Serialize the object
  45. //=========================================================================================
  46. CAutoBlock cab(m_pObj->GetCriticalSection());
  47. // Clear ErrorInfo
  48. g_pCError->ClearErrorInfo();
  49. //=========================================================================================
  50. // If URL is NULL return Invalid Argument
  51. //=========================================================================================
  52. if(pwszURL == NULL)
  53. {
  54. hr = E_INVALIDARG;
  55. }
  56. else
  57. {
  58. //=========================================================================================
  59. // Allocate the string
  60. //=========================================================================================
  61. strUrl = Wmioledb_SysAllocString(pwszURL);
  62. //=========================================================================================
  63. // Check if the flags passed are valid for the object requested
  64. //=========================================================================================
  65. if(!CheckBindURLFlags(dwBindURLFlags,rguid))
  66. {
  67. hr = E_INVALIDARG;
  68. }
  69. else
  70. if(!CheckIfProperURL(strUrl,rguid,pdwBindStatus))
  71. {
  72. hr = DB_E_OBJECTMISMATCH;
  73. }
  74. else
  75. if( pUnkOuter != NULL && riid != IID_IUnknown)
  76. {
  77. hr = DB_E_NOAGGREGATION;
  78. }
  79. if(SUCCEEDED(hr))
  80. {
  81. //=========================================================================================
  82. // Calling this to bind the URL to the appropriate object
  83. //=========================================================================================
  84. hr = BindURL(pUnkOuter,strUrl,dwBindURLFlags,rguid,riid,pImplSession,pdwBindStatus,ppUnk);
  85. }
  86. // Free the string
  87. SysFreeString(strUrl);
  88. }
  89. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource);
  90. CATCH_BLOCK_HRESULT(hr,L"IBindResource::Bind on Session object");
  91. return hr;
  92. }
  93. ////////////////////////////////////////////////////////////////////////////////////////////
  94. // Function which checks if the URL flags matches the requested object
  95. // This is as per the OLEDB specs
  96. ///////////////////////////////////////////////////////////////////////////////////////////
  97. BOOL CImplIBindRsrc::CheckBindURLFlags(DBBINDURLFLAG dwBindURLFlags , REFGUID rguid)
  98. {
  99. BOOL bFlag = FALSE;
  100. LONG lTemp = 0;
  101. if( DBGUID_DSO == rguid)
  102. {
  103. lTemp = DBBINDURLFLAG_ASYNCHRONOUS | DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
  104. //=========================================================================================
  105. // Flags can have only these values
  106. //=========================================================================================
  107. if((dwBindURLFlags & ~lTemp) == 0)
  108. bFlag = TRUE;
  109. }
  110. if( DBGUID_SESSION == rguid)
  111. {
  112. if( dwBindURLFlags == DBBINDURLFLAG_READ) // Flags can have only these values
  113. bFlag = TRUE;
  114. }
  115. if( DBGUID_COMMAND == rguid)
  116. {
  117. lTemp = DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
  118. if((dwBindURLFlags & ~lTemp) == 0)
  119. bFlag = TRUE;
  120. }
  121. if( DBGUID_ROW == rguid)
  122. {
  123. bFlag = TRUE;
  124. }
  125. if( DBGUID_ROWSET == rguid)
  126. {
  127. if(!((dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHCOLUMNS) || // Flags cannot have any of these two values
  128. (dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHSTREAM)))
  129. bFlag = TRUE;
  130. }
  131. if( DBGUID_STREAM == rguid)
  132. {
  133. }
  134. return bFlag;
  135. }
  136. ////////////////////////////////////////////////////////////////////////////////////////////
  137. // Function which checks if the URL is valid for the requested object
  138. ///////////////////////////////////////////////////////////////////////////////////////////
  139. BOOL CImplIBindRsrc::CheckIfProperURL(BSTR & strUrl,REFGUID rguid,DBBINDURLSTATUS * pdwBindStatus)
  140. {
  141. BOOL bRet = TRUE;
  142. LONG lUrlType = -1;
  143. CURLParser urlParser;
  144. //=========================================================================================
  145. // Set the URL string of the URL parser utility class
  146. //=========================================================================================
  147. if(SUCCEEDED(urlParser.SetURL(strUrl)))
  148. {
  149. // If the url is a valid URL
  150. if((lUrlType = urlParser.GetURLType()) != -1)
  151. {
  152. switch(lUrlType)
  153. {
  154. case URL_ROW:
  155. case URL_EMBEDEDCLASS:
  156. bRet = TRUE;
  157. //=========================================================================================
  158. // if the url is of type row or rowset and if the requested object is
  159. // datasource or session or command , then set the status
  160. //=========================================================================================
  161. if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
  162. *pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
  163. break;
  164. case URL_DATASOURCE:
  165. //=========================================================================================
  166. // check if the url is of type datasource and the requested object is
  167. // row or rowset or stream
  168. //=========================================================================================
  169. if(!(rguid == DBGUID_ROW || rguid == DBGUID_ROWSET || rguid == DBGUID_STREAM))
  170. bRet = TRUE;
  171. break;
  172. case URL_ROWSET:
  173. //=========================================================================================
  174. // if the url is of type rowset and if the requested object is
  175. // datasource or session or command , then set the status
  176. //=========================================================================================
  177. if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
  178. *pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
  179. bRet = TRUE;
  180. if(rguid == DBGUID_ROW)
  181. bRet = FALSE;
  182. break;
  183. };
  184. }
  185. }
  186. return bRet;
  187. }
  188. ///////////////////////////////////////////////////////////////////////////
  189. // Function to bind the requested URL
  190. // NTRaid:136545
  191. // 07/05/00
  192. ///////////////////////////////////////////////////////////////////////////
  193. HRESULT CImplIBindRsrc::BindURL(IUnknown * pUnkOuter,
  194. LPCOLESTR pwszURL,
  195. DBBINDURLFLAG dwBindURLFlags,
  196. REFGUID rguid,
  197. REFIID riid,
  198. DBIMPLICITSESSION * pImplSession,
  199. DBBINDURLSTATUS * pdwBindStatus,
  200. IUnknown ** ppUnk)
  201. {
  202. HRESULT hr = E_FAIL;
  203. BSTR strURL = NULL;
  204. strURL = Wmioledb_SysAllocString(pwszURL);
  205. //=========================================================================================
  206. // If the requested object is DSO then create the object aggregating with the outer object
  207. //=========================================================================================
  208. if( rguid == DBGUID_DSO)
  209. {
  210. hr = m_pObj->m_pCDataSource->QueryInterface(riid,(void **)ppUnk);
  211. }
  212. else
  213. //=========================================================================================
  214. // If the requested object is Session object then QI for the requiested object
  215. //=========================================================================================
  216. if( rguid == DBGUID_SESSION)
  217. {
  218. hr = m_pObj->QueryInterface(riid,(void **)ppUnk);
  219. }
  220. else
  221. //=========================================================================================
  222. // If requested object is command then call function to
  223. // to create a command
  224. //=========================================================================================
  225. if(rguid == DBGUID_COMMAND)
  226. {
  227. hr = m_pObj->CreateCommand(pUnkOuter,riid,ppUnk);
  228. }
  229. //=========================================================================================
  230. // If requested object is row then call function to
  231. // to create a row
  232. //=========================================================================================
  233. if( rguid == DBGUID_ROW)
  234. {
  235. hr = m_pObj->CreateRow(pUnkOuter,strURL,riid,ppUnk);
  236. }
  237. //=========================================================================================
  238. // If requested object is rowset then call function to
  239. // to create a rowset
  240. //=========================================================================================
  241. if( rguid == DBGUID_ROWSET)
  242. {
  243. hr = m_pObj->CreateRowset(pUnkOuter,strURL,riid,ppUnk);
  244. }
  245. if(! SUCCEEDED(hr))
  246. {
  247. *ppUnk = NULL;
  248. }
  249. SysFreeString(strURL);
  250. return hr ;
  251. }