Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

814 lines
26 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright � Microsoft Corporation. All rights reserved.
  4. //
  5. // FRQuery.cpp
  6. //
  7. // Purpose: Query functions
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include <analyser.h>
  12. #include <assertbreak.h>
  13. #include <comdef.h>
  14. #include <FWStrings.h>
  15. #include <vector>
  16. #include <smartptr.h>
  17. #include <brodcast.h>
  18. #include <utils.h>
  19. #include "multiplat.h"
  20. #include <helper.h>
  21. CFrameworkQuery::CFrameworkQuery()
  22. {
  23. m_pLevel1RPNExpression = NULL;
  24. m_QueryType = eUnknown;
  25. m_bKeysOnly = false;
  26. m_IClass = NULL;
  27. m_lFlags = 0;
  28. }
  29. CFrameworkQuery::~CFrameworkQuery()
  30. {
  31. if (m_pLevel1RPNExpression)
  32. {
  33. delete m_pLevel1RPNExpression;
  34. }
  35. if (m_IClass)
  36. {
  37. m_IClass->Release();
  38. }
  39. }
  40. HRESULT CFrameworkQuery::Init(
  41. const BSTR bstrQueryFormat,
  42. const BSTR bstrQuery,
  43. long lFlags,
  44. CHString &sNamespace
  45. )
  46. {
  47. HRESULT hRes = WBEM_S_NO_ERROR;
  48. // Clear out any old values
  49. Reset();
  50. // Start setting our values
  51. m_lFlags = lFlags;
  52. m_bstrtClassName = L"";
  53. m_QueryType = eWQLCommand;
  54. m_sNamespace = sNamespace;
  55. // Check for the obvious
  56. if (_wcsicmp(bstrQueryFormat, IDS_WQL) != 0)
  57. {
  58. hRes = WBEM_E_INVALID_QUERY_TYPE;
  59. LogErrorMessage2(L"Invalid query type: %s", bstrQueryFormat);
  60. }
  61. if (hRes == WBEM_S_NO_ERROR)
  62. {
  63. // Construct the lex source
  64. // ========================
  65. CTextLexSource LexSource(bstrQuery);
  66. // Use the lex source to set up for parser
  67. // =======================================
  68. SQL1_Parser QueryParser(&LexSource);
  69. int ParseRetValue = QueryParser.Parse(&m_pLevel1RPNExpression);
  70. if( SQL1_Parser::SUCCESS == ParseRetValue)
  71. {
  72. // Store some common values
  73. m_bstrtClassName = m_pLevel1RPNExpression->bsClassName;
  74. m_sQuery = bstrQuery;
  75. // Build the Requested Properies Array (m_csaPropertiesRequired)
  76. if (m_pLevel1RPNExpression->nNumberOfProperties > 0)
  77. {
  78. // Populate the m_csaPropertiesRequired array with all the required properties
  79. CHString sPropertyName;
  80. // First add the elements of the Select clause
  81. for (DWORD x=0; x < m_pLevel1RPNExpression->nNumberOfProperties; x++)
  82. {
  83. sPropertyName = m_pLevel1RPNExpression->pbsRequestedPropertyNames[x];
  84. sPropertyName.MakeUpper();
  85. if (IsInList(m_csaPropertiesRequired, sPropertyName) == -1)
  86. {
  87. m_csaPropertiesRequired.Add(sPropertyName);
  88. }
  89. }
  90. // Then add the elements of the where clause
  91. for (x=0; x < m_pLevel1RPNExpression->nNumTokens; x++)
  92. {
  93. if (m_pLevel1RPNExpression->pArrayOfTokens[x].nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION)
  94. {
  95. sPropertyName = m_pLevel1RPNExpression->pArrayOfTokens[x].pPropertyName;
  96. sPropertyName.MakeUpper();
  97. if (IsInList(m_csaPropertiesRequired, sPropertyName) == -1)
  98. {
  99. m_csaPropertiesRequired.Add(sPropertyName);
  100. }
  101. if (m_pLevel1RPNExpression->pArrayOfTokens[x].pPropName2 != NULL)
  102. {
  103. sPropertyName = m_pLevel1RPNExpression->pArrayOfTokens[x].pPropName2;
  104. sPropertyName.MakeUpper();
  105. if (IsInList(m_csaPropertiesRequired, sPropertyName) == -1)
  106. {
  107. m_csaPropertiesRequired.Add(sPropertyName);
  108. }
  109. }
  110. }
  111. }
  112. }
  113. }
  114. else
  115. {
  116. ASSERT_BREAK(FALSE);
  117. m_pLevel1RPNExpression = NULL;
  118. LogErrorMessage2(L"Can't parse query: %s", bstrQuery);
  119. hRes = WBEM_E_INVALID_QUERY;
  120. }
  121. }
  122. return hRes;
  123. }
  124. HRESULT CFrameworkQuery::Init(
  125. ParsedObjectPath *pParsedObjectPath,
  126. IWbemContext *pCtx,
  127. LPCWSTR lpwszClassName,
  128. CHString &sNamespace
  129. )
  130. {
  131. HRESULT hr = WBEM_S_NO_ERROR;
  132. variant_t vValue;
  133. // Clear out any old values
  134. Reset();
  135. // Start setting our values
  136. m_bstrtClassName = lpwszClassName;
  137. m_QueryType = eContextObject;
  138. m_lFlags = 0;
  139. m_sNamespace = sNamespace;
  140. // Check to see if get extensions are being used
  141. if ( (pCtx != NULL) &&
  142. (SUCCEEDED(pCtx->GetValue( L"__GET_EXTENSIONS", 0, &vValue))) &&
  143. (V_VT(&vValue) == VT_BOOL) &&
  144. (V_BOOL(&vValue) == VARIANT_TRUE) )
  145. {
  146. vValue.Clear();
  147. bool bKeysRequired = false;
  148. // Ok, did they ask for KeysOnly?
  149. // __GET_EXT_PROPERTIES and __GET_EXT_KEYS_ONLY are mutually exclusive. If they
  150. // specified KeysOnly, we'll go with that.
  151. if ( (SUCCEEDED(pCtx->GetValue( L"__GET_EXT_KEYS_ONLY", 0, &vValue))) &&
  152. (V_VT(&vValue) == VT_BOOL) &&
  153. (V_BOOL(&vValue) == VARIANT_TRUE) )
  154. {
  155. LogMessage(L"Recognized __GET_EXT_KEYS_ONLY");
  156. m_bKeysOnly = true;
  157. bKeysRequired = true;
  158. }
  159. else
  160. {
  161. vValue.Clear();
  162. if ( (SUCCEEDED(pCtx->GetValue( L"__GET_EXT_PROPERTIES", 0, &vValue))) &&
  163. (V_VT(&vValue) == (VT_ARRAY | VT_BSTR) ) &&
  164. ( SafeArrayGetDim ( V_ARRAY(&vValue) ) == 1 ) )
  165. {
  166. LogMessage(L"Recognized __GET_EXT_PROPERTIES");
  167. // Ok, they sent us an arry of properties. Add them to m_csaPropertiesRequired.
  168. LONG lDimension = 1 ;
  169. LONG lLowerBound ;
  170. SafeArrayGetLBound ( V_ARRAY(&vValue) , lDimension , & lLowerBound ) ;
  171. LONG lUpperBound ;
  172. SafeArrayGetUBound ( V_ARRAY(&vValue) , lDimension , & lUpperBound ) ;
  173. CHString sPropertyName;
  174. for ( long lIndex = lLowerBound ; lIndex <= lUpperBound ; lIndex ++ )
  175. {
  176. BSTR bstrElement ;
  177. HRESULT t_Result = SafeArrayGetElement ( V_ARRAY(&vValue), &lIndex , & bstrElement ) ;
  178. if ( (t_Result == S_OK) &&
  179. (bstrElement != NULL) )
  180. {
  181. OnDelete<BSTR,VOID(*)(BSTR),SysFreeString> smartbstrElement(bstrElement);
  182. sPropertyName = bstrElement;
  183. sPropertyName.MakeUpper();
  184. if (IsInList(m_csaPropertiesRequired, sPropertyName) == -1)
  185. {
  186. m_csaPropertiesRequired.Add(sPropertyName);
  187. }
  188. }
  189. }
  190. if ( (IsInList(m_csaPropertiesRequired, L"__RELPATH") != -1) ||
  191. (IsInList(m_csaPropertiesRequired, L"__PATH") != -1) )
  192. {
  193. bKeysRequired = true;
  194. }
  195. }
  196. }
  197. // If they specified KeysOnly or __RELPATH or __Path, we need to add the key properties
  198. // to the list.
  199. if (bKeysRequired)
  200. {
  201. if ((pParsedObjectPath != NULL) && (pParsedObjectPath->m_dwNumKeys > 0) && (pParsedObjectPath->m_paKeys[0]->m_pName != NULL))
  202. {
  203. CHString sPropertyName;
  204. for (DWORD x=0; x < pParsedObjectPath->m_dwNumKeys; x++)
  205. {
  206. sPropertyName = pParsedObjectPath->m_paKeys[x]->m_pName;
  207. sPropertyName.MakeUpper();
  208. if (IsInList(m_csaPropertiesRequired, sPropertyName) == -1)
  209. {
  210. m_csaPropertiesRequired.Add(sPropertyName);
  211. }
  212. }
  213. m_AddKeys = false;
  214. }
  215. else if ( (pParsedObjectPath != NULL) && (pParsedObjectPath->m_bSingletonObj) )
  216. {
  217. m_AddKeys = false;
  218. }
  219. else
  220. {
  221. // If they didn't give us a pParsedObjectPath or if the object path doesn't contain
  222. // the key property name, best we can do is add relpath. Hopefully they'll call
  223. // init2, and it will add the rest.
  224. if (IsInList(m_csaPropertiesRequired, L"__RELPATH") == -1)
  225. {
  226. m_csaPropertiesRequired.Add(L"__RELPATH");
  227. }
  228. }
  229. }
  230. }
  231. return hr;
  232. }
  233. // ===================================================================================================
  234. // Finds out if a particular field was requested by the query. Only
  235. // meaningful if we are in ExecQueryAsync and the query has been
  236. // sucessfully parsed.
  237. bool CFrameworkQuery::IsPropertyRequired(
  238. LPCWSTR propName
  239. )
  240. {
  241. bool bRet = AllPropertiesAreRequired();
  242. if (!bRet)
  243. {
  244. CHString sPropName(propName);
  245. sPropName.MakeUpper();
  246. bRet = (IsInList(m_csaPropertiesRequired, sPropName) != -1);
  247. }
  248. return bRet;
  249. }
  250. // Given a property name, it will return all the values
  251. // that the query requests in a CHStringArray.
  252. // Select * from win32_directory where drive = "C:" GetValuesForProp(L"Drive") -> C:
  253. // Where Drive = "C:" or Drive = "D:" GetValuesForProp(L"Drive") -> C:, D:
  254. // Where Path = "\DOS" GetValuesForProp(L"Drive") -> (empty)
  255. // Where Drive <> "C:" GetValuesForProp(L"Drive") -> (empty)
  256. HRESULT CFrameworkQuery::GetValuesForProp(
  257. LPCWSTR wszPropName,
  258. CHStringArray& achNames
  259. )
  260. {
  261. HRESULT hr = WBEM_S_NO_ERROR;
  262. if (wszPropName && (m_pLevel1RPNExpression != NULL))
  263. {
  264. hr = CQueryAnalyser::GetValuesForProp(m_pLevel1RPNExpression, wszPropName, achNames);
  265. if (SUCCEEDED(hr))
  266. {
  267. // If this is a reference property, we need to normalize the names to a common form
  268. // so the removal of duplicates works correctly.
  269. if (IsReference(wszPropName))
  270. {
  271. // Get the current computer name
  272. CHString sOutPath, sComputerName;
  273. DWORD dwBufferLength = MAX_COMPUTERNAME_LENGTH + 1;
  274. FRGetComputerName(sComputerName.GetBuffer( dwBufferLength ), &dwBufferLength);
  275. sComputerName.ReleaseBuffer();
  276. if (sComputerName.IsEmpty())
  277. {
  278. sComputerName = L"DEFAULT";
  279. }
  280. DWORD dwRet = e_OK;
  281. // Normalize the path names. Try leaving the property names alone
  282. for (int x = 0; x < achNames.GetSize(); x++)
  283. {
  284. // If we failed to parse the path, or if the namespace isn't our namespace, delete
  285. // the entry.
  286. dwRet = NormalizePath(achNames[x], sComputerName, GetNamespace(), 0, sOutPath);
  287. if (dwRet == e_OK)
  288. {
  289. achNames[x] = sOutPath;
  290. }
  291. else if (dwRet == e_NullName)
  292. {
  293. break;
  294. }
  295. else
  296. {
  297. achNames.RemoveAt(x);
  298. x--;
  299. }
  300. }
  301. // If the key property names of any of the values were null, we have to set them all
  302. // to null.
  303. if (dwRet == e_NullName)
  304. {
  305. // Normalize the path names
  306. for (int x = 0; x < achNames.GetSize(); x++)
  307. {
  308. // If we failed to parse the path, or if the namespace isn't our namespace, delete
  309. // the entry.
  310. dwRet = NormalizePath(achNames[x], sComputerName, GetNamespace(), NORMALIZE_NULL, sOutPath);
  311. if (dwRet == e_OK)
  312. {
  313. achNames[x] = sOutPath;
  314. }
  315. else
  316. {
  317. achNames.RemoveAt(x);
  318. x--;
  319. }
  320. }
  321. }
  322. }
  323. // Remove duplicates
  324. for (int x = 1; x < achNames.GetSize(); x++)
  325. {
  326. for (int y = 0; y < x; y++)
  327. {
  328. if (achNames[y].CompareNoCase(achNames[x]) == 0)
  329. {
  330. achNames.RemoveAt(x);
  331. x--;
  332. }
  333. }
  334. }
  335. }
  336. else
  337. {
  338. achNames.RemoveAll();
  339. if (hr == WBEMESS_E_REGISTRATION_TOO_BROAD)
  340. {
  341. hr = WBEM_S_NO_ERROR;
  342. }
  343. }
  344. }
  345. else
  346. {
  347. ASSERT_BREAK(FALSE);
  348. achNames.RemoveAll();
  349. hr = WBEM_E_FAILED;
  350. }
  351. return hr;
  352. }
  353. // Here's an overloaded version in case client wants to pass in a vector of _bstr_t's
  354. HRESULT CFrameworkQuery::GetValuesForProp(
  355. LPCWSTR wszPropName,
  356. std::vector<_bstr_t>& vectorNames
  357. )
  358. {
  359. HRESULT hr = WBEM_S_NO_ERROR;
  360. if (wszPropName && (m_pLevel1RPNExpression != NULL) )
  361. {
  362. hr = CQueryAnalyser::GetValuesForProp(m_pLevel1RPNExpression, wszPropName, vectorNames);
  363. if (SUCCEEDED(hr))
  364. {
  365. // If this is a reference property, we need to normalize the names to a common form
  366. // so the removal of duplicates works correctly.
  367. if (IsReference(wszPropName))
  368. {
  369. // Get the current computer name
  370. CHString sOutPath, sComputerName;
  371. DWORD dwBufferLength = MAX_COMPUTERNAME_LENGTH + 1;
  372. FRGetComputerName(sComputerName.GetBuffer( dwBufferLength ), &dwBufferLength);
  373. sComputerName.ReleaseBuffer();
  374. if (sComputerName.IsEmpty())
  375. {
  376. sComputerName = L"DEFAULT";
  377. }
  378. DWORD dwRet = e_OK;
  379. // Normalize the path names. Try leaving the property names alone
  380. for (int x = 0; x < vectorNames.size(); x++)
  381. {
  382. // If we failed to parse the path, or if the namespace isn't our namespace, delete
  383. // the entry.
  384. dwRet = NormalizePath(vectorNames[x], sComputerName, GetNamespace(), 0, sOutPath);
  385. if (dwRet == e_OK)
  386. {
  387. vectorNames[x] = sOutPath;
  388. }
  389. else if (dwRet == e_NullName)
  390. {
  391. break;
  392. }
  393. else
  394. {
  395. vectorNames.erase(vectorNames.begin() + x);
  396. x--;
  397. }
  398. }
  399. // If the key property names of any of the values were null, we have to set them all
  400. // to null.
  401. if (dwRet == e_NullName)
  402. {
  403. for (int x = 0; x < vectorNames.size(); x++)
  404. {
  405. // If we failed to parse the path, or if the namespace isn't our namespace, delete
  406. // the entry.
  407. dwRet = NormalizePath(vectorNames[x], sComputerName, GetNamespace(), NORMALIZE_NULL, sOutPath);
  408. if (dwRet == e_OK)
  409. {
  410. vectorNames[x] = sOutPath;
  411. }
  412. else
  413. {
  414. vectorNames.erase(vectorNames.begin() + x);
  415. x--;
  416. }
  417. }
  418. }
  419. }
  420. // Remove duplicates
  421. for (int x = 1; x < vectorNames.size(); x++)
  422. {
  423. for (int y = 0; y < x; y++)
  424. {
  425. if (_wcsicmp(vectorNames[y], vectorNames[x]) == 0)
  426. {
  427. vectorNames.erase(vectorNames.begin() + x);
  428. x--;
  429. }
  430. }
  431. }
  432. }
  433. else
  434. {
  435. vectorNames.clear();
  436. if (hr == WBEMESS_E_REGISTRATION_TOO_BROAD)
  437. {
  438. hr = WBEM_S_NO_ERROR;
  439. }
  440. }
  441. }
  442. else
  443. {
  444. ASSERT_BREAK(FALSE);
  445. vectorNames.clear();
  446. hr = WBEM_E_FAILED;
  447. }
  448. return hr;
  449. }
  450. // Returns a list of all the properties specified in the select statement.
  451. // If * is specified as one of the fields, it is returned in the same way as all
  452. // other properties.
  453. void CFrameworkQuery::GetRequiredProperties(
  454. CHStringArray &saProperties
  455. )
  456. {
  457. saProperties.RemoveAll();
  458. saProperties.Copy(m_csaPropertiesRequired);
  459. }
  460. // Initializes the KeysOnly data member. Should never be called by users.
  461. void CFrameworkQuery::Init2(
  462. IWbemClassObject *IClass
  463. )
  464. {
  465. // Store IClass object for use in GetValuesForProp
  466. m_IClass = IClass;
  467. m_IClass->AddRef();
  468. // If KeysOnly get set somewhere else, or if we already know all properties are requried
  469. // there's no point in looking for non-key properties.
  470. if (!m_bKeysOnly && !AllPropertiesAreRequired())
  471. {
  472. // First, we are going to correctly set the m_bKeysOnly member
  473. IWbemQualifierSetPtr pQualSet;
  474. HRESULT hr;
  475. DWORD dwSize = m_csaPropertiesRequired.GetSize();
  476. m_bKeysOnly = true;
  477. for (DWORD x=0; x < dwSize; x++)
  478. {
  479. if (m_csaPropertiesRequired[x].Left(2) != L"__")
  480. {
  481. // If we fail here, it could be due to an invalid property name specified in the query.
  482. if (SUCCEEDED(hr = IClass->GetPropertyQualifierSet( m_csaPropertiesRequired[x] , &pQualSet)))
  483. {
  484. hr = pQualSet->Get( L"Key", 0, NULL, NULL);
  485. if (hr == WBEM_E_NOT_FOUND)
  486. {
  487. m_bKeysOnly = false;
  488. break;
  489. }
  490. else if (FAILED(hr))
  491. {
  492. LogErrorMessage3(L"Can't Get 'key' on %s(%x)", (LPCWSTR)m_csaPropertiesRequired[x], hr);
  493. ASSERT_BREAK(FALSE);
  494. }
  495. }
  496. else
  497. {
  498. if (hr == WBEM_E_NOT_FOUND)
  499. {
  500. // This just means there are properties in the per-property list that don't exist
  501. hr = WBEM_S_NO_ERROR;
  502. }
  503. else
  504. {
  505. LogErrorMessage3(L"Can't get property GetPropertyQualifierSet on %s(%x)", (LPCWSTR)m_csaPropertiesRequired[x], hr);
  506. ASSERT_BREAK(FALSE);
  507. }
  508. }
  509. }
  510. }
  511. }
  512. // Second, if they specified a property list, and one of the properties was __path or __relpath,
  513. // then we need to add the name of the actual key properties to the list. Unless we added them
  514. // somewhere else.
  515. if ( m_AddKeys &&
  516. !AllPropertiesAreRequired() &&
  517. ( (IsInList(m_csaPropertiesRequired, L"__RELPATH") != -1) ||
  518. (IsInList(m_csaPropertiesRequired, L"__PATH") != -1) ) )
  519. {
  520. SAFEARRAY *pKeyNames = NULL;
  521. HRESULT hr;
  522. // Get the keys for the class
  523. if (SUCCEEDED(hr = IClass->GetNames(NULL, WBEM_FLAG_KEYS_ONLY, NULL, &pKeyNames)))
  524. {
  525. OnDelete<SAFEARRAY *,HRESULT(*)(SAFEARRAY *),SafeArrayDestroy> smartpKeyNames(pKeyNames);
  526. BSTR bstrName = NULL ;
  527. CHString sKeyName;
  528. LONG lLBound, lUBound;
  529. SafeArrayGetLBound(pKeyNames, 1, &lLBound);
  530. SafeArrayGetUBound(pKeyNames, 1, &lUBound);
  531. // Walk the key properties, and add any properties that
  532. // are not already in the list
  533. for (long i = lLBound; i <= lUBound; i++)
  534. {
  535. if (SUCCEEDED(SafeArrayGetElement( pKeyNames, &i, &bstrName )))
  536. {
  537. OnDeleteIf<BSTR,VOID(*)(BSTR),SysFreeString> smartbstrName(bstrName);
  538. sKeyName = bstrName;
  539. sKeyName.MakeUpper();
  540. if (IsInList(m_csaPropertiesRequired, sKeyName) == -1)
  541. {
  542. m_csaPropertiesRequired.Add(sKeyName);
  543. }
  544. }
  545. else
  546. {
  547. throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR ) ;
  548. }
  549. }
  550. }
  551. else
  552. {
  553. LogErrorMessage2(L"Failed to Get keys", hr);
  554. }
  555. }
  556. }
  557. const CHString &CFrameworkQuery::GetQuery()
  558. {
  559. if (m_QueryType == eContextObject)
  560. {
  561. if (m_sQuery.IsEmpty())
  562. {
  563. if (AllPropertiesAreRequired())
  564. {
  565. bstr_t t_Str ( GetQueryClassName() , FALSE) ;
  566. m_sQuery.Format(L"SELECT * FROM %s", (LPCWSTR)t_Str );
  567. }
  568. else if (KeysOnly())
  569. {
  570. bstr_t t_Str ( GetQueryClassName() , FALSE) ;
  571. m_sQuery.Format(L"SELECT __RELPATH FROM %s", (LPCWSTR)t_Str );
  572. }
  573. else
  574. {
  575. m_sQuery = L"SELECT " + m_csaPropertiesRequired[0];
  576. for (DWORD x=1; x < m_csaPropertiesRequired.GetSize(); x++)
  577. {
  578. m_sQuery += L", ";
  579. m_sQuery += m_csaPropertiesRequired[x];
  580. }
  581. m_sQuery += L" FROM ";
  582. bstr_t t_Str ( GetQueryClassName() , FALSE) ;
  583. m_sQuery += t_Str ;
  584. }
  585. }
  586. }
  587. return m_sQuery;
  588. }
  589. /*****************************************************************************
  590. *
  591. * FUNCTION : IsInList
  592. *
  593. * DESCRIPTION : Checks to see if a specified element is in the list
  594. *
  595. * INPUTS : Array to scan, and element
  596. *
  597. * OUTPUTS :
  598. *
  599. * RETURNS : -1 if not in list, else zero based element number
  600. *
  601. * COMMENTS : This routine does a CASE SENSITIVE compare
  602. *
  603. *****************************************************************************/
  604. DWORD CFrameworkQuery::IsInList(
  605. const CHStringArray &csaArray,
  606. LPCWSTR pwszValue
  607. )
  608. {
  609. DWORD dwSize = csaArray.GetSize();
  610. for (DWORD x=0; x < dwSize; x++)
  611. {
  612. // Note this is a CASE SENSITIVE compare
  613. if (wcscmp(csaArray[x], pwszValue) == 0)
  614. {
  615. return x;
  616. }
  617. }
  618. return -1;
  619. }
  620. /*****************************************************************************
  621. *
  622. * FUNCTION : Reset
  623. *
  624. * DESCRIPTION : Zeros out class data members
  625. *
  626. * INPUTS :
  627. *
  628. * OUTPUTS :
  629. *
  630. * RETURNS :
  631. *
  632. * COMMENTS :
  633. *
  634. *****************************************************************************/
  635. void CFrameworkQuery::Reset(void)
  636. {
  637. // Clear out any old values
  638. m_sQuery.Empty();
  639. m_sQueryFormat.Empty();
  640. m_bKeysOnly = false;
  641. m_AddKeys = true;
  642. m_csaPropertiesRequired.RemoveAll();
  643. if (m_pLevel1RPNExpression)
  644. {
  645. delete m_pLevel1RPNExpression;
  646. m_pLevel1RPNExpression = NULL;
  647. }
  648. if (m_IClass)
  649. {
  650. m_IClass->Release();
  651. m_IClass = NULL;
  652. }
  653. }
  654. /*****************************************************************************
  655. *
  656. * FUNCTION : IsReference
  657. *
  658. * DESCRIPTION : Determines whether the specified property is a reference
  659. * property.
  660. *
  661. * INPUTS :
  662. *
  663. * OUTPUTS :
  664. *
  665. * RETURNS :
  666. *
  667. * COMMENTS :
  668. *
  669. *****************************************************************************/
  670. BOOL CFrameworkQuery::IsReference(
  671. LPCWSTR lpwszPropertyName
  672. )
  673. {
  674. BOOL bRet = FALSE;
  675. if (m_IClass != NULL)
  676. {
  677. CIMTYPE ctCimType;
  678. if (SUCCEEDED(m_IClass->Get(lpwszPropertyName, 0, NULL, &ctCimType, NULL)))
  679. {
  680. bRet = ctCimType == CIM_REFERENCE;
  681. }
  682. }
  683. return bRet;
  684. }
  685. /*****************************************************************************
  686. *
  687. * FUNCTION : GetNamespace
  688. *
  689. * DESCRIPTION : Determines whether the specified property is a reference
  690. * property.
  691. *
  692. * INPUTS :
  693. *
  694. * OUTPUTS :
  695. *
  696. * RETURNS :
  697. *
  698. * COMMENTS :
  699. *
  700. *****************************************************************************/
  701. const CHString &CFrameworkQuery::GetNamespace()
  702. {
  703. return m_sNamespace;
  704. };