//*************************************************************************** // // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved // //*************************************************************************** #include "precomp.h" #include "wmicom.h" #include "wmimap.h" #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////// //********************************************************************************************** // THE CWbemInfoClass //********************************************************************************************** //////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////// //********************************************************************************************** // // NAME GetPropertiesInID_Order // PURPOSE Return a WCHAR string containing the class's // property names, orderd by an ID number // contained within the named property qualifier. // // WRAPPER Not a wrapper. This is a standalone filter/sort // utility function. // //********************************************************************************************** /////////////////////////////////////////////////////////////////////////////////////////////////// CWMI_IDOrder::CWMI_IDOrder(IWbemClassObject * pC, IWbemObjectAccess * pA) { m_pWMIDataIdList = NULL; InitMemberVars(); m_pClass = pC; m_pAccess = pA; } /////////////////////////////////////////////////////////////////////// CWMI_IDOrder::~CWMI_IDOrder() { // m_pClass & m_pAccess released elsewhere InitMemberVars(); } /////////////////////////////////////////////////////////////////////// void CWMI_IDOrder::InitMemberVars() { m_nTotal = 0; m_nCurrent = 0; if( m_pWMIDataIdList ) { SAFE_DELETE_ARRAY(m_pWMIDataIdList); m_pWMIDataIdList = NULL; } } /////////////////////////////////////////////////////////////////////// WCHAR * CWMI_IDOrder::GetFirstID() { m_nCurrent = -1 ; return GetNextID(); } /////////////////////////////////////////////////////////////////////// WCHAR * CWMI_IDOrder::GetNextID() { WCHAR * pChar = NULL; //=================================================================== // Go in a loop to find the next ID // Increment current first, remember, current has to stay valid at // all times //=================================================================== m_nCurrent++; //=================================================================== // If there is no property name, then we know we are done // with the properties //=================================================================== while( m_pWMIDataIdList[m_nCurrent].pwcsPropertyName ){ if( m_pWMIDataIdList[m_nCurrent].fPutProperty == FALSE ) { m_nCurrent++; } else { pChar = m_pWMIDataIdList[m_nCurrent].pwcsPropertyName; break; } }//End while loop return pChar; } /////////////////////////////////////////////////////////////////////// HRESULT CWMI_IDOrder::ProcessPropertyQualifiers ( LPCWSTR strPropName, BOOL fHiPerf, UINT uSizeArray, UINT uStartIndex ) { IWbemQualifierSet * pIWbemQualifierSet = NULL; CIMTYPE lType = 0; HRESULT hr = m_pClass->GetPropertyQualifierSet(strPropName,&pIWbemQualifierSet); if( SUCCEEDED(hr) ) { UINT nPosition = 0; CVARIANT v; hr = pIWbemQualifierSet->Get(L"WmiDataId", 0, &v, 0); if( hr == S_OK ) { nPosition = v.GetLONG(); // // it is required that WmiDataId is 1-based. provider // stores internally to 0-based array so decrement // nPosition-- ; } else { // // let's try mofcomp generated ID (methods only) as // class designers often don't use WmiDataId for // properties of __PARAMETERS // if ( WBEM_E_NOT_FOUND == hr ) { hr = pIWbemQualifierSet->Get(L"ID", 0, &v, 0); if( hr == S_OK ) { nPosition = v.GetLONG(); } } } if( SUCCEEDED(hr)) { // // now we need to find real index based on // ( ( ( id/size ) * size ) + ( id%size ) ) - startindex // UINT div = ( nPosition/uSizeArray ) ; UINT mod = ( nPosition%uSizeArray ) ; nPosition = ( ( div * uSizeArray ) + mod ) - uStartIndex ; if ( nPosition < uSizeArray ) { if ( FALSE == m_pWMIDataIdList[nPosition].bIsDirty ) { //=================================================== // Get the exact number and // copy property name into the correct array location // and get all of the attributes of the property // we will need in the future to process it. //=================================================== hr =m_pClass->Get(strPropName, 0, &v, &lType, NULL); if( SUCCEEDED(hr) ) { CVARIANT vQual; hr = pIWbemQualifierSet->Get(L"CIMType", 0, &vQual,0); if ( SUCCEEDED(hr) ) { //================================================================= // If we are accumulating hi perf info, then get the handle to // access the property instead of via property name //================================================================= if( fHiPerf ) { long lHandle = 0; if( S_OK == m_pAccess->GetPropertyHandle(strPropName, 0, &lHandle)) { m_pWMIDataIdList[nPosition].lHandle = (long)lHandle; } } //================================================================= // Now, set the rest of the property information //================================================================= m_pWMIDataIdList[nPosition].lType = (long)lType; m_pWMIDataIdList[nPosition].SetPropertyName((WCHAR*)strPropName); m_pWMIDataIdList[nPosition].fPutProperty = TRUE; CWMIDataTypeMap MapWMIData; CBSTR cbstrTmp(vQual.GetStr()); MapWMIData.GetSizeAndType ( cbstrTmp, &m_pWMIDataIdList[nPosition], m_pWMIDataIdList[nPosition].lType, m_pWMIDataIdList[nPosition].nWMISize ); // // check MAX or WmiSizeIs qualifiers // m_pWMIDataIdList[nPosition].dwArraySize = GetSizeOfArray ( strPropName ); // // set the dirty flag // m_pWMIDataIdList[nPosition].bIsDirty = TRUE ; m_nTotal++; } } } else { // // already set that position. this // means that there must be same WmiDataId used // hr = WBEM_E_INVALID_CLASS ; } } else { // // qualifier value is not contiguous // hr = WBEM_E_INVALID_CLASS ; } } else { // // only when qualifier was not found // if ( WBEM_E_NOT_FOUND == hr ) { // As some properties are ok not to have WMIDataIds, we have // to set this to OK, need to log this in the future hr = S_OK; } } } else { switch ( hr ) { case WBEM_E_SYSTEM_PROPERTY: { // // this is not really expected as GetNames called // inside of caller was supposed to ask for // non-system properties only, but keeping backward // behavior ... // hr = WBEM_S_NO_ERROR ; break ; } default : { // // populate this error back // break ; } } } SAFE_RELEASE_PTR(pIWbemQualifierSet); return hr; } /////////////////////////////////////////////////////////////////////// HRESULT CWMI_IDOrder::GetPropertiesInIDOrder ( BOOL fHiPerf, UINT uStartIndex ) { HRESULT hr = WBEM_E_FAILED; SAFEARRAY * psaNames = NULL; //====================================================== // Get Array boundaries //====================================================== hr = m_pClass->GetNames ( NULL, WBEM_FLAG_ALWAYS | WBEM_FLAG_NONSYSTEM_ONLY, NULL, &psaNames ) ; if (SUCCEEDED(hr)){ long lLower = 0, lUpper = 0; hr = SafeArrayGetLBound(psaNames,1,&lLower); if (SUCCEEDED(hr)){ hr = SafeArrayGetUBound(psaNames,1,&lUpper); if (SUCCEEDED(hr)){ //=========================================== // Get the total number of elements, so we // create the right sized array of ID structs //=========================================== UINT nSize = ( lUpper-lLower ) + 1; m_pWMIDataIdList = new IDOrder [ nSize + 1 ]; if( m_pWMIDataIdList ) { try { // // last item in array serves as stopper // memset ( m_pWMIDataIdList, NULL, ( sizeof ( IDOrder )* ( nSize + 1 ) ) ); for(long ndx = lLower; ndx <= lUpper; ndx++) { CBSTR cbstrPropName; hr = SafeArrayGetElement(psaNames, &ndx, &cbstrPropName); if (WBEM_S_NO_ERROR == hr) { hr = ProcessPropertyQualifiers ( cbstrPropName, fHiPerf, nSize, uStartIndex ) ; if( hr != WBEM_S_NO_ERROR ) { break; } } } } catch(...) { SAFE_DELETE_ARRAY(m_pWMIDataIdList); hr = WBEM_E_UNEXPECTED; throw; } } } } } if( psaNames ) { SafeArrayDestroy(psaNames); } return hr; } //////////////////////////////////////////////////////////////////////// DWORD CWMI_IDOrder::GetSizeOfArray(LPCWSTR strProp) { HRESULT hr = WBEM_E_OUT_OF_MEMORY; CAutoWChar pwcsArraySize(_MAX_PATH+2); DWORD dwCount = 0L; if( pwcsArraySize.Valid() ) { IWbemQualifierSet * pIWbemQualifierSet = NULL; hr = m_pClass->GetPropertyQualifierSet(strProp,&pIWbemQualifierSet); if( SUCCEEDED(hr) ) { CVARIANT v; BOOL bInClassObject = FALSE ; hr = pIWbemQualifierSet->Get(L"out", 0, &v, 0); if ( SUCCEEDED ( hr ) ) { if ( VT_BOOL != V_VT ( &v ) || ( VARIANT_TRUE != V_BOOL ( &v ) ) ) { bInClassObject = TRUE ; } } else { if ( WBEM_E_NOT_FOUND == hr ) { bInClassObject = TRUE ; } } if ( TRUE == bInClassObject ) { hr = pIWbemQualifierSet->Get(L"MAX", 0, &v, 0); if( SUCCEEDED(hr)) { dwCount = v.GetLONG(); } else { hr = pIWbemQualifierSet->Get(L"WMISizeIs", 0, &v, 0); if( hr == S_OK ) { CVARIANT var; CIMTYPE lTmpType=0; CWMIDataTypeMap MapWMIData; hr = m_pClass->Get(v, 0, &var, &lTmpType,NULL); if( hr == S_OK ) { dwCount = MapWMIData.ArraySize(lTmpType,var); } } } } } SAFE_RELEASE_PTR(pIWbemQualifierSet); } return dwCount; } //****************************************************************** //////////////////////////////////////////////////////////////////// // CWMIProcessClass //////////////////////////////////////////////////////////////////// //****************************************************************** // WbemClassInfo deals with all the pointers and info with one // particular wbem class // //****************************************************************** //////////////////////////////////////////////////////////////////// CWMIProcessClass::~CWMIProcessClass() { ReleaseInstancePointers(); SAFE_RELEASE_PTR(m_pAccess); SAFE_RELEASE_PTR(m_pClass ); SAFE_DELETE_ARRAY(m_pwcsClassName); SAFE_DELETE_PTR(m_pCurrentProperty); SAFE_DELETE_PTR(m_pWMI); } ///////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::Initialize() { HRESULT hr = WBEM_E_FAILED; SAFE_DELETE_PTR(m_pWMI); m_pWMI = new CWMIManagement; if( m_pWMI ) { hr = S_OK; m_fInit = TRUE; } return hr; } ///////////////////////////////////////////////////////////////////// CWMIProcessClass::CWMIProcessClass(BOOL b) { m_pWMI = NULL; m_fInit = FALSE; m_fGetNewInstance = TRUE; m_pAccessInstance = NULL; m_pClassInstance = NULL; m_pClass = NULL; m_pAccess = NULL; m_pCurrentProperty = NULL; m_pwcsClassName = NULL; m_wHardCodedGuid = 0; } ///////////////////////////////////////////////////////////////////// BOOL CWMIProcessClass::GetANewAccessInstance() { HRESULT hr = S_OK; hr = m_pAccess->SpawnInstance(0, &m_pClassInstance); m_pClassInstance->AddRef(); if( SUCCEEDED(hr) ) { hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance); } return ( hr == 0 ) ? TRUE : FALSE; } ///////////////////////////////////////////////////////////////////// BOOL CWMIProcessClass::GetANewInstance() { HRESULT hr = S_OK; if( m_fGetNewInstance ) { SAFE_RELEASE_PTR(m_pClassInstance); hr = m_pClass->SpawnInstance(0, &m_pClassInstance); if( SUCCEEDED(hr) ) { if( m_fHiPerf ) { SAFE_RELEASE_PTR(m_pAccessInstance); hr = m_pClassInstance->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccessInstance); } } } return ( hr == 0 ) ? TRUE : FALSE; } ///////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::SetKeyFromAccessPointer() { CVARIANT varName; HRESULT hr = m_pAccess->Get(L"InstanceName", 0, &varName, NULL, NULL); if( SUCCEEDED(hr)) { hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL); } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetKeyFromAccessPointer(CVARIANT * v) { return m_pAccessInstance->Get(L"InstanceName", 0, (VARIANT *)v, NULL, NULL); } ///////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::SetHiPerfProperties(LARGE_INTEGER TimeStamp) { LONG lHandle = 0; //========================================================================================================= // Timestamp_PerfTime = timestamp in PerfFreq units returned by (QueryPerformanceCounter) //========================================================================================================= HRESULT hr = m_pAccess->GetPropertyHandle(L"Frequency_PerfTime", 0, &lHandle); if(SUCCEEDED(hr)) { LARGE_INTEGER Counter; if( QueryPerformanceCounter(&Counter)) { hr = m_pAccessInstance->WriteQWORD(lHandle, Counter.QuadPart); } //===================================================================================================== // Timestamp_Sys100NS = timestamp in 100 NS units/QueryPerformanceCounter()dumbed down to 100NS //===================================================================================================== if ( SUCCEEDED( hr ) ) { hr = m_pAccess->GetPropertyHandle(L"Timestamp_Sys100NS", 0, &lHandle); if( SUCCEEDED(hr)) { LARGE_INTEGER Sys; Sys.QuadPart = Counter.QuadPart / 100; hr = m_pAccessInstance->WriteQWORD(lHandle, Sys.QuadPart); } } } //========================================================================================================= // Frequency_PerfTime = the value returned by QueryPerformanceFrequency //========================================================================================================= if ( SUCCEEDED( hr ) ) { hr = m_pAccess->GetPropertyHandle(L"Timestamp_PerfTime", 0, &lHandle); if( SUCCEEDED(hr)) { LARGE_INTEGER freq; if( QueryPerformanceFrequency (&freq)) { hr = m_pAccessInstance->WriteQWORD(lHandle, freq.QuadPart); } } } //========================================================================================================= // Timestamp_Object = (WnodeHeader)->TimeStamp //========================================================================================================= if ( SUCCEEDED( hr ) ) { hr = m_pAccess->GetPropertyHandle(L"Timestamp_Object", 0, &lHandle); if( SUCCEEDED(hr)) { hr = m_pAccessInstance->WriteQWORD(lHandle, TimeStamp.QuadPart); } } //========================================================================================================= // Frequency_Sys100NS = 10000000 // Frequency_Object = 10000000 //========================================================================================================= if ( SUCCEEDED( hr ) ) { LARGE_INTEGER Tmp; Tmp.QuadPart = 10000000; hr = m_pAccess->GetPropertyHandle(L"Frequency_Object", 0, &lHandle); if( SUCCEEDED(hr)) { hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart); } hr = m_pAccess->GetPropertyHandle(L"Frequency_Sys100NS", 0, &lHandle); if( SUCCEEDED(hr)) { hr = m_pAccessInstance->WriteQWORD(lHandle, Tmp.QuadPart); } } return hr; } ///////////////////////////////////////////////////////////////////// void CWMIProcessClass::SetActiveProperty() { CVARIANT vActive; vActive.SetBool(TRUE); if( !m_fHiPerf ) { m_pClassInstance->Put(L"Active", 0, &vActive, NULL); } } ///////////////////////////////////////////////////////////////////// void CWMIProcessClass::ReleaseInstancePointers() { SAFE_RELEASE_PTR( m_pClassInstance ); SAFE_RELEASE_PTR( m_pAccessInstance); } ///////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::SendInstanceBack() { HRESULT hr = WBEM_E_FAILED; //=============================================== // Send the object to the caller //=============================================== if( HANDLER ) { hr = HANDLER->Indicate(1,&m_pClassInstance); if( m_fGetNewInstance ) { ReleaseInstancePointers(); } } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::SetInstanceName(WCHAR * wName, BOOL fSetName) { CVARIANT varName(wName); HRESULT hr = WBEM_E_INVALID_OBJECT; if( fSetName ) { if( m_pClassInstance ) { if( !m_fHiPerf ) { hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL); } else { hr = m_pClassInstance->Put(L"InstanceName", 0, &varName, NULL); } } } else { hr = SetClassName(wName); } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetInstanceName(WCHAR *& p) { CVARIANT vValue; HRESULT hr = m_pClass->Get(L"InstanceName", 0, &vValue, NULL, NULL); if( SUCCEEDED(hr) ) { if( vValue.GetStr() ) { int nlen = wcslen(vValue.GetStr()); p = new WCHAR [nlen + 4]; if( p ) { hr = StringCchCopyW(p,nlen+4,vValue.GetStr()); } else { hr = WBEM_E_UNEXPECTED; } } } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetPropertiesInIDOrder ( BOOL fHiPerf, UINT uStartIndex ) { HRESULT hr = S_OK; //============================================ // If the pointer is NOT = to NULL, then this // means we haven't released the previous one // return FALSE, to prevent memory leaks //============================================ if( !m_pCurrentProperty ) { m_pCurrentProperty = new CWMI_IDOrder(m_pClass,m_pAccess); if( m_pCurrentProperty ) { try { hr = m_pCurrentProperty->GetPropertiesInIDOrder ( fHiPerf, uStartIndex ) ; if( hr != S_OK ) { SAFE_DELETE_PTR(m_pCurrentProperty); } } catch(...) { hr = WBEM_E_UNEXPECTED; SAFE_DELETE_PTR(m_pCurrentProperty); throw; } } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////// // NAME GetQualifierString (takes a class name) // PURPOSE Gets a qualifier value and returns it as a wide char string // WRAPPER High level // // PARAMETERS (1) [in] Pointer to an existing IWbemClassObject // (2) [in] Pointer to a Property Name string // (3) [in] Pointer to a Qualifier Name // (4) [in\out] Pointer to an external character buffer // // RETURNS Success: S_OK // Failure: non zero value /////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetQualifierString( WCHAR * ppwcsPropertyName, WCHAR * pwcsQualifierName, WCHAR * pwcsExternalOutputBuffer, int nSize ) { CVARIANT vQual; HRESULT hr = GetQualifierValue( ppwcsPropertyName, pwcsQualifierName, (CVARIANT*)&vQual); if (WBEM_S_NO_ERROR == hr) { if(vQual.GetType() != VT_BSTR) { VariantChangeType(&vQual, &vQual, 0, VT_BSTR); } int nTmp=wcslen(V_BSTR(&vQual)); if( nTmp > nSize ) { hr = WBEM_E_BUFFER_TOO_SMALL; } else { hr = StringCchCatW(pwcsExternalOutputBuffer, nSize, V_BSTR(&vQual)); } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetQualifierValue( WCHAR * ppwcsPropertyName, WCHAR * pwcsQualifierName, CVARIANT * vQual ) { IWbemClassObject * pClass = NULL; IWbemQualifierSet * pIWbemQualifierSet = NULL; HRESULT hr = WBEM_E_INVALID_PARAMETER; BOOL bDone = FALSE; if ( m_pClass ) { CBSTR cb(L"__GENUS"); CVARIANT v1; if ( SUCCEEDED ( m_pClass->Get(cb, 0, &v1, 0, 0 ) ) ) { if ( V_I4 (&v1) == 1 ) { ( pClass = m_pClass ) -> AddRef (); bDone = TRUE; } } } if ( !bDone ) { CBSTR cbstr(m_pwcsClassName); if ( WBEM_S_NO_ERROR == REPOSITORY->GetObject(cbstr, 0, CONTEXT, &pClass, NULL) ) { bDone = TRUE; } } if ( bDone ) { if(ppwcsPropertyName) { hr = pClass->GetPropertyQualifierSet(ppwcsPropertyName, &pIWbemQualifierSet); } else { hr = pClass->GetQualifierSet(&pIWbemQualifierSet); } } if ( SUCCEEDED ( hr ) && pIWbemQualifierSet ) { long lType = 0L; hr = pIWbemQualifierSet->Get(pwcsQualifierName, 0,(VARIANT *) vQual,&lType); } SAFE_RELEASE_PTR(pIWbemQualifierSet); SAFE_RELEASE_PTR(pClass); return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetPrivilegesQualifer(SAFEARRAY ** psaPrivReq) { IWbemClassObject * pClass = NULL; IWbemQualifierSet * pIWbemQualifierSet = NULL; CBSTR cbstr(m_pwcsClassName); HRESULT hr = REPOSITORY->GetObject(cbstr, 0,CONTEXT, &pClass, NULL); if(SUCCEEDED(hr)) { pClass->GetQualifierSet(&pIWbemQualifierSet); if( pIWbemQualifierSet ) { CVARIANT vQual; long lType = 0L; hr = pIWbemQualifierSet->Get(L"Privileges", 0, &vQual,&lType); if (SUCCEEDED(hr)){ VARIANT *p = (VARIANT *)vQual; SAFEARRAY * psa = V_ARRAY(p); if( !IsBadReadPtr( psaPrivReq, sizeof(SAFEARRAY))) { CSAFEARRAY Safe(psa); *psaPrivReq = OMSSafeArrayCreate(VT_BSTR,Safe.GetNumElements()); hr = SafeArrayCopy(psa,psaPrivReq ); Safe.Unbind(); // Don't need to destroy, it will be destroyed } } SAFE_RELEASE_PTR(pIWbemQualifierSet); } } SAFE_RELEASE_PTR(pClass); return hr; } /////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetGuid(void) { WCHAR pwcsGuidString[128]; HRESULT hr = S_OK; //======================================= // Initialize ptrs we will need //======================================= if( m_wHardCodedGuid ){ hr = StringCchCopyW( pwcsGuidString, 128, WMI_BINARY_MOF_GUID ); } else{ memset(pwcsGuidString,NULL,128); hr = GetQualifierString( NULL, L"guid", pwcsGuidString,128); } if(SUCCEEDED(hr)) { //=========================================================== // Set the GUID first, before we try to open the WMI // data block, if succeeds, then open WMI //=========================================================== if( !SetGuid(pwcsGuidString,m_Guid) ) { hr = WBEM_E_FAILED; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::SetClass(WCHAR * wcsClass) { HRESULT hr = WBEM_E_FAILED; if( wcsClass ) { hr = SetClassName(wcsClass); if( SUCCEEDED(hr)) { CBSTR cbstr(m_pwcsClassName); hr = m_pWMI->Repository()->GetObject(cbstr,0,CONTEXT,&m_pClass, NULL); if( hr == S_OK ) { hr = GetGuid(); // If there is no GUID for the class then set proper error message if(hr == WBEM_E_NOT_FOUND) { hr = WBEM_E_NOT_SUPPORTED; } if( SUCCEEDED(hr)) { //=========================================================== // Get the IWbemObjectAccess interface for the object // ========================================================== if( m_fHiPerf ) { hr = m_pClass->QueryInterface(IID_IWbemObjectAccess, (PVOID*)&m_pAccess); } if( SUCCEEDED(hr)) { hr = GetPropertiesInIDOrder(m_fHiPerf); } } } } } return hr; } //============================================================= //============================================================= HRESULT CWMIProcessClass::SetClassName(WCHAR * pIn ) { SAFE_DELETE_ARRAY(m_pwcsClassName); return AllocAndCopy(pIn,&m_pwcsClassName); } //============================================================= HRESULT CWMIProcessClass::SetClass ( IWbemClassObject * pPtr, UINT uStartIndex ) { HRESULT hr = WBEM_E_FAILED; if( pPtr ) { // // as this is input we must addref due to releasing in // class destructor as well as in the caller // ( m_pClass = pPtr ) -> AddRef () ; CVARIANT vName; hr = m_pClass->Get(L"__CLASS", 0, &vName, NULL, NULL); if( hr == S_OK ) { hr = SetClassName(vName.GetStr()); if( SUCCEEDED(hr)) { hr = GetPropertiesInIDOrder ( FALSE, uStartIndex ); } } } return hr; } //============================================================= HRESULT CWMIProcessClass::SetAccess(IWbemObjectAccess * pPtr) { HRESULT hr = WBEM_E_FAILED; if( pPtr ) { SAFE_RELEASE_PTR(m_pAccess); SAFE_RELEASE_PTR(m_pClass); m_pAccess = pPtr; m_pAccess->AddRef(); CVARIANT vName; hr = m_pAccess->Get(L"__CLASS", 0, &vName, NULL, NULL); if( SUCCEEDED(hr)) { hr = SetClassName(vName.GetStr()); if( hr == S_OK ) { CBSTR cbstr(m_pwcsClassName); hr = REPOSITORY->GetObject(cbstr, 0,CONTEXT, &m_pClass, NULL); if( SUCCEEDED(hr)) { hr = GetGuid(); if( SUCCEEDED(hr)) { hr = GetPropertiesInIDOrder(TRUE); } } } } } return hr; } //============================================================= HRESULT CWMIProcessClass::SetClassPointerOnly(IWbemClassObject * pPtr) { HRESULT hr = WBEM_E_FAILED; if( pPtr ) { SAFE_RELEASE_PTR(m_pClass); m_pClass = pPtr; m_pClass->AddRef(); hr = S_OK; } return hr; } //============================================================= void CWMIProcessClass::SaveEmbeddedClass(CVARIANT & v) { IDispatch * pAlterEgo = NULL; m_pClassInstance->QueryInterface(IID_IUnknown, (void**)&pAlterEgo); // VariantClear will call release() v.SetUnknown(pAlterEgo); } //============================================================= HRESULT CWMIProcessClass::ReadEmbeddedClassInstance( IUnknown * pUnknown, CVARIANT & v ) { HRESULT hr = WBEM_E_FAILED; //============================================= // Get the class //============================================= IUnknown * pUnk = NULL; if( pUnknown ) { pUnk = pUnknown; } else { pUnk = v.GetUnknown(); } IWbemClassObject * pClass = NULL; if( pUnk ) { pUnk->QueryInterface(IID_IWbemClassObject,(void**) &pClass ); if( pClass ) { //=============================================== // Get class definition, so we need to get the // class name CVARIANT vName; CAutoWChar wcsClassName(_MAX_PATH+2); if( wcsClassName.Valid() ) { hr = pClass->Get(L"__CLASS", 0, &vName, NULL, NULL); if( hr == S_OK ) { if ( SUCCEEDED ( hr = StringCchCopyW( wcsClassName, _MAX_PATH+2, vName.GetStr() ) ) ) { hr = SetClass(wcsClassName); if( S_OK == hr ) { hr = SetClassPointerOnly(pClass); } } } } else { hr = WBEM_E_OUT_OF_MEMORY; } } } SAFE_RELEASE_PTR( pClass ); return hr; } //======================================================================= int CWMIProcessClass::PropertyCategory() { if (!(m_pCurrentProperty->PropertyType() & CIM_FLAG_ARRAY) ) { if( m_pCurrentProperty->PropertyType() == VT_UNKNOWN ) { return CWMIProcessClass::EmbeddedClass; } else { return CWMIProcessClass::Data; } } else { return CWMIProcessClass::Array; } } /////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::InitializeEmbeddedClass(CWMIProcessClass * p) { SetWMIPointers(p); return SetClass(p->EmbeddedClassName()); } //======================================================================= HRESULT CWMIProcessClass::GetLargestDataTypeInClass(int & nSize) { HRESULT hr = WBEM_E_FAILED; WCHAR * pwcsProperty; BOOL fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = FALSE; int nNewSize = 0L; nSize = 0L; //========================================================= // Get size of largest data type within the class and // align it on that, however, if the class contains an // embedded class ONLY, then get the size of the largest // datatype within that embedded class. //========================================================= pwcsProperty = FirstProperty(); while (NULL != pwcsProperty) { switch( PropertyCategory()) { case CWMIProcessClass::EmbeddedClass: { if( !fClassContainsAnotherDataTypeBesidesAnEmbeddedClass ){ CWMIProcessClass EmbeddedClass(0); hr = EmbeddedClass.Initialize(); if( S_OK == hr ) { hr = EmbeddedClass.InitializeEmbeddedClass(this); if( hr != S_OK ){ break; } // embedded object hr = EmbeddedClass.GetLargestDataTypeInClass(nNewSize); if( hr != S_OK ){ break; } } } } break; case CWMIProcessClass::Array: case CWMIProcessClass::Data: fClassContainsAnotherDataTypeBesidesAnEmbeddedClass = TRUE; nNewSize = PropertySize(); break; } if( nNewSize == SIZEOFWBEMDATETIME ){ nNewSize = 1; } if( nNewSize > nSize ){ nSize = nNewSize; } pwcsProperty = NextProperty(); hr = WBEM_S_NO_ERROR; } return hr; } //////////////////////////////////////////////////////////////////// HRESULT CWMIProcessClass::GetSizeOfArray(long & lType, DWORD & dwCount, BOOL & fDynamic) { HRESULT hr = WBEM_E_OUT_OF_MEMORY; CAutoWChar pwcsArraySize(_MAX_PATH+2); if( pwcsArraySize.Valid() ) { dwCount = 0; lType = m_pCurrentProperty->PropertyType() &~ CIM_FLAG_ARRAY; pwcsArraySize[0]=NULL; //====================================================== // Get the number of elements in the array from the // "ArraySize" property qualifier //====================================================== hr = GetQualifierString(m_pCurrentProperty->PropertyName(), L"MAX",pwcsArraySize, MAX_PATH); if( hr == S_OK ) { dwCount = _wtol(pwcsArraySize); } else { hr = GetQualifierString(m_pCurrentProperty->PropertyName(),L"WMISizeIs",pwcsArraySize,MAX_PATH); if( hr == S_OK ) { CVARIANT var; CIMTYPE lTmpType; hr = WBEM_E_FAILED; fDynamic = TRUE; if( m_pClassInstance ) { hr = m_pClassInstance->Get(pwcsArraySize, 0, &var, &lTmpType,NULL); } else { if( m_pClass ) { hr = m_pClass->Get(pwcsArraySize, 0, &var, &lTmpType,NULL); } } if( hr == S_OK ) { CWMIDataTypeMap MapIt; dwCount = MapIt.ArraySize(lTmpType,var); } } } //============================================================================== // If all else fails, get the size of the array from the class definition. //============================================================================== if( hr != S_OK ) { dwCount = m_pCurrentProperty->ArraySize(); hr = S_OK; } } return hr; } //====================================================================== HRESULT CWMIProcessClass::GetSizeOfClass(DWORD & dwSize) { HRESULT hr = WBEM_E_FAILED; WCHAR * pwcsProperty; dwSize = 0; pwcsProperty = FirstProperty(); while (NULL != pwcsProperty) { switch( PropertyCategory()) { case CWMIProcessClass::EmbeddedClass: { DWORD dwEmbeddedSize; CWMIProcessClass EmbeddedClass(0); hr = EmbeddedClass.Initialize(); if( S_OK == hr ) { hr = EmbeddedClass.InitializeEmbeddedClass(this); if( hr != S_OK ){ break; } // embedded object hr = EmbeddedClass.GetSizeOfClass(dwEmbeddedSize); if( hr != S_OK ){ break; } dwSize += dwEmbeddedSize; } } break; case CWMIProcessClass::Array: { int nSize = PropertySize(); dwSize += (nSize * ArraySize()); } break; case CWMIProcessClass::Data: dwSize += PropertySize(); break; } pwcsProperty = NextProperty(); hr = WBEM_S_NO_ERROR; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ULONG CWMIProcessClass::GetMethodId(LPCWSTR strProp) { ULONG uMethodId = 0; IWbemQualifierSet * pIWbemQualifierSet = NULL; //====================================================== // Get the number of elements in the array from the // "ArraySize" property qualifier //====================================================== HRESULT hr = m_pClass->GetMethodQualifierSet(strProp,&pIWbemQualifierSet); if( SUCCEEDED(hr) ) { CVARIANT v; hr = pIWbemQualifierSet->Get(L"WMIMethodId", 0, &v, 0); if( SUCCEEDED(hr)) { uMethodId = v.GetLONG(); } SAFE_RELEASE_PTR(pIWbemQualifierSet); } return uMethodId; }