windows-nt/Source/XPSP1/NT/base/remoteboot/admin/cservice.cpp
2020-09-26 16:20:57 +08:00

1774 lines
34 KiB
C++

//
// Copyright 1997 - Microsoft
//
// CCOMPUTR.CPP - Handles the computer object property pages.
//
#include "pch.h"
#include "imos.h"
#include "local.h"
#include "newclnts.h"
#include "tools.h"
#include "varconv.h"
#include "cservice.h"
#include "cenumsif.h"
DEFINE_MODULE("IMADMUI")
DEFINE_THISCLASS("CService")
#define THISCLASS CService
#define LPTHISCLASS LPSERVICE
// ************************************************************************
//
// Constructor / Destructor
//
// ************************************************************************
//
// CreateInstance()
//
LPVOID
CService_CreateInstance( void )
{
TraceFunc( "CService_CreateInstance()\n" );
LPTHISCLASS lpcc = new THISCLASS( );
HRESULT hr = THR( lpcc->Init( ) );
if ( hr )
{
delete lpcc;
RETURN(NULL);
}
RETURN((LPVOID)lpcc);
}
//
// Constructor
//
THISCLASS::THISCLASS( )
{
TraceClsFunc( "CService()\n" );
InterlockIncrement( g_cObjects );
TraceFuncExit();
}
//
// Init()
//
STDMETHODIMP
THISCLASS::Init( )
{
TraceClsFunc( "Init()\n" );
// IUnknown stuff
BEGIN_QITABLE_IMP( CService, IShellExtInit );
QITABLE_IMP( IShellExtInit );
QITABLE_IMP( IShellPropSheetExt );
QITABLE_IMP( IIntelliMirrorSAP );
END_QITABLE_IMP( CService );
Assert( _cRef == 0);
Assert( !_pads );
Assert( !_pszSCPDN );
Assert( !_pszGroupDN );
Assert( !_pszMachineName );
AddRef( );
_InitParams.dwSize = sizeof(_InitParams);
HRESULT hr = S_OK;
hr = CheckClipboardFormats( );
// Private Members
Assert( _pads == NULL );
_uMode = MODE_SHELL; // default
HRETURN(hr);
}
STDMETHODIMP
THISCLASS::Init2( IADs * pads )
{
TraceClsFunc( "Init2( " );
TraceMsg( TF_FUNC, "pads = 0x%08x )\n", pads );
HRESULT hr;
if ( !pads )
HRETURN(E_INVALIDARG);
_pads = pads;
_pads->AddRef( );
hr = _GetComputerNameFromADs( );
if (FAILED( hr ))
goto Error;
Error:
HRETURN(hr);
}
//
// Destructor
//
THISCLASS::~THISCLASS( )
{
TraceClsFunc( "~CService()\n" );
// Private Members
if ( _pads )
{
//
// note: we shouldn't commit anything in the destructor -- we can't
// catch failures here. We'll just have to make sure that we
// explicitly commit changes when necessary
//
#if 0
// Commit any changes before we release
THR( _pads->SetInfo( ) );
#endif
_pads->Release( );
}
if ( _pszSCPDN )
TraceFree( _pszSCPDN );
if ( _pszGroupDN )
TraceFree( _pszGroupDN );
if ( _pszMachineName )
TraceFree( _pszMachineName );
if ( _pszDSServerName )
TraceFree( _pszDSServerName );
if ( _pDataObj )
_pDataObj->Release( );
#if 0 // EricB might be adding an AddRef( ) to this. Until then, don't release.
if ( _InitParams.pDsObj )
_InitParams.pDsObj->Release( );
#endif
InterlockDecrement( g_cObjects );
TraceFuncExit();
};
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//
// QueryInterface()
//
STDMETHODIMP
THISCLASS::QueryInterface(
REFIID riid,
LPVOID *ppv )
{
TraceClsFunc( "" );
HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
QIRETURN( hr, riid );
}
//
// AddRef()
//
STDMETHODIMP_(ULONG)
THISCLASS::AddRef( void )
{
TraceClsFunc( "[IUnknown] AddRef( )\n" );
InterlockIncrement( _cRef );
RETURN(_cRef);
}
//
// Release()
//
STDMETHODIMP_(ULONG)
THISCLASS::Release( void )
{
TraceClsFunc( "[IUnknown] Release( )\n" );
InterlockDecrement( _cRef );
if ( _cRef )
RETURN(_cRef);
TraceDo( delete this );
RETURN(0);
}
// ************************************************************************
//
// IShellExtInit
//
// ************************************************************************
//
// Initialize()
//
HRESULT
THISCLASS::Initialize(
LPCITEMIDLIST pidlFolder,
LPDATAOBJECT lpdobj, HKEY hkeyProgID)
{
TraceClsFunc( "[IShellExtInit] Initialize( " );
TraceMsg( TF_FUNC, " pidlFolder = 0x%08x, lpdobj = 0x%08x, hkeyProgID = 0x%08x )\n",
pidlFolder, lpdobj, hkeyProgID );
if ( !lpdobj )
RETURN(E_INVALIDARG);
HRESULT hr = S_OK;
FORMATETC fmte;
STGMEDIUM stg = { 0 };
STGMEDIUM stgOptions = { 0 };
LPWSTR pszObjectName;
LPWSTR pszClassName;
LPWSTR pszAttribPrefix;
LPDSOBJECT pDsObject;
LPDSOBJECTNAMES pDsObjectNames;
LPDSDISPLAYSPECOPTIONS pDsDisplayOptions;
BOOL b;
#if 0
IADs * padsGroup = NULL;
LPWSTR pszGroupClass = NULL;
LPWSTR pszParent = NULL;
#endif
_pDataObj = lpdobj;
_pDataObj->AddRef( );
//
// Retrieve the Object Names
//
fmte.cfFormat = (CLIPFORMAT)g_cfDsObjectNames;
fmte.tymed = TYMED_HGLOBAL;
fmte.dwAspect = DVASPECT_CONTENT;
fmte.lindex = -1;
fmte.ptd = 0;
hr = THR( _pDataObj->GetData( &fmte, &stg) );
if ( hr )
goto Cleanup;
pDsObjectNames = (LPDSOBJECTNAMES) stg.hGlobal;
Assert( stg.tymed == TYMED_HGLOBAL );
TraceMsg( TF_ALWAYS, "Object's Namespace CLSID: " );
TraceMsgGUID( TF_ALWAYS, pDsObjectNames->clsidNamespace );
TraceMsg( TF_ALWAYS, "\tNumber of Objects: %u \n", pDsObjectNames->cItems );
Assert( pDsObjectNames->cItems == 1 );
pDsObject = (LPDSOBJECT) pDsObjectNames->aObjects;
pszObjectName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetName );
pszClassName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetClass );
TraceMsg( TF_ALWAYS, "Object Name (Class): %s (%s)\n", pszObjectName, pszClassName );
_pszDSServerName = TraceStrDup( pszObjectName );
//
// If they handed us a "Computer" object, look at the NETBOOTSAP
// attribute to get the IMSAP object.
//
if ( StrCmp( pszClassName, DSCOMPUTERCLASSNAME ) == 0 )
{
IADs* pads = NULL;
VARIANT var;
VariantInit( &var );
Assert( !_pszMachineName );
//
// Bind to the MAO in the DS
//
hr = THR( ADsGetObject( pszObjectName, IID_IADs, (void **)&pads ) );
if (FAILED( hr ))
goto Computer_Cleanup;
hr = THR( pads->Get( NETBOOTSAP, &var ) );
if (FAILED( hr ))
goto Computer_Cleanup;
Assert( V_VT( &var ) == VT_BSTR );
// Try to parse the string to connect to the same server as the DSADMIN
hr = _FixObjectPath( V_BSTR( &var ), &_pszSCPDN );
if (FAILED( hr ))
goto Computer_Cleanup;
DebugMsg( "SCP Path: %s\n", _pszSCPDN );
VariantClear( &var );
// while we are here, might as well get the server's NETBIOS name
hr = THR( pads->Get( SAMNAME, &var ) );
if (FAILED( hr ))
goto Computer_Cleanup;
Assert( V_VT( &var) == VT_BSTR );
_pszMachineName = TraceStrDup( V_BSTR( &var ) );
if ( _pszMachineName )
{
LPWSTR psz = &_pszMachineName[ wcslen( _pszMachineName ) - 1 ];
if ( *psz == L'$' )
{
*psz = L'\0';
}
DebugMsg( "Server Name: %ws\n", _pszMachineName );
}
Computer_Cleanup:
VariantClear( &var );
if ( pads )
pads->Release( );
if (FAILED( hr ))
goto Error;
// create the DS notify object
hr = THR( ADsPropCreateNotifyObj( _pDataObj, pszObjectName, &_hwndNotify ) );
if (FAILED( hr ))
goto Error;
b = ADsPropGetInitInfo( _hwndNotify, &_InitParams );
if ( !b )
{
hr = E_FAIL;
goto Error;
}
hr = THR( _InitParams.hr );
if (FAILED( hr ))
goto Error;
// Bind to the IMSAP in the DS
Assert( _pszSCPDN );
hr = THR( ADsGetObject( _pszSCPDN, IID_IADs, (void **)&_pads ) );
if (FAILED( hr ))
goto Error;
}
else if ( StrCmp( pszClassName, DSIMSAPCLASSNAME ) )
{
//
// This should be a IMSAP.
//
hr = E_INVALIDARG;
goto Error;
}
else
{
// Keep the DN around
_pszSCPDN = TraceStrDup( pszObjectName );
Assert( !_pszMachineName );
// create the DS notify object
hr = THR( ADsPropCreateNotifyObj( _pDataObj, pszObjectName, &_hwndNotify ) );
if (FAILED( hr ))
goto Error;
b = ADsPropGetInitInfo( _hwndNotify, &_InitParams );
if ( !b )
{
hr = E_FAIL;
goto Error;
}
hr = THR( _InitParams.hr );
if (FAILED( hr ))
goto Error;
// Bind to the IMSAP in the DS
Assert( _pszSCPDN );
hr = THR( _InitParams.pDsObj->QueryInterface( IID_IADs, (void **)&_pads ) );
if (FAILED( hr ))
goto Error;
}
Assert( _pads );
//
// Retrieve the Display Spec Options
//
fmte.cfFormat = (CLIPFORMAT)g_cfDsDisplaySpecOptions;
fmte.tymed = TYMED_HGLOBAL;
fmte.dwAspect = DVASPECT_CONTENT;
fmte.lindex = -1;
fmte.ptd = 0;
hr = THR( _pDataObj->GetData( &fmte, &stgOptions ) );
if ( hr )
goto Error;
pDsDisplayOptions = (LPDSDISPLAYSPECOPTIONS) stgOptions.hGlobal;
Assert( stgOptions.tymed == TYMED_HGLOBAL );
Assert( pDsDisplayOptions->dwSize == sizeof(DSDISPLAYSPECOPTIONS) );
pszAttribPrefix = (LPWSTR) PtrToByteOffset( pDsDisplayOptions, pDsDisplayOptions->offsetAttribPrefix );
// TraceMsg( TF_ALWAYS, TEXT("Attribute Prefix: %s\n"), pszAttribPrefix );
if ( StrCmpW( pszAttribPrefix, STRING_ADMIN ) == 0 )
{
_uMode = MODE_ADMIN;
}
// else default from Init()
TraceMsg( TF_ALWAYS, TEXT("Mode: %s\n"), _uMode == MODE_ADMIN ? TEXT("Admin") : TEXT("Shell") );
ReleaseStgMedium( &stgOptions );
#if 0
//
// Check to see if it is in a Group by checking the parent DN's class
//
pszParent = StrChr( _pszSCPDN, L',' );
Assert( pszParent );
if ( !pszParent ) {
hr = THR(E_FAIL);
goto Error;
}
pszParent++; // move just past the comma
// create a new string by adding "LDAP://server/"
hr = _FixObjectPath( pszParent, &pszParent );
if (FAILED( hr ))
goto Error;
// Bind to the object
hr = THR( ADsGetObject( pszParent, IID_IADs, (void **)&padsGroup ) );
if (FAILED( hr ))
goto Error;
Assert( !pszGroupClass );
hr = THR( padsGroup->get_Class( &pszGroupClass ) );
if (FAILED( hr ))
goto Error;
Assert( !_pszGroupDN );
DebugMsg( "SCP's parents Class is '%s'\n", pszGroupClass );
if ( StrCmpI( pszGroupClass, DSGROUPCLASSNAME ) == 0 ) {
_pszGroupDN = (LPWSTR) TraceStrDup( pszObjectName );
TraceMsg( TF_ALWAYS, TEXT("Server is in group: %s\n"), _pszGroupDN );
}
#endif
Cleanup:
#if 0
if ( pszGroupClass )
SysFreeString( pszGroupClass );
if ( pszParent )
TraceFree( pszParent );
if ( padsGroup )
padsGroup->Release();
#endif
HRETURN(hr);
Error:
MessageBoxFromHResult( NULL, IDS_ERROR_READINGCOMPUTERACCOUNT, hr );
goto Cleanup;
}
// ************************************************************************
//
// IShellPropSheetExt
//
// ************************************************************************
//
// AddPages()
//
HRESULT
THISCLASS::AddPages(
LPFNADDPROPSHEETPAGE lpfnAddPage,
LPARAM lParam)
{
TraceClsFunc( "[IShellPropSheetExt] AddPages( )\n" );
if ( !lpfnAddPage )
RRETURN(E_POINTER);
HRESULT hr = S_OK;
hr = THR( ::AddPagesEx( NULL,
CNewClientsTab_CreateInstance,
lpfnAddPage,
lParam,
(LPUNKNOWN) (IShellExtInit*) this ) );
if (FAILED( hr ))
goto Error;
hr = THR( ::AddPagesEx( NULL,
CIntelliMirrorOSTab_CreateInstance,
lpfnAddPage,
lParam,
(LPUNKNOWN) (IShellExtInit*) this ) );
if (FAILED( hr ))
goto Error;
#ifdef LOCALOS_PAGE
hr = THR( ::AddPagesEx( NULL,
CLocalInstallOSTab_CreateInstance,
lpfnAddPage,
lParam,
(LPUNKNOWN) (IShellExtInit*) this ) );
if (FAILED( hr ))
goto Error;
#endif // LOCALOS_PAGE
hr = THR( ::AddPagesEx( NULL,
CToolsTab_CreateInstance,
lpfnAddPage,
lParam,
(LPUNKNOWN) (IShellExtInit*) this ) );
if (FAILED( hr ))
goto Error;
Error:
HRETURN(hr);
}
//
// ReplacePage()
//
HRESULT
THISCLASS::ReplacePage(
UINT uPageID,
LPFNADDPROPSHEETPAGE lpfnReplaceWith,
LPARAM lParam )
{
TraceClsFunc( "[IShellPropSheetExt] ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
RETURN(E_NOTIMPL);
}
// ************************************************************************
//
// IIntelliMirrorSAP
//
// ************************************************************************
//
// CommitChanges( )
//
HRESULT
THISCLASS::CommitChanges( void )
{
TraceClsFunc( "[IIntelliMirrorSAP] CommitChanges( )\n" );
Assert( _pads );
HRESULT hr;
SC_HANDLE schManager = NULL;
SC_HANDLE sch = NULL;
SERVICE_STATUS ss;
hr = THR( _pads->SetInfo( ) );
if ( FAILED( hr ) )
goto Error;
// if we don't have this yet, get it now.
if ( !_pszMachineName )
{
hr = _GetComputerNameFromADs( );
if (FAILED( hr ))
goto Error;
}
schManager = OpenSCManager( _pszMachineName, NULL, SC_MANAGER_CONNECT );
if (!schManager)
{
DWORD dwErr = GetLastError( );
hr = HRESULT_FROM_WIN32( dwErr );
goto Error;
}
sch = OpenService( schManager, BINL_SERVER_NAME, SERVICE_USER_DEFINED_CONTROL);
if (!sch)
{
DWORD dwErr = GetLastError( );
hr = HRESULT_FROM_WIN32( dwErr );
goto Error;
}
if ( !ControlService( sch, BINL_SERVICE_REREAD_SETTINGS, &ss ) )
{
DWORD dwErr = GetLastError( );
hr = THR(HRESULT_FROM_WIN32( dwErr ));
goto Error;
}
hr = HRESULT_FROM_WIN32( ss.dwWin32ExitCode );
Error:
if ( sch )
CloseServiceHandle( sch );
if ( schManager )
CloseServiceHandle( schManager );
if ( hr == HRESULT_FROM_WIN32( ERROR_SERVICE_NOT_ACTIVE ) )
{
hr = S_OK; // ignore error... by design
}
HRETURN(hr);
}
//
// IsAdmin( )
//
HRESULT
THISCLASS::IsAdmin(
BOOL * fAdmin )
{
TraceClsFunc( "[IIntelliMirrorSAP] IsAdmin( )\n" );
if ( !fAdmin )
RRETURN( E_INVALIDARG );
HRESULT hr = S_OK;
*fAdmin = (_uMode == MODE_ADMIN);
HRETURN(hr);
}
//
// GetAllowNewClients( )
//
HRESULT
THISCLASS::GetAllowNewClients(
BOOL *pbool )
{
TraceClsFunc("[IIntelliMirrorSAP] GetAllowNewClients( ... )\n" );
if ( !pbool )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTALLOWNEWCLIENTS, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BOOL )
{
*pbool = V_BOOL(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetAllowNewClients( )
//
HRESULT
THISCLASS::SetAllowNewClients(
BOOL boolval )
{
TraceClsFunc("[IIntelliMirrorSAP] SetAllowNewClients( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_BOOL;
V_BOOL( &var ) = (VARIANT_BOOL)boolval;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTALLOWNEWCLIENTS, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetLimitClients( )
//
HRESULT
THISCLASS::GetLimitClients(
BOOL *pbool )
{
TraceClsFunc("[IIntelliMirrorSAP] GetLimitClients( ... )\n" );
if ( !pbool )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTLIMITCLIENTS, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BOOL )
{
*pbool = V_BOOL(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetLimitClients( )
//
HRESULT
THISCLASS::SetLimitClients(
BOOL boolval )
{
TraceClsFunc("[IIntelliMirrorSAP] SetLimitClients( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_BOOL;
V_BOOL( &var ) = (VARIANT_BOOL)boolval;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTLIMITCLIENTS, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetMaxClients( )
//
HRESULT
THISCLASS::GetMaxClients(
UINT *puMax )
{
TraceClsFunc("[IIntelliMirrorSAP] GetMaxClients( ... )\n" );
if ( !puMax )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTMAXCLIENTS, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_I4 )
{
*puMax = V_I4(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetMaxClients( )
//
HRESULT
THISCLASS::SetMaxClients(
UINT uMax )
{
TraceClsFunc("[IIntelliMirrorSAP] SetMaxClients( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_I4;
V_I4( &var ) = uMax;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTMAXCLIENTS, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetCurrentClientCount( )
//
HRESULT
THISCLASS::GetCurrentClientCount(
UINT *puCount )
{
TraceClsFunc("[IIntelliMirrorSAP] GetCurrentClientCount( ... )\n" );
if ( !puCount )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTCURRENTCLIENTCOUNT, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_I4 )
{
*puCount = V_I4(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetCurrentClientCount( )
//
HRESULT
THISCLASS::SetCurrentClientCount(
UINT uCount )
{
TraceClsFunc("[IIntelliMirrorSAP] SetCurrentClientCount( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_I4;
V_I4( &var ) = uCount;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTCURRENTCLIENTCOUNT, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetAnswerRequests( )
//
HRESULT
THISCLASS::GetAnswerRequests(
BOOL *pbool )
{
TraceClsFunc("[IIntelliMirrorSAP] GetAnswerRequests( ... )\n" );
if ( !pbool )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTANSWERREQUESTS, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BOOL )
{
*pbool = V_BOOL(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetAnswerRequests( )
//
HRESULT
THISCLASS::SetAnswerRequests(
BOOL boolval )
{
TraceClsFunc("[IIntelliMirrorSAP] SetAnswerRequests( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_BOOL;
V_BOOL( &var ) = (VARIANT_BOOL)boolval;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTANSWERREQUESTS, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetAnswerOnlyValidClients( )
//
HRESULT
THISCLASS::GetAnswerOnlyValidClients(
BOOL *pbool )
{
TraceClsFunc("[IIntelliMirrorSAP] GetAnswerOnlyValidClients( ... )\n" );
if ( !pbool )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTANSWERONLYVALIDCLIENTS, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BOOL )
{
*pbool = V_BOOL(&var);
hr = S_OK;
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetAnswerOnlyValidClients( )
//
HRESULT
THISCLASS::SetAnswerOnlyValidClients(
BOOL boolval )
{
TraceClsFunc("[IIntelliMirrorSAP] SetAnswerOnlyValidClients( ... )\n" );
HRESULT hr;
VARIANT var;
VariantInit( &var );
V_VT( &var ) = VT_BOOL;
V_BOOL( &var ) = (VARIANT_BOOL)boolval;
Assert( _pads );
hr = THR( _pads->Put( NETBOOTANSWERONLYVALIDCLIENTS, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetNewMachineNamingPolicy( )
//
HRESULT
THISCLASS::GetNewMachineNamingPolicy(
LPWSTR *pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] GetNewMachineNamingPolicy( ... )\n" );
if ( !pwsz )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTNEWMACHINENAMINGPOLICY, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BSTR )
{
*pwsz = TraceStrDup( V_BSTR(&var) );
if (!*pwsz)
{
hr = E_OUTOFMEMORY;
}
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetNewMachineNamingPolicy( )
//
HRESULT
THISCLASS::SetNewMachineNamingPolicy(
LPWSTR pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] SetNewMachineNamingPolicy( ... )\n" );
HRESULT hr;
VARIANT var;
Assert( _pads );
if ( pwsz )
{
V_VT( &var ) = VT_BSTR;
V_BSTR( &var ) = SysAllocString( pwsz );
if (V_BSTR(&var) == NULL) {
RRETURN(E_OUTOFMEMORY);
}
hr = THR( _pads->Put( NETBOOTNEWMACHINENAMINGPOLICY, var ) );
VariantClear( &var );
}
else
{
VariantInit( &var );
hr = THR( _pads->PutEx( ADS_PROPERTY_CLEAR, NETBOOTNEWMACHINENAMINGPOLICY, var ) );
}
HRETURN(hr);
}
//
// GetNewMachineOU( )
//
HRESULT
THISCLASS::GetNewMachineOU(
LPWSTR *pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] GetNewMachineOU( ... )\n" );
if ( !pwsz )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTNEWMACHINEOU, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BSTR )
{
*pwsz = TraceStrDup( V_BSTR(&var) );
if (!*pwsz)
{
hr = E_OUTOFMEMORY;
}
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetNewMachineOU( )
//
HRESULT
THISCLASS::SetNewMachineOU(
LPWSTR pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] SetNewMachineOU( ... )\n" );
HRESULT hr;
VARIANT var;
Assert( _pads );
if ( pwsz )
{
V_VT( &var ) = VT_BSTR;
V_BSTR( &var ) = SysAllocString( pwsz );
if (V_BSTR(&var) == NULL) {
RRETURN(E_OUTOFMEMORY);
}
hr = THR( _pads->Put( NETBOOTNEWMACHINEOU, var ) );
VariantClear( &var );
}
else
{
VariantInit( &var );
hr = THR( _pads->PutEx( ADS_PROPERTY_CLEAR, NETBOOTNEWMACHINEOU, var ) );
}
HRETURN(hr);
}
//
// EnumIntelliMirrorOSes( )
//
HRESULT
THISCLASS::EnumIntelliMirrorOSes(
DWORD dwFlags,
LPUNKNOWN *punk )
{
TraceClsFunc("[IIntelliMirrorSAP] EnumIntelliMirrorOSes( ... )\n" );
if ( !punk )
RRETURN(E_INVALIDARG);
HRESULT hr = S_OK;
Assert( _pads );
*punk = (LPUNKNOWN)
CEnumIMSIFs_CreateInstance( REMOTE_INSTALL_IMAGE_DIR_W, NETBOOTINTELLIMIRROROSES, dwFlags, _pads );
if ( !*punk )
{
hr = E_FAIL;
}
HRETURN(hr);
}
//
// EnumTools( )
//
HRESULT
THISCLASS::EnumTools(
DWORD dwFlags,
LPUNKNOWN *punk )
{
TraceClsFunc("[IIntelliMirrorSAP] EnumTools( ... )\n" );
if ( !punk )
RETURN(E_INVALIDARG);
HRESULT hr = S_OK;
Assert( _pads );
*punk = (LPUNKNOWN)
CEnumIMSIFs_CreateInstance( REMOTE_INSTALL_TOOLS_DIR_W, NETBOOTTOOLS, dwFlags, _pads );
if ( !*punk )
{
hr = E_FAIL;
}
HRETURN(hr);}
//
// EnumLocalInstallOSes( )
//
HRESULT
THISCLASS::EnumLocalInstallOSes(
DWORD dwFlags,
LPUNKNOWN *punk )
{
TraceClsFunc("[IIntelliMirrorSAP] EnumLocalInstallOSes( ... )\n" );
if ( !punk )
RRETURN(E_INVALIDARG);
HRESULT hr = S_OK;
Assert( _pads );
#if 0
*punk = (LPUNKNOWN)
CEnumIMSIFs_CreateInstance( LOCALOSES, NETBOOTLOCALINSTALLOSES, dwFlags, _pads );
#else
*punk = NULL;
#endif
if ( !*punk )
{
hr = E_FAIL;
}
HRETURN(hr);}
//
// GetServerDN( )
//
HRESULT
THISCLASS::GetServerDN(
LPWSTR *pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] GetServerDN( ... )\n" );
if ( !pwsz )
RRETURN(E_POINTER);
HRESULT hr;
VARIANT var;
VariantInit( &var );
Assert( _pads );
hr = _pads->Get( NETBOOTSERVER, &var );
if (hr && hr != E_ADS_PROPERTY_NOT_FOUND )
goto Cleanup;
if ( V_VT(&var) == VT_BSTR )
{
*pwsz = TraceStrDup( V_BSTR(&var) );
if ( !*pwsz )
{
hr = E_OUTOFMEMORY;
}
}
Cleanup:
VariantClear( &var );
HRETURN(hr);
}
//
// SetServerDN( )
//
HRESULT
THISCLASS::SetServerDN(
LPWSTR pwsz )
{
TraceClsFunc("[IIntelliMirrorSAP] SetServerDN( ... )\n" );
if ( !pwsz )
RRETURN(E_INVALIDARG);
HRESULT hr;
VARIANT var;
V_VT( &var ) = VT_BSTR;
V_BSTR( &var ) = SysAllocString( pwsz );
if (V_BSTR(&var) == NULL) {
RRETURN(E_OUTOFMEMORY);
}
Assert( _pads );
hr = THR( _pads->Put( NETBOOTSERVER, var ) );
VariantClear( &var );
HRETURN(hr);
}
//
// GetDefaultIntelliMirrorOS( )
//
HRESULT
THISCLASS::GetDefaultIntelliMirrorOS(
LPWSTR * pszName,
LPWSTR * pszTimeout )
{
TraceClsFunc( "[IIntelliMirrorSAP] GetDefaultIntelliMirrorOS( ...)\n" );
HRESULT hr;
hr = _GetDefaultSIF( NETBOOTINTELLIMIRROROSES, pszName, pszTimeout );
HRETURN(hr);
}
//
// SetDefaultIntelliMirrorOS( )
//
HRESULT
THISCLASS::SetDefaultIntelliMirrorOS(
LPWSTR pszName,
LPWSTR pszTimeout )
{
TraceClsFunc( "[IIntelliMirrorSAP] SetDefaultIntelliMirrorOS( " );
TraceMsg( TF_FUNC, "pszName = '%s', pszTimeout = '%s' )\n",
pszName, pszTimeout );
HRESULT hr;
hr = _SetDefaultSIF( NETBOOTINTELLIMIRROROSES, pszName, pszTimeout );
HRETURN(hr);
}
//
// _GetDefaultSIF( )
//
HRESULT
THISCLASS::_GetDefaultSIF(
LPWSTR pszAttribute,
LPWSTR * pszName,
LPWSTR * pszTimeout )
{
TraceClsFunc( "_GetDefaultSIF( " );
TraceMsg( TF_FUNC, "pszAttribute = '%s', ... )\n" , pszAttribute );
if ( !pszAttribute )
RRETURN(E_POINTER);
if ( !pszName )
RRETURN(E_POINTER);
if ( !pszTimeout )
RRETURN(E_POINTER);
HRESULT hr;
LONG lUBound;
VARIANT var;
VARIANT * pvar;
VariantInit( &var );
*pszName = NULL;
*pszTimeout = NULL;
Assert( _pads );
hr = THR( _pads->GetEx( pszAttribute, &var ) );
if (FAILED( hr ))
goto Error;
//
// Make sure that the var is an array of VARIANTs
//
if ( V_VT( &var ) != ( VT_ARRAY | VT_VARIANT ) )
{
hr = ERROR_INVALID_DATA;
goto Error;
}
Assert( SafeArrayGetDim( V_ARRAY( &var ) ) == 1 );
#ifdef DEBUG
{
LONG lLBound;
SafeArrayGetLBound( V_ARRAY( &var ), 1, &lLBound );
Assert( lLBound == 0 );
}
#endif // DEBUG
SafeArrayGetUBound( V_ARRAY( &var ), 1, &lUBound );
//
// Copy the required data
//
SafeArrayAccessData( V_ARRAY( &var ), (void **)&pvar );
*pszName = (LPWSTR) TraceStrDup( V_BSTR( &pvar[ 0 ] ) );
if (!*pszName)
{
SafeArrayUnaccessData( V_ARRAY( &var ) );
hr = E_OUTOFMEMORY;
goto Error;
}
if ( lUBound == 2 )
{
*pszTimeout = (LPWSTR) TraceStrDup( V_BSTR( &pvar[ 1 ] ) );
if ( !*pszTimeout )
{
SafeArrayUnaccessData( V_ARRAY( &var ) );
hr = E_OUTOFMEMORY;
goto Error;
}
}
SafeArrayUnaccessData( V_ARRAY( &var ) );
Error:
VariantClear( &var );
HRETURN(hr);
}
//
// _SetDefaultSIF( )
//
HRESULT
THISCLASS::_SetDefaultSIF(
LPWSTR pszAttribute,
LPWSTR pszName,
LPWSTR pszTimeout )
{
TraceClsFunc( "_SetDefaultSIF( " );
TraceMsg( TF_FUNC, "pszAttribute = '%s', ... )\n" , pszAttribute );
if ( !pszAttribute )
RRETURN(E_POINTER);
if ( !pszName )
RRETURN(E_POINTER);
if ( !pszTimeout )
RRETURN(E_POINTER);
HRESULT hr;
LONG lUBound;
VARIANT var;
LPWSTR pszStrings[ 2 ];
pszStrings[0] = pszName;
pszStrings[1] = pszTimeout;
VariantInit( &var );
hr = THR( StringArrayToVariant( &var, pszStrings, 2 ) );
if (FAILED( hr ))
goto Error;
Assert( _pads );
hr = THR( _pads->Put( pszAttribute, var ) );
if (FAILED( hr ))
goto Error;
Error:
VariantClear( &var );
HRETURN(hr);
}
//
// GetSCPDN( )
//
HRESULT
THISCLASS::GetSCPDN(
LPWSTR * ppwsz )
{
TraceClsFunc( "[IIntelliMirrorSAP] GetSCPDN( )\n" );
HRESULT hr = S_OK;
if ( !ppwsz )
HRETURN( E_POINTER );
if ( _pszSCPDN ) {
LPWSTR psz = StrRChr( _pszSCPDN, NULL, L'/' );
if ( psz )
{
psz++;
}
else
{
psz = _pszSCPDN;
}
*ppwsz = (LPWSTR) TraceStrDup( psz );
if ( !*ppwsz )
{
hr = E_OUTOFMEMORY;
}
} else {
*ppwsz = NULL;
}
HRETURN(hr);
}
//
// GetGroupDN( )
//
HRESULT
THISCLASS::GetGroupDN(
LPWSTR * ppwsz )
{
TraceClsFunc( "[IIntelliMirrorSAP] GetGroupDN( )\n" );
HRESULT hr = S_OK;
if ( !ppwsz )
HRETURN( E_POINTER );
if ( _pszGroupDN ) {
*ppwsz = (LPWSTR) TraceStrDup( _pszGroupDN );
if ( !*ppwsz )
{
hr = E_OUTOFMEMORY;
}
} else {
*ppwsz = NULL;
hr = S_FALSE;
}
HRETURN(hr);
}
//
// GetServerName( )
//
STDMETHODIMP
THISCLASS::GetServerName(
LPWSTR * ppwsz )
{
TraceClsFunc( "[IIntelliMirrorSAP] GetServerName( )\n" );
HRESULT hr = S_OK;
if ( !ppwsz )
HRETURN(E_POINTER);
*ppwsz = NULL;
if ( !_pszMachineName )
{
hr = _GetComputerNameFromADs( );
if (FAILED( hr ))
goto Error;
}
if ( _pszMachineName )
{
*ppwsz = (LPWSTR) TraceStrDup( _pszMachineName );
if ( !*ppwsz )
{
hr = E_OUTOFMEMORY;
}
}
else
{
hr = S_FALSE;
}
Error:
HRETURN(hr);
}
//
// _GetComputerNameFromADs( )
//
HRESULT
THISCLASS::_GetComputerNameFromADs( )
{
TraceClsFunc( "_GetComputerNameFromADs( )\n" );
if ( _pszMachineName )
HRETURN(S_OK); // nop
HRESULT hr;
VARIANT var;
IADs *pads = NULL;
LPWSTR pszMachinePath = NULL;
LPWSTR psz;
VariantInit( &var );
// Retrieve the NETBOOTSERVER attribute
hr = THR( _pads->Get( NETBOOTSERVER, &var ) );
if (FAILED( hr ))
goto Cleanup;
Assert( V_VT( &var ) == VT_BSTR );
hr = _FixObjectPath( V_BSTR( &var ), &pszMachinePath );
if (FAILED( hr ))
goto Cleanup;
VariantClear( &var );
hr = THR( ADsGetObject( pszMachinePath, IID_IADs, (void**) &pads ) );
if (FAILED( hr ))
goto Cleanup;
hr = THR( pads->Get( SAMNAME, &var ) );
if (FAILED( hr ))
goto Cleanup;
Assert( V_VT( &var ) == VT_BSTR );
_pszMachineName = TraceStrDup( V_BSTR( &var ) );
if ( !_pszMachineName )
goto OutOfMemory;
psz = &_pszMachineName[ wcslen( _pszMachineName ) - 1 ];
if ( *psz == L'$' )
{
*psz = L'\0';
}
DebugMsg( "Server Name: %ws\n", _pszMachineName );
Cleanup:
VariantClear( &var );
if ( pads )
pads->Release( );
if ( pszMachinePath )
TraceFree( pszMachinePath );
HRETURN(hr);
OutOfMemory:
hr = E_OUTOFMEMORY;
goto Cleanup;
}
//
// _FixObjectPath( )
//
HRESULT
THISCLASS::_FixObjectPath( LPWSTR pszOldObjectPath, LPWSTR *ppszNewObjectPath )
{
TraceClsFunc( "_FixObjectPath()\n" );
if ( !ppszNewObjectPath )
HRETURN(E_POINTER);
HRESULT hr;
LPWSTR psz = NULL;
*ppszNewObjectPath = NULL;
// Try to parse the string to connect to the same server as the DSADMIN
if ( _pszDSServerName && StrCmpNI( _pszDSServerName, L"LDAP://", 7 ) == 0 )
{
psz = _pszDSServerName + 7;
}
else if ( _pszDSServerName && StrCmpNI( _pszDSServerName, L"GC://", 5 ) == 0 )
{
psz = _pszDSServerName + 5;
}
if ( psz )
{
psz = StrChr( psz, L'/' );
psz++;
INT_PTR uLen = psz - _pszDSServerName;
// get a chunk of memory, pre-zero'ed
psz = TraceAllocString( LPTR, (size_t) uLen + wcslen( pszOldObjectPath ) + 1 );
if ( !psz )
goto OutOfMemory;
MoveMemory( psz, _pszDSServerName, uLen * sizeof(WCHAR) );
wcscat( psz, pszOldObjectPath);
*ppszNewObjectPath = psz;
}
else
{ // find another server
hr = THR( LDAPPrefix( pszOldObjectPath, ppszNewObjectPath ) );
}
Assert( ppszNewObjectPath || hr != S_OK );
HRETURN(hr);
OutOfMemory:
HRETURN(E_OUTOFMEMORY);
}
//
// GetDataObject( )
//
STDMETHODIMP
THISCLASS::GetDataObject(
LPDATAOBJECT * pDataObj
)
{
TraceClsFunc( "GetDataObject( ... )\n" );
if ( !pDataObj )
HRETURN( E_POINTER );
*pDataObj = _pDataObj;
_pDataObj->AddRef( );
HRETURN(S_OK);
}
//
// GetNotifyWindow( )
//
STDMETHODIMP
THISCLASS::GetNotifyWindow(
HWND * phNotifyObj
)
{
TraceClsFunc( "GetNotifyWindow( ... )\n" );
if ( !phNotifyObj )
HRETURN(E_POINTER);
*phNotifyObj = _hwndNotify;
HRETURN(S_OK);
}