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.

346 lines
10 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. //
  5. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. // IBindResource.CPP CImplIBindResource interface implementation
  8. //
  9. ///////////////////////////////////////////////////////////////////////////
  10. #include "headers.h"
  11. ////////////////////////////////////////////////////////////////////////////////
  12. // Method of the IBindResource which binds the requested URL
  13. // Returns one of the following values:
  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 CImplIBindResource::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 = E_FAIL;
  40. BSTR strUrl;
  41. CSetStructuredExceptionHandler seh;
  42. TRY_BLOCK;
  43. // Serialize the object
  44. CAutoBlock cab(BINDER->GetCriticalSection());
  45. g_pCError->ClearErrorInfo();
  46. // If URL is NULL return Invalid Argument
  47. if(pwszURL == NULL)
  48. {
  49. hr = E_INVALIDARG;
  50. }
  51. else
  52. {
  53. // Allocate the string
  54. strUrl = Wmioledb_SysAllocString(pwszURL);
  55. // Check if the flags passed are valid for the object requested
  56. if(!CheckBindURLFlags(dwBindURLFlags,rguid))
  57. {
  58. hr = E_INVALIDARG;
  59. }
  60. else
  61. if(!CheckIfProperURL(strUrl,rguid,pdwBindStatus))
  62. {
  63. hr = DB_E_OBJECTMISMATCH;
  64. }
  65. else
  66. if( pUnkOuter != NULL && riid != IID_IUnknown)
  67. {
  68. hr = DB_E_NOAGGREGATION;
  69. }
  70. else
  71. {
  72. // Calling this to bind the URL to the appropriate object
  73. hr = BindURL(pUnkOuter,strUrl,dwBindURLFlags,rguid,riid,pImplSession,pdwBindStatus,ppUnk);
  74. }
  75. // Free the string
  76. SysFreeString(strUrl);
  77. }
  78. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IBindResource);
  79. CATCH_BLOCK_HRESULT(hr,L"IBindResource::Bind");
  80. return hr;
  81. }
  82. ////////////////////////////////////////////////////////////////////////////////////////////
  83. // Function which checks if the URL flags matches the requested object
  84. // This is as per the OLEDB specs
  85. ///////////////////////////////////////////////////////////////////////////////////////////
  86. BOOL CImplIBindResource::CheckBindURLFlags(DBBINDURLFLAG dwBindURLFlags , REFGUID rguid)
  87. {
  88. BOOL bFlag = FALSE;
  89. LONG lTemp = 0;
  90. if( DBGUID_DSO == rguid)
  91. {
  92. lTemp = DBBINDURLFLAG_ASYNCHRONOUS | DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
  93. // Flags can have only these values
  94. if((dwBindURLFlags & ~lTemp) == 0)
  95. bFlag = TRUE;
  96. }
  97. if( DBGUID_SESSION == rguid)
  98. {
  99. if( dwBindURLFlags == DBBINDURLFLAG_READ) // Flags can have only these values
  100. bFlag = TRUE;
  101. }
  102. if( DBGUID_COMMAND == rguid)
  103. {
  104. lTemp = DBBINDURLFLAG_READ | DBBINDURLFLAG_WAITFORINIT;
  105. if((dwBindURLFlags & ~lTemp) == 0)
  106. bFlag = TRUE;
  107. }
  108. if( DBGUID_ROW == rguid)
  109. {
  110. bFlag = TRUE;
  111. }
  112. if( DBGUID_ROWSET == rguid)
  113. {
  114. if(!((dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHCOLUMNS) || // Flags cannot have any of these two values
  115. (dwBindURLFlags & DBBINDURLFLAG_DELAYFETCHSTREAM)))
  116. bFlag = TRUE;
  117. }
  118. if( DBGUID_STREAM == rguid)
  119. {
  120. }
  121. return bFlag;
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////////////////
  124. // Function which checks if the URL is valid for the requested object
  125. ///////////////////////////////////////////////////////////////////////////////////////////
  126. BOOL CImplIBindResource::CheckIfProperURL(BSTR & strUrl,REFGUID rguid,DBBINDURLSTATUS * pdwBindStatus)
  127. {
  128. BOOL bRet = FALSE;
  129. LONG lUrlType = -1;
  130. m_pObj->m_pUrlParser->ClearParser();
  131. //==================================================================
  132. // Set the URL string of the URL parser utility class
  133. //==================================================================
  134. if(SUCCEEDED(m_pObj->m_pUrlParser->SetURL(strUrl)))
  135. {
  136. bRet = TRUE;
  137. //==================================================================
  138. // If the url is a valid URL
  139. //==================================================================
  140. if((lUrlType = m_pObj->m_pUrlParser->GetURLType()) != -1)
  141. {
  142. switch(lUrlType)
  143. {
  144. case URL_ROW:
  145. case URL_EMBEDEDCLASS:
  146. bRet = TRUE;
  147. //==================================================================
  148. // if the url is of type row or rowset and if the requested object is
  149. // datasource or session or command , then set the status
  150. //==================================================================
  151. if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
  152. *pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
  153. break;
  154. case URL_DATASOURCE:
  155. //==================================================================
  156. // check if the url is of type datasource and the requested object is
  157. // row or rowset or stream
  158. //==================================================================
  159. if(!(rguid == DBGUID_ROW || rguid == DBGUID_ROWSET || rguid == DBGUID_STREAM))
  160. bRet = TRUE;
  161. break;
  162. case URL_ROWSET:
  163. //==================================================================
  164. // if the url is of type rowset and if the requested object is
  165. // datasource or session or command , then set the status
  166. //==================================================================
  167. if(rguid == DBGUID_DSO || rguid == DBGUID_SESSION || rguid == DBGUID_COMMAND)
  168. *pdwBindStatus = DBBINDURLSTATUS_S_REDIRECTED;
  169. bRet = TRUE;
  170. if(rguid == DBGUID_ROW)
  171. bRet = FALSE;
  172. break;
  173. };
  174. }
  175. }
  176. return bRet;
  177. }
  178. ///////////////////////////////////////////////////////////////////////////
  179. // Function to bind the requested URL
  180. ///////////////////////////////////////////////////////////////////////////
  181. HRESULT CImplIBindResource::BindURL(IUnknown * pUnkOuter,
  182. LPCOLESTR pwszURL,
  183. DBBINDURLFLAG dwBindURLFlags,
  184. REFGUID rguid,
  185. REFIID riid,
  186. DBIMPLICITSESSION * pImplSession,
  187. DBBINDURLSTATUS * pdwBindStatus,
  188. IUnknown ** ppUnk)
  189. {
  190. HRESULT hr = E_FAIL;
  191. IUnknown *pTempUnk = NULL;
  192. LONG lInitFlags = 0;
  193. LONG lBindFlags = 0;
  194. REFGUID guidTemp = GUID_NULL;
  195. IUnknown* pReqestedPtr = NULL;
  196. GetInitAndBindFlagsFromBindFlags(dwBindURLFlags,lInitFlags,lBindFlags);
  197. //=========================================================================================
  198. // If the requested object is DSO then create the object aggregating with the outer object
  199. //=========================================================================================
  200. if( rguid == DBGUID_DSO)
  201. {
  202. if(DBBINDURLFLAG_WAITFORINIT & dwBindURLFlags)
  203. lInitFlags |= DBBINDURLFLAG_WAITFORINIT;
  204. hr = m_pObj->CreateDSO(pUnkOuter,lInitFlags,riid,&pReqestedPtr);
  205. }
  206. else
  207. {
  208. hr = m_pObj->CreateDSO(NULL,lInitFlags,guidTemp,NULL);
  209. }
  210. if(SUCCEEDED(hr))
  211. {
  212. if(rguid != DBGUID_DSO)
  213. {
  214. //=========================================================================================
  215. // If the requested object is DSO then create the object aggregating with the outer object
  216. //=========================================================================================
  217. pReqestedPtr = NULL;
  218. pTempUnk = NULL;
  219. if( rguid == DBGUID_SESSION)
  220. {
  221. hr = m_pObj->CreateSession(pUnkOuter,riid,&pReqestedPtr);
  222. }
  223. else
  224. {
  225. if(pImplSession != NULL)
  226. {
  227. pTempUnk = pImplSession->pUnkOuter;
  228. // if the session is to be created with aggregation
  229. // if the requested pointer is on IUnknown then throw error
  230. if( pTempUnk != NULL && *pImplSession->piid != IID_IUnknown)
  231. {
  232. hr = DB_E_NOAGGREGATION;
  233. }
  234. }
  235. if(SUCCEEDED(hr))
  236. {
  237. hr = m_pObj->CreateSession(pTempUnk,guidTemp,&pReqestedPtr);
  238. }
  239. }
  240. }
  241. if( SUCCEEDED(hr))
  242. {
  243. //=========================================================================================
  244. // If requested object is command then call function to
  245. // to create a command
  246. //=========================================================================================
  247. if(rguid == DBGUID_COMMAND)
  248. {
  249. pReqestedPtr = NULL;
  250. hr = m_pObj->CreateCommand(pUnkOuter,riid,&pReqestedPtr);
  251. }
  252. //=========================================================================================
  253. // If requested object is row then call function to
  254. // to create a row
  255. //=========================================================================================
  256. if( rguid == DBGUID_ROW)
  257. {
  258. pReqestedPtr = NULL;
  259. hr = m_pObj->CreateRow(pUnkOuter,riid,&pReqestedPtr);
  260. }
  261. //=========================================================================================
  262. // If requested object is rowset then call function to
  263. // to create a rowset
  264. //=========================================================================================
  265. if( rguid == DBGUID_ROWSET)
  266. {
  267. pReqestedPtr = NULL;
  268. hr = m_pObj->CreateRowset(pUnkOuter,riid,&pReqestedPtr);
  269. }
  270. }
  271. }
  272. //=========================================================================================
  273. // If failed due to some reason then release all the
  274. // object created for binding
  275. //=========================================================================================
  276. if( hr != S_OK)
  277. {
  278. m_pObj->ReleaseAllObjects();
  279. }
  280. if( SUCCEEDED(hr))
  281. {
  282. *ppUnk = pReqestedPtr;
  283. }
  284. return hr ;
  285. }