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.
1482 lines
43 KiB
1482 lines
43 KiB
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
CONNECTWMI.cpp
|
|
|
|
Abstract:
|
|
Contains functions to connect to wmi.
|
|
|
|
Author:
|
|
Vasundhara .G
|
|
|
|
Revision History:
|
|
Vasundhara .G 26-sep-2k : Created It.
|
|
--*/
|
|
|
|
// Include files
|
|
#include "pch.h"
|
|
#include "getmac.h"
|
|
#include "resource.h"
|
|
|
|
// messages
|
|
|
|
#define INPUT_PASSWORD GetResString( IDS_STR_INPUT_PASSWORD )
|
|
|
|
// error constants
|
|
|
|
#define E_SERVER_NOTFOUND 0x800706ba
|
|
|
|
// function prototypes
|
|
|
|
BOOL
|
|
IsValidUserEx(
|
|
IN LPCWSTR pwszUser
|
|
);
|
|
|
|
HRESULT
|
|
GetSecurityArguments(
|
|
IN IUnknown *pInterface,
|
|
OUT DWORD& dwAuthorization,
|
|
OUT DWORD& dwAuthentication
|
|
);
|
|
|
|
HRESULT
|
|
SetInterfaceSecurity(
|
|
IN IUnknown *pInterface,
|
|
IN LPCWSTR pwszUser,
|
|
IN LPCWSTR pwszPassword,
|
|
OUT COAUTHIDENTITY **ppAuthIdentity
|
|
);
|
|
|
|
HRESULT
|
|
WINAPI SetProxyBlanket(
|
|
IN IUnknown *pInterface,
|
|
IN DWORD dwAuthnSvc,
|
|
IN DWORD dwAuthzSvc,
|
|
IN LPWSTR pwszPrincipal,
|
|
IN DWORD dwAuthLevel,
|
|
IN DWORD dwImpLevel,
|
|
IN RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
|
|
IN DWORD dwCapabilities
|
|
);
|
|
|
|
HRESULT
|
|
WINAPI WbemAllocAuthIdentity(
|
|
IN LPCWSTR pwszUser,
|
|
IN LPCWSTR pwszPassword,
|
|
IN LPCWSTR pwszDomain,
|
|
OUT COAUTHIDENTITY **ppAuthIdent
|
|
);
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IN IWbemClassObject *pWmiObject,
|
|
IN LPCWSTR pwszProperty,
|
|
OUT CHString& strValue,
|
|
IN LPCWSTR pwszDefault = V_NOT_AVAILABLE
|
|
);
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IN IWbemClassObject* pWmiObject,
|
|
IN LPCWSTR pwszProperty,
|
|
OUT CHString& strValue,
|
|
IN LPCWSTR pwszDefault
|
|
);
|
|
|
|
HRESULT
|
|
PropertyGet(
|
|
IN IWbemClassObject* pWmiObject,
|
|
IN LPCWSTR pwszProperty,
|
|
OUT _variant_t& varValue
|
|
);
|
|
|
|
BOOL
|
|
IsValidUserEx(
|
|
IN LPCWSTR pwszUser
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Validates the user name.
|
|
|
|
Arguments:
|
|
[IN] pwszUser - Holds the user name to be validated.
|
|
|
|
Return Value:
|
|
returns TRUE if user name is a valid user else FALSE.
|
|
--*/
|
|
{
|
|
// local variables
|
|
CHString strUser;
|
|
LONG lPos = 0;
|
|
|
|
if ( ( NULL == pwszUser ) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
if( 0 == StringLength( pwszUser, 0 ) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
try
|
|
{
|
|
// get user into local memory
|
|
strUser = pwszUser;
|
|
|
|
// user name should not be just '\'
|
|
if ( 0 == strUser.CompareNoCase( L"\\" ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
// user name should not contain invalid characters
|
|
if ( -1 != strUser.FindOneOf( L"/[]:|<>+=;,?*" ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
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(
|
|
IN LPCWSTR pwszServer,
|
|
OUT BOOL &bLocalSystem
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Checks whether the server name is a valid server name or not.
|
|
|
|
Arguments:
|
|
[IN] pwszServer - Server name to be validated.
|
|
[OUT] bLocalSystem - Set to TRUE if server specified is local system.
|
|
|
|
Return Value:
|
|
TRUE if server is valid else FALSE.
|
|
--*/
|
|
{
|
|
// local variables
|
|
CHString strTemp;
|
|
|
|
if( NULL == pwszServer )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if( 0 == StringLength( pwszServer, 0 ) )
|
|
{
|
|
bLocalSystem = TRUE;
|
|
return TRUE;
|
|
}
|
|
bLocalSystem = FALSE;
|
|
try
|
|
{
|
|
// get a local copy
|
|
strTemp = pwszServer;
|
|
|
|
if( TRUE == IsNumeric( pwszServer, 10, FALSE ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// remove the forward slashes (UNC) if exist in the begining of the server name
|
|
if ( TRUE == IsUNCFormat( strTemp ) )
|
|
{
|
|
strTemp = strTemp.Mid( 2 );
|
|
if ( 0 == strTemp.GetLength() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
if ( -1 != strTemp.FindOneOf( L"`~!@#$^&*()+=[]{}|\\<>,?/\"':;" ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
// now check if any '\' character appears in the server name. If so error
|
|
if ( -1 != strTemp.Find( L'\\' ) )
|
|
{
|
|
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 ( 0 == strTemp.CompareNoCase( L"." ) )
|
|
{
|
|
bLocalSystem = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bLocalSystem = IsLocalSystem( strTemp );
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
|
|
// valid server name
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
ConnectWmi(
|
|
IN IWbemLocator *pLocator,
|
|
OUT IWbemServices **ppServices,
|
|
IN LPCWSTR pwszServer,
|
|
OUT LPCWSTR pwszUser,
|
|
OUT LPCWSTR pwszPassword,
|
|
OUT COAUTHIDENTITY **ppAuthIdentity,
|
|
IN BOOL bCheckWithNullPwd,
|
|
IN LPCWSTR pwszNamespace,
|
|
OUT HRESULT *phRes,
|
|
OUT BOOL *pbLocalSystem
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Connects to wmi.
|
|
|
|
Arguments:
|
|
[IN] pLocator - Pointer to the IWbemLocator object.
|
|
[OUT] ppServics - Pointer to IWbemServices object.
|
|
[IN] pwszServer - Holds the server name to connect to.
|
|
[OUT] pwszUser - Holds the user name.
|
|
[OUT] pwszPassword - Holds the password.
|
|
[OUT] ppAuthIdentity - Pointer to authentication structure.
|
|
[IN] bCheckWithNullPwd - Specifies whether to connect through null password.
|
|
[IN] pwszNamespace - Specifies the namespace to connect to.
|
|
[OUT] hRes - Holds the error value.
|
|
[OUT] pbLocalSystem - Holds the boolean value to represent whether the server
|
|
name is local or not.
|
|
Return Value:
|
|
TRUE if successfully connected, FALSE if not.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 0;
|
|
BOOL bResult = FALSE;
|
|
BOOL bLocalSystem = FALSE;
|
|
_bstr_t bstrServer;
|
|
_bstr_t bstrNamespace;
|
|
_bstr_t bstrUser;
|
|
_bstr_t bstrPassword;
|
|
|
|
// clear the error
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
if ( NULL != pbLocalSystem )
|
|
{
|
|
*pbLocalSystem = FALSE;
|
|
}
|
|
if ( NULL != phRes )
|
|
{
|
|
*phRes = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
// check whether locator object exists or not
|
|
// if not exists, return
|
|
if ( ( NULL == pLocator ) ||
|
|
( NULL == ppServices ) ||
|
|
( NULL != *ppServices ) ||
|
|
( NULL == pwszNamespace ) ||
|
|
( NULL == pbLocalSystem ) )
|
|
{
|
|
if ( NULL != phRes )
|
|
{
|
|
*phRes = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
// return failure
|
|
return FALSE;
|
|
}
|
|
|
|
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 ( FALSE == IsValidServerEx( pwszServer, bLocalSystem ) )
|
|
{
|
|
_com_issue_error( E_SERVER_NOTFOUND );
|
|
}
|
|
// validate the user name
|
|
if ( FALSE == IsValidUserEx( pwszUser ) )
|
|
{
|
|
_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 ( TRUE == IsUNCFormat( pwszServer ) )
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|
|
hRes = pLocator->ConnectServer( bstrNamespace,
|
|
bstrUser, bstrPassword, 0L, 0L, NULL, NULL, ppServices );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
//
|
|
// 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 ( E_ACCESSDENIED == hRes )
|
|
{
|
|
// 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 ...
|
|
hRes = pLocator->ConnectServer( bstrNamespace,
|
|
bstrUser, _bstr_t( L"" ), 0L, 0L, NULL, NULL, ppServices );
|
|
}
|
|
}
|
|
else if ( WBEM_E_LOCAL_CREDENTIALS == hRes )
|
|
{
|
|
// 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
|
|
hRes = pLocator->ConnectServer( bstrNamespace,
|
|
NULL, NULL, 0L, 0L, NULL, NULL, ppServices );
|
|
|
|
// check the result
|
|
if ( SUCCEEDED( hRes ) && NULL != phRes )
|
|
{
|
|
// set the last error
|
|
*phRes = WBEM_E_LOCAL_CREDENTIALS;
|
|
}
|
|
}
|
|
else if ( REGDB_E_CLASSNOTREG == hRes )
|
|
{
|
|
SetReason( ERROR_REMOTE_INCOMPATIBLE );
|
|
*phRes = REGDB_E_CLASSNOTREG;
|
|
bResult = FALSE;
|
|
return bResult;
|
|
}
|
|
|
|
// now check the result again .. if failed .. ummmm..
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
_com_issue_error( hRes );
|
|
}
|
|
else
|
|
{
|
|
bstrPassword = L"";
|
|
}
|
|
}
|
|
|
|
// set the security at the interface level also
|
|
SAFE_EXECUTE( SetInterfaceSecurity( *ppServices,
|
|
bstrUser, bstrPassword, ppAuthIdentity ) );
|
|
|
|
// connection to WMI is successful
|
|
bResult = TRUE;
|
|
|
|
// save the hr value if needed by the caller
|
|
if ( NULL != phRes )
|
|
{
|
|
*phRes = WBEM_S_NO_ERROR;
|
|
}
|
|
if ( NULL != pbLocalSystem )
|
|
{
|
|
*pbLocalSystem = bLocalSystem;
|
|
}
|
|
bResult = TRUE;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
// save the error
|
|
WMISaveError( e );
|
|
|
|
// save the hr value if needed by the caller
|
|
if ( NULL != phRes )
|
|
{
|
|
*phRes = e.Error();
|
|
}
|
|
SAFE_RELEASE( *ppServices );
|
|
bResult = FALSE;
|
|
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
BOOL
|
|
ConnectWmiEx(
|
|
IN IWbemLocator *pLocator,
|
|
OUT IWbemServices **ppServices,
|
|
IN LPCWSTR strServer,
|
|
OUT CHString &strUserName,
|
|
OUT CHString &strPassword,
|
|
OUT COAUTHIDENTITY **ppAuthIdentity,
|
|
IN BOOL bNeedPassword,
|
|
IN LPCWSTR pwszNamespace,
|
|
OUT BOOL *pbLocalSystem
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Connects to wmi.
|
|
|
|
Arguments:
|
|
[IN] pLocator - Pointer to the IWbemLocator object.
|
|
[OUT] ppServices - Pointer to IWbemServices object.
|
|
[IN] strServer - Holds the server name to connect to.
|
|
[OUT] strUserName - Holds the user name.
|
|
[OUT] strPassword - Holds the password.
|
|
[OUT] ppAuthIdentity - Pointer to authentication structure.
|
|
[IN] bNeedPassword - Specifies whether to prompt for password.
|
|
[IN] pwszNamespace - Specifies the namespace to connect to.
|
|
[OUT] pbLocalSystem - Holds the boolean value to represent whether the server
|
|
name is local or not.
|
|
Return Value:
|
|
TRUE if successfully connected, FALSE if not.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 0;
|
|
DWORD dwSize = 0;
|
|
BOOL bResult = FALSE;
|
|
LPWSTR pwszPassword = NULL;
|
|
|
|
try
|
|
{
|
|
|
|
CHString strBuffer = L"\0";
|
|
|
|
// clear the error .. if any
|
|
SetLastError( WBEM_S_NO_ERROR );
|
|
|
|
// 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,
|
|
strServer, NULL, NULL, ppAuthIdentity,
|
|
FALSE, pwszNamespace, &hRes, pbLocalSystem );
|
|
}
|
|
else
|
|
{
|
|
// credentials were supplied
|
|
// but password might not be specified ... so check and act accordingly
|
|
LPCWSTR pwszTemp = NULL;
|
|
BOOL bCheckWithNull = TRUE;
|
|
if ( FALSE == bNeedPassword )
|
|
{
|
|
pwszTemp = strPassword;
|
|
bCheckWithNull = FALSE;
|
|
}
|
|
|
|
// ...
|
|
bResult = ConnectWmi( pLocator, ppServices, strServer, strUserName,
|
|
pwszTemp, ppAuthIdentity, bCheckWithNull, pwszNamespace, &hRes, pbLocalSystem );
|
|
}
|
|
|
|
// check the result ... if successful in establishing connection ... return
|
|
if ( TRUE == bResult )
|
|
{
|
|
SetLastError( hRes ); // set the error code
|
|
return TRUE;
|
|
}
|
|
// now check the kind of error occurred
|
|
switch( hRes )
|
|
{
|
|
case E_ACCESSDENIED:
|
|
break;
|
|
case WBEM_E_LOCAL_CREDENTIALS:
|
|
// 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( hRes );
|
|
return FALSE; // no use of accepting the password .. return failure
|
|
}
|
|
|
|
// 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 ( FALSE == bNeedPassword )
|
|
{
|
|
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;
|
|
|
|
// get the required buffer
|
|
pwszUserName = strUserName.GetBufferSetLength( MAX_STRING_LENGTH );
|
|
|
|
// get the user name
|
|
DWORD dwUserLength = MAX_STRING_LENGTH;
|
|
if ( FALSE == GetUserNameEx( NameSamCompatible, pwszUserName, &dwUserLength ) )
|
|
{
|
|
// error occured while trying to get the current user info
|
|
SaveLastError();
|
|
return( FALSE );
|
|
}
|
|
|
|
// release the extra buffer allocated
|
|
strUserName.ReleaseBuffer();
|
|
}
|
|
|
|
// get the required buffer
|
|
pwszPassword = strPassword.GetBufferSetLength( MAX_STRING_LENGTH );
|
|
|
|
// accept the password from the user
|
|
strBuffer.Format( INPUT_PASSWORD, strUserName );
|
|
WriteConsoleW( GetStdHandle( STD_OUTPUT_HANDLE ),
|
|
strBuffer, strBuffer.GetLength(), &dwSize, NULL );
|
|
bResult = GetPassword( pwszPassword, 256 );
|
|
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, strServer,
|
|
strUserName, strPassword, ppAuthIdentity, FALSE, pwszNamespace, &hRes, pbLocalSystem );
|
|
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
WMISaveError( WBEM_E_OUT_OF_MEMORY );
|
|
return FALSE;
|
|
}
|
|
// return the success
|
|
return bResult;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
GetSecurityArguments(
|
|
IN IUnknown *pInterface,
|
|
OUT DWORD& dwAuthorization,
|
|
OUT DWORD& dwAuthentication
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Gets the security arguments for an interface.
|
|
|
|
Arguments:
|
|
[IN] pInterface - Pointer to interface stucture.
|
|
[OUT] dwAuthorization - Holds Authorization value.
|
|
[OUT] dwAuthentication - Holds the Authentication value.
|
|
|
|
Return Value:
|
|
Returns HRESULT value.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 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
|
|
hRes = pInterface->QueryInterface( IID_IClientSecurity, (void**) &pClientSecurity );
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
// got the client security interface
|
|
// now try to get the security services values
|
|
hRes = pClientSecurity->QueryBlanket( pInterface,
|
|
&dwAuthnSvc, &dwAuthzSvc, NULL, NULL, NULL, NULL, NULL );
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
// we've got the values from the interface
|
|
dwAuthentication = dwAuthnSvc;
|
|
dwAuthorization = dwAuthzSvc;
|
|
}
|
|
|
|
// release the client security interface
|
|
SAFE_RELEASE( pClientSecurity );
|
|
}
|
|
|
|
// return always success
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
SetInterfaceSecurity(
|
|
IN IUnknown *pInterface,
|
|
IN LPCWSTR pwszUser,
|
|
IN LPCWSTR pwszPassword,
|
|
OUT COAUTHIDENTITY **ppAuthIdentity
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Sets interface security.
|
|
|
|
Arguments:
|
|
[IN] pInterface - Pointer to the interface to which security has to be set.
|
|
[IN] pwszUser - Holds the user name of the server.
|
|
[IN] pwszPassword - Hold the password of the user.
|
|
[OUT] ppAuthIdentity - Pointer to authentication structure.
|
|
|
|
Return Value:
|
|
returns HRESULT value.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 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 );
|
|
}
|
|
// get the current security argument value
|
|
// GetSecurityArguments( pInterface, dwAuthorization, dwAuthentication );
|
|
|
|
// 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
|
|
hRes = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization,
|
|
NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
|
|
|
|
// return the result
|
|
return hRes;
|
|
}
|
|
|
|
// 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 ( ( lPos = strUser.Find( L'\\' ) ) != -1 )
|
|
{
|
|
// user name contains domain name ... domain\user format
|
|
strDomain = strUser.Left( lPos );
|
|
strUser = strUser.Mid( lPos + 1 );
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
// check if authenication info is available or not ...
|
|
// initialize the security authenication information ... UNICODE VERSION STRUCTURE
|
|
if ( NULL == ppAuthIdentity )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
else if ( NULL == *ppAuthIdentity )
|
|
{
|
|
hRes = WbemAllocAuthIdentity( pwszUserArg, pwszPassword, pwszDomainArg, ppAuthIdentity );
|
|
if ( FAILED(hRes) )
|
|
{
|
|
return hRes;
|
|
}
|
|
}
|
|
|
|
// set the security information to the interface
|
|
hRes = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization, NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, *ppAuthIdentity, EOAC_NONE );
|
|
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
hRes = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
// return the result
|
|
return hRes;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
SetInterfaceSecurity(
|
|
IN IUnknown *pInterface,
|
|
IN COAUTHIDENTITY *pAuthIdentity
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Sets the interface security for the interface.
|
|
|
|
Arguments:
|
|
[IN] pInterface - pointer to the interface.
|
|
[IN] pAuthIdentity - pointer to authentication structure.
|
|
|
|
Return Value:
|
|
returns HRESULT value.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = S_OK;
|
|
DWORD dwAuthorization = RPC_C_AUTHZ_NONE;
|
|
DWORD dwAuthentication = RPC_C_AUTHN_WINNT;
|
|
|
|
// check the interface
|
|
if ( NULL == pInterface )
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
// get the current security argument value
|
|
hRes = GetSecurityArguments( pInterface, dwAuthorization, dwAuthentication );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
// set the security information to the interface
|
|
hRes = SetProxyBlanket( pInterface, dwAuthentication, dwAuthorization, NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, pAuthIdentity, EOAC_NONE );
|
|
|
|
// return the result
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
WINAPI SetProxyBlanket(
|
|
IN IUnknown *pInterface,
|
|
IN DWORD dwAuthnSvc,
|
|
IN DWORD dwAuthzSvc,
|
|
IN LPWSTR pwszPrincipal,
|
|
IN DWORD dwAuthLevel,
|
|
IN DWORD dwImpLevel,
|
|
IN RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
|
|
IN DWORD dwCapabilities
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Sets proxy blanket for the interface.
|
|
|
|
Arguments:
|
|
[IN] pInterface - pointer to the inteface.
|
|
[IN] dwAuthnsvc - Authentication service to use.
|
|
[IN] dwAuthzSvc - Authorization service to use.
|
|
[IN] pwszPricipal - Server principal name to use with the authentication service.
|
|
[IN] dwAuthLevel - Authentication level to use.
|
|
[IN] dwImpLevel - Impersonation level to use.
|
|
[IN] pAuthInfo - Identity of the client.
|
|
[IN] dwCapabilities - Capability flags.
|
|
|
|
Return Value:
|
|
Return HRESULT value.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 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
|
|
hRes = pInterface->QueryInterface( IID_IUnknown, (void **) &pUnknown );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
return hRes;
|
|
}
|
|
// now get the client security interface
|
|
hRes = pInterface->QueryInterface( IID_IClientSecurity, (void **) &pClientSecurity );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
SAFE_RELEASE( pUnknown );
|
|
return hRes;
|
|
}
|
|
|
|
// now set the security
|
|
hRes = pClientSecurity->SetBlanket( pInterface, dwAuthnSvc, dwAuthzSvc, pwszPrincipal,
|
|
dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities );
|
|
|
|
if( FAILED( hRes ) )
|
|
{
|
|
SAFE_RELEASE( pUnknown );
|
|
SAFE_RELEASE( pClientSecurity );
|
|
return hRes;
|
|
}
|
|
|
|
// release the security interface
|
|
SAFE_RELEASE( pClientSecurity );
|
|
|
|
// we should check the auth identity structure. if exists .. set for IUnknown also
|
|
if ( NULL != pAuthInfo )
|
|
{
|
|
hRes = pUnknown->QueryInterface( IID_IClientSecurity, (void **) &pClientSecurity );
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
// set security authentication
|
|
hRes = pClientSecurity->SetBlanket(
|
|
pUnknown, dwAuthnSvc, dwAuthzSvc, pwszPrincipal,
|
|
dwAuthLevel, dwImpLevel, pAuthInfo, dwCapabilities );
|
|
|
|
// release
|
|
SAFE_RELEASE( pClientSecurity );
|
|
}
|
|
else if ( E_NOINTERFACE == hRes )
|
|
{
|
|
hRes = S_OK; // ignore no interface errors
|
|
}
|
|
}
|
|
|
|
// release the IUnknown
|
|
SAFE_RELEASE( pUnknown );
|
|
|
|
// return the result
|
|
return hRes;
|
|
}
|
|
|
|
HRESULT
|
|
WINAPI WbemAllocAuthIdentity(
|
|
IN LPCWSTR pwszUser,
|
|
IN LPCWSTR pwszPassword,
|
|
IN LPCWSTR pwszDomain,
|
|
OUT COAUTHIDENTITY **ppAuthIdent
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Allocate memory for authentication variables.
|
|
|
|
Arguments:
|
|
[IN] pwszUser - User name.
|
|
[IN] pwszPassword - Password.
|
|
[IN] pwszDomain - Domain name.
|
|
[OUT] ppAuthIdent - Pointer to authentication structure.
|
|
|
|
Return Value:
|
|
Returns HRESULT value.
|
|
--*/
|
|
{
|
|
// 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 ( pAuthIdent == NULL )
|
|
{
|
|
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(
|
|
IN COAUTHIDENTITY** ppAuthIdentity
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Frees the memory of authentication stucture variable.
|
|
|
|
Arguments:
|
|
[IN] ppAuthIdentity - Pointer to authentication structure.
|
|
|
|
Return Value:
|
|
none.
|
|
--*/
|
|
{
|
|
// make sure we have a pointer, then walk the structure members and cleanup.
|
|
if ( NULL != *ppAuthIdentity )
|
|
{
|
|
// 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(
|
|
IN HRESULT hResError
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Gets WMI error description.
|
|
|
|
Arguments:
|
|
[IN] hResError - Contain error value.
|
|
|
|
Return Value:
|
|
none.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes;
|
|
IWbemStatusCodeText *pWbemStatus = NULL;
|
|
|
|
CHString strBuffer = L"\0";
|
|
|
|
// if the error is win32 based, choose FormatMessage to get the message
|
|
switch( hResError )
|
|
{
|
|
case E_ACCESSDENIED: // Message: "Access Denied"
|
|
case ERROR_NO_SUCH_USER: // Message: "The specified user does not exist."
|
|
{
|
|
// change the error message to "Logon failure: unknown user name or bad password."
|
|
if ( E_ACCESSDENIED == hResError )
|
|
{
|
|
hResError = ERROR_LOGON_FAILURE;
|
|
}
|
|
// ...
|
|
SetLastError( hResError );
|
|
SaveLastError();
|
|
return;
|
|
}
|
|
case REGDB_E_CLASSNOTREG: // Message: Class not registered.
|
|
{
|
|
SetLastError( hResError );
|
|
SetReason( ERROR_REMOTE_INCOMPATIBLE );
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
try
|
|
{
|
|
// get the pointer to buffer
|
|
LPWSTR pwszBuffer = NULL;
|
|
pwszBuffer = strBuffer.GetBufferSetLength( MAX_STRING_LENGTH );
|
|
|
|
// get the wbem specific status code text
|
|
hRes = CoCreateInstance( CLSID_WbemStatusCodeText,
|
|
NULL, CLSCTX_INPROC_SERVER, IID_IWbemStatusCodeText, ( LPVOID* ) &pWbemStatus );
|
|
|
|
// check whether we got the interface or not
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
// get the error message
|
|
BSTR bstr = NULL;
|
|
hRes = pWbemStatus->GetErrorCodeText( hResError, 0, 0, &bstr );
|
|
if ( SUCCEEDED( hRes ) )
|
|
{
|
|
// get the error message in proper format
|
|
StringCopyW( pwszBuffer, bstr, MAX_STRING_LENGTH );
|
|
|
|
// free the BSTR
|
|
SysFreeString( bstr );
|
|
bstr = NULL;
|
|
|
|
// now release status code interface
|
|
SAFE_RELEASE( pWbemStatus );
|
|
}
|
|
else
|
|
{
|
|
// failed to get the error message ... get the com specific error message
|
|
_com_issue_error( hResError );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// failed to get the error message ... get the com specific error message
|
|
_com_issue_error( hResError );
|
|
}
|
|
|
|
// release the buffer
|
|
strBuffer.ReleaseBuffer();
|
|
// set the reason
|
|
strBuffer += L"\n";
|
|
SetReason( strBuffer );
|
|
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
try
|
|
{
|
|
// get the error message
|
|
strBuffer.ReleaseBuffer();
|
|
if ( NULL != e.ErrorMessage() )
|
|
{
|
|
strBuffer = e.ErrorMessage();
|
|
}
|
|
}
|
|
catch( CHeap_Exception )
|
|
{
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
SaveLastError();
|
|
}
|
|
}
|
|
catch(CHeap_Exception)
|
|
{
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
SaveLastError();
|
|
return;
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
GetTargetVersionEx(
|
|
IN IWbemServices* pWbemServices,
|
|
IN COAUTHIDENTITY* pAuthIdentity
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Get the OS version of the target machine.
|
|
Arguments:
|
|
[IN] pWbemServices - Pointer to IWbemServices object.
|
|
[IN] pAuthIdentity - Poointer to authentication structure.
|
|
Return Value:
|
|
0 if failed to get version number, else non-zero value.
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = S_OK;
|
|
LONG lPos = 0;
|
|
DWORD dwMajor = 0;
|
|
DWORD dwMinor = 0;
|
|
DWORD dwVersion = 0;
|
|
ULONG ulReturned = 0;
|
|
IWbemClassObject* pWbemObject = NULL;
|
|
IEnumWbemClassObject* pWbemInstances = NULL;
|
|
CHString strVersion;
|
|
|
|
// 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
|
|
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;
|
|
}
|
|
|
|
// return
|
|
return dwVersion;
|
|
}
|
|
|
|
BOOL
|
|
PropertyGet(
|
|
IN IWbemClassObject* pWmiObject,
|
|
IN LPCWSTR pwszProperty,
|
|
OUT CHString& strValue,
|
|
IN LPCWSTR pwszDefault
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Gets the value of the property from the WMI class object in string format
|
|
Arguments:
|
|
[IN] pWmiObject : pointer to the WBEM class object
|
|
[IN] pwszProperty : the name of the property to retrieve
|
|
[OUT] strValue : variable to hold the retrieved property
|
|
[IN] pwszDefault : 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 hRes = 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
|
|
hRes = PropertyGet( pWmiObject, pwszProperty, var );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
_com_issue_error( hRes );
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
HRESULT
|
|
PropertyGet(
|
|
IN IWbemClassObject* pWmiObject,
|
|
IN LPCWSTR pwszProperty,
|
|
OUT _variant_t& varValue
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Gets the value of the property from the WMI class object
|
|
Arguments:
|
|
[IN] pWmiObject : pointer to the WBEM class object
|
|
[IN] pwszProperty : property name
|
|
[OUT] varValue : value of the property
|
|
Return Value:
|
|
HRESULT
|
|
--*/
|
|
{
|
|
// local variables
|
|
HRESULT hRes = 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.
|
|
hRes = pWmiObject->Get( _bstr_t( pwszProperty ), 0, &vtValue, NULL, NULL );
|
|
if ( FAILED( hRes ) )
|
|
{
|
|
// Clear the variant variable
|
|
VariantClear( &vtValue );
|
|
// Return error.
|
|
return hRes;
|
|
}
|
|
|
|
// set the value
|
|
varValue = vtValue;
|
|
}
|
|
catch( _com_error& e )
|
|
{
|
|
hRes = e.Error();
|
|
}
|
|
|
|
// Clear the variables.
|
|
VariantClear( &vtValue );
|
|
// Return.
|
|
return hRes;
|
|
}
|