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.
2688 lines
74 KiB
2688 lines
74 KiB
/*********************************************************************************************
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
WMI.cpp
|
|
|
|
Abstract:
|
|
|
|
Common functionlity for dealing with WMI.
|
|
|
|
Author:
|
|
|
|
Wipro Technologies
|
|
|
|
Revision History:
|
|
|
|
22-Dec-2000 : Created It.
|
|
24-Apr-2001 : Closing the review comments given by client.
|
|
|
|
*********************************************************************************************/
|
|
|
|
#include "pch.h"
|
|
#include "wmi.h"
|
|
#include "resource.h"
|
|
|
|
//
|
|
// messages
|
|
//
|
|
#define INPUT_PASSWORD GetResString( IDS_STR_INPUT_PASSWORD )
|
|
#define INPUT_PASSWORD_LEN 256
|
|
// error constants
|
|
#define E_SERVER_NOTFOUND 0x800706ba
|
|
|
|
//
|
|
// private function prototype(s)
|
|
//
|
|
BOOL IsValidUserEx( LPCWSTR pwszUser );
|
|
HRESULT GetSecurityArguments( IUnknown* pInterface,
|
|
DWORD& dwAuthorization, DWORD& dwAuthentication );
|
|
HRESULT SetInterfaceSecurity( IUnknown* pInterface,
|
|
LPCWSTR pwszUser,
|
|
LPCWSTR pwszPassword, COAUTHIDENTITY** ppAuthIdentity );
|
|
HRESULT WINAPI SetProxyBlanket( IUnknown* pInterface,
|
|
DWORD dwAuthnSvc, DWORD dwAuthzSvc,
|
|
LPWSTR pwszPrincipal, DWORD dwAuthLevel, DWORD dwImpLevel,
|
|
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
|
|
HRESULT WINAPI WbemAllocAuthIdentity( LPCWSTR pwszUser, LPCWSTR pwszPassword,
|
|
LPCWSTR pwszDomain, COAUTHIDENTITY** ppAuthIdent );
|
|
HRESULT RegQueryValueWMI( IWbemServices* pWbemServices,
|
|
LPCWSTR pwszMethod, DWORD dwHDefKey,
|
|
LPCWSTR pwszSubKeyName, LPCWSTR pwszValueName, _variant_t& varValue );
|
|
|
|
|
|
BOOL
|
|
IsValidUserEx(
|
|
LPCWSTR pwszUser
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks wether the User name is a valid one or not
|
|
|
|
Arguments:
|
|
|
|
[in] LPCWSTR : String containing the user name
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
CHString strUser;
|
|
LONG lPos = 0;
|
|
|
|
if ( ( NULL == pwszUser ) || ( 0 == StringLength( pwszUser, 0 ) ) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// get user into local memory
|
|
strUser = pwszUser;
|
|
|
|
// user name should not be just '\'
|
|
if ( strUser.CompareNoCase( L"\\" ) == 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// user name should not contain invalid characters
|
|
if ( strUser.FindOneOf( L"/[]:|<>+=;,?*" ) != -1 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// SPECIAL CHECK
|
|
// check for multiple '\' characters in the user name
|
|
lPos = strUser.Find( L'\\' );
|
|
if ( -1 != lPos )
|
|
{
|
|
// '\' character exists in the user name
|
|
// strip off the user info upto first '\' character
|
|
// check for one more '\' in the remaining string
|
|
// if it exists, invalid user
|
|
strUser = strUser.Mid( lPos + 1 );
|
|
lPos = strUser.Find( L'\\' );
|
|
if ( -1 != lPos )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// user name is valid
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
IsValidServerEx(
|
|
LPCWSTR pwszServer,
|
|
BOOL& bLocalSystem
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks wether the Server name is a valid one or not
|
|
|
|
Arguments:
|
|
|
|
[in] LPCWSTR : String containing the user name
|
|
[out] BOOL : Is set to TRUE if the local system is being queried.
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
CHString strTemp;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pwszServer ) || ( 0 == StringLength( pwszServer, 0 ) ) )
|
|
{
|
|
bLocalSystem = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// kick-off
|
|
bLocalSystem = FALSE;
|
|
|
|
if( IsNumeric( pwszServer, 10, FALSE ) == TRUE )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// get a local copy
|
|
strTemp = pwszServer;
|
|
|
|
// remove the forward slashes (UNC) if exist in the begining of the server name
|
|
if ( IsUNCFormat( strTemp ) == TRUE )
|
|
{
|
|
strTemp = strTemp.Mid( 2 );
|
|
if ( strTemp.GetLength() == 0 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ( strTemp.FindOneOf( L"`~!@#$^&*()+=[]{}|\\<>,?/\"':;" ) != -1 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// now check if any '\' character appears in the server name. If so error
|
|
if ( strTemp.Find( L'\\' ) != -1 )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// now check if server name is '.' only which represent local system in WMI
|
|
// else determine whether this is a local system or not
|
|
if ( strTemp.CompareNoCase( L"." ) == 0 )
|
|
{
|
|
bLocalSystem = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bLocalSystem = IsLocalSystem( strTemp );
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// inform that server name is valid
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InitializeCom(
|
|
IWbemLocator** ppLocator
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Initializes the COM library
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemLocator : pointer to the IWbemLocator
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
BOOL bResult = FALSE;
|
|
|
|
// clear the error
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
try
|
|
{
|
|
// Validate input arguments.
|
|
if( ( NULL == ppLocator ) ||
|
|
( NULL != *ppLocator ) )
|
|
{
|
|
_com_issue_error( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
// initialize the COM library
|
|
SAFE_EXECUTE( CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) );
|
|
|
|
// initialize the security
|
|
SAFE_EXECUTE( CoInitializeSecurity( NULL, -1, NULL, NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0 ) );
|
|
|
|
// create the locator and get the pointer to the interface of IWbemLocator
|
|
SAFE_EXECUTE( CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator, ( LPVOID* ) ppLocator ) );
|
|
|
|
// initialization successful
|
|
bResult = TRUE;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
// save the WMI error
|
|
WMISaveError( e );
|
|
// Error is returned. Release any interface pointers.
|
|
SAFE_RELEASE( *ppLocator );
|
|
}
|
|
|
|
// return the result;
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ConnectWmi(
|
|
IWbemLocator* pLocator,
|
|
IWbemServices** ppServices,
|
|
LPCWSTR pwszServer,
|
|
LPCWSTR pwszUser,
|
|
LPCWSTR pwszPassword,
|
|
COAUTHIDENTITY** ppAuthIdentity,
|
|
BOOL bCheckWithNullPwd,
|
|
LPCWSTR pwszNamespace,
|
|
HRESULT* phr,
|
|
BOOL* pbLocalSystem,
|
|
IWbemContext* pWbemContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function makes a connection to WMI.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemLocator : pointer to the IWbemLocator
|
|
[in] IWbemServices : pointer to the IWbemServices
|
|
[in] LPCWSTR : string containing the server name
|
|
[in] LPCWSTR : string containing the User name
|
|
[in] LPCWSTR : string containing the password
|
|
[in] COAUTHIDENTITY : pointer to AUTHIDENTITY structure
|
|
[in] BOOL : set to TRUE if we should try to connect with
|
|
current credentials
|
|
[in] LPCWSTR : string containing the namespace to connect to
|
|
[out] HRESULT : the hResult value returned
|
|
[out] BOOL : set to TRUE if we are querying for the local system
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
BOOL bResult = FALSE;
|
|
BOOL bLocalSystem = FALSE;
|
|
_bstr_t bstrServer;
|
|
_bstr_t bstrNamespace;
|
|
_bstr_t bstrUser, bstrPassword;
|
|
|
|
// clear the error
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// check whether locator object exists or not
|
|
// if not exists, return
|
|
if ( ( NULL == pLocator ) ||
|
|
( NULL == ppServices ) ||
|
|
( NULL != *ppServices ) ||
|
|
( NULL == pwszNamespace ) )
|
|
{
|
|
if ( NULL != phr )
|
|
{
|
|
*phr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
// return failure
|
|
return FALSE;
|
|
}
|
|
|
|
// kick-off
|
|
if ( NULL != pbLocalSystem )
|
|
{
|
|
*pbLocalSystem = FALSE;
|
|
}
|
|
|
|
// ...
|
|
if ( NULL != phr )
|
|
{
|
|
*phr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
try
|
|
{
|
|
|
|
// assume that connection to WMI namespace is failed
|
|
bResult = FALSE;
|
|
|
|
// validate the server name
|
|
// NOTE: The error being raised in custom define for '0x800706ba' value
|
|
// The message that will be displayed in "The RPC server is unavailable."
|
|
if ( IsValidServerEx( pwszServer, bLocalSystem ) == FALSE )
|
|
{
|
|
_com_issue_error( E_SERVER_NOTFOUND );
|
|
}
|
|
|
|
// validate the user name
|
|
if ( IsValidUserEx( pwszUser ) == FALSE )
|
|
{
|
|
_com_issue_error( ERROR_NO_SUCH_USER );
|
|
}
|
|
|
|
// prepare namespace
|
|
bstrNamespace = pwszNamespace; // name space
|
|
if ( ( NULL != pwszServer ) && ( FALSE == bLocalSystem ) )
|
|
{
|
|
// get the server name
|
|
bstrServer = pwszServer;
|
|
|
|
// prepare the namespace
|
|
// NOTE: check for the UNC naming format of the server and do
|
|
if ( IsUNCFormat( pwszServer ) == TRUE )
|
|
{
|
|
bstrNamespace = bstrServer + L"\\" + pwszNamespace;
|
|
}
|
|
else
|
|
{
|
|
bstrNamespace = L"\\\\" + bstrServer + L"\\" + pwszNamespace;
|
|
}
|
|
|
|
// user credentials
|
|
if ( ( NULL != pwszUser ) && ( 0 != StringLength( pwszUser, 0 ) ) )
|
|
{
|
|
// copy the user name
|
|
bstrUser = pwszUser;
|
|
|
|
// if password is empty string and if we need to check with
|
|
// null password, then do not set the password and try
|
|
bstrPassword = pwszPassword;
|
|
if ( ( TRUE == bCheckWithNullPwd ) && ( 0 == bstrPassword.length() ) )
|
|
{
|
|
bstrPassword = (LPWSTR) NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ // Display warning message, credentials not required for local system.
|
|
if( ( TRUE == bLocalSystem ) && ( NULL != pwszUser ) &&
|
|
( 0 != StringLength( pwszUser, 0 ) ) )
|
|
{
|
|
// got the credentials for the local system
|
|
if ( NULL != phr )
|
|
{
|
|
*phr = WBEM_E_LOCAL_CREDENTIALS;
|
|
}
|
|
}
|
|
}
|
|
|
|
// connect to the remote system's WMI
|
|
// there is a twist here ...
|
|
// do not trap the ConnectServer function failure into exception
|
|
// instead handle that action manually
|
|
// by default try the ConnectServer function as the information which we have
|
|
// in our hands at this point. If the ConnectServer is failed,
|
|
// check whether password variable has any contents are not ... if no contents
|
|
// check with "" (empty) password ... this might pass in this situation ..
|
|
// if this call is also failed ... nothing is there that we can do ... throw the exception
|
|
hr = pLocator->ConnectServer( bstrNamespace,
|
|
bstrUser, bstrPassword, 0L, 0L, NULL, pWbemContext, ppServices );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
//
|
|
// special case ...
|
|
|
|
// check whether password exists or not
|
|
// NOTE: do not check for 'WBEM_E_ACCESS_DENIED'
|
|
// this error code says that user with the current credentials is not
|
|
// having access permisions to the 'namespace'
|
|
if ( hr == E_ACCESSDENIED )
|
|
{
|
|
// check if we tried to connect to the system using null password
|
|
// if so, then try connecting to the remote system with empty string
|
|
if ( bCheckWithNullPwd == TRUE &&
|
|
bstrUser.length() != 0 && bstrPassword.length() == 0 )
|
|
{
|
|
// now invoke with ...
|
|
hr = pLocator->ConnectServer( bstrNamespace,
|
|
bstrUser, _bstr_t( L"" ), 0L, 0L, NULL, pWbemContext, ppServices );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( WBEM_E_LOCAL_CREDENTIALS == hr )
|
|
{
|
|
// credentials were passed to the local system.
|
|
// So ignore the credentials and try to reconnect
|
|
bLocalSystem = TRUE;
|
|
bstrUser = (LPWSTR) NULL;
|
|
bstrPassword = (LPWSTR) NULL;
|
|
bstrNamespace = pwszNamespace; // name space
|
|
hr = pLocator->ConnectServer( bstrNamespace,
|
|
NULL, NULL, 0L, 0L, NULL, pWbemContext, ppServices );
|
|
}
|
|
}
|
|
|
|
// now check the result again .. if failed .. ummmm..
|
|
if ( FAILED( hr ) )
|
|
{
|
|
_com_issue_error( hr );
|
|
}
|
|
else
|
|
{
|
|
bstrPassword = L"";
|
|
}
|
|
}
|
|
|
|
// set the security at the interface level also
|
|
SAFE_EXECUTE( SetInterfaceSecurity( *ppServices,
|
|
bstrUser, bstrPassword, ppAuthIdentity ) );
|
|
|
|
// ...
|
|
if ( NULL != pbLocalSystem )
|
|
{
|
|
*pbLocalSystem = bLocalSystem;
|
|
}
|
|
|
|
// connection to WMI is successful
|
|
bResult = TRUE;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
// save the error
|
|
WMISaveError( e );
|
|
|
|
// save the hr value if needed by the caller
|
|
if ( NULL != phr )
|
|
{
|
|
*phr = e.Error();
|
|
}
|
|
SAFE_RELEASE( *ppServices );
|
|
bResult = FALSE;
|
|
}
|
|
|
|
// return the result
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ConnectWmiEx(
|
|
IWbemLocator* pLocator,
|
|
IWbemServices** ppServices,
|
|
LPCWSTR pwszServer,
|
|
CHString& strUserName,
|
|
CHString& strPassword,
|
|
COAUTHIDENTITY** ppAuthIdentity,
|
|
BOOL bNeedPassword,
|
|
LPCWSTR pwszNamespace,
|
|
BOOL* pbLocalSystem,
|
|
DWORD dwPasswordLen,
|
|
IWbemContext* pWbemContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function is a wrapper function for the ConnectWmi function.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemLocator : pointer to the IWbemLocator
|
|
[in] IWbemServices : pointer to the IWbemServices
|
|
[in] LPCWSTR : string containing the server name
|
|
[in] LPCWSTR : string containing the User name
|
|
[in] LPCWSTR : string containing the password
|
|
[in] COAUTHIDENTITY : pointer to AUTHIDENTITY structure
|
|
[in] BOOL : set to TRUE if we should try to connect with
|
|
current credentials
|
|
[in] LPCWSTR : string containing the namespace to connect to
|
|
[out] HRESULT : the hResult value returned
|
|
[out] BOOL : set to TRUE if we are querying for the local system
|
|
[ in ] DWORD : Contains maximum password buffer length.
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: 'dwPasswordLen' WILL BE TAKEN AS 'MAX_STRING_LENGTH' IF NOT SPECIFIED.
|
|
IT IS USER RESPOSIBILITY TO SET THIS PARAMETER TO LIMITING VALUE.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSize = 0;
|
|
BOOL bResult = FALSE;
|
|
LPWSTR pwszPassword = NULL;
|
|
CHString strBuffer;
|
|
|
|
// clear the error .. if any
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
try
|
|
{
|
|
// sometime users want the utility to prompt for the password
|
|
// check what user wants the utility to do
|
|
if ( ( TRUE == bNeedPassword ) &&
|
|
( 0 == strPassword.Compare( L"*" ) ) )
|
|
{
|
|
// user wants the utility to prompt for the password
|
|
// so skip this part and let the flow directly jump the password acceptance part
|
|
}
|
|
else
|
|
{
|
|
// try to establish connection to the remote system with the credentials supplied
|
|
if ( 0 == strUserName.GetLength() )
|
|
{
|
|
// user name is empty
|
|
// so, it is obvious that password will also be empty
|
|
// even if password is specified, we have to ignore that
|
|
bResult = ConnectWmi( pLocator, ppServices,
|
|
pwszServer, NULL, NULL, ppAuthIdentity, FALSE, pwszNamespace, &hr, pbLocalSystem, pWbemContext );
|
|
}
|
|
else
|
|
{
|
|
// credentials were supplied
|
|
// but password might not be specified ... so check and act accordingly
|
|
LPCWSTR pwszTemp = NULL;
|
|
BOOL bCheckWithNull = TRUE;
|
|
if ( bNeedPassword == FALSE )
|
|
{
|
|
pwszTemp = strPassword;
|
|
bCheckWithNull = FALSE;
|
|
}
|
|
|
|
// ...
|
|
bResult = ConnectWmi( pLocator, ppServices, pwszServer,
|
|
strUserName, pwszTemp, ppAuthIdentity, bCheckWithNull, pwszNamespace, &hr, pbLocalSystem, pWbemContext );
|
|
}
|
|
|
|
SetLastError( hr );
|
|
// check the result ... if successful in establishing connection ... return
|
|
if ( TRUE == bResult )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// now check the kind of error occurred
|
|
switch( hr )
|
|
{
|
|
case E_ACCESSDENIED:
|
|
SetLastError( hr );
|
|
break;
|
|
|
|
case WBEM_E_LOCAL_CREDENTIALS:
|
|
SetLastError( hr );
|
|
// needs to do special processing
|
|
break;
|
|
|
|
case WBEM_E_ACCESS_DENIED:
|
|
default:
|
|
// NOTE: do not check for 'WBEM_E_ACCESS_DENIED'
|
|
// this error code says that user with the current credentials is not
|
|
// having access permisions to the 'namespace'
|
|
WMISaveError( hr );
|
|
return FALSE; // no use of accepting the password .. return failure
|
|
break;
|
|
}
|
|
|
|
// if failed in establishing connection to the remote terminal
|
|
// even if the password is specifed, then there is nothing to do ... simply return failure
|
|
if ( bNeedPassword == FALSE )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// check whether user name is specified or not
|
|
// if not, get the local system's current user name under whose credentials, the process
|
|
// is running
|
|
if ( 0 == strUserName.GetLength() )
|
|
{
|
|
// sub-local variables
|
|
LPWSTR pwszUserName = NULL;
|
|
DWORD dwUserLength = 0; // Username buffer length.
|
|
// Retrieve the buffer length need to store username.
|
|
GetUserNameEx( NameSamCompatible, pwszUserName, &dwUserLength );
|
|
|
|
// get the required buffer
|
|
pwszUserName = strUserName.GetBufferSetLength( dwUserLength );
|
|
|
|
if ( FALSE == GetUserNameEx( NameSamCompatible, pwszUserName, &dwUserLength ) )
|
|
{
|
|
// error occured while trying to get the current user info
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
// No need to call 'ReleaseBuffer' since only sufficient memory is allocated.
|
|
}
|
|
|
|
// get the required buffer
|
|
if( 0 == dwPasswordLen )
|
|
{
|
|
dwPasswordLen = INPUT_PASSWORD_LEN;
|
|
}
|
|
pwszPassword = strPassword.GetBufferSetLength( dwPasswordLen );
|
|
|
|
// accept the password from the user
|
|
strBuffer.Format( INPUT_PASSWORD, strUserName );
|
|
WriteConsoleW( GetStdHandle( STD_OUTPUT_HANDLE ),
|
|
strBuffer, strBuffer.GetLength(), &dwSize, NULL );
|
|
|
|
bResult = GetPassword( pwszPassword, dwPasswordLen );
|
|
if ( TRUE != bResult )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// release the buffer allocated for password
|
|
strPassword.ReleaseBuffer();
|
|
|
|
// now again try to establish the connection using the currently
|
|
// supplied credentials
|
|
bResult = ConnectWmi( pLocator, ppServices, pwszServer,
|
|
strUserName, strPassword, ppAuthIdentity, FALSE, pwszNamespace,
|
|
NULL, pbLocalSystem, pWbemContext );
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// return the failure
|
|
return bResult;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
GetSecurityArguments(
|
|
IUnknown* pInterface,
|
|
DWORD& dwAuthorization,
|
|
DWORD& dwAuthentication
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function gets the values for the security services.
|
|
|
|
Arguments:
|
|
|
|
[in] IUnknown : pointer to the IUnkown interface
|
|
[out] DWORD : to hold the authentication service value
|
|
[out] DWORD : to hold the authorization service value
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
DWORD dwAuthnSvc = 0, dwAuthzSvc = 0;
|
|
IClientSecurity* pClientSecurity = NULL;
|
|
|
|
if ( NULL == pInterface )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
// try to get the client security services values if possible
|
|
hr = pInterface->QueryInterface( IID_IClientSecurity, (void**) &pClientSecurity );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
// got the client security interface
|
|
// now try to get the security services values
|
|
hr = pClientSecurity->QueryBlanket( pInterface,
|
|
&dwAuthnSvc, &dwAuthzSvc, NULL, NULL, NULL, NULL, NULL );
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
// we've got the values from the interface
|
|
dwAuthentication = dwAuthnSvc;
|
|
dwAuthorization = dwAuthzSvc;
|
|
}
|
|
|
|
// release the client security interface
|
|
SAFE_RELEASE( pClientSecurity );
|
|
}
|
|
|
|
// return always success
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
SetInterfaceSecurity(
|
|
IUnknown* pInterface,
|
|
LPCWSTR pwszUser,
|
|
LPCWSTR pwszPassword,
|
|
COAUTHIDENTITY** ppAuthIdentity
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sets the interface security parameters.
|
|
|
|
Arguments:
|
|
|
|
[in] IUnknown : pointer to the IUnkown interface
|
|
[in] LPCWSTR : string containing the User name
|
|
[in] LPCWSTR : string containing the password
|
|
[in] COAUTHIDENTITY : pointer to AUTHIDENTITY structure
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
CHString strUser;
|
|
CHString strDomain;
|
|
LPCWSTR pwszUserArg = NULL;
|
|
LPCWSTR pwszDomainArg = NULL;
|
|
DWORD dwAuthorization = RPC_C_AUTHZ_NONE;
|
|
DWORD dwAuthentication = RPC_C_AUTHN_WINNT;
|
|
|
|
try
|
|
{
|
|
// check the interface
|
|
if ( NULL == pInterface )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// check the authentity strcuture ... if authentity structure is already ready
|
|
// simply invoke the 2nd version of SetInterfaceSecurity
|
|
if ( NULL != *ppAuthIdentity )
|
|
{
|
|
return SetInterfaceSecurity( pInterface, *ppAuthIdentity );
|
|
}
|
|
|
|
// If we are doing trivial case, just pass in a null authenication structure
|
|
// for which the current logged in user's credentials will be considered
|
|
if ( ( NULL == pwszUser ) &&
|
|
( NULL == pwszPassword ) )
|
|
{
|
|
// set the security
|
|
hr = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization,
|
|
NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
|
|
|
|
// return the result
|
|
return hr;
|
|
}
|
|
|
|
// if authority srtucture is NULL then no need to proceed
|
|
if ( NULL == ppAuthIdentity )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// check if authenication info is available or not ...
|
|
// initialize the security authenication information ... UNICODE VERSION STRUCTURE
|
|
if ( NULL == *ppAuthIdentity )
|
|
{
|
|
// parse and find out if the user name contains the domain name
|
|
// if contains, extract the domain value from it
|
|
LONG lPos = -1;
|
|
strDomain = L"";
|
|
strUser = pwszUser;
|
|
if ( -1 != ( lPos = strUser.Find( L'\\' ) ) )
|
|
{
|
|
// user name contains domain name ... domain\user format
|
|
strDomain = strUser.Left( lPos );
|
|
strUser = strUser.Mid( lPos + 1 );
|
|
}
|
|
else
|
|
{
|
|
if ( -1 != ( lPos = strUser.Find( L'@' ) ) )
|
|
{
|
|
// NEED TO IMPLEMENT THIS ... IF NEEDED
|
|
// This implementation needs to be done if WMI does not support
|
|
// UPN name formats directly and if we have to split the
|
|
// name(user@domain)
|
|
}
|
|
else
|
|
{
|
|
// server itself is the domain
|
|
// NOTE: NEED TO DO SOME R & D ON BELOW COMMENTED LINE
|
|
// strDomain = pwszServer;
|
|
}
|
|
}
|
|
|
|
// get the domain info if it exists only
|
|
if ( 0 != strDomain.GetLength() )
|
|
{
|
|
pwszDomainArg = strDomain;
|
|
}
|
|
|
|
// get the user info if it exists only
|
|
if ( 0 != strUser.GetLength() )
|
|
{
|
|
pwszUserArg = strUser;
|
|
}
|
|
|
|
hr = WbemAllocAuthIdentity( pwszUserArg, pwszPassword, pwszDomainArg, ppAuthIdentity );
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
// set the security information to the interface
|
|
hr = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization, NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, *ppAuthIdentity, EOAC_NONE );
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// return the result
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
SetInterfaceSecurity(
|
|
IUnknown* pInterface,
|
|
COAUTHIDENTITY* pAuthIdentity
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sets the interface security parameters.
|
|
|
|
Arguments:
|
|
|
|
[in] IUnknown : pointer to the IUnkown interface
|
|
[in] COAUTHIDENTITY : pointer to AUTHIDENTITY structure
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
DWORD dwAuthorization = RPC_C_AUTHZ_NONE;
|
|
DWORD dwAuthentication = RPC_C_AUTHN_WINNT;
|
|
|
|
// check the interface
|
|
// 'pAuthIdentity' can be NULL or not, so need to check.
|
|
if ( NULL == pInterface )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// get the current security argument value
|
|
hr = GetSecurityArguments( pInterface, dwAuthorization, dwAuthentication );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// set the security information to the interface
|
|
hr = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization, NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, pAuthIdentity, EOAC_NONE );
|
|
|
|
// return the result
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
WINAPI SetProxyBlanket(
|
|
IUnknown* pInterface,
|
|
DWORD dwAuthnSvc,
|
|
DWORD dwAuthzSvc,
|
|
LPWSTR pwszPrincipal,
|
|
DWORD dwAuthLevel,
|
|
DWORD dwImpLevel,
|
|
RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
|
|
DWORD dwCapabilities
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function sets the authentication information (the security blanket)
|
|
that will be used to make calls.
|
|
|
|
Arguments:
|
|
|
|
[in] IUnknown : pointer to the IUnkown interface
|
|
[in] DWORD : contains the authentication service to use
|
|
[in] DWORD : contains the authorization service to use
|
|
[in] LPWSTR : the server principal name to use
|
|
[in] DWORD : contains the authentication level to use
|
|
[in] DWORD : contains the impersonation level to use
|
|
[in] RPC_AUTH_IDENTITY_HANDLE : pointer to the identity of the client
|
|
[in] DWORD : contains the capability flags
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
IUnknown * pUnknown = NULL;
|
|
IClientSecurity * pClientSecurity = NULL;
|
|
|
|
// Validate input arguments.
|
|
//
|
|
// Can't set pAuthInfo if cloaking requested, as cloaking implies
|
|
// that the current proxy identity in the impersonated thread (rather
|
|
// than the credentials supplied explicitly by the RPC_AUTH_IDENTITY_HANDLE)
|
|
// is to be used.
|
|
// See MSDN info on CoSetProxyBlanket for more details.
|
|
//
|
|
if( ( NULL == pInterface ) ||
|
|
( ( dwCapabilities & (EOAC_STATIC_CLOAKING | EOAC_DYNAMIC_CLOAKING) ) &&
|
|
( NULL != pAuthInfo ) )
|
|
)
|
|
{
|
|
return( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
// get the IUnknown interface ... to check whether this is a valid interface or not
|
|
hr = pInterface->QueryInterface( IID_IUnknown, (void **) &pUnknown );
|
|
if ( FAILED(hr) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// now get the client security interface
|
|
hr = pInterface->QueryInterface( IID_IClientSecurity, (void **) &pClientSecurity );
|
|
if ( FAILED(hr) )
|
|
{
|
|
SAFE_RELEASE( pUnknown );
|
|
return hr;
|
|
}
|
|
|
|
// now set the security
|
|
hr = pClientSecurity->SetBlanket( pInterface, dwAuthnSvc, dwAuthzSvc, pwszPrincipal,
|
|
dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities );
|
|
if( FAILED( hr ) )
|
|
{
|
|
SAFE_RELEASE( pUnknown );
|
|
SAFE_RELEASE( pClientSecurity );
|
|
return hr;
|
|
}
|
|
|
|
// release the security interface
|
|
SAFE_RELEASE( pClientSecurity );
|
|
|
|
// we should check the auth identity structure. if exists .. set for IUnknown also
|
|
if ( NULL != pAuthInfo )
|
|
{
|
|
hr = pUnknown->QueryInterface( IID_IClientSecurity, (void **) &pClientSecurity );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
// set security authentication
|
|
hr = pClientSecurity->SetBlanket( pUnknown, dwAuthnSvc, dwAuthzSvc, pwszPrincipal,
|
|
dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities );
|
|
|
|
// release
|
|
SAFE_RELEASE( pClientSecurity );
|
|
}
|
|
else
|
|
{
|
|
if ( E_NOINTERFACE == hr )
|
|
{
|
|
hr = S_OK; // ignore no interface errors
|
|
}
|
|
}
|
|
}
|
|
|
|
// release the IUnknown
|
|
SAFE_RELEASE( pUnknown );
|
|
|
|
// return the result
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
WINAPI WbemAllocAuthIdentity(
|
|
LPCWSTR pwszUser,
|
|
LPCWSTR pwszPassword,
|
|
LPCWSTR pwszDomain,
|
|
COAUTHIDENTITY** ppAuthIdent
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function allocates memory for the AUTHIDENTITY structure.
|
|
|
|
Arguments:
|
|
|
|
[in] LPCWSTR : string containing the user name
|
|
[in] LPCWSTR : string containing the password
|
|
[in] LPCWSTR : string containing the domain name
|
|
[out] COAUTHIDENTITY : pointer to the pointer to AUTHIDENTITY structure
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
NOTE: 'ppAuthIdent' should be freed by calling 'WbemFreeAuthIdentity' by the user after
|
|
their work is done.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
COAUTHIDENTITY* pAuthIdent = NULL;
|
|
|
|
// validate the input parameter
|
|
if ( NULL == ppAuthIdent )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// allocation thru COM API
|
|
pAuthIdent = ( COAUTHIDENTITY* ) CoTaskMemAlloc( sizeof( COAUTHIDENTITY ) );
|
|
if ( NULL == pAuthIdent )
|
|
{
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// init with 0's
|
|
SecureZeroMemory( ( void* ) pAuthIdent, sizeof( COAUTHIDENTITY ) );
|
|
|
|
//
|
|
// Allocate needed memory and copy in data. Cleanup if anything goes wrong
|
|
|
|
// user
|
|
if ( NULL != pwszUser )
|
|
{
|
|
// allocate memory for user
|
|
LONG lLength = StringLength( pwszUser, 0 );
|
|
pAuthIdent->User = ( LPWSTR ) CoTaskMemAlloc( (lLength + 1) * sizeof( WCHAR ) );
|
|
if ( NULL == pAuthIdent->User )
|
|
{
|
|
WbemFreeAuthIdentity( &pAuthIdent );
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// set the length and do copy contents
|
|
pAuthIdent->UserLength = lLength;
|
|
StringCopy( pAuthIdent->User, pwszUser, (lLength + 1) );
|
|
}
|
|
|
|
// domain
|
|
if ( NULL != pwszDomain )
|
|
{
|
|
// allocate memory for domain
|
|
LONG lLength = StringLength( pwszDomain, 0 );
|
|
pAuthIdent->Domain = ( LPWSTR ) CoTaskMemAlloc( (lLength + 1) * sizeof( WCHAR ) );
|
|
if ( NULL == pAuthIdent->Domain )
|
|
{
|
|
WbemFreeAuthIdentity( &pAuthIdent );
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// set the length and do copy contents
|
|
pAuthIdent->DomainLength = lLength;
|
|
StringCopy( pAuthIdent->Domain, pwszDomain, (lLength + 1) );
|
|
}
|
|
|
|
// passsord
|
|
if ( NULL != pwszPassword )
|
|
{
|
|
// allocate memory for passsord
|
|
LONG lLength = StringLength( pwszPassword, 0 );
|
|
pAuthIdent->Password = ( LPWSTR ) CoTaskMemAlloc( (lLength + 1) * sizeof( WCHAR ) );
|
|
if ( NULL == pAuthIdent->Password )
|
|
{
|
|
WbemFreeAuthIdentity( &pAuthIdent );
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// set the length and do copy contents
|
|
pAuthIdent->PasswordLength = lLength;
|
|
StringCopy( pAuthIdent->Password, pwszPassword, (lLength + 1) );
|
|
}
|
|
|
|
// type of the structure
|
|
pAuthIdent->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
|
|
|
// final set the address to out parameter
|
|
*ppAuthIdent = pAuthIdent;
|
|
|
|
// return result
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
VOID
|
|
WINAPI WbemFreeAuthIdentity(
|
|
COAUTHIDENTITY** ppAuthIdentity
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function releases the memory allocated for the AUTHIDENTITY structure.
|
|
|
|
Arguments:
|
|
|
|
[in] COAUTHIDENTITY : pointer to the pointer to AUTHIDENTITY structure
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
// make sure we have a pointer, then walk the structure members and cleanup.
|
|
if ( *ppAuthIdentity != NULL )
|
|
{
|
|
// free the memory allocated for user
|
|
if ( NULL != (*ppAuthIdentity)->User )
|
|
{
|
|
CoTaskMemFree( (*ppAuthIdentity)->User );
|
|
(*ppAuthIdentity)->User = NULL;
|
|
}
|
|
|
|
// free the memory allocated for password
|
|
if ( NULL != (*ppAuthIdentity)->Password )
|
|
{
|
|
CoTaskMemFree( (*ppAuthIdentity)->Password );
|
|
(*ppAuthIdentity)->Password = NULL;
|
|
}
|
|
|
|
// free the memory allocated for domain
|
|
if ( NULL != (*ppAuthIdentity)->Domain )
|
|
{
|
|
CoTaskMemFree( (*ppAuthIdentity)->Domain );
|
|
(*ppAuthIdentity)->Domain = NULL;
|
|
}
|
|
|
|
// final the structure
|
|
CoTaskMemFree( *ppAuthIdentity );
|
|
*ppAuthIdentity = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
WMISaveError(
|
|
HRESULT hrError
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function saves the description of the last error returned by WMI
|
|
|
|
Arguments:
|
|
|
|
HRESULT : The last return value from WMI
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
IWbemStatusCodeText* pWbemStatus = NULL;
|
|
_bstr_t bstrErrorString;
|
|
|
|
try
|
|
{
|
|
// Set error to different value.
|
|
if ( E_ACCESSDENIED == hrError )
|
|
{
|
|
// change the error message to "Logon failure: unknown user name or bad password."
|
|
hrError = ERROR_LOGON_FAILURE;
|
|
}
|
|
|
|
//Set the reason to incompatible os when no class is registered on remote mechine
|
|
if( 0x80040154 == hrError )
|
|
{
|
|
bstrErrorString = _bstr_t( GetResString(IDS_ERROR_REMOTE_INCOMPATIBLE) );
|
|
SetReason( bstrErrorString );
|
|
return;
|
|
}
|
|
else
|
|
{ // Get error string.
|
|
hr = CoCreateInstance( CLSID_WbemStatusCodeText,
|
|
NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemStatusCodeText,
|
|
(LPVOID*) &pWbemStatus );
|
|
if( SUCCEEDED( hr ) )
|
|
{
|
|
BSTR bstrString = NULL;
|
|
// Get error string from error code.
|
|
hr = pWbemStatus->GetErrorCodeText( hrError, 0, 0,
|
|
&bstrString );
|
|
if( NULL != bstrString )
|
|
{
|
|
bstrErrorString = _bstr_t( bstrString );
|
|
SysFreeString( bstrString );
|
|
}
|
|
if( FAILED( hr ) )
|
|
{
|
|
_com_issue_error( hrError );
|
|
}
|
|
SAFE_RELEASE(pWbemStatus);
|
|
}
|
|
else
|
|
{
|
|
_com_issue_error( hrError );
|
|
}
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{ // We have got the error. Needs to handle carefully.
|
|
LPWSTR lpwszGetString = NULL;
|
|
SAFE_RELEASE(pWbemStatus);
|
|
try
|
|
{ // ErrorMessage() can throw an exception.
|
|
DWORD dwLength = StringLength( e.ErrorMessage(), 0 ) + 5 ;
|
|
lpwszGetString = ( LPWSTR )AllocateMemory( dwLength * sizeof( WCHAR ) );
|
|
if( NULL != lpwszGetString )
|
|
{
|
|
StringCopy( lpwszGetString, e.ErrorMessage(), dwLength );
|
|
StringConcat( lpwszGetString, L"\n", dwLength );
|
|
SetReason( ( LPCWSTR )lpwszGetString );
|
|
FreeMemory( (LPVOID*) &lpwszGetString );
|
|
}
|
|
else
|
|
{ // Failed to know the exact error occured
|
|
// due to insufficient memory.
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
SaveLastError();
|
|
}
|
|
}
|
|
catch( ... )
|
|
{
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
SaveLastError();
|
|
}
|
|
return;
|
|
}
|
|
|
|
SetReason( (LPCWSTR) bstrErrorString );
|
|
return;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
_variant_t& varValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : property name
|
|
[out] _variant_t : value of the property
|
|
|
|
Return Value:
|
|
|
|
HRESULT
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
VARIANT vtValue;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
try
|
|
{
|
|
// initialize the variant and then get the value of the specified property
|
|
VariantInit( &vtValue );
|
|
// Call 'Get' method to retireve the value from WMI.
|
|
hr = pWmiObject->Get( _bstr_t( pwszProperty ), 0, &vtValue, NULL, NULL );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
// Clear the variant variable
|
|
VariantClear( &vtValue );
|
|
// Return error.
|
|
return hr;
|
|
}
|
|
|
|
// set the value
|
|
varValue = vtValue;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
hr = e.Error();
|
|
}
|
|
|
|
// Clear the variables.
|
|
VariantClear( &vtValue );
|
|
// Return.
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
CHString& strValue,
|
|
LPCWSTR pwszDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in string format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] CHString : variable to hold the retrieved property
|
|
[in] LPCWSTR : string containing the default value for the property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
_variant_t var;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
strValue.Empty();
|
|
|
|
try
|
|
{
|
|
// first copy the default value
|
|
strValue = pwszDefault;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
_com_issue_error( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
// get the property value
|
|
hr = PropertyGet( pWmiObject, pwszProperty, var );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
_com_issue_error( hr );
|
|
}
|
|
|
|
// Get the value
|
|
// If 'var' does not contain value of requested type
|
|
// then default value is returned.
|
|
if ( VT_BSTR == V_VT( &var ) )
|
|
{
|
|
strValue = (LPCWSTR) _bstr_t( var );
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
DWORD& dwValue,
|
|
DWORD dwDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in dword format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] DWORD : variable to hold the retrieved property
|
|
[in] DWORD : dword containing the default value for the property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr;
|
|
_variant_t var;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
try
|
|
{
|
|
// first set the defaul value
|
|
dwValue = dwDefault;
|
|
|
|
// check with object and property passed to the function are valid or not
|
|
// if not, return failure
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
_com_issue_error( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
// get the value of the property
|
|
hr = PropertyGet( pWmiObject, pwszProperty, var );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
_com_issue_error( hr );
|
|
}
|
|
|
|
// get the process id from the variant
|
|
switch( V_VT( &var ) )
|
|
{
|
|
case VT_I2:
|
|
dwValue = V_I2( &var );
|
|
break;
|
|
case VT_I4:
|
|
dwValue = V_I4( &var );
|
|
break;
|
|
case VT_UI2:
|
|
dwValue = V_UI2( &var );
|
|
break;
|
|
case VT_UI4:
|
|
dwValue = V_UI4( &var );
|
|
break;
|
|
case VT_INT:
|
|
dwValue = V_INT( &var );
|
|
break;
|
|
case VT_UINT:
|
|
dwValue = V_UINT( &var );
|
|
break;
|
|
default:
|
|
// Requested type is not found.
|
|
// If 'var' does not contain value of requested type
|
|
// then default value is returned.
|
|
break;
|
|
};
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
BOOL& bValue,
|
|
BOOL bDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in bool format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] BOOL : variable to hold the retrieved property
|
|
[in] BOOL : bool containing the default value for the property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
_variant_t var;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
try
|
|
{
|
|
// first set the default value
|
|
bValue = bDefault;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
_com_issue_error( WBEM_E_INVALID_PARAMETER );
|
|
}
|
|
|
|
// get the value of the property
|
|
hr = PropertyGet( pWmiObject, pwszProperty, var );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
_com_issue_error( hr );
|
|
}
|
|
|
|
// Save value obtained.
|
|
// If 'var' does not contain value of requested type
|
|
// then default value is returned.
|
|
if ( VT_BOOL == V_VT( &var ) )
|
|
{
|
|
bValue = var.boolVal;
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
ULONGLONG& ullValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in ulongulong format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] ULONGULONG : variable to hold the retrieved property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
|
|
{
|
|
// Local variables
|
|
CHString str;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
str.Empty();
|
|
|
|
try
|
|
{
|
|
// first set the default value
|
|
ullValue = 1;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
// get the value of the property
|
|
if ( FALSE == PropertyGet( pWmiObject, pwszProperty, str, _T( "0" ) ) )
|
|
{ // Error is already set in 'PropertyGet' function.
|
|
return FALSE;
|
|
}
|
|
|
|
// get the 64-bit value
|
|
ullValue = _wtoi64( str );
|
|
|
|
// Check for error condition.
|
|
if( 0 == ullValue )
|
|
{
|
|
ullValue = 1;
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
WBEMTime& wbemtime )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in wbemtime format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] WBEMTime : variable to hold the retrieved property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
CHString str;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Clear method sets the time in the WBEMTime object to an invalid time.
|
|
wbemtime.Clear();
|
|
try
|
|
{
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
// get the value of the property
|
|
if ( FALSE == PropertyGet( pWmiObject, pwszProperty, str, _T( "0" ) ) )
|
|
{ // Error is already set in 'PropertyGet' function.
|
|
return FALSE;
|
|
}
|
|
|
|
// convert into the time value
|
|
wbemtime = _bstr_t( str );
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
SYSTEMTIME& systime )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the value of the property from the WMI class object in systemtime format
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[out] WBEMTime : variable to hold the retrieved property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
|
|
{
|
|
// local variables
|
|
CHString strTime;
|
|
|
|
// Validate input arguments.
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// get the value of the property
|
|
// 16010101000000.000000+000 is the default time
|
|
if ( FALSE == PropertyGet( pWmiObject, pwszProperty, strTime, _T( "16010101000000.000000+000" ) ) )
|
|
{ // Error is already set.
|
|
return FALSE;
|
|
}
|
|
|
|
// prepare the systemtime structure
|
|
// yyyymmddHHMMSS.mmmmmmsUUU
|
|
// NOTE: NO NEED CALL 'IsNumeric()' BEFORE 'AsLong'.
|
|
// Left and MID methods can throw an exception.
|
|
systime.wYear = (WORD) AsLong( strTime.Left( 4 ), 10 );
|
|
systime.wMonth = (WORD) AsLong( strTime.Mid( 4, 2 ), 10 );
|
|
systime.wDayOfWeek = 0;
|
|
systime.wDay = (WORD) AsLong( strTime.Mid( 6, 2 ), 10 );
|
|
systime.wHour = (WORD) AsLong( strTime.Mid( 8, 2 ), 10 );
|
|
systime.wMinute = (WORD) AsLong( strTime.Mid( 10, 2 ), 10 );
|
|
systime.wSecond = (WORD) AsLong( strTime.Mid( 12, 2 ), 10 );
|
|
systime.wMilliseconds = (WORD) AsLong( strTime.Mid( 15, 6 ), 10 );
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
PropertyPut(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
_variant_t& varValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the value of the property to the WMI class object
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[in] WBEMTime : variable holding the property to set
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
VARIANT var;
|
|
HRESULT hr = S_OK;
|
|
|
|
// check the input value
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
try
|
|
{
|
|
// put the value
|
|
var = varValue;
|
|
hr = pWmiObject->Put( _bstr_t( pwszProperty ), 0, &var, 0 );
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
hr = e.Error();
|
|
}
|
|
|
|
// return the result
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
PropertyPut(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
LPCWSTR pwszValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the string value of the property to the WMI class object
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[in] LPCWSTR : variable holding the property to set
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
_variant_t varValue;
|
|
HRESULT hr = S_OK;
|
|
|
|
// check the input value
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) ||
|
|
( NULL == pwszValue ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
try
|
|
{
|
|
varValue = pwszValue;
|
|
SAFE_EXECUTE( PropertyPut( pWmiObject, pwszProperty, varValue ) );
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
hr = e.Error();
|
|
}
|
|
|
|
// return
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
PropertyPut(
|
|
IWbemClassObject* pWmiObject,
|
|
LPCWSTR pwszProperty,
|
|
DWORD dwValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the dword value of the property to the WMI class object.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemClassObject : pointer to the WBEM class object
|
|
[in] LPCWSTR : the name of the property to retrieve
|
|
[in] DWORD : variable holding the property to set
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
_variant_t varValue;
|
|
HRESULT hr = S_OK;
|
|
|
|
// check the input value
|
|
if ( ( NULL == pWmiObject ) ||
|
|
( NULL == pwszProperty ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
try
|
|
{
|
|
varValue = ( LONG )dwValue;
|
|
SAFE_EXECUTE( PropertyPut( pWmiObject, pwszProperty, varValue ) );
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
return e.Error();
|
|
}
|
|
|
|
// return
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
RegQueryValueWMI(
|
|
IWbemServices* pWbemServices,
|
|
LPCWSTR pwszMethod,
|
|
DWORD dwHDefKey,
|
|
LPCWSTR pwszSubKeyName,
|
|
LPCWSTR pwszValueName,
|
|
_variant_t& varValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function retrieves the value of the property from the specified registry key.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemServices : pointer to the IWbemServices object
|
|
[in] LPCWSTR : the name of the method to execute
|
|
[in] DWORD : the key in the registry whose value has to be retrieved
|
|
[in] LPCWSTR : the name of the subkey to retrieve
|
|
[in] LPCWSTR : the name of the value to retrieve
|
|
[in] _variant_t : variable holding the property value retrieved
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: Pass arguments of type mentioned in declaration of this function.
|
|
EX: Don't pass 'CHString' argument if 'LPWSTR' is expected.
|
|
Reason: 'CHString' can throw an exception of type 'CHEAP_EXCEPTION'
|
|
which is not handled by this function.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
BOOL bResult = FALSE;
|
|
DWORD dwReturnValue = 0;
|
|
IWbemClassObject* pClass = NULL;
|
|
IWbemClassObject* pMethod = NULL;
|
|
IWbemClassObject* pInParams = NULL;
|
|
IWbemClassObject* pInParamsInstance = NULL;
|
|
IWbemClassObject* pOutParamsInstance = NULL;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// check the input value
|
|
if ( ( NULL == pWbemServices ) ||
|
|
( NULL == pwszMethod ) ||
|
|
( NULL == pwszSubKeyName ) ||
|
|
( NULL == pwszValueName ) )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// NOTE: If SAFE_EXECUTE( pWbemServices->GetObject(
|
|
// _bstr_t( WMI_REGISTRY ), WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pClass, NULL ) );
|
|
// is executed then,
|
|
// NO NEED TO CHECK FOR ( PCLASS == NULL ) SINCE IN ALL CASES
|
|
// OF ERROR THIS VARIABLE WILL BE NULL.
|
|
|
|
try
|
|
{
|
|
// get the registry class object
|
|
SAFE_EXECUTE( pWbemServices->GetObject(
|
|
_bstr_t( WMI_REGISTRY ), WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pClass, NULL ) );
|
|
|
|
// get the method reference required
|
|
SAFE_EXECUTE( pClass->GetMethod( pwszMethod, 0, &pInParams, NULL ) );
|
|
|
|
// create the instance for the in parameters
|
|
SAFE_EXECUTE( pInParams->SpawnInstance( 0, &pInParamsInstance ) );
|
|
|
|
// set the input values
|
|
SAFE_EXECUTE(PropertyPut( pInParamsInstance, _bstr_t( WMI_REGISTRY_IN_HDEFKEY ), dwHDefKey ) );
|
|
SAFE_EXECUTE(PropertyPut( pInParamsInstance, _bstr_t( WMI_REGISTRY_IN_SUBKEY ), pwszSubKeyName ) );
|
|
SAFE_EXECUTE(PropertyPut( pInParamsInstance, _bstr_t( WMI_REGISTRY_IN_VALUENAME ), pwszValueName ) );
|
|
|
|
// now execute the method
|
|
SAFE_EXECUTE( pWbemServices->ExecMethod( _bstr_t( WMI_REGISTRY ),
|
|
_bstr_t( pwszMethod ), 0, NULL, pInParamsInstance, &pOutParamsInstance, NULL ) );
|
|
if ( NULL == pOutParamsInstance ) // check the object .. safety sake
|
|
{
|
|
_com_issue_error( STG_E_UNKNOWN );
|
|
}
|
|
|
|
// now check the return value of the method from the output params object
|
|
bResult = PropertyGet( pOutParamsInstance,
|
|
_bstr_t( WMI_REGISTRY_OUT_RETURNVALUE ), dwReturnValue );
|
|
if ( ( FALSE == bResult ) ||
|
|
( 0 != dwReturnValue ) )
|
|
{
|
|
_com_issue_error( STG_E_UNKNOWN );
|
|
}
|
|
|
|
// Comapre string and take appropriate action.
|
|
if ( 0 == StringCompare( pwszMethod, WMI_REGISTRY_M_DWORDVALUE, TRUE, 0 ) )
|
|
{
|
|
SAFE_EXECUTE( PropertyGet( pOutParamsInstance,
|
|
_bstr_t( WMI_REGISTRY_OUT_VALUE_DWORD ), varValue ) );
|
|
}
|
|
else
|
|
{
|
|
SAFE_EXECUTE( PropertyGet( pOutParamsInstance,
|
|
_bstr_t( WMI_REGISTRY_OUT_VALUE ), varValue ) );
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
hr = e.Error();
|
|
SAFE_RELEASE( pClass );
|
|
SAFE_RELEASE( pMethod );
|
|
SAFE_RELEASE( pInParams );
|
|
SAFE_RELEASE( pInParamsInstance );
|
|
SAFE_RELEASE( pOutParamsInstance );
|
|
}
|
|
|
|
// release the interfaces
|
|
SAFE_RELEASE( pClass );
|
|
SAFE_RELEASE( pMethod );
|
|
SAFE_RELEASE( pInParams );
|
|
SAFE_RELEASE( pInParamsInstance );
|
|
SAFE_RELEASE( pOutParamsInstance );
|
|
|
|
// return success
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL
|
|
RegQueryValueWMI(
|
|
IWbemServices* pWbemServices,
|
|
DWORD dwHDefKey,
|
|
LPCWSTR pwszSubKeyName,
|
|
LPCWSTR pwszValueName,
|
|
CHString& strValue,
|
|
LPCWSTR pwszDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function retrieves the string value of the property from the specified registry key.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemServices : pointer to the IWbemServices object
|
|
[in] DWORD : the key in the registry whose value has to be retrieved
|
|
[in] LPCWSTR : the name of the subkey to retrieve
|
|
[in] LPCWSTR : the name of the value to retrieve
|
|
[out] CHString : variable holding the property value retrieved
|
|
[in] LPCWSTR : the default value for this property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF '0' IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
This function won't return values if they are obtained as reference
|
|
from WMI.
|
|
EX: 'VARTYPE' recieved is of type 'VT_BSTR | VT_BYREF' then FALSE is
|
|
returned.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
_variant_t varValue;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Check the input
|
|
if ( ( NULL == pWbemServices ) ||
|
|
( NULL == pwszSubKeyName ) ||
|
|
( NULL == pwszValueName ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Set the default value
|
|
if ( NULL != pwszDefault )
|
|
{
|
|
strValue = pwszDefault;
|
|
}
|
|
|
|
// Get the value
|
|
hr = RegQueryValueWMI( pWbemServices,
|
|
WMI_REGISTRY_M_STRINGVALUE, dwHDefKey, pwszSubKeyName, pwszValueName, varValue );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
WMISaveError( hr );
|
|
return FALSE;
|
|
}
|
|
|
|
// Get the value from the variant
|
|
// Get the value
|
|
if ( VT_BSTR == V_VT( &varValue ) )
|
|
{
|
|
strValue = (LPCWSTR)_bstr_t( varValue );
|
|
}
|
|
else
|
|
{
|
|
// Requested type is not found.
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{ // Exception throw by '_variant_t'.
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
|
|
// return success
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
RegQueryValueWMI(
|
|
IWbemServices* pWbemServices,
|
|
DWORD dwHDefKey,
|
|
LPCWSTR pwszSubKeyName,
|
|
LPCWSTR pwszValueName,
|
|
DWORD& dwValue,
|
|
DWORD dwDefault
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function retrieves the dword value of the property from the specified registry key.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemServices : pointer to the IWbemServices object
|
|
[in] DWORD : the key in the registry whose value has to be retrieved
|
|
[in] LPCWSTR : the name of the subkey to retrieve
|
|
[in] LPCWSTR : the name of the value to retrieve
|
|
[out] DWORD : variable holding the property value retrieved
|
|
[in] DWORD : the default value for this property
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF '0' IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
This function won't return values if they are obtained as reference
|
|
from WMI.
|
|
EX: 'VARTYPE' recieved is of type 'VT_I4 | VT_BYREF' then FALSE is
|
|
returned.
|
|
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
_variant_t varValue;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Check the input.
|
|
if ( ( NULL == pWbemServices ) ||
|
|
( NULL == pwszSubKeyName ) ||
|
|
( NULL == pwszValueName ) ||
|
|
( NULL == dwValue ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// Set the default value.
|
|
dwValue = dwDefault;
|
|
|
|
// Get the value.
|
|
hr = RegQueryValueWMI( pWbemServices, WMI_REGISTRY_M_DWORDVALUE, dwHDefKey,
|
|
pwszSubKeyName, pwszValueName, varValue );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
WMISaveError( hr );
|
|
return FALSE;
|
|
}
|
|
|
|
// get the value from the variant
|
|
switch( V_VT( &varValue ) )
|
|
{
|
|
case VT_I2:
|
|
dwValue = V_I2( &varValue );
|
|
break;
|
|
case VT_I4:
|
|
dwValue = V_I4( &varValue );
|
|
break;
|
|
case VT_UI2:
|
|
dwValue = V_UI2( &varValue );
|
|
break;
|
|
case VT_UI4:
|
|
dwValue = V_UI4( &varValue );
|
|
break;
|
|
case VT_INT:
|
|
dwValue = V_INT( &varValue );
|
|
break;
|
|
case VT_UINT:
|
|
dwValue = V_UINT( &varValue );
|
|
break;
|
|
default:
|
|
// Requested type is not found.
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
}
|
|
catch( _com_error& e )
|
|
{ // Exception thrown by _variant_t
|
|
WMISaveError( e );
|
|
return FALSE;
|
|
}
|
|
|
|
// return success
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetTargetVersionEx(
|
|
IWbemServices* pWbemServices,
|
|
COAUTHIDENTITY* pAuthIdentity
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function gets the version of the system from which we are trying to retrieve
|
|
information from.
|
|
|
|
Arguments:
|
|
|
|
[in] IWbemServices : pointer to the IWbemServices object
|
|
[in] COAUTHIDENTITY : pointer to the pointer to AUTHIDENTITY structure
|
|
|
|
Return Value:
|
|
|
|
DWORD - Target version of the machine if found else 0.
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF '0' IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
|
|
{
|
|
// local variables
|
|
HRESULT hr = S_OK;
|
|
LONG lPos = 0;
|
|
DWORD dwMajor = 0;
|
|
DWORD dwMinor = 0;
|
|
DWORD dwVersion = 0;
|
|
ULONG ulReturned = 0;
|
|
CHString strVersion;
|
|
IWbemClassObject* pWbemObject = NULL;
|
|
IEnumWbemClassObject* pWbemInstances = NULL;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Check the input value
|
|
if ( NULL == pWbemServices )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return 0;
|
|
}
|
|
|
|
try
|
|
{
|
|
// get the OS information
|
|
SAFE_EXECUTE( pWbemServices->CreateInstanceEnum(
|
|
_bstr_t( CLASS_CIMV2_Win32_OperatingSystem ),
|
|
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemInstances ) );
|
|
|
|
// set the security on the enumerated object
|
|
SAFE_EXECUTE( SetInterfaceSecurity( pWbemInstances, pAuthIdentity ) );
|
|
|
|
// get the enumerated objects information
|
|
// NOTE: This needs to be traversed only one time.
|
|
SAFE_EXECUTE( pWbemInstances->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned ) );
|
|
|
|
// to be on safer side ... check the count of objects returned
|
|
if ( 0 == ulReturned )
|
|
{
|
|
// release the interfaces
|
|
WMISaveError( WBEM_S_FALSE );
|
|
SAFE_RELEASE( pWbemObject );
|
|
SAFE_RELEASE( pWbemInstances );
|
|
return 0;
|
|
}
|
|
|
|
// now get the os version value
|
|
if ( FALSE == PropertyGet( pWbemObject, L"Version", strVersion ) )
|
|
{
|
|
// release the interfaces
|
|
// Error is already set in the called function.
|
|
SAFE_RELEASE( pWbemObject );
|
|
SAFE_RELEASE( pWbemInstances );
|
|
return 0;
|
|
}
|
|
|
|
// release the interfaces .. we dont need them furthur
|
|
SAFE_RELEASE( pWbemObject );
|
|
SAFE_RELEASE( pWbemInstances );
|
|
|
|
//
|
|
// now determine the os version
|
|
dwMajor = dwMinor = 0;
|
|
|
|
// Get the major version
|
|
lPos = strVersion.Find( L'.' );
|
|
if ( -1 == lPos )
|
|
{
|
|
// The version string itself is version ... THIS WILL NEVER HAPPEN
|
|
if( FALSE == IsNumeric( strVersion, 10, FALSE ) )
|
|
{
|
|
return 0;
|
|
}
|
|
dwMajor = AsLong( strVersion, 10 );
|
|
}
|
|
else
|
|
{
|
|
// major version
|
|
if( FALSE == IsNumeric( strVersion.Mid( 0, lPos ), 10, FALSE ) )
|
|
{
|
|
return 0;
|
|
}
|
|
dwMajor = AsLong( strVersion.Mid( 0, lPos ), 10 );
|
|
|
|
// get the minor version
|
|
strVersion = strVersion.Mid( lPos + 1 );
|
|
lPos = strVersion.Find( L'.' );
|
|
if ( -1 == lPos)
|
|
{
|
|
if( FALSE == IsNumeric( strVersion, 10, FALSE ) )
|
|
{
|
|
return 0;
|
|
}
|
|
dwMinor = AsLong( strVersion, 10 );
|
|
}
|
|
else
|
|
{
|
|
if( FALSE == IsNumeric( strVersion.Mid( 0, lPos ), 10, FALSE ) )
|
|
{
|
|
return 0;
|
|
}
|
|
dwMinor = AsLong( strVersion.Mid( 0, lPos ), 10 );
|
|
}
|
|
}
|
|
|
|
// mix the version info
|
|
dwVersion = dwMajor * 1000 + dwMinor;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
WMISaveError( e );
|
|
SAFE_RELEASE( pWbemObject );
|
|
SAFE_RELEASE( pWbemInstances );
|
|
return 0;
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
SAFE_RELEASE( pWbemObject );
|
|
SAFE_RELEASE( pWbemInstances );
|
|
return 0;
|
|
}
|
|
|
|
// If successful then 'pWbemObject' and 'pWbemInstances' are already released.
|
|
// return
|
|
return dwVersion;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetPropertyFromSafeArray(
|
|
SAFEARRAY *pSafeArray,
|
|
LONG lIndex,
|
|
CHString& strValue,
|
|
VARTYPE vartype
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function retrieves a property from the safe array.
|
|
|
|
Arguments:
|
|
|
|
[in] SAFEARRAY : pointer to the array of elements
|
|
[in] LONG : index to retrieve the data from
|
|
[out] CHString : variable to hold the return value
|
|
[in] VARTYPE : The type of variable to retrieve from the array
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
--*/
|
|
{
|
|
// Local variables.
|
|
VARIANT var;
|
|
HRESULT hRes = S_OK;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Check the inputs.
|
|
if ( NULL == pSafeArray )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize variant.
|
|
VariantInit( &var );
|
|
|
|
try
|
|
{
|
|
// get the value
|
|
V_VT( &var ) = vartype;
|
|
hRes = SafeArrayGetElement( pSafeArray, &lIndex, &V_UI1( &var ) );
|
|
if( FAILED( hRes ) )
|
|
{ // Set error occured.
|
|
WMISaveError( hRes );
|
|
VariantClear( &var );
|
|
return FALSE;
|
|
}
|
|
|
|
// Store requested information in
|
|
switch( vartype )
|
|
{
|
|
case VT_BSTR:
|
|
strValue = (LPCWSTR)_bstr_t( var );
|
|
break;
|
|
default:
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
VariantClear( &var );
|
|
return FALSE;
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{ // Exception thrown from 'strValue'.
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
VariantClear( &var );
|
|
return FALSE; // failure
|
|
}
|
|
|
|
// Clean-Up and return.
|
|
VariantClear( &var );
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetPropertyFromSafeArray(
|
|
SAFEARRAY *pSafeArray,
|
|
LONG lIndex,
|
|
IWbemClassObject **pScriptObject,
|
|
VARTYPE vartype
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
This function retrieves a property from the safe array.
|
|
|
|
Arguments:
|
|
|
|
[in] SAFEARRAY : pointer to the array of elements
|
|
[in] LONG : index to retrieve the data from
|
|
[out] IWbemClassObject : variable to hold the return value
|
|
[in] VARTYPE : The type of variable to retrieve from the array
|
|
|
|
Return Value:
|
|
|
|
TRUE on success
|
|
FALSE on failure
|
|
|
|
NOTE: CALLED FUNCTION HAS TO MAKE SURE THAT '*pScriptObject' DOES NOT CONTAIN ANY
|
|
VALUE WHICH MAY CAUSE MEMORY LEAK.
|
|
THIS FUNCTION SAVES LAST ERROR OCCURED. IF FALSE IS RETURNED THEN ERROR
|
|
OCCURED STRING CAN BE RETRIEVED BY CALLING 'GetReason()'.
|
|
|
|
NOTE: If TRUE is returned then 'VariantClear' is not called over 'var' since if
|
|
a call is made to 'Variantcler' we will loose Interface pointer. Not calling
|
|
'VariantClear' will free 'var' when its out of scope and leaving
|
|
the interface pointer in memory which can be used by the called function.
|
|
IT IS CALLING FUNCTION RESPONSIBILITY TO RELEASE THE INTERFACE POINTER.
|
|
|
|
--*/
|
|
{
|
|
// Local variables.
|
|
VARIANT var;
|
|
HRESULT hRes = S_OK;
|
|
|
|
// Clear any errors.
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// Validate the inputs
|
|
if ( ( NULL == pSafeArray ) ||
|
|
( NULL == pScriptObject ) )
|
|
{
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize variant.
|
|
VariantInit( &var );
|
|
|
|
// Set type of value expected.
|
|
V_VT( &var ) = vartype;
|
|
|
|
hRes = SafeArrayGetElement( pSafeArray, &lIndex, &V_UI1( &var ) );
|
|
// check for return value.
|
|
if( FAILED( hRes ) )
|
|
{ // Set error occured.
|
|
WMISaveError( hRes );
|
|
VariantClear( &var );
|
|
return FALSE;
|
|
}
|
|
// Store information requested.
|
|
switch( vartype )
|
|
{
|
|
case VT_UNKNOWN:
|
|
*pScriptObject = (IWbemClassObject *) var.punkVal;
|
|
break;
|
|
default:
|
|
WMISaveError( WBEM_E_INVALID_PARAMETER );
|
|
VariantClear( &var );
|
|
return FALSE;
|
|
}
|
|
|
|
// return
|
|
return TRUE;
|
|
}
|