|
|
#include "testwmi.h"
//
// The function connects to the namespace.
//
IWbemServices *ConnectToNamespace (VOID) { IWbemServices *pIWbemServices = NULL; IWbemLocator *pIWbemLocator = NULL; HRESULT hr;
//
// Create an instance of WbemLocator interface.
//
hr = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pIWbemLocator ); if ( hr == S_OK ) {
//
// Using the locator, connect to COM in the given namespace.
//
hr = pIWbemLocator->ConnectServer( DEFAULT_NAMESPACE, NULL, // current account.
NULL, // current password.
0L, // locale
0L, // securityFlags
NULL, // domain for NTLM
NULL, // context
&pIWbemServices );
if ( hr == WBEM_S_NO_ERROR) { //
// Switch the security level to IMPERSONATE so that provider(s)
// will grant access to system-level objects, and so that
// CALL authorization will be used.
//
hr = CoSetProxyBlanket( (IUnknown *)pIWbemServices, // proxy
RPC_C_AUTHN_WINNT, // authentication service
RPC_C_AUTHZ_NONE, // authorization service
NULL, // server principle name
RPC_C_AUTHN_LEVEL_CALL, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation
NULL, // identity of the client
EOAC_NONE ); // capability flags
if ( hr != S_OK ) {
pIWbemServices->Release(); pIWbemServices = NULL;
PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't impersonate, program exiting...") ); } } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't connect to root\\wmi, program exiting...") ); }
//
// Done with IWbemLocator.
//
pIWbemLocator->Release(); } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't create an instance of ") TEXT("IWbemLocator interface, programm exiting...") ); }
return pIWbemServices; }
//
// Given a class name, the function populates the combo box with all
// the instances of the class.
//
VOID EnumInstances (IWbemServices *pIWbemServices, LPTSTR lpszClass, HWND hwndInstTree) { IEnumWbemClassObject *pEnumInst; IWbemClassObject *pInst; VARIANT varInstanceName; BSTR bstrClass; LPTSTR lpszInstance; ULONG ulFound; HRESULT hr;
bstrClass = StringToBstr( lpszClass, -1 ); if ( !bstrClass ) {
PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY), __LINE__, TEXT(__FILE__), TEXT("Not enough memory to enumerate instances of %s"), lpszClass );
return; }
hr = pIWbemServices->CreateInstanceEnum( bstrClass, // Name of the root class.
WBEM_FLAG_SHALLOW | // Enumerate at current root only.
WBEM_FLAG_FORWARD_ONLY, // Forward-only enumeration.
NULL, // Context.
&pEnumInst ); // pointer to class enumerator
if ( hr == WBEM_S_NO_ERROR ) {
//
// Begin enumerating instances.
//
ulFound = 0;
hr = pEnumInst->Next( 2000, // two seconds timeout
1, // return just one instance.
&pInst, // pointer to instance.
&ulFound); // Number of instances returned.
while ( (hr == WBEM_S_NO_ERROR) && (ulFound == 1) ) {
VariantInit( &varInstanceName );
//
// Get the instance name stored in __RELPATH property.
//
hr = pInst->Get( L"__RELPATH", // property name
0L, // Reserved, must be zero.
&varInstanceName, // property value returned.
NULL, // CIM type not needed.
NULL ); // Flavor not needed.
if ( hr == WBEM_S_NO_ERROR ) {
lpszInstance = BstrToString( V_BSTR(&varInstanceName), -1 ); if ( lpszInstance ) {
InsertItem( hwndInstTree, lpszInstance );
SysFreeString( (BSTR)lpszInstance ); } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Out of memory while enumerating instaces of") TEXT(" %s, no more instances will") TEXT(" be listed."), lpszClass ); }
VariantClear( &varInstanceName ); } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't retrieve __RELPATH of an instance") TEXT(" of %s, no more instances will be listed."), lpszClass ); }
//
// Done with this instance.
//
pInst->Release();
if ( hr == WBEM_S_NO_ERROR ) {
hr = pEnumInst->Next( 2000, // two seconds timeout.
1, // return just one class.
&pInst, // pointer to returned class.
&ulFound); // Number of classes returned.
} } pEnumInst->Release();
} else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't create an instance of ") TEXT("IEnumWbemClassObject interface, instances of %s ") TEXT("will not be listed."), lpszClass ); }
SysFreeString( bstrClass );
return; }
//
// Given a class name and __RELPATH of an instance, the function lists all the
// local non-system properties in a tree list.
//
VOID EnumProperties (IWbemServices *pIWbemServices, LPTSTR lpszClass, LPTSTR lpszInstance, HWND hwndPropTree) { IWbemClassObject *pInst; SAFEARRAY *psaPropNames; BSTR bstrProperty; long lLower; long lUpper; long i; HRESULT hr; LPTSTR lpszProperty;
//
// Get a pointer to the instance.
//
pInst = GetInstanceReference( pIWbemServices, lpszClass, lpszInstance );
if ( pInst ) {
//
// psaPropNames must be null prior to making the call.
//
psaPropNames = NULL;
//
// Get all the properties.
//
hr = pInst->GetNames( NULL, // No qualifier names.
WBEM_FLAG_ALWAYS | // All non-system properties
WBEM_FLAG_LOCAL_ONLY, NULL, // No qualifier values.
&psaPropNames); // Returned property names
if ( hr == WBEM_S_NO_ERROR ) {
//
// Get the number of properties returned.
//
SafeArrayGetLBound( psaPropNames, 1, &lLower ); SafeArrayGetUBound( psaPropNames, 1, &lUpper );
//
// List all properties or stop when encountered an error.
//
for (i=lLower; (hr == WBEM_S_NO_ERROR) && (i <= lUpper); i++) {
//
// Add the property name into the list box.
//
bstrProperty = NULL;
hr = SafeArrayGetElement( psaPropNames, &i, &bstrProperty);
if ( SUCCEEDED(hr) ) {
lpszProperty = BstrToString( bstrProperty, -1 );
if ( lpszProperty ) {
InsertItem( hwndPropTree, lpszProperty );
SysFreeString( (BSTR)lpszProperty ); } else { PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY), __LINE__, TEXT(__FILE__), TEXT("Out of memory while enumerating") TEXT(" properties of %s, no more properties") TEXT(" will be listed"), lpszInstance ); }
//
// Done with the property name.
//
SysFreeString( bstrProperty ); } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't get the name of a property(%d). ") TEXT("No more properties will be listed."), i ); } }
//
// Done with the array of properties.
//
SafeArrayDestroy( psaPropNames ); } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't retrieve the properties of %s, ") TEXT("an instance of class %s. Properties will not be ") TEXT("listed."), lpszInstance, lpszClass ); }
} else { PrintError( HRESULT_FROM_WIN32(ERROR_WMI_INSTANCE_NOT_FOUND), __LINE__, TEXT(__FILE__), TEXT("Couldn't retrieve a pointer to instance %s of class %s.") TEXT("Its properties will not be listed."), lpszInstance, lpszClass ); }
return; }
//
// Given a class name and __RELPATH of an instance, the function returns a
// pointer to the instance.
//
IWbemClassObject *GetInstanceReference (IWbemServices *pIWbemServices, LPTSTR lpszClass, LPTSTR lpszInstance) { IWbemClassObject *pInst; IEnumWbemClassObject *pEnumInst; ULONG ulCount; BSTR bstrClass; BOOL bFound; HRESULT hr;
hr = 0;
bstrClass = StringToBstr( lpszClass, -1 ); if ( !bstrClass ) {
PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY), __LINE__, TEXT(__FILE__), TEXT("Not enough memory to get a pointer to %s."), lpszInstance );
return NULL; }
//
// pInst pointer must be NULL initially,
//
pInst = NULL;
//
// Get Instance Enumerator Interface.
//
pEnumInst = NULL;
hr = pIWbemServices->CreateInstanceEnum(bstrClass, WBEM_FLAG_SHALLOW | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumInst );
if ( hr == WBEM_S_NO_ERROR ) {
//
// Get a pointer to the instance.
//
// We enumerate all the instances and compare their __RELPATH with
// the specified __RELPATH. If we find a match then, that is the one
// we are looking for.
//
// The other more efficient way is to create a WQL query and execute
// it.
//
hr = WBEM_S_NO_ERROR; bFound = FALSE;
while ( (hr == WBEM_S_NO_ERROR) && (bFound == FALSE) ) {
hr = pEnumInst->Next( 2000, // two seconds timeout
1, // return just one instance.
&pInst, // pointer to instance.
&ulCount); // Number of instances returned.
if ( ulCount > 0 ) {
bFound = IsInstance( pInst, lpszInstance );
if ( bFound == FALSE ) { pInst->Release(); } } }
if ( bFound == FALSE ) pInst = NULL;
//
// Done with the instance enumerator.
//
pEnumInst->Release(); }
SysFreeString( bstrClass ); return pInst; }
//
// Given a pointer, the function returns TRUE if the pointer points to
// the instance specified by lpszInstance.
//
BOOL IsInstance (IWbemClassObject *pInst, LPTSTR lpszInstance) { VARIANT varPropVal; LPTSTR lpInstance; BOOL bRet;
bRet = GetPropertyValue( pInst, TEXT("__RELPATH"), &varPropVal, NULL );
if ( bRet == TRUE ) {
lpInstance = BstrToString( V_BSTR(&varPropVal), -1 ); if ( !lpInstance ) {
PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY), __LINE__, TEXT(__FILE__), TEXT("Not enough memory to search for an instance.") );
bRet = FALSE; } else { bRet = _tcsicmp( lpszInstance, lpInstance ) == 0;
SysFreeString( (BSTR)lpInstance ); }
VariantClear( &varPropVal ); }
return bRet; }
//
// The function returns property value and its type of a given class/instance.
//
BOOL GetPropertyValue (IWbemClassObject *pRef, LPTSTR lpszProperty, VARIANT *pvaPropertyValue, LPTSTR *lppszPropertyType) { IWbemQualifierSet *pQual; VARIANT vaQual; BSTR bstrProperty; HRESULT hr; BOOL bRet;
//
// Get the property value.
//
bstrProperty = StringToBstr( lpszProperty, -1 );
if ( !bstrProperty ) {
return FALSE;
}
bRet = FALSE;
if ( lppszPropertyType ) {
//
// Get the textual name of the property type.
//
hr = pRef->GetPropertyQualifierSet( bstrProperty, &pQual );
if ( hr == WBEM_S_NO_ERROR ) {
//
// Get the textual name of the property type.
//
hr = pQual->Get( L"CIMTYPE", 0, &vaQual, NULL );
if ( hr == WBEM_S_NO_ERROR ) { *lppszPropertyType = BstrToString( V_BSTR(&vaQual), -1 );
VariantClear( &vaQual ); }
pQual->Release(); } }
VariantInit( pvaPropertyValue );
hr = pRef->Get( bstrProperty, 0, pvaPropertyValue, NULL, NULL );
if ( hr == WBEM_S_NO_ERROR ) { bRet = TRUE; } else { if ( lppszPropertyType && *lppszPropertyType ) { SysFreeString( (BSTR)*lppszPropertyType ); } }
SysFreeString( bstrProperty ); return bRet; }
//
// Given a pointer to an instance, its property and and variant specifying
// the value for the property, the function updates the property and the
// instance.
//
HRESULT UpdatePropertyValue (IWbemServices *pIWbemServices, IWbemClassObject *pInstance, LPTSTR lpszProperty, LPVARIANT pvaNewValue) { BSTR bstrProperty; HRESULT hr;
bstrProperty = StringToBstr( lpszProperty, -1 );
if ( !bstrProperty ) {
PrintError( HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY), __LINE__, TEXT(__FILE__), TEXT("Not enough memory to update %s."), lpszProperty );
return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } hr = pInstance->Put( bstrProperty, 0, pvaNewValue, 0 );
if ( hr == WBEM_S_NO_ERROR ) { hr = pIWbemServices->PutInstance( pInstance, WBEM_FLAG_UPDATE_ONLY, NULL, NULL );
if ( hr != WBEM_S_NO_ERROR ) { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Failed to save the instance,") TEXT(" %s will not be updated."), lpszProperty ); } } else { PrintError( hr, __LINE__, TEXT(__FILE__), TEXT("Couldn't update %s."), lpszProperty ); }
SysFreeString( bstrProperty );
return hr; }
BSTR StringToBstr (LPTSTR lpSrc, int nLenSrc) { BSTR lpDest;
//
// In case of ANSI version, we need to change the ANSI string to UNICODE since
// BSTRs are essentially UNICODE strings.
//
#if !defined(UNICODE) || !defined(_UNICODE)
int nLenDest;
nLenDest = MultiByteToWideChar( CP_ACP, 0, lpSrc, nLenSrc, NULL, 0);
lpDest = SysAllocStringLen( NULL, nLenDest );
if ( lpDest ) { MultiByteToWideChar( CP_ACP, 0, lpSrc, nLenSrc, lpDest, nLenDest ); }
//
// In case of UNICODE version, we simply allocate memory and copy the string.
//
#else
if ( lpSrc == NULL ) { nLenSrc = 0; } else { if ( nLenSrc == -1 ) { nLenSrc = _tcslen( lpSrc ) + sizeof(TCHAR); } }
lpDest = SysAllocStringLen( lpSrc, nLenSrc ); #endif
return lpDest; }
//
// The function converts a BSTR string into ANSI and returns it in an allocated
// memory. The memory must be freed by the caller using SysFreeString()
// function. If nLenSrc is -1, the string is null terminated.
//
LPTSTR BstrToString (BSTR lpSrc, int nLenSrc) { LPTSTR lpDest;
//
// In case of ANSI version, we need to change BSTRs which are UNICODE strings
// into ANSI version.
//
#if !defined(UNICODE) || !defined(_UNICODE)
int nLenDest;
nLenDest = WideCharToMultiByte( CP_ACP, 0, lpSrc, nLenSrc, NULL, 0, NULL, NULL ); lpDest = (LPTSTR)SysAllocStringLen( NULL, (size_t)nLenDest );
if ( lpDest ) { WideCharToMultiByte( CP_ACP, 0, lpSrc, nLenSrc, lpDest, nLenDest, NULL, NULL ); } //
// In case of UNICODE version, we simply allocate memory and copy the BSTR
// into allocate memory and return its address.
//
#else
if ( lpSrc ) { if ( nLenSrc == -1 ) { nLenSrc = _tcslen( lpSrc ) + sizeof(TCHAR); } } else { nLenSrc = 0; }
lpDest = (LPTSTR)SysAllocStringLen( lpSrc, nLenSrc ); #endif
return lpDest; }
|