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.

2407 lines
80 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // WmiOleDBMap.cpp: implementation of the CWmiOleDBMap class.
  7. //
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////////
  10. #include "headers.h"
  11. #include "dataconvert.h"
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction of class for Schema Rowsets
  14. //////////////////////////////////////////////////////////////////////
  15. CWmiOleDBMap::CWmiOleDBMap()
  16. {
  17. m_pWbemClassParms = NULL;
  18. m_pWbemClassDefinition = NULL;
  19. m_paWbemClassInstances = NULL;
  20. m_pWbemCommandManager = NULL;
  21. m_pWbemCollectionManager = NULL;
  22. m_pWbemCurInst = NULL;
  23. m_cRef = 0;
  24. m_bMethodRowset = FALSE;
  25. }
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. CWmiOleDBMap::~CWmiOleDBMap()
  28. {
  29. SAFE_DELETE_PTR(m_pWbemClassParms);
  30. SAFE_DELETE_PTR(m_pWbemClassDefinition);
  31. SAFE_DELETE_PTR(m_paWbemClassInstances);
  32. SAFE_DELETE_PTR(m_pWbemCommandManager);
  33. SAFE_DELETE_PTR(m_pWbemCollectionManager);
  34. }
  35. STDMETHODIMP_( ULONG ) CWmiOleDBMap::AddRef( void )
  36. {
  37. return InterlockedIncrement((long*)&m_cRef);
  38. }
  39. /////////////////////////////////////////////////////////////////////////////////////////////////
  40. //
  41. // Decrements a persistence count for the object and if persistence count is 0, the object
  42. // destroys itself.
  43. //
  44. /////////////////////////////////////////////////////////////////////////////////////////////////
  45. STDMETHODIMP_( ULONG ) CWmiOleDBMap::Release( void )
  46. {
  47. if (!InterlockedDecrement((long*)&m_cRef)){
  48. delete this;
  49. return 0;
  50. }
  51. return m_cRef;
  52. }
  53. //////////////////////////////////////////////////////////////////////
  54. // Initialization function for Schema Rowsets
  55. //////////////////////////////////////////////////////////////////////
  56. HRESULT CWmiOleDBMap::FInit(int nSchemaType, DWORD dwFlags, WCHAR * pClassName, WCHAR * pSpecificTable, CWbemConnectionWrapper * Connect)
  57. {
  58. // NTRaid:111784 - 111787
  59. // 06/07/00
  60. HRESULT hr = S_OK;
  61. m_pWbemClassParms = new CWbemClassParameters(dwFlags,pClassName,Connect);
  62. if(m_pWbemClassParms)
  63. {
  64. m_pWbemClassParms->SetClassName(pClassName);
  65. switch( nSchemaType )
  66. {
  67. case SOURCES_ROWSET:
  68. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaSourcesClassDefinitionWrapper(m_pWbemClassParms);
  69. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaSourcesInstanceList(m_pWbemClassParms);
  70. break;
  71. case PROVIDER_TYPES_ROWSET:
  72. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaProviderTypesClassDefinitionWrapper(m_pWbemClassParms);
  73. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaProviderTypesInstanceList(m_pWbemClassParms);
  74. break;
  75. case CATALOGS_ROWSET:
  76. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaCatalogsClassDefinitionWrapper(m_pWbemClassParms);
  77. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaCatalogsInstanceList(m_pWbemClassParms);
  78. break;
  79. case COLUMNS_ROWSET:
  80. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaColumnsClassDefinitionWrapper(m_pWbemClassParms);
  81. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaColumnsInstanceList(m_pWbemClassParms,pSpecificTable);
  82. break;
  83. case TABLES_ROWSET:
  84. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaTablesClassDefinitionWrapper(m_pWbemClassParms);
  85. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaTablesInstanceList(m_pWbemClassParms,pSpecificTable);
  86. break;
  87. case PRIMARY_KEYS_ROWSET:
  88. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaPrimaryKeysClassDefinitionWrapper(m_pWbemClassParms);
  89. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaPrimaryKeysInstanceList(m_pWbemClassParms,pSpecificTable);
  90. break;
  91. case TABLES_INFO_ROWSET:
  92. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaTablesInfoClassDefinitionWrapper(m_pWbemClassParms);
  93. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaTablesInfoInstanceList(m_pWbemClassParms,pSpecificTable);
  94. break;
  95. case PROCEDURES_ROWSET:
  96. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaProceduresClassDefinitionWrapper(m_pWbemClassParms);
  97. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaProceduresInstanceList(m_pWbemClassParms,pSpecificTable);
  98. break;
  99. case PROCEDURE_PARAMETERS_ROWSET:
  100. m_pWbemClassDefinition = (CWbemSchemaClassDefinitionWrapper*)new CWbemSchemaProceduresParametersClassDefinitionWrapper(m_pWbemClassParms);
  101. m_paWbemClassInstances = (CWbemSchemaInstanceList*)new CWbemSchemaProceduresParametersInstanceList(m_pWbemClassParms,pSpecificTable);
  102. break;
  103. }
  104. }
  105. else
  106. {
  107. hr = E_OUTOFMEMORY;
  108. }
  109. if(!m_pWbemClassDefinition || !m_pWbemClassDefinition)
  110. {
  111. hr = E_OUTOFMEMORY;
  112. }
  113. return hr;
  114. }
  115. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. // Initialization function for opening a class
  117. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. HRESULT CWmiOleDBMap::FInit(DWORD dwFlags, WCHAR * pClassName, CWbemConnectionWrapper * Connect)
  119. {
  120. HRESULT hr = S_OK;
  121. m_pWbemClassParms = new CWbemClassParameters(dwFlags,pClassName,Connect);
  122. // NTRaid:111784 - 111787
  123. // 06/07/00
  124. if(m_pWbemClassParms)
  125. {
  126. m_pWbemClassParms->SetClassName(pClassName);
  127. m_pWbemCurInst = NULL;
  128. m_cRef = 0;
  129. m_pWbemCommandManager = NULL;
  130. m_bMethodRowset = FALSE;
  131. m_pWbemCollectionManager = NULL;
  132. m_pWbemClassDefinition = new CWbemClassDefinitionWrapper(m_pWbemClassParms);
  133. m_paWbemClassInstances = new CWbemInstanceList(m_pWbemClassParms);
  134. }
  135. else
  136. {
  137. hr = E_OUTOFMEMORY;
  138. }
  139. if(!m_pWbemClassDefinition || !m_paWbemClassInstances)
  140. {
  141. hr = E_OUTOFMEMORY;
  142. }
  143. return hr;
  144. }
  145. //////////////////////////////////////////////////////////////////////
  146. // Initialization function for Commands or methods
  147. // NTRaid:111788,111890 - 111792
  148. // 06/07/00
  149. //////////////////////////////////////////////////////////////////////
  150. HRESULT CWmiOleDBMap::FInit(DWORD dwFlags, CQuery * p, CWbemConnectionWrapper * Connect)
  151. {
  152. HRESULT hr = E_OUTOFMEMORY;
  153. //=========================================================
  154. // If it is a COMMAND_ROWSET or METHOD_ROWSET
  155. //=========================================================
  156. switch( p->GetType() ){
  157. case COMMAND_ROWSET:
  158. m_pWbemCommandManager = new CWbemCommandManager(p);
  159. if(m_pWbemCommandManager)
  160. {
  161. m_pWbemClassParms = new CWbemCommandParameters(dwFlags,Connect,m_pWbemCommandManager);
  162. if(m_pWbemClassParms)
  163. {
  164. // m_pWbemClassParms->SetEnumeratorFlags(WBEM_FLAG_FORWARD_ONLY);
  165. m_pWbemClassParms->SetQueryFlags(WBEM_FLAG_DEEP);
  166. m_paWbemClassInstances = new CWbemCommandInstanceList(m_pWbemClassParms,m_pWbemCommandManager);
  167. m_pWbemClassDefinition = new CWbemCommandClassDefinitionWrapper(m_pWbemClassParms,m_pWbemCommandManager);
  168. if(m_paWbemClassInstances && m_pWbemClassDefinition)
  169. {
  170. m_pWbemCommandManager->Init((CWbemCommandInstanceList*)m_paWbemClassInstances,
  171. (CWbemCommandParameters*)m_pWbemClassParms,
  172. (CWbemCommandClassDefinitionWrapper*)m_pWbemClassDefinition);
  173. hr = S_OK;
  174. }
  175. }
  176. }
  177. break;
  178. case METHOD_ROWSET:
  179. m_pWbemClassParms = new CWbemMethodParameters(p,dwFlags,Connect);
  180. if(m_pWbemClassParms)
  181. {
  182. m_pWbemClassParms->SetEnumeratorFlags(WBEM_FLAG_FORWARD_ONLY);
  183. m_pWbemClassParms->SetQueryFlags(WBEM_FLAG_SHALLOW);
  184. m_pWbemClassDefinition = new CWbemMethodClassDefinitionWrapper((CWbemMethodParameters*)m_pWbemClassParms);
  185. if(m_pWbemClassDefinition)
  186. {
  187. m_paWbemClassInstances = new CWbemMethodInstanceList((CWbemMethodParameters*)m_pWbemClassParms,
  188. (CWbemMethodClassDefinitionWrapper *) m_pWbemClassDefinition );
  189. if(m_paWbemClassInstances)
  190. {
  191. hr = ((CWbemMethodClassDefinitionWrapper*)m_pWbemClassDefinition)->Init();
  192. m_bMethodRowset = TRUE;
  193. }
  194. }
  195. }
  196. break;
  197. }
  198. return hr;
  199. }
  200. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  201. // Initialization function for representing objects in Scope/Container
  202. // if the namespace of the object is different from the current object then , a new Connect will be instantiated
  203. // whic aggregates the existing connection pointer and store IwbemServices pointer opened on the given path and
  204. // sets bConnectChanged to TRUE
  205. // NTRaid:111793
  206. // 06/07/00
  207. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  208. HRESULT CWmiOleDBMap::FInit(DWORD dwFlags, WCHAR * pObjectPath, CWbemConnectionWrapper * Connect,INSTANCELISTTYPE instListType)
  209. {
  210. HRESULT hr = E_OUTOFMEMORY;
  211. m_pWbemClassParms = new CWbemCollectionParameters(dwFlags,Connect,pObjectPath);
  212. if(m_pWbemClassParms)
  213. {
  214. if(SUCCEEDED(hr = ((CWbemCollectionParameters *)m_pWbemClassParms)->Init(pObjectPath,Connect)))
  215. {
  216. m_pWbemCollectionManager = new CWbemCollectionManager;
  217. if(m_pWbemCollectionManager)
  218. {
  219. m_pWbemClassDefinition = new CWbemCollectionClassDefinitionWrapper(m_pWbemClassParms,pObjectPath,instListType);
  220. m_paWbemClassInstances = new CWbemCollectionInstanceList(m_pWbemClassParms,m_pWbemCollectionManager);
  221. if(m_pWbemClassDefinition && m_paWbemClassInstances)
  222. {
  223. if(SUCCEEDED(hr = ((CWbemCollectionClassDefinitionWrapper *)m_pWbemClassDefinition)->Initialize(pObjectPath)))
  224. {
  225. m_pWbemCollectionManager->Init((CWbemCollectionInstanceList *)m_paWbemClassInstances,
  226. (CWbemCollectionParameters *)m_pWbemClassParms,
  227. (CWbemCollectionClassDefinitionWrapper*) m_pWbemClassDefinition);
  228. hr = S_OK;
  229. }
  230. }
  231. }
  232. }
  233. }
  234. return hr;
  235. }
  236. HRESULT CWmiOleDBMap::SetSearchPreferences(ULONG cProps , DBPROP rgProp[])
  237. {
  238. return m_pWbemClassParms->SetSearchPreferences(cProps,rgProp);
  239. }
  240. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  241. // Find the type of column given the column
  242. // ie. find if a property is PROPERTY or PROPERTY_QUALIFIER or CLASS_QUALLIFIER
  243. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  244. int CWmiOleDBMap::ParseQualifiedNameToGetColumnType(WCHAR * wcsName )
  245. {
  246. int nRc = WMI_PROPERTY;
  247. WCHAR * p = NULL;
  248. //========================================================================
  249. // If there is not a separator in the name, then we know it is simply
  250. // a WMI property.
  251. // If there is a separator and the parsed value is equal to the name of
  252. // the class, then we know we are dealing with a class qualifier,
  253. // otherwise, it is a property qualifier.
  254. //========================================================================
  255. p = wcsstr(wcsName, SEPARATOR);
  256. if( p ){
  257. nRc = WMI_PROPERTY_QUALIFIER;
  258. //====================================================================
  259. p = NULL;
  260. p= wcsstr(wcsName,m_pWbemClassParms->GetClassName());
  261. if( p != NULL && p == wcsName)
  262. {
  263. nRc = WMI_CLASS_QUALIFIER;
  264. }
  265. }
  266. return nRc;
  267. }
  268. //
  269. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  270. BOOL CWmiOleDBMap::ParseQualifiedName(WCHAR * Root, WCHAR *& Parent, WCHAR *& Child)
  271. {
  272. BOOL fRc = FALSE;
  273. //========================================================================
  274. // If there is not a separator in the name, then we know it is simply
  275. // a WMI property.
  276. // If there is a separator and the parsed value is equal to the name of
  277. // the class, then we know we are dealing with a class qualifier,
  278. // otherwise, it is a property qualifier.
  279. //========================================================================
  280. WCHAR *szTemp = NULL;
  281. try
  282. {
  283. szTemp = new WCHAR[wcslen(Root) +1];
  284. }
  285. catch(...)
  286. {
  287. SAFE_DELETE_ARRAY(szTemp);
  288. }
  289. wcscpy(szTemp,Root);
  290. WCHAR * p = wcstok(szTemp, SEPARATOR);
  291. if( p ){
  292. AllocateAndCopy(Parent,p);
  293. p = wcstok( NULL, SEPARATOR );
  294. if( p ){
  295. if( AllocateAndCopy(Child,p)){
  296. fRc = TRUE;
  297. }
  298. else{
  299. SAFE_DELETE_PTR(Parent);
  300. }
  301. }
  302. }
  303. SAFE_DELETE_ARRAY(szTemp);
  304. return fRc;
  305. }
  306. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  307. // Check if the property is a vallid
  308. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  309. HRESULT CWmiOleDBMap::ValidProperty(const DBCOLUMNDESC * prgColDesc)
  310. {
  311. HRESULT hr = S_OK;
  312. if( !(prgColDesc->dbcid.eKind == DBKIND_NAME && prgColDesc->dbcid.uName.pwszName != NULL))
  313. {
  314. hr = E_INVALIDARG;
  315. }
  316. return hr;
  317. }
  318. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  319. // Map the DBPROP to the appropriate qualifier
  320. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  321. HRESULT CWmiOleDBMap::MapDBPROPToStdPropertyQualifier( DBPROP pProp, CVARIANT & Qualifier, CVARIANT & Value, LONG & lFlavor )
  322. {
  323. HRESULT hr = E_INVALIDARG;
  324. //========================================================================
  325. // we do not need to handle qualifier flavors for these standard qualifers
  326. // because, if a user is going to add a qualifier flavor on a qualifier
  327. // that just 'happens' to match to a DBPROP, they will be adding it as
  328. // a wmi qualifier, this function is to just catch the DBPROPS that are
  329. // matched without the consumers knowledge, so in this case there will
  330. // be no qualifier flavor
  331. //========================================================================
  332. switch(pProp.dwPropertyID){
  333. //=================================================================
  334. // WMI "Not_Null" standard qualifier only take true value.
  335. //=================================================================
  336. case DBPROP_COL_NULLABLE:
  337. if ( VT_BOOL == V_VT(&pProp.vValue) ) {
  338. if ( VARIANT_TRUE == V_BOOL(&pProp.vValue) ){
  339. Qualifier.SetStr(L"Not_Null");
  340. Value.SetBool(TRUE);
  341. hr = S_OK;
  342. }
  343. }
  344. break;
  345. //=================================================================
  346. // WMI "Key" standard qualifier
  347. //=================================================================
  348. case DBPROP_COL_UNIQUE:
  349. case DBPROP_COL_PRIMARYKEY:
  350. if ( VT_BOOL == V_VT(&pProp.vValue) ) {
  351. Qualifier.SetStr(L"Key");
  352. Value.SetBool(TRUE);
  353. hr = S_OK;
  354. }
  355. break;
  356. //=================================================================
  357. // WMI Flavor
  358. //=================================================================
  359. case DBPROP_WMIOLEDB_QUALIFIERFLAVOR:
  360. if ( VT_I4 == V_VT(&pProp.vValue) ) {
  361. lFlavor = V_I4(&pProp.vValue) ;
  362. hr = S_OK;
  363. }
  364. break;
  365. default:
  366. hr = WBEM_E_NOT_SUPPORTED;
  367. break;
  368. }
  369. return hr;
  370. }
  371. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  372. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  373. HRESULT CWmiOleDBMap::MapDBPROPToStdClassQualifier( DBPROP pProp, CVARIANT & Qualifier, CVARIANT & Value, LONG & uFlavor )
  374. {
  375. HRESULT hr = E_INVALIDARG;
  376. //========================================================================
  377. // Now, the qualifier flavor will be passed through here, so, we need
  378. // to pick it up as we are doing the double checking. Regarding other
  379. // maps, see comments in MapDBPROPTStdPropertyQualifier as to why we
  380. // don't care about flavors on DBPROP matches to standard qualifiers.
  381. //========================================================================
  382. switch(pProp.dwPropertyID){
  383. //=================================================================
  384. // WMI Flavor
  385. // DON'T set the return code to S_OK, because we want to save the
  386. // flavor for later....
  387. //=================================================================
  388. case DBPROP_WMIOLEDB_QUALIFIERFLAVOR:
  389. if ( VT_I4 == V_VT(&pProp.vValue) ) {
  390. uFlavor = V_I4(&pProp.vValue) ;
  391. }
  392. break;
  393. default:
  394. hr = WBEM_E_NOT_SUPPORTED;
  395. break;
  396. }
  397. return hr;
  398. }
  399. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  400. // save the property
  401. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  402. HRESULT CWmiOleDBMap::SetWMIProperty(const DBCOLUMNDESC * prgColDesc)
  403. {
  404. HRESULT hr = S_OK;
  405. CBSTR bstrProperty(prgColDesc->dbcid.uName.pwszName);
  406. VARIANT varDefault , *pDefaultValue = NULL;
  407. VariantInit(&varDefault);
  408. CDataMap map;
  409. LONG lType = 0;
  410. //==================================================================================
  411. // Ok, we already know we have a valid class here so just check if we have a valid
  412. // property
  413. //==================================================================================
  414. if( S_OK == (hr = ValidProperty(prgColDesc))){
  415. // Get the default value for the property if any specified
  416. GetDefaultValue(prgColDesc , varDefault);
  417. map.MapOLEDBTypeToCIMType(prgColDesc->wType,lType);
  418. if(V_VT(&varDefault) == VT_EMPTY || V_VT(&varDefault) == VT_NULL)
  419. {
  420. pDefaultValue = NULL;
  421. }
  422. else
  423. {
  424. pDefaultValue = &varDefault;
  425. }
  426. //==============================================================================
  427. // Now, set it property and its value
  428. //==============================================================================
  429. hr = m_pWbemClassDefinition->SetProperty((BSTR)bstrProperty,pDefaultValue,lType);
  430. if ( SUCCEEDED(hr) ){
  431. //==========================================================================
  432. // Now, go through the DBPROPSETS and the DBPROPS in them to see if they
  433. // happen to match some of the standard qualifiers we have mapped to them
  434. //==========================================================================
  435. for( ULONG i = 0; i < prgColDesc->cPropertySets; i++ ){
  436. for ( ULONG j = 0; j < prgColDesc->rgPropertySets[i].cProperties; j++ ) {
  437. if(prgColDesc->rgPropertySets[i].rgProperties[j].dwPropertyID != DBPROP_COL_DEFAULT &&
  438. prgColDesc->rgPropertySets[i].rgProperties[j].dwPropertyID != DBPROP_COL_NULLABLE )
  439. {
  440. CVARIANT Value,Qualifier;
  441. LONG lFlavor;
  442. //==================================================================
  443. // See if we have a match, if we do, save it to WMI
  444. //==================================================================
  445. hr = MapDBPROPToStdPropertyQualifier(prgColDesc->rgPropertySets[i].rgProperties[j],Qualifier,Value, lFlavor);
  446. if( hr == S_OK){
  447. hr = m_pWbemClassDefinition->SetPropertyQualifier((BSTR)bstrProperty,Qualifier,Value,0);
  448. if( hr != S_OK){
  449. break;
  450. }
  451. }
  452. }
  453. }
  454. }
  455. }
  456. }
  457. return hr;
  458. }
  459. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  460. // Function set value for a qualifier
  461. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  462. HRESULT CWmiOleDBMap::SetWMIClassQualifier(const DBCOLUMNDESC * prgColDesc,BOOL bDefault)
  463. {
  464. HRESULT hr = S_OK;
  465. WCHAR * pwcsQualifierName = NULL;
  466. WCHAR * pwcsClass = NULL;
  467. VARIANT varDefaultValue;
  468. VariantInit(&varDefaultValue);
  469. //==================================================================================
  470. // Ok, we already know we have a valid class here so just check if we have a valid
  471. // property
  472. //==================================================================================
  473. if( S_OK == (hr = ValidProperty(prgColDesc))){
  474. if( ParseQualifiedName(prgColDesc->dbcid.uName.pwszName,pwcsClass,pwcsQualifierName) ){
  475. //==========================================================================
  476. // Now, go through the DBPROPSETS and the DBPROPS in them to see if they
  477. // have a flavor for this qualifier or happen to map to other class
  478. // qualifiers
  479. //==========================================================================
  480. LONG lQualifierFlavor = 0L;
  481. for( ULONG i = 0; i < prgColDesc->cPropertySets; i++ ){
  482. for ( ULONG j = 0; j < prgColDesc->rgPropertySets[i].cProperties; j++ ) {
  483. CVARIANT Value,Qualifier;
  484. //==================================================================
  485. // Get the qualifier flavor property if any
  486. //==================================================================
  487. if( prgColDesc->rgPropertySets[i].rgProperties[j].dwPropertyID == DBPROP_WMIOLEDB_QUALIFIERFLAVOR &&
  488. V_VT(&prgColDesc->rgPropertySets[i].rgProperties[j].vValue) == VT_I4)
  489. {
  490. lQualifierFlavor = V_I4(&prgColDesc->rgPropertySets[i].rgProperties[j].vValue);
  491. }
  492. }
  493. }
  494. if( hr == S_OK )
  495. {
  496. CBSTR strQualifier(pwcsQualifierName);
  497. // If a new qualifer is to be added the get the default value
  498. if(bDefault == TRUE)
  499. {
  500. GetDefaultValue(prgColDesc,varDefaultValue);
  501. }
  502. else
  503. {
  504. hr = m_pWbemClassDefinition->GetClassQualifier((BSTR)strQualifier, &varDefaultValue, NULL,NULL);
  505. }
  506. hr = m_pWbemClassDefinition->SetClassQualifier(pwcsQualifierName, &varDefaultValue, lQualifierFlavor);
  507. }
  508. }
  509. }
  510. SAFE_DELETE_PTR(pwcsQualifierName);
  511. SAFE_DELETE_PTR(pwcsClass);
  512. return hr;
  513. }
  514. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  515. // Function set value for a particular property
  516. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  517. HRESULT CWmiOleDBMap::SetWMIPropertyQualifier(const DBCOLUMNDESC * prgColDesc,BOOL bDefault)
  518. {
  519. HRESULT hr = S_OK;
  520. WCHAR * pwcsQualifierName = NULL;
  521. WCHAR * pwcsProperty = NULL;
  522. VARIANT varDefaultValue;
  523. VariantInit(&varDefaultValue);
  524. //==================================================================================
  525. // Ok, we already know we have a valid class here so just check if we have a valid
  526. // property
  527. //==================================================================================
  528. if( S_OK == (hr = ValidProperty(prgColDesc))){
  529. if( ParseQualifiedName(prgColDesc->dbcid.uName.pwszName,pwcsProperty,pwcsQualifierName) ){
  530. LONG lQualifierFlavor = 0L;
  531. //==========================================================================
  532. // Now, go through the DBPROPSETS and the DBPROPS in them to see if they
  533. // have a flavor for this qualifier or happen to map to other class
  534. // qualifiers
  535. //==========================================================================
  536. for( ULONG i = 0; i < prgColDesc->cPropertySets; i++ ){
  537. for ( ULONG j = 0; j < prgColDesc->rgPropertySets[i].cProperties; j++ ) {
  538. CVARIANT Value,Qualifier;
  539. //==================================================================
  540. // Get the qualifier flavor property if any
  541. //==================================================================
  542. if( prgColDesc->rgPropertySets[i].rgProperties[j].dwPropertyID == DBPROP_WMIOLEDB_QUALIFIERFLAVOR &&
  543. V_VT(&prgColDesc->rgPropertySets[i].rgProperties[j].vValue) == VT_I4)
  544. {
  545. lQualifierFlavor = V_I4(&prgColDesc->rgPropertySets[i].rgProperties[j].vValue);
  546. }
  547. }
  548. }
  549. if( hr == S_OK ){
  550. CBSTR strQualifier(pwcsQualifierName),strProperty(pwcsProperty);
  551. if(bDefault == TRUE)
  552. {
  553. GetDefaultValue(prgColDesc,varDefaultValue);
  554. }
  555. else
  556. {
  557. GetPropertyQualifier((BSTR)strProperty,(BSTR)strQualifier,varDefaultValue);
  558. }
  559. hr = m_pWbemClassDefinition->SetPropertyQualifier(pwcsProperty,pwcsQualifierName, &varDefaultValue, lQualifierFlavor);
  560. }
  561. }
  562. }
  563. SAFE_DELETE_PTR(pwcsQualifierName);
  564. SAFE_DELETE_PTR(pwcsProperty);
  565. return MapWbemErrorToOLEDBError(hr);
  566. }
  567. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  568. // Function to initialize the DBCOLUMNINFO structure
  569. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  570. HRESULT CWmiOleDBMap::SetCommonDBCOLUMNINFO(DBCOLUMNINFO ** pCol, DBORDINAL uCurrentIndex)
  571. {
  572. (*pCol)->columnid.eKind = DBKIND_GUID_PROPID;
  573. (*pCol)->columnid.uGuid.guid = GUID_NULL;
  574. (*pCol)->columnid.uName.ulPropid = (ULONG)uCurrentIndex;
  575. (*pCol)->iOrdinal = uCurrentIndex;
  576. (*pCol)->pTypeInfo = NULL;
  577. (*pCol)->bPrecision = (BYTE) ~0;
  578. (*pCol)->bScale = (BYTE) ~0;
  579. (*pCol)->dwFlags = 0;
  580. //==================================================================
  581. // We do support nulls
  582. //==================================================================
  583. (*pCol)->dwFlags |= DBCOLUMNFLAGS_ISNULLABLE;
  584. (*pCol)->dwFlags |= DBCOLUMNFLAGS_MAYBENULL;
  585. //==================================================================
  586. //We should always be able to write to the column
  587. //==================================================================
  588. (*pCol)->dwFlags |= DBCOLUMNFLAGS_WRITE;
  589. return S_OK;
  590. }
  591. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  592. // Function which gets column info for qualifier
  593. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  594. HRESULT CWmiOleDBMap::GetQualifiedNameColumnInfo( cRowColumnInfoMemMgr * pParentCol,DBCOLUMNINFO ** pCol, WCHAR * pName)
  595. {
  596. HRESULT hr = E_UNEXPECTED;
  597. WCHAR * pColumnName = new WCHAR[ wcslen(pName) + wcslen(QUALIFIER_) + wcslen(SEPARATOR) +2];
  598. if( pColumnName ){
  599. swprintf(pColumnName,L"%s%s%s",pName,SEPARATOR,QUALIFIER_);
  600. // if the column is already present in the col info info return
  601. // This will happen when for row objects obtained from rowsets
  602. if(((DB_LORDINAL)pParentCol->GetColOrdinal(pColumnName)) >=0)
  603. {
  604. hr = S_OK;
  605. }
  606. else
  607. {
  608. hr = pParentCol->AddColumnNameToList(pColumnName, pCol);
  609. if( hr == S_OK ){
  610. //==================================================================
  611. // We use ordinal numbers for our columns
  612. //==================================================================
  613. SetCommonDBCOLUMNINFO(pCol, pParentCol->GetCurrentIndex());
  614. (*pCol)->wType = DBTYPE_HCHAPTER ;
  615. (*pCol)->ulColumnSize = sizeof(HCHAPTER);
  616. (*pCol)->dwFlags = DBCOLUMNFLAGS_ISCHAPTER | DBCOLUMNFLAGS_ISFIXEDLENGTH ;
  617. // NTRaid:111762
  618. // 06/13/00
  619. hr = pParentCol->CommitColumnInfo();
  620. }
  621. }
  622. }
  623. SAFE_DELETE_PTR(pColumnName);
  624. return hr;
  625. }
  626. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  627. // Get column info for a property of a class
  628. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  629. HRESULT CWmiOleDBMap::GetPropertyColumnInfo( cRowColumnInfoMemMgr * pColumn, DBCOLUMNINFO ** pCol,CBSTR & pProperty,LONG &lFlavor)
  630. {
  631. HRESULT hr = E_FAIL;
  632. VARIANT vValue;
  633. CIMTYPE propertyType;
  634. CBSTR strWrite(L"write");
  635. DBORDINAL lOrdinal = -1;
  636. VariantInit(&vValue);
  637. BSTR bstrPath ;
  638. BSTR bstrProperty;
  639. if((BSTR)pProperty == NULL)
  640. {
  641. //===========================================================================
  642. // Get the next property
  643. //===========================================================================
  644. hr = m_pWbemClassDefinition->GetNextProperty((unsigned short **)&pProperty,(VARIANT *)&vValue, &propertyType,&lFlavor);
  645. }
  646. else
  647. {
  648. hr = m_pWbemClassDefinition->GetProperty(pProperty,(VARIANT *)&vValue, &propertyType, &lFlavor);
  649. }
  650. if( hr == S_OK)
  651. {
  652. bstrProperty = Wmioledb_SysAllocString((WCHAR *)(BSTR)pProperty);
  653. bstrPath = Wmioledb_SysAllocString(L"__PATH");
  654. // Ignore the __PATH column if the rowset type to be dealt is a rowset for executing
  655. // a method. This is because , __PATH property exists in __PARAMETERS object but the
  656. // object obtained for output parameters does not contain this property
  657. if(wbem_wcsicmp(bstrProperty , bstrPath) == 0 && m_bMethodRowset == TRUE &&
  658. ((CWbemMethodParameters *)m_pWbemClassParms)->m_pQuery != NULL &&
  659. ((CWbemMethodParameters *)m_pWbemClassParms)->m_pQuery->GetType() == METHOD_ROWSET )
  660. {
  661. pProperty.Clear();
  662. VariantClear(&vValue);
  663. hr = m_pWbemClassDefinition->GetNextProperty((unsigned short **)&pProperty,(VARIANT *)&vValue, &propertyType,&lFlavor);
  664. }
  665. SysFreeString(bstrPath);
  666. SysFreeString(bstrProperty);
  667. lOrdinal = pColumn->GetColOrdinal((WCHAR *)(BSTR)pProperty);
  668. // if the column is already present in the col info info return
  669. // This will happen when for row objects obtained from rowsets
  670. if((DB_LORDINAL)lOrdinal < 0)
  671. {
  672. hr = pColumn->AddColumnNameToList(pProperty, pCol);
  673. if( hr == S_OK )
  674. {
  675. //==================================================================
  676. // We use ordinal numbers for our columns
  677. //==================================================================
  678. SetCommonDBCOLUMNINFO(pCol, pColumn->GetCurrentIndex());
  679. // if the property is system property then it cannot be updated
  680. if(lFlavor == WBEM_FLAVOR_ORIGIN_SYSTEM ||
  681. m_pWbemClassDefinition->IsClassSchema())
  682. {
  683. SetColumnReadOnly(*pCol,TRUE);
  684. }
  685. else
  686. {
  687. hr = GetPropertyQualifier(pProperty,(BSTR)strWrite,vValue);
  688. //if((hr == S_OK) && (VARIANT_TRUE == V_BOOL(&vValue)))
  689. {
  690. SetColumnReadOnly(*pCol,FALSE);
  691. }
  692. //else
  693. {
  694. // SetColumnReadOnly(*pCol,TRUE);
  695. }
  696. }
  697. pColumn->SetCIMType(propertyType);
  698. if((propertyType == CIM_OBJECT) || (propertyType == CIM_OBJECTARRAY))
  699. {
  700. if( propertyType == CIM_OBJECTARRAY)
  701. {
  702. propertyType = VT_ARRAY | VT_BSTR;
  703. }
  704. else
  705. {
  706. propertyType = CIM_STRING;
  707. }
  708. SetColumnTypeURL(*pCol);
  709. }
  710. hr = S_OK;
  711. CDataMap DataMap;
  712. DataMap.MapCIMTypeToOLEDBType(propertyType,(*pCol)->wType,(*pCol)->ulColumnSize,(*pCol)->dwFlags);
  713. // NTRaid:111762
  714. // 06/13/00
  715. hr = pColumn->CommitColumnInfo();
  716. }
  717. }
  718. }
  719. return hr;
  720. }
  721. //**********************************************************************************************************************
  722. //
  723. // PUBLIC FUNCTIONS
  724. //
  725. //**********************************************************************************************************************
  726. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  727. // Function to initialize the DBCOLUMNDESC structure for various types of column
  728. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  729. HRESULT CWmiOleDBMap::SetColumns( const DBORDINAL cColumnDescs, const DBCOLUMNDESC rgColumnDescs[])
  730. {
  731. HRESULT hr = S_OK;
  732. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  733. for( DBORDINAL i = 0; i < cColumnDescs && SUCCEEDED(hr); i++ ) { //for each column
  734. // switch(ParseQualifiedNameToGetColumnType(rgColumnDescs[i]->pwszTypeName)){
  735. switch(ParseQualifiedNameToGetColumnType(rgColumnDescs[i].dbcid.uName.pwszName)){
  736. case WMI_CLASS_QUALIFIER:
  737. hr = SetWMIClassQualifier(&rgColumnDescs[i]);
  738. break;
  739. case WMI_PROPERTY_QUALIFIER:
  740. hr = SetWMIPropertyQualifier(&rgColumnDescs[i]);
  741. break;
  742. case WMI_PROPERTY:
  743. hr = SetWMIProperty(&rgColumnDescs[i]);
  744. break;
  745. default:
  746. hr = E_INVALIDARG;
  747. break;
  748. }
  749. }
  750. }
  751. return hr;
  752. }
  753. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  754. // Function to create a new table ( which maps to a new class)
  755. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  756. HRESULT CWmiOleDBMap::CreateTable( DBORDINAL cColumnDescs, const DBCOLUMNDESC rgColumnDescs[],
  757. ULONG cPropertySets, DBPROPSET rgPropertySets[])
  758. {
  759. HRESULT hr ;
  760. BSTR strSuperClass = Wmioledb_SysAllocString(NULL);
  761. // If the class already exists then return error
  762. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass()))
  763. {
  764. hr = DB_E_DUPLICATETABLEID;
  765. }
  766. else
  767. {
  768. hr = m_pWbemClassDefinition->CreateClass();
  769. if( S_OK == hr ){
  770. hr = SetColumns(cColumnDescs, rgColumnDescs);
  771. if( hr == S_OK)
  772. {
  773. hr = m_pWbemClassDefinition->SaveClass();
  774. }
  775. }
  776. }
  777. return hr;
  778. }
  779. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  780. // Funtion to add a table ( which maps to a class)
  781. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  782. HRESULT CWmiOleDBMap::DropTable()
  783. {
  784. HRESULT hr = S_OK;
  785. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  786. hr = m_pWbemClassDefinition->DeleteClass();
  787. if( hr == S_OK)
  788. {
  789. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  790. }
  791. }
  792. return hr;
  793. }
  794. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  795. // Funtion to add a column( which maps to property/qualifier)
  796. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  797. HRESULT CWmiOleDBMap::AddColumn(const DBCOLUMNDESC* prgColDesc, DBID** pColumnID) //Add a column to current ClassObject definition or instance
  798. {
  799. HRESULT hr ;
  800. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  801. hr = SetColumns(1, prgColDesc);
  802. if( hr == S_OK)
  803. {
  804. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  805. }
  806. }
  807. return hr;
  808. }
  809. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  810. // Funtion to drop a column( which maps to property/qualifier)
  811. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  812. HRESULT CWmiOleDBMap::DropColumn(const DBID* pColumnID) //Drop a column from current ClassObject definition or instance
  813. {
  814. HRESULT hr ;
  815. WCHAR * pwcsClass = NULL;
  816. WCHAR * pwcsQualifier = NULL;
  817. WCHAR * pwcsProperty = NULL;
  818. CBSTR strColumnName(pColumnID->uName.pwszName);
  819. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  820. switch(ParseQualifiedNameToGetColumnType((WCHAR*)pColumnID->uName.pwszName)){
  821. case WMI_CLASS_QUALIFIER:
  822. if( ParseQualifiedName((WCHAR*)pColumnID->uName.pwszName,pwcsClass,pwcsQualifier) ){
  823. hr = m_pWbemClassDefinition->DeleteClassQualifier(pwcsQualifier);
  824. }
  825. break;
  826. case WMI_PROPERTY_QUALIFIER:
  827. if( ParseQualifiedName((WCHAR*)pColumnID->uName.pwszName,pwcsProperty,pwcsQualifier) ){
  828. hr = m_pWbemClassDefinition->DeletePropertyQualifier(pwcsProperty,pwcsQualifier);
  829. }
  830. break;
  831. case WMI_PROPERTY:
  832. hr = m_pWbemClassDefinition->DeleteProperty((BSTR)strColumnName);
  833. break;
  834. default:
  835. hr = E_INVALIDARG;
  836. break;
  837. }
  838. }
  839. // If everthing is fine then save the changes to WMI
  840. if( hr == S_OK)
  841. {
  842. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  843. }
  844. SAFE_DELETE_PTR(pwcsClass);
  845. SAFE_DELETE_PTR(pwcsQualifier);
  846. SAFE_DELETE_PTR(pwcsProperty);
  847. return hr;
  848. }
  849. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  850. // Get the count of the number of columns
  851. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  852. HRESULT CWmiOleDBMap::GetColumnCount( DBCOUNTITEM & cTotalColumns,DBCOUNTITEM & cParentColumns,DBCOUNTITEM &cNestedCols)
  853. {
  854. HRESULT hr;
  855. cTotalColumns = 0L;
  856. cParentColumns = 0L;
  857. cNestedCols = 0L;
  858. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  859. int nCnt = 1;
  860. //========================================================================
  861. // If we are dealing with class qualifiers, then add one column which
  862. // will contain the rowset of class qualifiers.
  863. //========================================================================
  864. if( m_pWbemClassDefinition->GetFlags() & CLASS_QUALIFIERS ){
  865. cTotalColumns++;
  866. cNestedCols++;
  867. }
  868. //========================================================================
  869. // if we are dealing with property qualifiers, then we will need to add
  870. // on a property qualifier for each property column
  871. //========================================================================
  872. if( m_pWbemClassDefinition->GetFlags() & PROPERTY_QUALIFIERS ){
  873. nCnt = 2;
  874. }
  875. //========================================================================
  876. // Now, get the number of properties for this class
  877. //========================================================================
  878. ULONG ulProperties = 0, ulSysPropCount = 0;
  879. hr= m_pWbemClassDefinition->TotalPropertiesInClass(ulProperties,ulSysPropCount);
  880. // NTRaid : 142133 & 141923
  881. // 07/12/00
  882. if(hr == S_FALSE)
  883. {
  884. cTotalColumns = 0;
  885. cParentColumns = 0;
  886. cNestedCols = 0;
  887. hr = S_OK;
  888. }
  889. else
  890. if(SUCCEEDED(hr))
  891. {
  892. // Ignore the __PATH column if the rowset type to be dealt is a rowset for executing
  893. // a method. This is because , __PATH property exists in __PARAMETERS object but the
  894. // object obtained for output parameters does not contain this property
  895. // So if the rowset to be constructed is to represent output parameters of a method
  896. // execution , decrement the number of system properties
  897. if(m_bMethodRowset == TRUE && ((CWbemMethodParameters *)m_pWbemClassParms)->m_pQuery != NULL &&
  898. ((CWbemMethodParameters *)m_pWbemClassParms)->m_pQuery->GetType() == METHOD_ROWSET && ulSysPropCount> 0)
  899. {
  900. ulSysPropCount--;
  901. }
  902. if( hr == S_OK ){
  903. cParentColumns = cTotalColumns + ulSysPropCount + ulProperties;
  904. cTotalColumns += ulSysPropCount + ulProperties * nCnt;
  905. cTotalColumns++; // Adding for the first bookmark column
  906. // If property is included in the rowset
  907. if( nCnt>1){
  908. cNestedCols += ulProperties;
  909. }
  910. }
  911. }
  912. }
  913. return hr;
  914. }
  915. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  916. // Gets column information for the class
  917. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  918. HRESULT CWmiOleDBMap::GetColumnInfoForParentColumns(cRowColumnInfoMemMgr * pParentCol)
  919. {
  920. HRESULT hr = S_OK;
  921. LONG lFlavour = 0;
  922. INSTANCELISTTYPE objListType = NORMAL;
  923. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  924. if(m_pWbemCommandManager)
  925. {
  926. objListType = m_pWbemCommandManager->GetObjListType();
  927. }
  928. else
  929. if(m_pWbemCollectionManager)
  930. {
  931. objListType = m_pWbemCollectionManager->GetObjListType();
  932. }
  933. switch(objListType)
  934. {
  935. case NORMAL:
  936. {
  937. if( S_OK == (hr = m_pWbemClassDefinition->BeginPropertyEnumeration()))
  938. {
  939. pParentCol->ResetColumns();
  940. //====================================================================
  941. // get the column info for class qualifiers
  942. //====================================================================
  943. if( m_pWbemClassDefinition->GetFlags() & CLASS_QUALIFIERS ){
  944. hr = GetQualifiedNameColumnInfo(pParentCol,pParentCol->CurrentColInfo(),m_pWbemClassParms->GetClassName());
  945. }
  946. if( hr == S_OK ){
  947. CBSTR pProperty;
  948. //=================================================================
  949. // Go through all of the columns we have allocated
  950. //=================================================================
  951. while(TRUE){
  952. // CBSTR pProperty;
  953. hr = GetPropertyColumnInfo(pParentCol,pParentCol->CurrentColInfo(),pProperty,lFlavour);
  954. if( hr!= S_OK ){
  955. break;
  956. }
  957. //=============================================================
  958. // if we are supposed to support property qualifiers
  959. //=============================================================
  960. if( m_pWbemClassDefinition->GetFlags() & PROPERTY_QUALIFIERS && (lFlavour != WBEM_FLAVOR_ORIGIN_SYSTEM )){
  961. hr = GetQualifiedNameColumnInfo(pParentCol,pParentCol->CurrentColInfo(),pProperty);
  962. }
  963. pProperty.Clear();
  964. pProperty.Unbind();
  965. }
  966. if( hr == WBEM_S_NO_MORE_DATA ){
  967. hr = S_OK;
  968. }
  969. }
  970. m_pWbemClassDefinition->EndPropertyEnumeration();
  971. }
  972. }
  973. break;
  974. case MIXED:
  975. case SCOPE:
  976. case CONTAINER:
  977. {
  978. if( m_pWbemClassDefinition->GetFlags() & CLASS_QUALIFIERS ){
  979. hr = GetQualifiedNameColumnInfo(pParentCol,pParentCol->CurrentColInfo(),m_pWbemClassParms->GetClassName());
  980. }
  981. /* CBSTR pProperty(L"__PATH");
  982. hr = GetPropertyColumnInfo(pParentCol,pParentCol->CurrentColInfo(),pProperty,lFlavour);
  983. */ hr = GetPropertyColumnInfoForMixedRowsets(pParentCol,pParentCol->CurrentColInfo());
  984. }
  985. break;
  986. }
  987. }
  988. return hr;
  989. }
  990. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  991. HRESULT CWmiOleDBMap::ResetInstances()
  992. {
  993. return m_paWbemClassInstances->Reset();
  994. }
  995. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  996. HRESULT CWmiOleDBMap::ResetInstancesToNewPosition(DBROWOFFSET lRowOffset) // Start getting at new position
  997. {
  998. return m_paWbemClassInstances->ResetRelPosition(lRowOffset);
  999. // return m_paWbemClassInstances->ResetInstancesToNewPosition(lRowOffset);
  1000. return S_OK;
  1001. }
  1002. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1003. HRESULT CWmiOleDBMap::ResetPropQualiferToNewPosition(CWbemClassWrapper *pInst,DBROWOFFSET lRowOffset,BSTR strPropertyName)
  1004. {
  1005. return pInst->SetQualifierRelPos(lRowOffset,strPropertyName);
  1006. }
  1007. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1008. HRESULT CWmiOleDBMap::ResetClassQualiferToNewPosition(CWbemClassWrapper *pInst,DBROWOFFSET lRowOffset)
  1009. {
  1010. return pInst->SetQualifierRelPos(lRowOffset);
  1011. }
  1012. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1013. // Method to get the properties values and put it into the local buffer
  1014. // In the code the code if(WBEM_FLAG_DEEP != lFlags) check if
  1015. // all instances of child class is obtained or not. This will enable us to check if enumerator is to be
  1016. // used or not. If this is true , then the col info need not be in the same order as that of the
  1017. // enumerator, So properties has to be obtained in the order of the column information
  1018. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1019. HRESULT CWmiOleDBMap::GetProperties(CRowDataMemMgr * pRow,CWbemClassWrapper * pClass,cRowColumnInfoMemMgr *pColInfoMgr)
  1020. {
  1021. HRESULT hr = S_OK;
  1022. LONG lFlags = 0;
  1023. // Get the flags of the class
  1024. lFlags = pClass->GetQueryFlags();
  1025. // Property Enumerator is not used if Deep flag is set or
  1026. // if the query executed results in heterogenous object , in which case
  1027. // only __PATH is fetched
  1028. CVARIANT vValue ,vChapter;
  1029. LONG lFlavor = 0;
  1030. CBSTR pProperty;
  1031. BSTR bstProperty = NULL;
  1032. BYTE * pData = NULL;
  1033. CIMTYPE lType = 0;
  1034. CDataMap map;
  1035. DBORDINAL lIndex = 1;
  1036. DBCOUNTITEM cCols = 0;
  1037. // IF class Qualifiers are requested updated the qualifier
  1038. if(pClass->GetFlags() & CLASS_QUALIFIERS) {
  1039. vChapter.SetLONG(/*m_pWbemClassDefinition->GetNewHChapter()*/ 0);
  1040. if( S_OK != (hr = pRow->CommitColumnToRowData(vChapter,VT_UI4))){
  1041. }
  1042. lIndex++;
  1043. }
  1044. cCols = pColInfoMgr->GetTotalNumberOfColumns();
  1045. bstProperty = Wmioledb_SysAllocString(pColInfoMgr->ColumnName(lIndex));
  1046. while (lIndex < (ULONG_PTR)cCols)
  1047. {
  1048. // Get the specified property
  1049. if(pColInfoMgr->ColumnType(lIndex) != DBTYPE_HCHAPTER)
  1050. {
  1051. if (SysReAllocString(&bstProperty, pColInfoMgr->ColumnName(lIndex)))
  1052. {
  1053. hr = pClass->GetProperty(bstProperty,(VARIANT *)&vValue, &lType, &lFlavor);
  1054. }
  1055. else
  1056. {
  1057. hr = WBEM_E_OUT_OF_MEMORY;
  1058. break;
  1059. }
  1060. }
  1061. if( FAILED(hr) ){
  1062. break;
  1063. }
  1064. if(( lType != vValue.GetType() && VT_NULL != vValue.GetType() && VT_EMPTY != vValue.GetType()) &&
  1065. lType != (CIM_FLAG_ARRAY | CIM_DATETIME ))
  1066. {
  1067. map.ConvertVariantType((VARIANT &)vValue ,(VARIANT &)vValue,lType);
  1068. }
  1069. else
  1070. if((vValue.GetType() == VT_UNKNOWN) || (vValue.GetType() == CIM_OBJECTARRAY) || (vValue.GetType() == CIM_OBJECT) )
  1071. {
  1072. GetEmbededObjects((CWbemClassInstanceWrapper *)pClass,bstProperty ,vValue);
  1073. }
  1074. //=======================================================================
  1075. // Set the data into the row
  1076. //=======================================================================
  1077. if( S_OK != (hr = pRow->CommitColumnToRowData(vValue,(DBTYPE)lType))){
  1078. break;
  1079. }
  1080. lIndex++;
  1081. //======================================================================================
  1082. // This is where we Get Property Qualifiers if the property is not a system property
  1083. //=======================================================================================
  1084. if( pClass->GetFlags() & PROPERTY_QUALIFIERS && lFlavor != WBEM_FLAVOR_ORIGIN_SYSTEM) {
  1085. vChapter.SetLONG(/*m_pWbemClassDefinition->GetNewHChapter()*/ 0);
  1086. if( S_OK != (hr = pRow->CommitColumnToRowData(vChapter,VT_UI4))){
  1087. break;
  1088. }
  1089. lIndex++;
  1090. }
  1091. vValue.Clear();
  1092. }
  1093. SysFreeString(bstProperty);
  1094. hr = hr == WBEM_S_NO_MORE_DATA ? S_OK : hr;
  1095. return hr;
  1096. }
  1097. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1098. // Get the next instance
  1099. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1100. HRESULT CWmiOleDBMap::GetNextInstance(CWbemClassWrapper *&pInst,CBSTR &strKey , BOOL bFetchBack)
  1101. {
  1102. HRESULT hr = WBEM_S_NO_MORE_DATA;
  1103. CWbemClassInstanceWrapper *pInstTemp = NULL;
  1104. if( bFetchBack == FALSE)
  1105. {
  1106. hr = m_paWbemClassInstances->NextInstance(strKey, &pInstTemp);
  1107. }
  1108. else
  1109. {
  1110. hr = m_paWbemClassInstances->PrevInstance(strKey, pInstTemp);
  1111. }
  1112. if(hr == S_OK)
  1113. {
  1114. pInst = (CWbemClassWrapper *)pInstTemp;
  1115. }
  1116. return hr;
  1117. }
  1118. //==========================================================================================================================
  1119. // Functin to get data for a particular instance
  1120. //==========================================================================================================================
  1121. HRESULT CWmiOleDBMap::GetDataForInstance(CRowDataMemMgr * pRow,CWbemClassWrapper *pInst,cRowColumnInfoMemMgr *pColInfoMgr)
  1122. {
  1123. HRESULT hr = S_OK;
  1124. if( pInst != NULL ){
  1125. //========================================================
  1126. // Now, get the properties
  1127. //========================================================
  1128. hr = GetProperties(pRow,(CWbemClassWrapper*)pInst,pColInfoMgr);
  1129. }
  1130. return hr;
  1131. }
  1132. //==========================================================================================================================
  1133. // Functin to get data for a particular Schema instance
  1134. //==========================================================================================================================
  1135. HRESULT CWmiOleDBMap::GetDataForSchemaInstance(CRowDataMemMgr * pRow,CWbemClassWrapper *pPtr,cRowColumnInfoMemMgr *pColInfoMgr)
  1136. {
  1137. HRESULT hr = E_INVALIDARG;
  1138. CWbemSchemaClassInstanceWrapper * pClass = (CWbemSchemaClassInstanceWrapper * ) pPtr;
  1139. if( pClass != NULL ){
  1140. CVARIANT vValue;
  1141. LONG lFlavor;
  1142. CBSTR pProperty;
  1143. BYTE * pData = NULL;
  1144. CIMTYPE lType = 0;
  1145. CDataMap map;
  1146. DBORDINAL lIndex = 1;
  1147. DBLENGTH cCols = 0;
  1148. hr = S_OK;
  1149. cCols = pColInfoMgr->GetTotalNumberOfColumns();
  1150. while ( ( S_OK == hr) && (lIndex < cCols)){
  1151. hr = pClass->GetSchemaProperty((WCHAR *)pColInfoMgr->ColumnName(lIndex),(VARIANT*)vValue, &lType, &lFlavor);
  1152. if( hr == WBEM_S_NO_MORE_DATA ){
  1153. hr = S_OK;
  1154. break;
  1155. }
  1156. if( lType != vValue.GetType() && VT_NULL != vValue.GetType() && VT_EMPTY != vValue.GetType()){
  1157. map.ConvertVariantType((VARIANT &)vValue ,(VARIANT &)vValue,lType);
  1158. }
  1159. //=======================================================================
  1160. // Set the data into the row
  1161. //=======================================================================
  1162. if( S_OK != (hr = pRow->CommitColumnToRowData(vValue,(DBTYPE)lType))){
  1163. break;
  1164. }
  1165. lIndex++;
  1166. VariantClear(&vValue);
  1167. }
  1168. }
  1169. if( hr == WBEM_S_NO_MORE_DATA)
  1170. {
  1171. hr = S_OK;
  1172. }
  1173. return hr;
  1174. }
  1175. //==========================================================================================================================
  1176. // Function to get next property qualifer
  1177. //==========================================================================================================================
  1178. HRESULT CWmiOleDBMap::GetNextPropertyQualifier(CWbemClassWrapper *pInst,BSTR strPropName,BSTR &strQualifier,BOOL bFetchBack)
  1179. {
  1180. HRESULT hr = E_INVALIDARG;
  1181. CVARIANT vValue;
  1182. LONG lType = 0;
  1183. LONG lFlavor = 0;
  1184. CVARIANT var;
  1185. if( S_OK == (hr = pInst->ValidClass()))
  1186. {
  1187. if(bFetchBack == FALSE)
  1188. {
  1189. hr = pInst->GetNextPropertyQualifier(strPropName,&strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1190. }
  1191. else
  1192. {
  1193. hr = pInst->GetPrevPropertyQualifier(strPropName,&strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1194. }
  1195. }
  1196. return hr;
  1197. }
  1198. //==========================================================================================================================
  1199. // Function to get data for property qualifer
  1200. //==========================================================================================================================
  1201. HRESULT CWmiOleDBMap::GetDataForPropertyQualifier(CRowDataMemMgr * pRow,CWbemClassWrapper *pInst,BSTR strPropName, BSTR strQualifier, cRowColumnInfoMemMgr *pColInfoMgr)
  1202. {
  1203. HRESULT hr = E_INVALIDARG;
  1204. CVARIANT vValue;
  1205. LONG lType = 0;
  1206. LONG lFlavor = 0;
  1207. CVARIANT var;
  1208. if(SUCCEEDED(hr = pInst->ValidClass()))
  1209. {
  1210. hr = pInst->GetPropertyQualifier(strPropName,strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1211. if( SUCCEEDED(hr) )
  1212. {
  1213. hr = CommitRowDataForQualifier(pRow,strQualifier,vValue,lType,lFlavor);
  1214. }
  1215. }
  1216. return hr;
  1217. }
  1218. //==========================================================================================================================
  1219. // Function to get next class qualifer
  1220. //==========================================================================================================================
  1221. HRESULT CWmiOleDBMap::GetNextClassQualifier(CWbemClassWrapper *pInst,BSTR &strQualifier,BOOL bFetchBack)
  1222. {
  1223. HRESULT hr = E_INVALIDARG;
  1224. CVARIANT vValue;
  1225. LONG lType = 0;
  1226. LONG lFlavor = 0;
  1227. CVARIANT var;
  1228. if( SUCCEEDED (hr = pInst->ValidClass()))
  1229. {
  1230. if( bFetchBack == FALSE)
  1231. {
  1232. hr = pInst->GetNextClassQualifier(&strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1233. }
  1234. else
  1235. {
  1236. hr = pInst->GetPrevClassQualifier(&strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1237. }
  1238. }
  1239. return hr;
  1240. }
  1241. //==========================================================================================================================
  1242. // Function to get data for class qualifer
  1243. //==========================================================================================================================
  1244. HRESULT CWmiOleDBMap::GetDataForClassQualifier(CRowDataMemMgr * pRow,CWbemClassWrapper *pInst, BSTR strQualifier, cRowColumnInfoMemMgr *pColInfoMgr)
  1245. {
  1246. HRESULT hr = E_INVALIDARG;
  1247. CVARIANT vValue;
  1248. LONG lType = 0;
  1249. LONG lFlavor = 0;
  1250. CVARIANT var;
  1251. if(SUCCEEDED(hr = pInst->ValidClass()))
  1252. {
  1253. hr = pInst->GetClassQualifier(strQualifier,(VARIANT *)&vValue, &lType,&lFlavor);
  1254. if( hr == S_OK )
  1255. {
  1256. hr = CommitRowDataForQualifier(pRow,strQualifier,vValue,lType,lFlavor);
  1257. }
  1258. }
  1259. return hr;
  1260. }
  1261. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1262. BOOL CWmiOleDBMap::IsPropQualiferIncluded()
  1263. {
  1264. BOOL bRet = FALSE;
  1265. if( m_pWbemClassDefinition->GetFlags() & PROPERTY_QUALIFIERS )
  1266. {
  1267. bRet = TRUE;
  1268. }
  1269. return bRet;
  1270. }
  1271. /*
  1272. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1273. // Get the column info for the Property Qualifiers
  1274. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1275. HRESULT CWmiOleDBMap::GetNextPropertyQualifier( CWbemClassWrapper *pInst,BSTR &strPropName,CVARIANT &vValue,LONG &lType)
  1276. {
  1277. HRESULT hr = S_OK;
  1278. /*
  1279. LONG lFlavor;
  1280. //===========================================================================
  1281. // Get the next property qualifier
  1282. //===========================================================================
  1283. hr = pInst->GetNextPropertyQualifier((unsigned short **)&strPropName,(VARIANT *)&vValue, &lType,&lFlavor);
  1284. return hr;
  1285. }
  1286. */
  1287. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1288. // Get the property qualifer
  1289. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1290. HRESULT CWmiOleDBMap::GetPropertyQualifier(BSTR strPropName, BSTR strQualifierName ,VARIANT &vValue)
  1291. {
  1292. HRESULT hr = S_OK;
  1293. LONG lFlavor;
  1294. CIMTYPE QualifierDataType;
  1295. if( SUCCEEDED(hr = m_pWbemClassDefinition->ValidClass())){
  1296. if(SUCCEEDED (hr = m_pWbemClassDefinition->BeginPropertyQualifierEnumeration(strPropName)))
  1297. {
  1298. // call this function to get a specific property
  1299. hr = m_pWbemClassDefinition->GetPropertyQualifier(strQualifierName,(VARIANT *)&vValue, &QualifierDataType,&lFlavor);
  1300. m_pWbemClassDefinition->EndPropertyQualifierEnumeration();
  1301. }
  1302. }
  1303. return hr;
  1304. }
  1305. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1306. // set a particular column's as readonly property
  1307. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1308. void CWmiOleDBMap::SetColumnReadOnly(DBCOLUMNINFO * pCol, BOOL bReadOnly)
  1309. {
  1310. if(bReadOnly == FALSE)
  1311. {
  1312. pCol->dwFlags |= DBCOLUMNFLAGS_WRITE;
  1313. }
  1314. else
  1315. {
  1316. pCol->dwFlags &= ~(DBCOLUMNFLAGS_WRITE);
  1317. }
  1318. }
  1319. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1320. // Delete a particular instance
  1321. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1322. HRESULT CWmiOleDBMap::DeleteInstance(CWbemClassWrapper * pClass )
  1323. {
  1324. HRESULT hr = S_OK;
  1325. CWbemClassInstanceWrapper *pTemp = (CWbemClassInstanceWrapper *) pClass;
  1326. hr = m_paWbemClassInstances->DeleteInstance(pTemp);
  1327. return hr;
  1328. }
  1329. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1330. // update a instance
  1331. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1332. HRESULT CWmiOleDBMap::UpdateInstance(CWbemClassWrapper *pInst,BOOL bNewInst)
  1333. {
  1334. CWbemClassInstanceWrapper *pTemp = (CWbemClassInstanceWrapper *) pInst;
  1335. return m_paWbemClassInstances->UpdateInstance(pTemp,bNewInst);
  1336. }
  1337. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1338. // Add new instance
  1339. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1340. HRESULT CWmiOleDBMap::AddNewInstance(CWbemClassWrapper ** ppClass )
  1341. {
  1342. HRESULT hr = S_OK;
  1343. // NTRaid:111794
  1344. // 06/07/00
  1345. CWbemClassInstanceWrapper *pNewInst = NULL ;
  1346. hr = m_paWbemClassInstances->AddNewInstance((CWbemClassWrapper *)m_pWbemClassDefinition ,&pNewInst);
  1347. if(SUCCEEDED(hr))
  1348. {
  1349. *ppClass = pNewInst;
  1350. }
  1351. return hr;
  1352. }
  1353. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1354. // Set navigation flags for enumerator
  1355. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1356. void CWmiOleDBMap::SetNavigationFlags(DWORD dwFlags)
  1357. {
  1358. m_pWbemClassParms->SetEnumeratorFlags(dwFlags);
  1359. }
  1360. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1361. // Set navigation flags for enumerator
  1362. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1363. void CWmiOleDBMap::SetQueryFlags(DWORD dwFlags)
  1364. {
  1365. m_pWbemClassParms->SetQueryFlags(dwFlags);
  1366. }
  1367. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1368. // Refresh a particular instance
  1369. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1370. HRESULT CWmiOleDBMap::RefreshInstance(CWbemClassWrapper * pInstance )
  1371. {
  1372. return ((CWbemClassInstanceWrapper *)pInstance)->RefreshInstance();
  1373. }
  1374. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1375. // Get a particular property of the instance
  1376. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1377. HRESULT CWmiOleDBMap::GetProperty(CWbemClassWrapper *pInst,BSTR pProperty, BYTE *& pData,DBTYPE &dwType ,DBLENGTH & dwSize, DWORD &dwFlags )
  1378. {
  1379. CVARIANT varValue;
  1380. CIMTYPE cType = 0;
  1381. LONG lFlavor = 0;
  1382. CDataMap map;
  1383. HRESULT hr = 0;
  1384. DBTYPE dbType = 0;
  1385. hr = pInst->GetProperty(pProperty, &varValue, (LONG *)&cType ,&lFlavor );
  1386. if( hr == S_OK)
  1387. {
  1388. dbType = (DBTYPE)varValue.GetType();
  1389. // NTRaid 135384
  1390. if(cType == CIM_DATETIME || cType == CIM_IUNKNOWN)
  1391. {
  1392. dbType = (DBTYPE)cType;
  1393. }
  1394. else
  1395. // If the property is an embeded instance
  1396. if( dbType == VT_UNKNOWN || dbType == CIM_OBJECTARRAY || dbType == CIM_OBJECT)
  1397. {
  1398. hr = GetEmbededObjects((CWbemClassInstanceWrapper *)pInst,pProperty,varValue);
  1399. dbType = varValue.GetType();
  1400. }
  1401. // return value of this function will be the status
  1402. if(SUCCEEDED(hr = map.AllocateAndMapCIMTypeToOLEDBType(varValue,pData,dbType,dwSize, dwFlags)))
  1403. {
  1404. dwType = dbType;
  1405. if((cType == (CIM_DATETIME | CIM_FLAG_ARRAY)) || (cType == (DBTYPE_DBTIMESTAMP | CIM_FLAG_ARRAY)) )
  1406. {
  1407. dwType = (DBTYPE)cType;
  1408. }
  1409. else
  1410. if(cType == CIM_IUNKNOWN)
  1411. {
  1412. dwType = DBTYPE_IUNKNOWN;
  1413. }
  1414. hr = S_OK;
  1415. }
  1416. }
  1417. return hr;
  1418. }
  1419. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1420. // Get the instance pointerd by the path
  1421. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1422. CWbemClassWrapper * CWmiOleDBMap::GetInstance(BSTR strPath)
  1423. {
  1424. CWbemClassWrapper *pInst = NULL;
  1425. pInst = m_pWbemClassDefinition->GetInstance(strPath);
  1426. // Add the instance to the list so that this get released when class is destructed
  1427. if(pInst != NULL)
  1428. {
  1429. m_paWbemClassInstances->AddInstance((CWbemClassInstanceWrapper *)pInst);
  1430. }
  1431. return pInst;
  1432. }
  1433. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1434. // Get Embeded objects and generate URLS for every embeded instance and put it into SAFEARRATS of URLS
  1435. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1436. HRESULT CWmiOleDBMap::GetEmbededObjects(CWbemClassInstanceWrapper * pClass,BSTR strProperty,CVARIANT &vValue)
  1437. {
  1438. CVARIANT vTemp;
  1439. HRESULT hr = S_OK;
  1440. CWbemClassInstanceWrapper * pNewInst = NULL;
  1441. IWbemClassObject * pClassObject = NULL;
  1442. CBSTR strKey;
  1443. SAFEARRAY * pArray;
  1444. SAFEARRAY * pArrayOut;
  1445. LONG rgIndices[1];
  1446. IUnknown * pUnk = NULL;
  1447. void * p = NULL;
  1448. SAFEARRAYBOUND rgsabound[1];
  1449. LONG lBound = 0 , uBound = 0;
  1450. VariantCopy(&vTemp, vValue);
  1451. vValue.Clear();
  1452. try
  1453. {
  1454. pNewInst = new CWbemClassInstanceWrapper(m_pWbemClassParms);
  1455. }
  1456. catch(...)
  1457. {
  1458. SAFE_DELETE_PTR(pNewInst);
  1459. throw;
  1460. }
  1461. if(pNewInst == NULL)
  1462. {
  1463. hr = E_OUTOFMEMORY;
  1464. }
  1465. else
  1466. {
  1467. if(vTemp.GetType() & VT_ARRAY)
  1468. {
  1469. pArray = (SAFEARRAY *)vTemp;
  1470. hr = SafeArrayGetLBound(pArray,1,&lBound);
  1471. hr = SafeArrayGetUBound(pArray,1,&uBound);
  1472. rgsabound[0].lLbound = lBound;
  1473. rgsabound[0].cElements = uBound - lBound + 1; // This is because the bounds includes both the bounds
  1474. pArrayOut = SafeArrayCreate(VT_BSTR, 1, rgsabound);
  1475. for( int nIndex = lBound ; nIndex <= uBound ; nIndex++)
  1476. {
  1477. strKey.Clear();
  1478. rgIndices[0] = nIndex;
  1479. hr = SafeArrayGetElement(pArray,&rgIndices[0],(void *)&pUnk);
  1480. hr = pUnk->QueryInterface(IID_IWbemClassObject , (void **)&pClassObject);
  1481. if(SUCCEEDED(hr))
  1482. {
  1483. pNewInst->SetClass(pClassObject);
  1484. hr = pNewInst->GetKey(strKey);
  1485. pUnk->Release();
  1486. pClassObject->Release();
  1487. GenerateURL(pClass,strProperty,nIndex, strKey);
  1488. hr = SafeArrayPutElement(pArrayOut,&rgIndices[0],(void *)strKey);
  1489. }
  1490. }
  1491. // If the elements in the array is not equal to zero
  1492. if(SUCCEEDED(hr) && (uBound - lBound + 1 != 0))
  1493. {
  1494. vValue.SetArray(pArrayOut,VT_ARRAY|VT_BSTR);
  1495. }
  1496. }
  1497. else
  1498. {
  1499. hr = vTemp.GetUnknown()->QueryInterface(IID_IWbemClassObject , (void **)&pClassObject);
  1500. if(SUCCEEDED(hr))
  1501. {
  1502. pNewInst->SetClass(pClassObject);
  1503. hr = pNewInst->GetKey(strKey);
  1504. pClassObject->Release();
  1505. GenerateURL(pClass,strProperty,-1, strKey);
  1506. vValue.SetStr(strKey);
  1507. }
  1508. }
  1509. SAFE_DELETE_PTR(pNewInst);
  1510. }
  1511. return hr;
  1512. }
  1513. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1514. // Generate URL for an instance , Used for embeded instance
  1515. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1516. void CWmiOleDBMap::GenerateURL(CWbemClassInstanceWrapper * pClass,BSTR strProperty,ULONG nIndex,CBSTR &strIn)
  1517. {
  1518. // NTRaid: 136446
  1519. // 07/05/00
  1520. CURLParser urlParser;
  1521. BSTR bstrURL = NULL;
  1522. if((strIn == NULL) || (SysStringLen(strIn) == 0))
  1523. {
  1524. pClass->GetKey(strIn);
  1525. }
  1526. urlParser.SetPath(strIn);
  1527. urlParser.SetEmbededInstInfo(strProperty,nIndex);
  1528. urlParser.GetURL(bstrURL);
  1529. strIn.Clear();
  1530. strIn.SetStr((LPWSTR)bstrURL);
  1531. SysFreeString(bstrURL);
  1532. }
  1533. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1534. // Get embeded instance
  1535. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1536. CWbemClassWrapper *CWmiOleDBMap::GetEmbededInstance(BSTR strPath,BSTR strProperty,int nIndex)
  1537. {
  1538. CWbemClassInstanceWrapper * pParentInst = NULL;
  1539. CWbemClassInstanceWrapper * pInstance = NULL;
  1540. IWbemClassObject *pObject = NULL;
  1541. IUnknown *pUnk = NULL;
  1542. CVARIANT vValue;
  1543. LONG lType;
  1544. LONG lFlavor;
  1545. HRESULT hr = S_OK;
  1546. pParentInst = (CWbemClassInstanceWrapper *)m_pWbemClassDefinition->GetInstance(strPath);
  1547. if(pParentInst)
  1548. {
  1549. hr = pParentInst->GetProperty(strProperty,(VARIANT *)&vValue, &lType, &lFlavor);
  1550. if(hr == S_OK && (vValue.GetType() == VT_UNKNOWN || vValue.GetType() == CIM_OBJECTARRAY ))
  1551. {
  1552. if( nIndex < 0 && vValue.GetType() == VT_UNKNOWN)
  1553. {
  1554. hr = vValue.GetUnknown()->QueryInterface(IID_IWbemClassObject,(void **)&pObject);
  1555. }
  1556. else
  1557. if( nIndex >= 0 && vValue.GetType() == CIM_OBJECTARRAY)
  1558. {
  1559. hr = SafeArrayGetElement(vValue,(long *)&nIndex,(void *)&pUnk);
  1560. if( hr == S_OK)
  1561. {
  1562. hr = pUnk->QueryInterface(IID_IWbemClassObject,(void **)&pObject);
  1563. pUnk->Release();
  1564. }
  1565. }
  1566. if(hr == S_OK)
  1567. {
  1568. try
  1569. {
  1570. pInstance = new CWbemClassInstanceWrapper(m_pWbemClassParms);
  1571. }
  1572. catch(...)
  1573. {
  1574. SAFE_DELETE_PTR(pInstance);
  1575. throw;
  1576. }
  1577. if(pInstance == NULL)
  1578. {
  1579. hr = E_OUTOFMEMORY;
  1580. }
  1581. else
  1582. {
  1583. pInstance->SetClass(pObject);
  1584. // Add the instance to the list so that this get released when class is destructed
  1585. m_paWbemClassInstances->AddInstance((CWbemClassInstanceWrapper *)pInstance);
  1586. }
  1587. }
  1588. }
  1589. SAFE_RELEASE_PTR(pObject);
  1590. SAFE_DELETE_PTR(pParentInst);
  1591. }
  1592. return pInstance;
  1593. }
  1594. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1595. // Check if a particular property is a system property
  1596. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1597. BOOL CWmiOleDBMap::IsSystemProperty(BSTR strProperty)
  1598. {
  1599. LONG lFlavour = 0;
  1600. BOOL bRet = FALSE;
  1601. if( S_OK == m_pWbemClassDefinition->GetProperty(strProperty,NULL,NULL,&lFlavour) &&
  1602. (lFlavour == WBEM_FLAVOR_ORIGIN_SYSTEM))
  1603. {
  1604. bRet = TRUE;
  1605. }
  1606. return bRet;
  1607. }
  1608. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1609. // Get default value from the DBCOLUMNDESC for a particular property
  1610. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1611. void CWmiOleDBMap::GetDefaultValue(const DBCOLUMNDESC * prgColDesc, VARIANT & varDefault)
  1612. {
  1613. ULONG lIndex = 0,lColPropIndex = 0 , lPropType = 0;
  1614. BOOL bDefault = FALSE;
  1615. DBTYPE lType ;
  1616. BSTR strDate;
  1617. BOOL bDateTime = FALSE;
  1618. VARIANT *pDefaultData;
  1619. CDataMap map;
  1620. memset(&varDefault,0,sizeof(VARIANT));
  1621. // search for the DBPROP_COL_DEFAULT property in DBPROPSET_COLUMN in the property sets
  1622. if(prgColDesc->cPropertySets > 0)
  1623. {
  1624. for ( lIndex = 0 ; lIndex < prgColDesc->cPropertySets;lIndex++)
  1625. {
  1626. if(prgColDesc->rgPropertySets[lIndex].guidPropertySet == DBPROPSET_COLUMN)
  1627. for( lColPropIndex = 0; lColPropIndex < prgColDesc->rgPropertySets[lIndex].cProperties ; lColPropIndex++)
  1628. {
  1629. if(prgColDesc->rgPropertySets[lIndex].rgProperties[lColPropIndex].dwPropertyID == DBPROP_COL_DEFAULT)
  1630. {
  1631. pDefaultData = &prgColDesc->rgPropertySets[lIndex].rgProperties[lColPropIndex].vValue;
  1632. lType = prgColDesc->wType;
  1633. switch(lType)
  1634. {
  1635. case DBTYPE_DBTIMESTAMP :
  1636. map.ConvertOledbDateToCIMType(pDefaultData,strDate);
  1637. bDateTime = TRUE;
  1638. break;
  1639. case DBTYPE_DBDATE :
  1640. map.ConvertVariantDateToCIMType(pDefaultData->pdate,strDate);
  1641. bDateTime = TRUE;
  1642. break;
  1643. case DBTYPE_DBTIME :
  1644. bDateTime = TRUE;
  1645. break;
  1646. default:
  1647. VariantCopy(&varDefault,pDefaultData);
  1648. }
  1649. if(bDateTime == TRUE)
  1650. {
  1651. varDefault.vt = VT_BSTR;
  1652. varDefault.bstrVal = strDate;
  1653. }
  1654. }
  1655. }
  1656. }
  1657. }
  1658. lPropType = ParseQualifiedNameToGetColumnType(prgColDesc->dbcid.uName.pwszName);
  1659. lType = prgColDesc->wType;
  1660. // If there is no default and if it is a qualilfier then
  1661. if( bDefault == FALSE && (lPropType == WMI_CLASS_QUALIFIER || lPropType == WMI_PROPERTY_QUALIFIER))
  1662. {
  1663. memset(&varDefault,0,sizeof(VARIANT));
  1664. switch(lType)
  1665. {
  1666. case DBTYPE_I1:
  1667. case DBTYPE_UI1:
  1668. case DBTYPE_I2:
  1669. case DBTYPE_UI2:
  1670. case DBTYPE_I4:
  1671. case DBTYPE_UI4:
  1672. case DBTYPE_I8:
  1673. case DBTYPE_UI8:
  1674. case DBTYPE_R4:
  1675. case DBTYPE_R8:
  1676. case DBTYPE_WSTR:
  1677. case DBTYPE_STR:
  1678. case DBTYPE_IDISPATCH :
  1679. varDefault.vt = (SHORT)lType;
  1680. break;
  1681. case DBTYPE_BSTR:
  1682. varDefault.vt = VT_BSTR;
  1683. varDefault.bstrVal = SysAllocString(L"");
  1684. break;
  1685. case DBTYPE_BOOL:
  1686. varDefault.vt = VT_BOOL;
  1687. varDefault.boolVal = VARIANT_TRUE;
  1688. break;
  1689. case DBTYPE_DBTIMESTAMP:
  1690. varDefault.vt = VT_DATE;
  1691. break;
  1692. }
  1693. }
  1694. }
  1695. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1696. // Commit the row data for qualifier rowset
  1697. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1698. HRESULT CWmiOleDBMap::CommitRowDataForQualifier(CRowDataMemMgr * pRow,BSTR strQualifier,CVARIANT &vValue, ULONG lType, ULONG lFlavor)
  1699. {
  1700. HRESULT hr = S_OK;
  1701. CVARIANT var;
  1702. var.SetStr(strQualifier);
  1703. hr = pRow->CommitColumnToRowData(var,DBTYPE_BSTR);
  1704. if( hr == S_OK)
  1705. {
  1706. var.Clear();
  1707. var.SetLONG(vValue.GetType());
  1708. hr = pRow->CommitColumnToRowData(var,DBTYPE_UI4);
  1709. }
  1710. if( hr == S_OK)
  1711. {
  1712. hr = pRow->CommitColumnToRowData(vValue,DBTYPE_VARIANT);
  1713. }
  1714. if( hr == S_OK)
  1715. {
  1716. var.Clear();
  1717. var.SetLONG(lFlavor);
  1718. hr = pRow->CommitColumnToRowData(var,DBTYPE_BSTR);
  1719. }
  1720. return hr;
  1721. }
  1722. //////////////////////////////////////////////////////////////////////////////////////////
  1723. // Function to release a qualifer
  1724. //////////////////////////////////////////////////////////////////////////////////////////
  1725. void CWmiOleDBMap::ReleaseQualifier(CWbemClassWrapper *pInst,BSTR strProperty)
  1726. {
  1727. if( strProperty == NULL)
  1728. {
  1729. pInst->ReleaseClassQualifier();
  1730. }
  1731. else
  1732. {
  1733. pInst->ReleasePropertyQualifier(strProperty);
  1734. }
  1735. }
  1736. HRESULT CWmiOleDBMap::SetQualifier(CWbemClassWrapper *pInst,BSTR bstrColName,BSTR bstrQualifier ,VARIANT *pvarData,LONG lFlavor)
  1737. {
  1738. HRESULT hr = E_FAIL;
  1739. if(bstrColName == NULL)
  1740. {
  1741. hr = pInst->SetClassQualifier(bstrQualifier,pvarData,lFlavor);
  1742. }
  1743. else
  1744. {
  1745. hr = pInst->SetPropertyQualifier(bstrColName,bstrQualifier,pvarData,lFlavor);
  1746. }
  1747. return hr;
  1748. }
  1749. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1750. // Funtion to add a index qualifier for a property
  1751. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1752. HRESULT CWmiOleDBMap::AddIndex(const DBID* pColumnID)
  1753. {
  1754. HRESULT hr ;
  1755. CBSTR strColumnName(pColumnID->uName.pwszName);
  1756. CBSTR strIndexQualifier((WCHAR *)strIndex);
  1757. VARIANT varIndexValue;
  1758. VariantInit(&varIndexValue);
  1759. varIndexValue.vt = VT_BOOL;
  1760. varIndexValue.boolVal = VARIANT_TRUE;
  1761. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  1762. //===================================================================================
  1763. // If the passed columnID is a property then add a index qualifier to the property
  1764. //===================================================================================
  1765. if(WMI_PROPERTY == ParseQualifiedNameToGetColumnType((WCHAR*)pColumnID->uName.pwszName))
  1766. {
  1767. hr = SetQualifier(m_pWbemClassDefinition,strColumnName,strIndexQualifier ,&varIndexValue,0);
  1768. }
  1769. else
  1770. {
  1771. hr = DB_E_BADCOLUMNID;
  1772. }
  1773. }
  1774. //=================================================================
  1775. // If everthing is fine then save the changes to WMI
  1776. //=================================================================
  1777. if( hr == S_OK)
  1778. {
  1779. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  1780. }
  1781. return hr;
  1782. }
  1783. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1784. // Funtion to delete a index qualifier as mentioned in pIndexID
  1785. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1786. HRESULT CWmiOleDBMap::DropIndex(const DBID* pIndexID)
  1787. {
  1788. HRESULT hr ;
  1789. CBSTR strColumnName(pIndexID->uName.pwszName);
  1790. WCHAR *pStrIndex = NULL;
  1791. WCHAR * pwcsQualifier = NULL;
  1792. WCHAR * pwcsProperty = NULL;
  1793. try
  1794. {
  1795. pStrIndex = new WCHAR [wcslen(strIndex) + 1];
  1796. }
  1797. catch(...)
  1798. {
  1799. SAFE_DELETE_ARRAY(pStrIndex);
  1800. throw;
  1801. }
  1802. if(pStrIndex == NULL)
  1803. {
  1804. hr = E_OUTOFMEMORY;
  1805. }
  1806. else
  1807. {
  1808. wcscpy(pStrIndex,(WCHAR *)strIndex);
  1809. _wcsupr(pStrIndex);
  1810. if( S_OK == (hr = m_pWbemClassDefinition->ValidClass())){
  1811. if(WMI_PROPERTY_QUALIFIER == ParseQualifiedNameToGetColumnType((WCHAR*)pIndexID->uName.pwszName))
  1812. {
  1813. if( ParseQualifiedName((WCHAR*)pIndexID->uName.pwszName,pwcsProperty,pwcsQualifier))
  1814. {
  1815. _wcsupr(pwcsQualifier);
  1816. //=================================================================
  1817. // If the qualifer name is "Index" then delete the index
  1818. //=================================================================
  1819. if(wbem_wcsicmp(pStrIndex,pwcsQualifier) == 0)
  1820. hr = m_pWbemClassDefinition->DeletePropertyQualifier(pwcsProperty,pwcsQualifier);
  1821. else
  1822. hr = E_INVALIDARG; // the index ID passed is invalid
  1823. }
  1824. }
  1825. else
  1826. {
  1827. hr = E_INVALIDARG; // passed index is not a valid index
  1828. }
  1829. }
  1830. // free the memory
  1831. SAFE_DELETE_ARRAY(pStrIndex);
  1832. SAFE_DELETE_ARRAY(pwcsProperty);
  1833. SAFE_DELETE_ARRAY(pwcsQualifier);
  1834. //=================================================================
  1835. // If everthing is fine then save the changes to WMI
  1836. //=================================================================
  1837. if(SUCCEEDED( hr))
  1838. {
  1839. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  1840. }
  1841. }
  1842. return hr;
  1843. }
  1844. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1845. // Converts the OLEDB COLUMN properties to appropriate WMI properties/flavors
  1846. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1847. HRESULT CWmiOleDBMap::SetColumnProperties(const DBCOLUMNDESC * prgColDesc)
  1848. {
  1849. HRESULT hr = E_FAIL;
  1850. CBSTR bstrProperty(prgColDesc->dbcid.uName.pwszName);
  1851. CDataMap map;
  1852. LONG lType = 0;
  1853. BOOL bIsColProperty = FALSE;
  1854. //==================================================================================
  1855. // Ok, we already know we have a valid class here so just check if we have a valid
  1856. // property
  1857. //==================================================================================
  1858. if( SUCCEEDED(hr = ValidProperty(prgColDesc)))
  1859. {
  1860. switch(ParseQualifiedNameToGetColumnType(prgColDesc->dbcid.uName.pwszName))
  1861. {
  1862. case WMI_CLASS_QUALIFIER:
  1863. hr = SetWMIClassQualifier(prgColDesc,FALSE);
  1864. break;
  1865. case WMI_PROPERTY_QUALIFIER:
  1866. hr = SetWMIPropertyQualifier(prgColDesc,FALSE);
  1867. break;
  1868. case WMI_PROPERTY:
  1869. bIsColProperty = TRUE;
  1870. break;
  1871. default:
  1872. hr = E_INVALIDARG;
  1873. break;
  1874. }
  1875. // If the column passed is a property , then add qualifiers for the different
  1876. // column properties
  1877. if( bIsColProperty == TRUE)
  1878. {
  1879. //==========================================================================
  1880. // Go through the DBPROPSETS and the DBPROPS in them to see if they
  1881. // happen to match some of the standard qualifiers we have mapped to them
  1882. //==========================================================================
  1883. for( ULONG i = 0; i < prgColDesc->cPropertySets; i++ )
  1884. {
  1885. for ( ULONG j = 0; j < prgColDesc->rgPropertySets[i].cProperties; j++ )
  1886. {
  1887. CVARIANT Value,Qualifier;
  1888. LONG lFlavor;
  1889. //==================================================================
  1890. // See if we have a match, if we do, save it to WMI
  1891. //==================================================================
  1892. hr = MapDBPROPToStdPropertyQualifier(prgColDesc->rgPropertySets[i].rgProperties[j],Qualifier,Value, lFlavor);
  1893. if( hr == S_OK)
  1894. {
  1895. hr = m_pWbemClassDefinition->SetPropertyQualifier((BSTR)bstrProperty,Qualifier,Value,0);
  1896. if( FAILED(hr))
  1897. {
  1898. hr = E_FAIL;
  1899. break;
  1900. }
  1901. else
  1902. {
  1903. hr = m_pWbemClassDefinition->SaveClass(FALSE);
  1904. }
  1905. }
  1906. }
  1907. }
  1908. }
  1909. }
  1910. return hr;
  1911. }
  1912. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1913. // Function to get class name of an instance
  1914. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1915. WCHAR * CWmiOleDBMap::GetClassName()
  1916. {
  1917. WCHAR *pRet = NULL;
  1918. //================================================================
  1919. // if this class is opened on command by executing query then
  1920. // return NULL as the class name
  1921. //================================================================
  1922. if(!(m_pWbemCommandManager || m_pWbemCollectionManager))
  1923. {
  1924. pRet = m_pWbemClassParms->GetClassName();
  1925. }
  1926. return pRet;
  1927. }
  1928. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1929. // Function to delete a quallifier
  1930. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1931. HRESULT CWmiOleDBMap::DeleteQualifier(CWbemClassWrapper *pInst,
  1932. BSTR strQualifierName,
  1933. BOOL bClassQualifier ,
  1934. BSTR strPropertyName )
  1935. {
  1936. HRESULT hr = S_OK;
  1937. if(bClassQualifier)
  1938. {
  1939. hr = pInst->DeletePropertyQualifier(strPropertyName,strQualifierName);
  1940. }
  1941. else
  1942. {
  1943. hr = ((CWbemClassDefinitionWrapper *)pInst)->DeleteClassQualifier(strPropertyName);
  1944. }
  1945. return hr;
  1946. }
  1947. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1948. // Function to remove an object from a container
  1949. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1950. HRESULT CWmiOleDBMap::UnlinkObjectFromContainer(BSTR strContainerObj,BSTR strObject)
  1951. {
  1952. return m_pWbemClassParms->RemoveObjectFromContainer(strContainerObj,strObject);
  1953. }
  1954. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1955. // Function to add an object to a container
  1956. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1957. HRESULT CWmiOleDBMap::LinkObjectFromContainer(BSTR strContainerObj,BSTR strObject)
  1958. {
  1959. return m_pWbemClassParms->AddObjectFromContainer(strContainerObj,strObject);
  1960. }
  1961. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1962. // Function to copy an existing instance to another scope
  1963. //////////////////////////////////////////////////////////////////////////////////////////////////////
  1964. HRESULT CWmiOleDBMap::CloneAndAddNewObjectInScope(BSTR strObj, BSTR strScope,WCHAR *& pstrNewPath)
  1965. {
  1966. HRESULT hr = DB_E_NOTFOUND;
  1967. CWbemClassWrapper *pInstance = GetInstance(strScope);
  1968. if(pInstance)
  1969. {
  1970. hr = m_pWbemClassParms->CloneAndAddNewObjectInScope(pInstance,strObj,pstrNewPath);
  1971. }
  1972. return hr;
  1973. }
  1974. HRESULT CWmiOleDBMap::GetPropertyColumnInfoForMixedRowsets( cRowColumnInfoMemMgr * pColumn, DBCOLUMNINFO ** pCol)
  1975. {
  1976. HRESULT hr = S_OK;
  1977. DBORDINAL lOrdinal = -1;
  1978. BSTR bstrProperty = Wmioledb_SysAllocString(L"__PATH");
  1979. lOrdinal = pColumn->GetColOrdinal((WCHAR *)L"__PATH");
  1980. // if the column is already present in the col info info return
  1981. // This will happen when for row objects obtained from rowsets
  1982. if((DB_LORDINAL)lOrdinal < 0)
  1983. {
  1984. hr = pColumn->AddColumnNameToList(bstrProperty, pCol);
  1985. SysFreeString(bstrProperty);
  1986. if( hr == S_OK )
  1987. {
  1988. //==================================================================
  1989. // We use ordinal numbers for our columns
  1990. //==================================================================
  1991. SetCommonDBCOLUMNINFO(pCol, pColumn->GetCurrentIndex());
  1992. SetColumnReadOnly(*pCol,TRUE);
  1993. pColumn->SetCIMType(VT_BSTR);
  1994. (*pCol)->wType = VT_BSTR;
  1995. (*pCol)->ulColumnSize = ~0;
  1996. (*pCol)->dwFlags = 0;
  1997. hr = S_OK;
  1998. // NTRaid:111762
  1999. // 06/13/00
  2000. hr = pColumn->CommitColumnInfo();
  2001. }
  2002. }
  2003. return hr;
  2004. }
  2005. INSTANCELISTTYPE CWmiOleDBMap::GetObjListType()
  2006. {
  2007. INSTANCELISTTYPE qType = NORMAL;
  2008. if(m_pWbemCommandManager)
  2009. {
  2010. qType = m_pWbemCommandManager->GetObjListType();
  2011. }
  2012. else
  2013. if(m_pWbemCollectionManager)
  2014. {
  2015. qType = m_pWbemCollectionManager->GetObjListType();
  2016. }
  2017. return qType;
  2018. }