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.

838 lines
25 KiB

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