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.

280 lines
8.9 KiB

  1. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // interface implementation
  7. //
  8. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include "headers.h"
  10. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. //
  12. // Opens and returns a rowset that includes all rows from a single base table
  13. //
  14. // HRESULT
  15. // S_OK The method succeeded
  16. // E_INVALIDARG pTableID was NULL
  17. // E_FAIL Provider-specific error
  18. // DB_E_NOTABLE Specified table does not exist in current Data Data Source object
  19. // E_OUTOFMEMORY Out of memory
  20. // E_NOINTERFACE The requested interface was not available
  21. //
  22. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  23. STDMETHODIMP CImpIOpenRowset::OpenRowset( IUnknown* pUnkOuter, // IN Controlling unknown, if any
  24. DBID* pTableID, // IN table to open
  25. DBID* pIndexID, // IN DBID of the index
  26. REFIID riid, // IN interface to return
  27. ULONG cPropertySets, // IN count of properties
  28. DBPROPSET rgPropertySets[], // INOUT array of property values
  29. IUnknown** ppRowset // OUT where to return interface
  30. )
  31. {
  32. CRowset* pRowset = NULL;
  33. HRESULT hr = S_OK;
  34. HRESULT hrProp = S_OK ;
  35. BOOL bRowRequested = FALSE;
  36. CRow* pRow = NULL;
  37. ULONG cErrors = 0;
  38. CSetStructuredExceptionHandler seh;
  39. TRY_BLOCK;
  40. assert( m_pObj );
  41. assert( m_pObj->m_pUtilProp );
  42. //=====================================================================
  43. // NULL out-params in case of error
  44. //=====================================================================
  45. if( ppRowset )
  46. {
  47. *ppRowset = NULL;
  48. }
  49. // Seriliaze the object
  50. CAutoBlock cab(m_pObj->GetCriticalSection());
  51. // Clear Error information
  52. g_pCError->ClearErrorInfo();
  53. //=====================================================================
  54. // Check Arguments
  55. //=====================================================================
  56. if ( !pTableID && !pIndexID )
  57. {
  58. hr = E_INVALIDARG;
  59. // return g_pCError->PostHResult(E_INVALIDARG,&IID_IOpenRowset);
  60. }
  61. else
  62. if ( riid == IID_NULL)
  63. {
  64. hr = E_NOINTERFACE;
  65. // return g_pCError->PostHResult(E_NOINTERFACE,&IID_IOpenRowset) ;
  66. }
  67. else
  68. //==========================================================
  69. // We only accept NULL for pIndexID at this present time
  70. //==========================================================
  71. if( pIndexID )
  72. {
  73. hr = DB_E_NOINDEX;
  74. // return g_pCError->PostHResult(DB_E_NOINDEX,&IID_IOpenRowset) ;
  75. }
  76. else
  77. //===================================================================================
  78. // We do not allow the riid to be anything other than IID_IUnknown for aggregation
  79. //===================================================================================
  80. if ( (pUnkOuter) && (riid != IID_IUnknown) )
  81. {
  82. hr = DB_E_NOAGGREGATION;
  83. // return g_pCError->PostHResult(DB_E_NOAGGREGATION,&IID_IOpenRowset) ;
  84. }
  85. else
  86. //==============================================
  87. // validate the property sets to be set
  88. //==============================================
  89. if( SUCCEEDED(hr = m_pObj->m_pUtilProp->SetPropertiesArgChk(cPropertySets, rgPropertySets,TRUE)) )
  90. {
  91. //=================================================================
  92. // If the eKind is not known to use, basically it means we have no
  93. // table identifier
  94. //=================================================================
  95. if ( (!pTableID ) || ( pTableID->eKind != DBKIND_NAME ) || ( (pTableID->eKind == DBKIND_NAME) && (!(pTableID->uName.pwszName)) ) ||
  96. ( wcslen(pTableID->uName.pwszName) == 0 ) || ( wcslen(pTableID->uName.pwszName) > _MAX_FNAME ) )
  97. {
  98. hr = DB_E_NOTABLE ;
  99. }
  100. else
  101. {
  102. if( riid == IID_IRow || riid == IID_IRowChange ||
  103. GetIRowProp(cPropertySets,rgPropertySets) == TRUE)
  104. {
  105. bRowRequested = TRUE;
  106. }
  107. // If rowset is to be created then create a new rowset
  108. if( bRowRequested == FALSE)
  109. {
  110. //===============================================================================
  111. // open and initialize a rowset\cursor object
  112. //===============================================================================
  113. // pRowset = new CRowset(pUnkOuter,NO_QUALIFIERS,(LPWSTR)(pTableID->uName.pwszName),m_pObj);
  114. try
  115. {
  116. pRowset = new CRowset(pUnkOuter,m_pObj);
  117. }
  118. catch(...)
  119. {
  120. SAFE_DELETE_PTR(pRowset);
  121. throw;;
  122. }
  123. if (!pRowset)
  124. {
  125. hr = E_OUTOFMEMORY ;
  126. }
  127. else
  128. {
  129. //===========================================================================
  130. // if properties failed or ppRowset NULL
  131. //===========================================================================
  132. hr = pRowset->InitRowset(cPropertySets, rgPropertySets,(LPWSTR)(pTableID->uName.pwszName));
  133. if( (SUCCEEDED(hr)) )
  134. {
  135. if(hr != S_OK)
  136. {
  137. cErrors++;
  138. }
  139. //=======================================================================
  140. // get requested interface pointer on rowset\cursor
  141. //=======================================================================
  142. if(ppRowset != NULL)
  143. {
  144. hr = pRowset->QueryInterface( riid, (void **) ppRowset );
  145. if (SUCCEEDED( hr ))
  146. {
  147. //===================================================================
  148. //Assign creator pointer. Used for IRowsetInfo::GetSpecification
  149. //===================================================================
  150. // m_pObj->m_fRowsetCreated = TRUE;
  151. }
  152. }
  153. else
  154. {
  155. SAFE_DELETE_PTR(pRowset);
  156. hr = cErrors > 0 ? DB_S_ERRORSOCCURRED : S_OK;
  157. }
  158. }
  159. } // else for failure of allocation of pRowset
  160. }
  161. // Create a row
  162. else
  163. {
  164. CURLParser urlParser;
  165. VARIANT varNameSpace;
  166. BSTR strClassName,strObject;
  167. strObject = Wmioledb_SysAllocString(pTableID->uName.pwszName);
  168. VariantInit(&varNameSpace);
  169. // Get the namespace of the datasource
  170. m_pObj->GetDataSrcProperty(DBPROP_INIT_DATASOURCE,varNameSpace);
  171. hr = urlParser.SetURL(strObject);
  172. SAFE_FREE_SYSSTRING(strObject);
  173. if(SUCCEEDED(hr))
  174. {
  175. // urlParser.SetNameSpace(varNameSpace.bstrVal);
  176. urlParser.GetClassName(strClassName);
  177. urlParser.GetPath(strObject);
  178. try
  179. {
  180. // Create a new row on the instance
  181. pRow = new CRow(pUnkOuter,m_pObj);
  182. }
  183. catch(...)
  184. {
  185. SAFE_DELETE_PTR(pRow);
  186. throw;
  187. }
  188. if(pRow == NULL)
  189. {
  190. hr = E_OUTOFMEMORY;
  191. }
  192. else
  193. {
  194. // call this function to initialize the row
  195. hr = pRow->InitRow(strObject,strClassName);
  196. if(hr == S_OK)
  197. {
  198. // QI for the required interface
  199. hr = pRow->QueryInterface(riid,(void **)ppRowset);
  200. }
  201. }
  202. }
  203. // Freeing the variables
  204. VariantClear(&varNameSpace);
  205. SysFreeString(strClassName);
  206. SysFreeString(strObject);
  207. } // end of creating row
  208. } // if valid table name
  209. }
  210. if( FAILED(hr ) )
  211. {
  212. SAFE_DELETE_PTR( pRowset );
  213. SAFE_DELETE_PTR( pRow );
  214. }
  215. if(hr == S_OK && cErrors > 0)
  216. {
  217. hr = DB_S_ERRORSOCCURRED;
  218. }
  219. hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IOpenRowset);
  220. CATCH_BLOCK_HRESULT(hr,L"IOpenRowset::OpenRowset");
  221. return hr;
  222. }
  223. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  224. // Function to get a DBPROP_IRow property
  225. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. BOOL CImpIOpenRowset::GetIRowProp(ULONG cPropertySets, // IN count of properties
  227. DBPROPSET rgPropertySets[])
  228. {
  229. BOOL bRet = FALSE;
  230. for( ULONG lIndex = 0 ; lIndex < cPropertySets ; lIndex++)
  231. {
  232. if(rgPropertySets[lIndex].guidPropertySet == DBPROPSET_ROWSET)
  233. {
  234. for ( ULONG nPropIndex = 0 ; nPropIndex < rgPropertySets[lIndex].cProperties ; nPropIndex++ )
  235. {
  236. if(rgPropertySets[lIndex].rgProperties[nPropIndex].dwPropertyID == DBPROP_IRow &&
  237. rgPropertySets[lIndex].rgProperties[nPropIndex].vValue.boolVal == VARIANT_TRUE)
  238. {
  239. bRet = TRUE;
  240. } // if DBPROP_IRow is true;
  241. }// for loop
  242. } // if propertyset is DBPROPSET_ROWSET
  243. } // outer for loop
  244. return bRet;
  245. }