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.

1280 lines
37 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //***************************************************************************
  6. #include "precomp.h"
  7. #include "wmicom.h"
  8. #include "wmimap.h"
  9. #include <stdlib.h>
  10. #include <winerror.h>
  11. #include <crc32.h>
  12. ////////////////////////////////////////////////////////////////////////////////////////////////
  13. //**********************************************************************************************
  14. // THE CWbemInfoClass
  15. //**********************************************************************************************
  16. ////////////////////////////////////////////////////////////////////////////////////////////////
  17. ////////////////////////////////////////////////////////////////////////////////////////////////
  18. //**********************************************************************************************
  19. //
  20. // NAME GetPropertiesInID_Order
  21. // PURPOSE Return a WCHAR string containing the class's
  22. // property names, orderd by an ID number
  23. // contained within the named property qualifier.
  24. //
  25. // WRAPPER Not a wrapper. This is a standalone filter/sort
  26. // utility function.
  27. //
  28. //**********************************************************************************************
  29. ///////////////////////////////////////////////////////////////////////////////////////////////////
  30. CWMI_IDOrder::CWMI_IDOrder(IWbemClassObject * pC, IWbemObjectAccess * pA)
  31. {
  32. m_pWMIDataIdList = NULL;
  33. InitMemberVars();
  34. m_pClass = pC;
  35. m_pAccess = pA;
  36. }
  37. ///////////////////////////////////////////////////////////////////////
  38. CWMI_IDOrder::~CWMI_IDOrder()
  39. {
  40. // m_pClass & m_pAccess released elsewhere
  41. InitMemberVars();
  42. }
  43. ///////////////////////////////////////////////////////////////////////
  44. void CWMI_IDOrder::InitMemberVars()
  45. {
  46. m_nTotal = 0;
  47. m_nCurrent = 0;
  48. if( m_pWMIDataIdList )
  49. {
  50. SAFE_DELETE_ARRAY(m_pWMIDataIdList);
  51. m_pWMIDataIdList = NULL;
  52. }
  53. }
  54. ///////////////////////////////////////////////////////////////////////
  55. WCHAR * CWMI_IDOrder::GetFirstID()
  56. {
  57. m_nCurrent = -1 ;
  58. return GetNextID();
  59. }
  60. ///////////////////////////////////////////////////////////////////////
  61. WCHAR * CWMI_IDOrder::GetNextID()
  62. {
  63. WCHAR * pChar = NULL;
  64. //===================================================================
  65. // Go in a loop to find the next ID
  66. // Increment current first, remember, current has to stay valid at
  67. // all times
  68. //===================================================================
  69. m_nCurrent++;
  70. //===================================================================
  71. // If there is no property name, then we know we are done
  72. // with the properties
  73. //===================================================================
  74. while( m_pWMIDataIdList[m_nCurrent].pwcsPropertyName ){
  75. if( m_pWMIDataIdList[m_nCurrent].fPutProperty == FALSE )
  76. {
  77. m_nCurrent++;
  78. }
  79. else
  80. {
  81. pChar = m_pWMIDataIdList[m_nCurrent].pwcsPropertyName;
  82. break;
  83. }
  84. }//End while loop
  85. return pChar;
  86. }
  87. ///////////////////////////////////////////////////////////////////////
  88. HRESULT CWMI_IDOrder::ProcessPropertyQualifiers ( LPCWSTR strPropName, BOOL fHiPerf, UINT uSizeArray, UINT uStartIndex )
  89. {
  90. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  91. CIMTYPE lType = 0;
  92. HRESULT hr = m_pClass->GetPropertyQualifierSet(strPropName,&pIWbemQualifierSet);
  93. if( SUCCEEDED(hr) )
  94. {
  95. UINT nPosition = 0;
  96. CVARIANT v;
  97. hr = pIWbemQualifierSet->Get(L"WmiDataId", 0, &v, 0);
  98. if( hr == S_OK )
  99. {
  100. nPosition = v.GetLONG();
  101. //
  102. // it is required that WmiDataId is 1-based. provider
  103. // stores internally to 0-based array so decrement
  104. //
  105. nPosition-- ;
  106. }
  107. else
  108. {
  109. //
  110. // let's try mofcomp generated ID (methods only) as
  111. // class designers often don't use WmiDataId for
  112. // properties of __PARAMETERS
  113. //
  114. if ( WBEM_E_NOT_FOUND == hr )
  115. {
  116. hr = pIWbemQualifierSet->Get(L"ID", 0, &v, 0);
  117. if( hr == S_OK )
  118. {
  119. nPosition = v.GetLONG();
  120. }
  121. }
  122. }
  123. if( SUCCEEDED(hr))
  124. {
  125. //
  126. // now we need to find real index based on
  127. // ( ( ( id/size ) * size ) + ( id%size ) ) - startindex
  128. //
  129. UINT div = ( nPosition/uSizeArray ) ;
  130. UINT mod = ( nPosition%uSizeArray ) ;
  131. nPosition = ( ( div * uSizeArray ) + mod ) - uStartIndex ;
  132. if ( nPosition < uSizeArray )
  133. {
  134. if ( FALSE == m_pWMIDataIdList[nPosition].bIsDirty )
  135. {
  136. //===================================================
  137. // Get the exact number and
  138. // copy property name into the correct array location
  139. // and get all of the attributes of the property
  140. // we will need in the future to process it.
  141. //===================================================
  142. hr =m_pClass->Get(strPropName, 0, &v, &lType, NULL);
  143. if( SUCCEEDED(hr) )
  144. {
  145. CVARIANT vQual;
  146. hr = pIWbemQualifierSet->Get(L"CIMType", 0, &vQual,0);
  147. if ( SUCCEEDED(hr) )
  148. {
  149. //=================================================================
  150. // If we are accumulating hi perf info, then get the handle to
  151. // access the property instead of via property name
  152. //=================================================================
  153. if( fHiPerf )
  154. {
  155. long lHandle = 0;
  156. if( S_OK == m_pAccess->GetPropertyHandle(strPropName, 0, &lHandle))
  157. {
  158. m_pWMIDataIdList[nPosition].lHandle = (long)lHandle;
  159. }
  160. }
  161. //=================================================================
  162. // Now, set the rest of the property information
  163. //=================================================================
  164. m_pWMIDataIdList[nPosition].lType = (long)lType;
  165. m_pWMIDataIdList[nPosition].SetPropertyName((WCHAR*)strPropName);
  166. m_pWMIDataIdList[nPosition].fPutProperty = TRUE;
  167. CWMIDataTypeMap MapWMIData;
  168. CBSTR cbstrTmp(vQual.GetStr());
  169. MapWMIData.GetSizeAndType (
  170. cbstrTmp,
  171. &m_pWMIDataIdList[nPosition],
  172. m_pWMIDataIdList[nPosition].lType,
  173. m_pWMIDataIdList[nPosition].nWMISize
  174. );
  175. //
  176. // check MAX or WmiSizeIs qualifiers
  177. //
  178. m_pWMIDataIdList[nPosition].dwArraySize = GetSizeOfArray ( strPropName );
  179. //
  180. // set the dirty flag
  181. //
  182. m_pWMIDataIdList[nPosition].bIsDirty = TRUE ;
  183. m_nTotal++;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. //
  190. // already set that position. this
  191. // means that there must be same WmiDataId used
  192. //
  193. hr = WBEM_E_INVALID_CLASS ;
  194. }
  195. }
  196. else
  197. {
  198. //
  199. // qualifier value is not contiguous
  200. //
  201. hr = WBEM_E_INVALID_CLASS ;
  202. }
  203. }
  204. else
  205. {
  206. //
  207. // only when qualifier was not found
  208. //
  209. if ( WBEM_E_NOT_FOUND == hr )
  210. {
  211. // As some properties are ok not to have WMIDataIds, we have
  212. // to set this to OK, need to log this in the future
  213. hr = S_OK;
  214. }
  215. }
  216. }
  217. else
  218. {
  219. switch ( hr )
  220. {
  221. case WBEM_E_SYSTEM_PROPERTY:
  222. {
  223. //
  224. // this is not really expected as GetNames called
  225. // inside of caller was supposed to ask for
  226. // non-system properties only, but keeping backward
  227. // behavior ...
  228. //
  229. hr = WBEM_S_NO_ERROR ;
  230. break ;
  231. }
  232. default :
  233. {
  234. //
  235. // populate this error back
  236. //
  237. break ;
  238. }
  239. }
  240. }
  241. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  242. return hr;
  243. }
  244. ///////////////////////////////////////////////////////////////////////
  245. HRESULT CWMI_IDOrder::GetPropertiesInIDOrder ( BOOL fHiPerf, UINT uStartIndex )
  246. {
  247. HRESULT hr = WBEM_E_FAILED;
  248. SAFEARRAY * psaNames = NULL;
  249. //======================================================
  250. // Get Array boundaries
  251. //======================================================
  252. hr = m_pClass->GetNames ( NULL, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames ) ;
  253. if (SUCCEEDED(hr)){
  254. long lLower = 0, lUpper = 0;
  255. hr = SafeArrayGetLBound(psaNames,1,&lLower);
  256. if (SUCCEEDED(hr)){
  257. hr = SafeArrayGetUBound(psaNames,1,&lUpper);
  258. if (SUCCEEDED(hr)){
  259. //===========================================
  260. // Get the total number of elements, so we
  261. // create the right sized array of ID structs
  262. //===========================================
  263. UINT nSize = ( lUpper-lLower ) + 1;
  264. m_pWMIDataIdList = new IDOrder [ nSize + 1 ];
  265. if( m_pWMIDataIdList )
  266. {
  267. try
  268. {
  269. //
  270. // last item in array serves as stopper
  271. //
  272. memset ( m_pWMIDataIdList, NULL, ( sizeof ( IDOrder )* ( nSize + 1 ) ) );
  273. for(long ndx = lLower; ndx <= lUpper; ndx++)
  274. {
  275. CBSTR cbstrPropName;
  276. hr = SafeArrayGetElement(psaNames, &ndx, &cbstrPropName);
  277. if (WBEM_S_NO_ERROR == hr)
  278. {
  279. hr = ProcessPropertyQualifiers ( cbstrPropName, fHiPerf, nSize, uStartIndex ) ;
  280. if( hr != WBEM_S_NO_ERROR )
  281. {
  282. break;
  283. }
  284. }
  285. }
  286. }
  287. catch(...)
  288. {
  289. SAFE_DELETE_ARRAY(m_pWMIDataIdList);
  290. hr = WBEM_E_UNEXPECTED;
  291. throw;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. if( psaNames )
  298. {
  299. SafeArrayDestroy(psaNames);
  300. }
  301. return hr;
  302. }
  303. ////////////////////////////////////////////////////////////////////////
  304. DWORD CWMI_IDOrder::GetSizeOfArray(LPCWSTR strProp)
  305. {
  306. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  307. CAutoWChar pwcsArraySize(_MAX_PATH+2);
  308. DWORD dwCount = 0L;
  309. if( pwcsArraySize.Valid() )
  310. {
  311. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  312. hr = m_pClass->GetPropertyQualifierSet(strProp,&pIWbemQualifierSet);
  313. if( SUCCEEDED(hr) )
  314. {
  315. CVARIANT v;
  316. BOOL bInClassObject = FALSE ;
  317. hr = pIWbemQualifierSet->Get(L"out", 0, &v, 0);
  318. if ( SUCCEEDED ( hr ) )
  319. {
  320. if ( VT_BOOL != V_VT ( &v ) || ( VARIANT_TRUE != V_BOOL ( &v ) ) )
  321. {
  322. bInClassObject = TRUE ;
  323. }
  324. }
  325. else
  326. {
  327. if ( WBEM_E_NOT_FOUND == hr )
  328. {
  329. bInClassObject = TRUE ;
  330. }
  331. }
  332. if ( TRUE == bInClassObject )
  333. {
  334. hr = pIWbemQualifierSet->Get(L"MAX", 0, &v, 0);
  335. if( SUCCEEDED(hr))
  336. {
  337. dwCount = v.GetLONG();
  338. }
  339. else
  340. {
  341. hr = pIWbemQualifierSet->Get(L"WMISizeIs", 0, &v, 0);
  342. if( hr == S_OK )
  343. {
  344. CVARIANT var;
  345. CIMTYPE lTmpType=0;
  346. CWMIDataTypeMap MapWMIData;
  347. hr = m_pClass->Get(v, 0, &var, &lTmpType,NULL);
  348. if( hr == S_OK )
  349. {
  350. dwCount = MapWMIData.ArraySize(lTmpType,var);
  351. }
  352. }
  353. }
  354. }
  355. }
  356. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  357. }
  358. return dwCount;
  359. }
  360. //******************************************************************
  361. ////////////////////////////////////////////////////////////////////
  362. // CWMIProcessClass
  363. ////////////////////////////////////////////////////////////////////
  364. //******************************************************************
  365. // WbemClassInfo deals with all the pointers and info with one
  366. // particular wbem class
  367. //
  368. //******************************************************************
  369. ////////////////////////////////////////////////////////////////////
  370. CWMIProcessClass::~CWMIProcessClass()
  371. {
  372. ReleaseInstancePointers();
  373. SAFE_RELEASE_PTR(m_pAccess);
  374. SAFE_RELEASE_PTR(m_pClass );
  375. SAFE_DELETE_ARRAY(m_pwcsClassName);
  376. SAFE_DELETE_PTR(m_pCurrentProperty);
  377. SAFE_DELETE_PTR(m_pWMI);
  378. }
  379. /////////////////////////////////////////////////////////////////////
  380. HRESULT CWMIProcessClass::Initialize()
  381. {
  382. HRESULT hr = WBEM_E_FAILED;
  383. SAFE_DELETE_PTR(m_pWMI);
  384. m_pWMI = new CWMIManagement;
  385. if( m_pWMI )
  386. {
  387. hr = S_OK;
  388. m_fInit = TRUE;
  389. }
  390. return hr;
  391. }
  392. /////////////////////////////////////////////////////////////////////
  393. CWMIProcessClass::CWMIProcessClass(BOOL b)
  394. {
  395. m_pWMI = NULL;
  396. m_fInit = FALSE;
  397. m_fGetNewInstance = TRUE;
  398. m_pAccessInstance = NULL;
  399. m_pClassInstance = NULL;
  400. m_pClass = NULL;
  401. m_pAccess = NULL;
  402. m_pCurrentProperty = NULL;
  403. m_pwcsClassName = NULL;
  404. m_wHardCodedGuid = 0;
  405. }
  406. /////////////////////////////////////////////////////////////////////
  407. BOOL CWMIProcessClass::GetANewAccessInstance()
  408. {
  409. HRESULT hr = S_OK;
  410. hr = m_pAccess->SpawnInstance(0, &m_pClassInstance);
  411. m_pClassInstance->AddRef();
  412. if( SUCCEEDED(hr) )
  413. {
  414. hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance);
  415. }
  416. return ( hr == 0 ) ? TRUE : FALSE;
  417. }
  418. /////////////////////////////////////////////////////////////////////
  419. BOOL CWMIProcessClass::GetANewInstance()
  420. {
  421. HRESULT hr = S_OK;
  422. if( m_fGetNewInstance )
  423. {
  424. SAFE_RELEASE_PTR(m_pClassInstance);
  425. hr = m_pClass->SpawnInstance(0, &m_pClassInstance);
  426. if( SUCCEEDED(hr) )
  427. {
  428. if( m_fHiPerf )
  429. {
  430. SAFE_RELEASE_PTR(m_pAccessInstance);
  431. hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance);
  432. }
  433. }
  434. }
  435. return ( hr == 0 ) ? TRUE : FALSE;
  436. }
  437. /////////////////////////////////////////////////////////////////////
  438. HRESULT CWMIProcessClass::SetKeyFromAccessPointer()
  439. {
  440. CVARIANT varName;
  441. HRESULT hr = m_pAccess->Get(L"InstanceName", 0, &varName, NULL, NULL);
  442. if( SUCCEEDED(hr))
  443. {
  444. hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
  445. }
  446. return hr;
  447. }
  448. ////////////////////////////////////////////////////////////////////
  449. HRESULT CWMIProcessClass::GetKeyFromAccessPointer(CVARIANT * v)
  450. {
  451. return m_pAccessInstance->Get(L"InstanceName", 0, (VARIANT *)v, NULL, NULL);
  452. }
  453. /////////////////////////////////////////////////////////////////////
  454. HRESULT CWMIProcessClass::SetHiPerfProperties(LARGE_INTEGER TimeStamp)
  455. {
  456. LONG lHandle = 0;
  457. //=========================================================================================================
  458. // Timestamp_PerfTime = timestamp in PerfFreq units returned by (QueryPerformanceCounter)
  459. //=========================================================================================================
  460. HRESULT hr = m_pAccess->GetPropertyHandle(L"Frequency_PerfTime", 0, &lHandle);
  461. if(SUCCEEDED(hr))
  462. {
  463. LARGE_INTEGER Counter;
  464. if( QueryPerformanceCounter(&Counter))
  465. {
  466. hr = m_pAccessInstance->WriteQWORD(lHandle, Counter.QuadPart);
  467. }
  468. //=====================================================================================================
  469. // Timestamp_Sys100NS = timestamp in 100 NS units/QueryPerformanceCounter()dumbed down to 100NS
  470. //=====================================================================================================
  471. if ( SUCCEEDED( hr ) )
  472. {
  473. hr = m_pAccess->GetPropertyHandle(L"Timestamp_Sys100NS", 0, &lHandle);
  474. if( SUCCEEDED(hr))
  475. {
  476. LARGE_INTEGER Sys;
  477. Sys.QuadPart = Counter.QuadPart / 100;
  478. hr = m_pAccessInstance->WriteQWORD(lHandle, Sys.QuadPart);
  479. }
  480. }
  481. }
  482. //=========================================================================================================
  483. // Frequency_PerfTime = the value returned by QueryPerformanceFrequency
  484. //=========================================================================================================
  485. if ( SUCCEEDED( hr ) )
  486. {
  487. hr = m_pAccess->GetPropertyHandle(L"Timestamp_PerfTime", 0, &lHandle);
  488. if( SUCCEEDED(hr))
  489. {
  490. LARGE_INTEGER freq;
  491. if( QueryPerformanceFrequency (&freq))
  492. {
  493. hr = m_pAccessInstance->WriteQWORD(lHandle, freq.QuadPart);
  494. }
  495. }
  496. }
  497. //=========================================================================================================
  498. // Timestamp_Object = (WnodeHeader)->TimeStamp
  499. //=========================================================================================================
  500. if ( SUCCEEDED( hr ) )
  501. {
  502. hr = m_pAccess->GetPropertyHandle(L"Timestamp_Object", 0, &lHandle);
  503. if( SUCCEEDED(hr))
  504. {
  505. hr = m_pAccessInstance->WriteQWORD(lHandle, TimeStamp.QuadPart);
  506. }
  507. }
  508. //=========================================================================================================
  509. // Frequency_Sys100NS = 10000000
  510. // Frequency_Object = 10000000
  511. //=========================================================================================================
  512. if ( SUCCEEDED( hr ) )
  513. {
  514. LARGE_INTEGER Tmp;
  515. Tmp.QuadPart = 10000000;
  516. hr = m_pAccess->GetPropertyHandle(L"Frequency_Object", 0, &lHandle);
  517. if( SUCCEEDED(hr))
  518. {
  519. hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart);
  520. }
  521. hr = m_pAccess->GetPropertyHandle(L"Frequency_Sys100NS", 0, &lHandle);
  522. if( SUCCEEDED(hr))
  523. {
  524. hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart);
  525. }
  526. }
  527. return hr;
  528. }
  529. /////////////////////////////////////////////////////////////////////
  530. void CWMIProcessClass::SetActiveProperty()
  531. {
  532. CVARIANT vActive;
  533. vActive.SetBool(TRUE);
  534. if( !m_fHiPerf )
  535. {
  536. m_pClassInstance->Put(L"Active", 0, &vActive, NULL);
  537. }
  538. }
  539. /////////////////////////////////////////////////////////////////////
  540. void CWMIProcessClass::ReleaseInstancePointers()
  541. {
  542. SAFE_RELEASE_PTR( m_pClassInstance );
  543. SAFE_RELEASE_PTR( m_pAccessInstance);
  544. }
  545. /////////////////////////////////////////////////////////////////////
  546. HRESULT CWMIProcessClass::SendInstanceBack()
  547. {
  548. HRESULT hr = WBEM_E_FAILED;
  549. //===============================================
  550. // Send the object to the caller
  551. //===============================================
  552. if( HANDLER )
  553. {
  554. hr = HANDLER->Indicate(1,&m_pClassInstance);
  555. if( m_fGetNewInstance )
  556. {
  557. ReleaseInstancePointers();
  558. }
  559. }
  560. return hr;
  561. }
  562. ////////////////////////////////////////////////////////////////////
  563. HRESULT CWMIProcessClass::SetInstanceName(WCHAR * wName, BOOL fSetName)
  564. {
  565. CVARIANT varName(wName);
  566. HRESULT hr = WBEM_E_INVALID_OBJECT;
  567. if( fSetName )
  568. {
  569. if( m_pClassInstance )
  570. {
  571. if( !m_fHiPerf )
  572. {
  573. hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
  574. }
  575. else
  576. {
  577. hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL);
  578. }
  579. }
  580. }
  581. else
  582. {
  583. hr = SetClassName(wName);
  584. }
  585. return hr;
  586. }
  587. ////////////////////////////////////////////////////////////////////
  588. HRESULT CWMIProcessClass::GetInstanceName(WCHAR *& p)
  589. {
  590. CVARIANT vValue;
  591. HRESULT hr = m_pClass->Get(L"InstanceName", 0, &vValue, NULL, NULL);
  592. if( SUCCEEDED(hr) )
  593. {
  594. if( vValue.GetStr() )
  595. {
  596. int nlen = wcslen(vValue.GetStr());
  597. p = new WCHAR [nlen + 4];
  598. if( p )
  599. {
  600. hr = StringCchCopyW(p,nlen+4,vValue.GetStr());
  601. }
  602. else
  603. {
  604. hr = WBEM_E_UNEXPECTED;
  605. }
  606. }
  607. }
  608. return hr;
  609. }
  610. ////////////////////////////////////////////////////////////////////
  611. HRESULT CWMIProcessClass::GetPropertiesInIDOrder ( BOOL fHiPerf, UINT uStartIndex )
  612. {
  613. HRESULT hr = S_OK;
  614. //============================================
  615. // If the pointer is NOT = to NULL, then this
  616. // means we haven't released the previous one
  617. // return FALSE, to prevent memory leaks
  618. //============================================
  619. if( !m_pCurrentProperty )
  620. {
  621. m_pCurrentProperty = new CWMI_IDOrder(m_pClass,m_pAccess);
  622. if( m_pCurrentProperty )
  623. {
  624. try
  625. {
  626. hr = m_pCurrentProperty->GetPropertiesInIDOrder ( fHiPerf, uStartIndex ) ;
  627. if( hr != S_OK )
  628. {
  629. SAFE_DELETE_PTR(m_pCurrentProperty);
  630. }
  631. }
  632. catch(...)
  633. {
  634. hr = WBEM_E_UNEXPECTED;
  635. SAFE_DELETE_PTR(m_pCurrentProperty);
  636. throw;
  637. }
  638. }
  639. }
  640. return hr;
  641. }
  642. ///////////////////////////////////////////////////////////////////////////////////////////////////
  643. // NAME GetQualifierString (takes a class name)
  644. // PURPOSE Gets a qualifier value and returns it as a wide char string
  645. // WRAPPER High level
  646. //
  647. // PARAMETERS (1) [in] Pointer to an existing IWbemClassObject
  648. // (2) [in] Pointer to a Property Name string
  649. // (3) [in] Pointer to a Qualifier Name
  650. // (4) [in\out] Pointer to an external character buffer
  651. //
  652. // RETURNS Success: S_OK
  653. // Failure: non zero value
  654. ///////////////////////////////////////////////////////////////////////////////////////////////////
  655. HRESULT CWMIProcessClass::GetQualifierString( WCHAR * ppwcsPropertyName,
  656. WCHAR * pwcsQualifierName,
  657. WCHAR * pwcsExternalOutputBuffer,
  658. int nSize )
  659. {
  660. CVARIANT vQual;
  661. HRESULT hr = GetQualifierValue( ppwcsPropertyName, pwcsQualifierName, (CVARIANT*)&vQual);
  662. if (WBEM_S_NO_ERROR == hr)
  663. {
  664. if(vQual.GetType() != VT_BSTR)
  665. {
  666. VariantChangeType(&vQual, &vQual, 0, VT_BSTR);
  667. }
  668. int nTmp=wcslen(V_BSTR(&vQual));
  669. if( nTmp > nSize )
  670. {
  671. hr = WBEM_E_BUFFER_TOO_SMALL;
  672. }
  673. else
  674. {
  675. hr = StringCchCatW(pwcsExternalOutputBuffer, nSize, V_BSTR(&vQual));
  676. }
  677. }
  678. return hr;
  679. }
  680. ///////////////////////////////////////////////////////////////////////////////////////////////////
  681. HRESULT CWMIProcessClass::GetQualifierValue( WCHAR * ppwcsPropertyName, WCHAR * pwcsQualifierName, CVARIANT * vQual )
  682. {
  683. IWbemClassObject * pClass = NULL;
  684. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  685. HRESULT hr = WBEM_E_INVALID_PARAMETER;
  686. BOOL bDone = FALSE;
  687. if ( m_pClass )
  688. {
  689. CBSTR cb(L"__GENUS");
  690. CVARIANT v1;
  691. if ( SUCCEEDED ( m_pClass->Get(cb, 0, &v1, 0, 0 ) ) )
  692. {
  693. if ( V_I4 (&v1) == 1 )
  694. {
  695. ( pClass = m_pClass ) -> AddRef ();
  696. bDone = TRUE;
  697. }
  698. }
  699. }
  700. if ( !bDone )
  701. {
  702. CBSTR cbstr(m_pwcsClassName);
  703. if ( WBEM_S_NO_ERROR == REPOSITORY->GetObject(cbstr, 0, CONTEXT, &pClass, NULL) )
  704. {
  705. bDone = TRUE;
  706. }
  707. }
  708. if ( bDone )
  709. {
  710. if(ppwcsPropertyName)
  711. {
  712. hr = pClass->GetPropertyQualifierSet(ppwcsPropertyName, &pIWbemQualifierSet);
  713. }
  714. else
  715. {
  716. hr = pClass->GetQualifierSet(&pIWbemQualifierSet);
  717. }
  718. }
  719. if ( SUCCEEDED ( hr ) && pIWbemQualifierSet )
  720. {
  721. long lType = 0L;
  722. hr = pIWbemQualifierSet->Get(pwcsQualifierName, 0,(VARIANT *) vQual,&lType);
  723. }
  724. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  725. SAFE_RELEASE_PTR(pClass);
  726. return hr;
  727. }
  728. ///////////////////////////////////////////////////////////////////////////////////////////////////
  729. HRESULT CWMIProcessClass::GetPrivilegesQualifer(SAFEARRAY ** psaPrivReq)
  730. {
  731. IWbemClassObject * pClass = NULL;
  732. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  733. CBSTR cbstr(m_pwcsClassName);
  734. HRESULT hr = REPOSITORY->GetObject(cbstr, 0,CONTEXT, &pClass, NULL);
  735. if(SUCCEEDED(hr))
  736. {
  737. pClass->GetQualifierSet(&pIWbemQualifierSet);
  738. if( pIWbemQualifierSet ) {
  739. CVARIANT vQual;
  740. long lType = 0L;
  741. hr = pIWbemQualifierSet->Get(L"Privileges", 0, &vQual,&lType);
  742. if (SUCCEEDED(hr)){
  743. VARIANT *p = (VARIANT *)vQual;
  744. SAFEARRAY * psa = V_ARRAY(p);
  745. if( !IsBadReadPtr( psaPrivReq, sizeof(SAFEARRAY)))
  746. {
  747. CSAFEARRAY Safe(psa);
  748. *psaPrivReq = OMSSafeArrayCreate(VT_BSTR,Safe.GetNumElements());
  749. hr = SafeArrayCopy(psa,psaPrivReq );
  750. Safe.Unbind();
  751. // Don't need to destroy, it will be destroyed
  752. }
  753. }
  754. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  755. }
  756. }
  757. SAFE_RELEASE_PTR(pClass);
  758. return hr;
  759. }
  760. ///////////////////////////////////////////////////////////////////////////////////////////////
  761. HRESULT CWMIProcessClass::GetGuid(void)
  762. {
  763. WCHAR pwcsGuidString[128];
  764. HRESULT hr = S_OK;
  765. //=======================================
  766. // Initialize ptrs we will need
  767. //=======================================
  768. if( m_wHardCodedGuid ){
  769. hr = StringCchCopyW( pwcsGuidString, 128, WMI_BINARY_MOF_GUID );
  770. }
  771. else{
  772. memset(pwcsGuidString,NULL,128);
  773. hr = GetQualifierString( NULL, L"guid", pwcsGuidString,128);
  774. }
  775. if(SUCCEEDED(hr))
  776. {
  777. //===========================================================
  778. // Set the GUID first, before we try to open the WMI
  779. // data block, if succeeds, then open WMI
  780. //===========================================================
  781. if( !SetGuid(pwcsGuidString,m_Guid) )
  782. {
  783. hr = WBEM_E_FAILED;
  784. }
  785. }
  786. return hr;
  787. }
  788. ///////////////////////////////////////////////////////////////////////////////////////////////
  789. HRESULT CWMIProcessClass::SetClass(WCHAR * wcsClass)
  790. {
  791. HRESULT hr = WBEM_E_FAILED;
  792. if( wcsClass )
  793. {
  794. hr = SetClassName(wcsClass);
  795. if( SUCCEEDED(hr))
  796. {
  797. CBSTR cbstr(m_pwcsClassName);
  798. hr = m_pWMI->Repository()->GetObject(cbstr,0,CONTEXT,&m_pClass, NULL);
  799. if( hr == S_OK )
  800. {
  801. hr = GetGuid();
  802. // If there is no GUID for the class then set proper error message
  803. if(hr == WBEM_E_NOT_FOUND)
  804. {
  805. hr = WBEM_E_NOT_SUPPORTED;
  806. }
  807. if( SUCCEEDED(hr))
  808. {
  809. //===========================================================
  810. // Get the IWbemObjectAccess interface for the object
  811. // ==========================================================
  812. if( m_fHiPerf )
  813. {
  814. hr = m_pClass->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccess);
  815. }
  816. if( SUCCEEDED(hr))
  817. {
  818. hr = GetPropertiesInIDOrder(m_fHiPerf);
  819. }
  820. }
  821. }
  822. }
  823. }
  824. return hr;
  825. }
  826. //=============================================================
  827. //=============================================================
  828. HRESULT CWMIProcessClass::SetClassName(WCHAR * pIn )
  829. {
  830. SAFE_DELETE_ARRAY(m_pwcsClassName);
  831. return AllocAndCopy(pIn,&m_pwcsClassName);
  832. }
  833. //=============================================================
  834. HRESULT CWMIProcessClass::SetClass ( IWbemClassObject * pPtr, UINT uStartIndex )
  835. {
  836. HRESULT hr = WBEM_E_FAILED;
  837. if( pPtr )
  838. {
  839. //
  840. // as this is input we must addref due to releasing in
  841. // class destructor as well as in the caller
  842. //
  843. ( m_pClass = pPtr ) -> AddRef () ;
  844. CVARIANT vName;
  845. hr = m_pClass->Get(L"__CLASS", 0, &vName, NULL, NULL);
  846. if( hr == S_OK )
  847. {
  848. hr = SetClassName(vName.GetStr());
  849. if( SUCCEEDED(hr))
  850. {
  851. hr = GetPropertiesInIDOrder ( FALSE, uStartIndex );
  852. }
  853. }
  854. }
  855. return hr;
  856. }
  857. //=============================================================
  858. HRESULT CWMIProcessClass::SetAccess(IWbemObjectAccess * pPtr)
  859. {
  860. HRESULT hr = WBEM_E_FAILED;
  861. if( pPtr )
  862. {
  863. SAFE_RELEASE_PTR(m_pAccess);
  864. SAFE_RELEASE_PTR(m_pClass);
  865. m_pAccess = pPtr;
  866. m_pAccess->AddRef();
  867. CVARIANT vName;
  868. hr = m_pAccess->Get(L"__CLASS", 0, &vName, NULL, NULL);
  869. if( SUCCEEDED(hr))
  870. {
  871. hr = SetClassName(vName.GetStr());
  872. if( hr == S_OK )
  873. {
  874. CBSTR cbstr(m_pwcsClassName);
  875. hr = REPOSITORY->GetObject(cbstr, 0,CONTEXT, &m_pClass, NULL);
  876. if( SUCCEEDED(hr))
  877. {
  878. hr = GetGuid();
  879. if( SUCCEEDED(hr))
  880. {
  881. hr = GetPropertiesInIDOrder(TRUE);
  882. }
  883. }
  884. }
  885. }
  886. }
  887. return hr;
  888. }
  889. //=============================================================
  890. HRESULT CWMIProcessClass::SetClassPointerOnly(IWbemClassObject * pPtr)
  891. {
  892. HRESULT hr = WBEM_E_FAILED;
  893. if( pPtr )
  894. {
  895. SAFE_RELEASE_PTR(m_pClass);
  896. m_pClass = pPtr;
  897. m_pClass->AddRef();
  898. hr = S_OK;
  899. }
  900. return hr;
  901. }
  902. //=============================================================
  903. void CWMIProcessClass::SaveEmbeddedClass(CVARIANT & v)
  904. {
  905. IDispatch * pAlterEgo = NULL;
  906. m_pClassInstance->QueryInterface(IID_IUnknown, (void**)&pAlterEgo);
  907. // VariantClear will call release()
  908. v.SetUnknown(pAlterEgo);
  909. }
  910. //=============================================================
  911. HRESULT CWMIProcessClass::ReadEmbeddedClassInstance( IUnknown * pUnknown, CVARIANT & v )
  912. {
  913. HRESULT hr = WBEM_E_FAILED;
  914. //=============================================
  915. // Get the class
  916. //=============================================
  917. IUnknown * pUnk = NULL;
  918. if( pUnknown )
  919. {
  920. pUnk = pUnknown;
  921. }
  922. else
  923. {
  924. pUnk = v.GetUnknown();
  925. }
  926. IWbemClassObject * pClass = NULL;
  927. if( pUnk )
  928. {
  929. pUnk->QueryInterface(IID_IWbemClassObject,(void**) &pClass );
  930. if( pClass )
  931. {
  932. //===============================================
  933. // Get class definition, so we need to get the
  934. // class name
  935. CVARIANT vName;
  936. CAutoWChar wcsClassName(_MAX_PATH+2);
  937. if( wcsClassName.Valid() )
  938. {
  939. hr = pClass->Get(L"__CLASS", 0, &vName, NULL, NULL);
  940. if( hr == S_OK )
  941. {
  942. if ( SUCCEEDED ( hr = StringCchCopyW( wcsClassName, _MAX_PATH+2, vName.GetStr() ) ) )
  943. {
  944. hr = SetClass(wcsClassName);
  945. if( S_OK == hr )
  946. {
  947. hr = SetClassPointerOnly(pClass);
  948. }
  949. }
  950. }
  951. }
  952. else
  953. {
  954. hr = WBEM_E_OUT_OF_MEMORY;
  955. }
  956. }
  957. }
  958. SAFE_RELEASE_PTR( pClass );
  959. return hr;
  960. }
  961. //=======================================================================
  962. int CWMIProcessClass::PropertyCategory()
  963. {
  964. if (!(m_pCurrentProperty->PropertyType() & CIM_FLAG_ARRAY) )
  965. {
  966. if( m_pCurrentProperty->PropertyType() == VT_UNKNOWN )
  967. {
  968. return CWMIProcessClass::EmbeddedClass;
  969. }
  970. else
  971. {
  972. return CWMIProcessClass::Data;
  973. }
  974. }
  975. else
  976. {
  977. return CWMIProcessClass::Array;
  978. }
  979. }
  980. ///////////////////////////////////////////////////////////////////////////////////////////////////
  981. HRESULT CWMIProcessClass::InitializeEmbeddedClass(CWMIProcessClass * p)
  982. {
  983. SetWMIPointers(p);
  984. return SetClass(p->EmbeddedClassName());
  985. }
  986. //=======================================================================
  987. HRESULT CWMIProcessClass::GetLargestDataTypeInClass(int & nSize)
  988. {
  989. HRESULT hr = WBEM_E_FAILED;
  990. WCHAR * pwcsProperty;
  991. BOOL fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = FALSE;
  992. int nNewSize = 0L;
  993. nSize = 0L;
  994. //=========================================================
  995. // Get size of largest data type within the class and
  996. // align it on that, however, if the class contains an
  997. // embedded class ONLY, then get the size of the largest
  998. // datatype within that embedded class.
  999. //=========================================================
  1000. pwcsProperty = FirstProperty();
  1001. while (NULL != pwcsProperty)
  1002. {
  1003. switch( PropertyCategory())
  1004. {
  1005. case CWMIProcessClass::EmbeddedClass:
  1006. {
  1007. if( !fClassContainsAnotherDataTypeBesidesAnEmbeddedClass ){
  1008. CWMIProcessClass EmbeddedClass(0);
  1009. hr = EmbeddedClass.Initialize();
  1010. if( S_OK == hr )
  1011. {
  1012. hr = EmbeddedClass.InitializeEmbeddedClass(this);
  1013. if( hr != S_OK ){
  1014. break;
  1015. }
  1016. // embedded object
  1017. hr = EmbeddedClass.GetLargestDataTypeInClass(nNewSize);
  1018. if( hr != S_OK ){
  1019. break;
  1020. }
  1021. }
  1022. }
  1023. }
  1024. break;
  1025. case CWMIProcessClass::Array:
  1026. case CWMIProcessClass::Data:
  1027. fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = TRUE;
  1028. nNewSize = PropertySize();
  1029. break;
  1030. }
  1031. if( nNewSize == SIZEOFWBEMDATETIME ){
  1032. nNewSize = 1;
  1033. }
  1034. if( nNewSize > nSize ){
  1035. nSize = nNewSize;
  1036. }
  1037. pwcsProperty = NextProperty();
  1038. hr = WBEM_S_NO_ERROR;
  1039. }
  1040. return hr;
  1041. }
  1042. ////////////////////////////////////////////////////////////////////
  1043. HRESULT CWMIProcessClass::GetSizeOfArray(long & lType, DWORD & dwCount, BOOL & fDynamic)
  1044. {
  1045. HRESULT hr = WBEM_E_OUT_OF_MEMORY;
  1046. CAutoWChar pwcsArraySize(_MAX_PATH+2);
  1047. if( pwcsArraySize.Valid() )
  1048. {
  1049. dwCount = 0;
  1050. lType = m_pCurrentProperty->PropertyType() &~ CIM_FLAG_ARRAY;
  1051. pwcsArraySize[0]=NULL;
  1052. //======================================================
  1053. // Get the number of elements in the array from the
  1054. // "ArraySize" property qualifier
  1055. //======================================================
  1056. hr = GetQualifierString(m_pCurrentProperty->PropertyName(), L"MAX",pwcsArraySize, MAX_PATH);
  1057. if( hr == S_OK )
  1058. {
  1059. dwCount = _wtol(pwcsArraySize);
  1060. }
  1061. else
  1062. {
  1063. hr = GetQualifierString(m_pCurrentProperty->PropertyName(),L"WMISizeIs",pwcsArraySize,MAX_PATH);
  1064. if( hr == S_OK )
  1065. {
  1066. CVARIANT var;
  1067. CIMTYPE lTmpType;
  1068. hr = WBEM_E_FAILED;
  1069. fDynamic = TRUE;
  1070. if( m_pClassInstance )
  1071. {
  1072. hr = m_pClassInstance->Get(pwcsArraySize, 0, &var, &lTmpType,NULL);
  1073. }
  1074. else
  1075. {
  1076. if( m_pClass )
  1077. {
  1078. hr = m_pClass->Get(pwcsArraySize, 0, &var, &lTmpType,NULL);
  1079. }
  1080. }
  1081. if( hr == S_OK )
  1082. {
  1083. CWMIDataTypeMap MapIt;
  1084. dwCount = MapIt.ArraySize(lTmpType,var);
  1085. }
  1086. }
  1087. }
  1088. //==============================================================================
  1089. // If all else fails, get the size of the array from the class definition.
  1090. //==============================================================================
  1091. if( hr != S_OK )
  1092. {
  1093. dwCount = m_pCurrentProperty->ArraySize();
  1094. hr = S_OK;
  1095. }
  1096. }
  1097. return hr;
  1098. }
  1099. //======================================================================
  1100. HRESULT CWMIProcessClass::GetSizeOfClass(DWORD & dwSize)
  1101. {
  1102. HRESULT hr = WBEM_E_FAILED;
  1103. WCHAR * pwcsProperty;
  1104. dwSize = 0;
  1105. pwcsProperty = FirstProperty();
  1106. while (NULL != pwcsProperty)
  1107. {
  1108. switch( PropertyCategory())
  1109. {
  1110. case CWMIProcessClass::EmbeddedClass:
  1111. {
  1112. DWORD dwEmbeddedSize;
  1113. CWMIProcessClass EmbeddedClass(0);
  1114. hr = EmbeddedClass.Initialize();
  1115. if( S_OK == hr )
  1116. {
  1117. hr = EmbeddedClass.InitializeEmbeddedClass(this);
  1118. if( hr != S_OK ){
  1119. break;
  1120. }
  1121. // embedded object
  1122. hr = EmbeddedClass.GetSizeOfClass(dwEmbeddedSize);
  1123. if( hr != S_OK ){
  1124. break;
  1125. }
  1126. dwSize += dwEmbeddedSize;
  1127. }
  1128. }
  1129. break;
  1130. case CWMIProcessClass::Array:
  1131. {
  1132. int nSize = PropertySize();
  1133. dwSize += (nSize * ArraySize());
  1134. }
  1135. break;
  1136. case CWMIProcessClass::Data:
  1137. dwSize += PropertySize();
  1138. break;
  1139. }
  1140. pwcsProperty = NextProperty();
  1141. hr = WBEM_S_NO_ERROR;
  1142. }
  1143. return hr;
  1144. }
  1145. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1146. ULONG CWMIProcessClass::GetMethodId(LPCWSTR strProp)
  1147. {
  1148. ULONG uMethodId = 0;
  1149. IWbemQualifierSet * pIWbemQualifierSet = NULL;
  1150. //======================================================
  1151. // Get the number of elements in the array from the
  1152. // "ArraySize" property qualifier
  1153. //======================================================
  1154. HRESULT hr = m_pClass->GetMethodQualifierSet(strProp,&pIWbemQualifierSet);
  1155. if( SUCCEEDED(hr) )
  1156. {
  1157. CVARIANT v;
  1158. hr = pIWbemQualifierSet->Get(L"WMIMethodId", 0, &v, 0);
  1159. if( SUCCEEDED(hr))
  1160. {
  1161. uMethodId = v.GetLONG();
  1162. }
  1163. SAFE_RELEASE_PTR(pIWbemQualifierSet);
  1164. }
  1165. return uMethodId;
  1166. }