1774 lines
34 KiB
C++
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);
|
||
|
}
|