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.

1174 lines
35 KiB

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