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.
734 lines
21 KiB
734 lines
21 KiB
//--------------------------------------------------------------------------
|
|
|
|
#ifndef _WIN32_WINNT
|
|
#define _WIN32_WINNT 0x0510
|
|
#endif
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
#endif
|
|
|
|
#define SECURITY_WIN32
|
|
#include <windows.h>
|
|
#include <tchar.h>
|
|
#include <assert.h>
|
|
#include <objbase.h>
|
|
#include <objsel.h>
|
|
#include <Security.h>
|
|
#include <sddl.h>
|
|
#include <Secext.h>
|
|
|
|
#include "objectpicker.h"
|
|
|
|
#define OP_GENERIC_EXCEPTION ( ( DWORD ) 1 )
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
UINT g_cfDsObjectPicker = RegisterClipboardFormat( CFSTR_DSOP_DS_SELECTION_LIST );
|
|
|
|
static HRESULT InitObjectPicker( ObjectType oType,
|
|
IDsObjectPicker *pDsObjectPicker,
|
|
PTCHAR szTarget );
|
|
|
|
static HRESULT InitObjectPickerForComputers( IDsObjectPicker *pDsObjectPicker );
|
|
|
|
static HRESULT InitObjectPickerForGroups( IDsObjectPicker *pDsObjectPicker,
|
|
BOOL fMultiselect,
|
|
LPCTSTR pszMachineName,
|
|
BOOL fWantSidPath );
|
|
|
|
static HRESULT InitObjectPickerForUsers( IDsObjectPicker *pDsObjectPicker,
|
|
BOOL fMultiselect,
|
|
LPCTSTR pszMachineName );
|
|
|
|
static bool ProcessSelectedObjects( IDataObject *pdo,
|
|
ObjectType oType,
|
|
PTCHAR szObjectName,
|
|
ULONG uBufSize );
|
|
|
|
//--------------------------------------------------------------------------
|
|
// returns true if no errors, false otherwise
|
|
// use GetLastError() to get error code
|
|
//
|
|
bool
|
|
ObjectPicker( HWND hwndParent,
|
|
ObjectType oType,
|
|
PTCHAR szObjectName,
|
|
ULONG uBufSize,
|
|
PTCHAR szTarget )
|
|
{
|
|
IDsObjectPicker *pDsObjectPicker = NULL;
|
|
IDataObject *pdo = NULL;
|
|
bool bRet = true; // assume no errors
|
|
|
|
try
|
|
{
|
|
HRESULT hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
|
|
if( FAILED( hr ) )
|
|
{
|
|
throw (DWORD)HRESULT_CODE( hr );
|
|
}
|
|
|
|
//
|
|
// Create an instance of the object picker.
|
|
//
|
|
hr = CoCreateInstance( CLSID_DsObjectPicker,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDsObjectPicker,
|
|
reinterpret_cast<void **>( &pDsObjectPicker ) );
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
throw (DWORD)HRESULT_CODE(hr);
|
|
}
|
|
|
|
//
|
|
// Initialize the object picker instance.
|
|
//
|
|
hr = InitObjectPicker( oType, pDsObjectPicker, szTarget );
|
|
if( FAILED( hr ) )
|
|
{
|
|
throw (DWORD)HRESULT_CODE(hr);
|
|
}
|
|
|
|
//
|
|
// Invoke the modal dialog.
|
|
//
|
|
hr = pDsObjectPicker->InvokeDialog( hwndParent, &pdo );
|
|
if( S_OK == hr )
|
|
{
|
|
if( !ProcessSelectedObjects( pdo, oType, szObjectName, uBufSize ))
|
|
{
|
|
throw GetLastError();
|
|
}
|
|
}
|
|
else if( S_FALSE == hr ) // user pressed cancel
|
|
{
|
|
throw (DWORD)OP_GENERIC_EXCEPTION;
|
|
}
|
|
else
|
|
{
|
|
throw (DWORD)HRESULT_CODE(hr);
|
|
}
|
|
}
|
|
catch( DWORD dwErr )
|
|
{
|
|
SetLastError( dwErr );
|
|
bRet = false;
|
|
}
|
|
catch( ... )
|
|
{
|
|
bRet = false;
|
|
}
|
|
|
|
//
|
|
// Cleanup.
|
|
//
|
|
if( pdo )
|
|
pdo->Release();
|
|
|
|
if( pDsObjectPicker )
|
|
pDsObjectPicker->Release();
|
|
|
|
CoUninitialize();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
static HRESULT
|
|
InitObjectPicker( ObjectType oType, IDsObjectPicker *pDsObjectPicker, PTCHAR szTarget )
|
|
{
|
|
if( NULL == pDsObjectPicker )
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if( OT_Computer == oType )
|
|
{
|
|
hr = InitObjectPickerForComputers( pDsObjectPicker );
|
|
}
|
|
else if( OT_User == oType )
|
|
{
|
|
hr = InitObjectPickerForUsers( pDsObjectPicker, FALSE, szTarget );
|
|
}
|
|
else if( OT_Group == oType )
|
|
{
|
|
hr = InitObjectPickerForGroups( pDsObjectPicker, FALSE, szTarget, FALSE );
|
|
}
|
|
else if( OT_GroupSID == oType )
|
|
{
|
|
hr = InitObjectPickerForGroups( pDsObjectPicker, FALSE, szTarget, TRUE );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
static bool
|
|
ProcessSelectedObjects( IDataObject *pdo, ObjectType oType, PTCHAR szObjectName, ULONG uBufSize )
|
|
{
|
|
PDS_SELECTION_LIST pDsSelList = NULL;
|
|
bool dwRet = true; // assume ok
|
|
|
|
STGMEDIUM stgmedium =
|
|
{
|
|
TYMED_HGLOBAL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
FORMATETC formatetc =
|
|
{
|
|
( CLIPFORMAT ) g_cfDsObjectPicker,
|
|
NULL,
|
|
DVASPECT_CONTENT,
|
|
-1,
|
|
TYMED_HGLOBAL
|
|
};
|
|
|
|
try
|
|
{
|
|
//
|
|
// Get the global memory block containing a user's selections.
|
|
//
|
|
HRESULT hr = pdo->GetData( &formatetc, &stgmedium );
|
|
if( FAILED( hr ) )
|
|
throw HRESULT_CODE( hr );
|
|
|
|
//
|
|
// Retrieve pointer to DS_SELECTION_LIST structure.
|
|
//
|
|
pDsSelList = ( PDS_SELECTION_LIST ) GlobalLock( stgmedium.hGlobal );
|
|
if( !pDsSelList )
|
|
{
|
|
throw GetLastError();
|
|
}
|
|
|
|
//
|
|
// assume there is only 1 item returned because
|
|
// we have multi-select turned off
|
|
//
|
|
if( pDsSelList->cItems != 1 )
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
|
|
UINT i = 0;
|
|
|
|
//
|
|
// did we request a computer name? If so, we get it directly in the pwzName field
|
|
//
|
|
if( 0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "computer" )) )
|
|
{
|
|
assert( uBufSize > _tcslen( pDsSelList->aDsSelection[i].pwzName ) );
|
|
_tcsncpy( szObjectName, pDsSelList->aDsSelection[i].pwzName, uBufSize - 1 );
|
|
szObjectName[ uBufSize - 1 ] = NULL;
|
|
}
|
|
//
|
|
// user name or group takes some post-processsing...
|
|
//
|
|
else if( 0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "user" ) ) ||
|
|
0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "group" ) ) )
|
|
{
|
|
//
|
|
// user names from the domain begin with "LDAP:"
|
|
// strip off the prefix info, up to the first "cn="
|
|
// then use the TranslateName API to get the form "domain\user" or "domain\group"
|
|
//
|
|
if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "LDAP:" ), 5 ) )
|
|
{
|
|
if( OT_Group == oType )
|
|
{
|
|
PTCHAR p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "CN=" ) );
|
|
if( NULL == p )
|
|
p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "cn=" ) );
|
|
|
|
if( NULL == p )
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
|
|
if( !TranslateName( p, NameFullyQualifiedDN, NameSamCompatible, szObjectName, &uBufSize ) )
|
|
throw GetLastError();
|
|
}
|
|
else if( OT_GroupSID == oType )
|
|
{
|
|
//
|
|
// If we are here, then we should expect a string LDAP://SID=<xxxxx>
|
|
//
|
|
if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "LDAP:" ), 5 ) )
|
|
{
|
|
LPTSTR p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "=" ) );
|
|
if( p )
|
|
{
|
|
p++;
|
|
p[ _tcslen( p ) - 1 ] = NULL;
|
|
|
|
LPTSTR szSID = NULL;
|
|
BYTE sidArray[ 512 ];
|
|
TCHAR szDigit[ 3 ];
|
|
|
|
ZeroMemory( sidArray, sizeof sidArray );
|
|
ZeroMemory( szDigit, sizeof szDigit );
|
|
|
|
size_t len = _tcslen(p) / 2;
|
|
for (size_t j=0; j < len; j++)
|
|
{
|
|
_tcsncpy( szDigit, p, 2 );
|
|
LPTSTR stopPtr = NULL;
|
|
|
|
sidArray[ j ] = (BYTE)_tcstoul( szDigit, &stopPtr, 16 );
|
|
|
|
p+=2;
|
|
}
|
|
|
|
if( !ConvertSidToStringSid( sidArray, &szSID ) )
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
else
|
|
{
|
|
_tcsncpy( szObjectName, szSID, uBufSize - 1 );
|
|
LocalFree( szSID );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
}
|
|
//
|
|
// otherwise, names on the local box begin with "winnt:"
|
|
// and we are only interested in the last two sections of the string,
|
|
// delimited by "/"
|
|
//
|
|
else if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "WINNT:" ), 6 ) )
|
|
{
|
|
PTCHAR p = pDsSelList->aDsSelection[i].pwzADsPath;
|
|
PTCHAR pend = p + _tcslen( p );
|
|
UINT uCount = 0;
|
|
while( pend > p )
|
|
{
|
|
if( '/' == *pend )
|
|
{
|
|
*pend = '\\';
|
|
uCount++;
|
|
|
|
if( uCount == 2 )
|
|
{
|
|
p = pend + 1;
|
|
break;
|
|
}
|
|
}
|
|
pend--;
|
|
}
|
|
|
|
//
|
|
// if this fails, assert during debug but do not stop
|
|
//
|
|
if( p == pend )
|
|
assert( false );
|
|
|
|
assert( uBufSize > _tcslen( p ) );
|
|
_tcsncpy( szObjectName, p, uBufSize - 1 );
|
|
szObjectName[ uBufSize - 1 ] = NULL;
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert( false );
|
|
throw OP_GENERIC_EXCEPTION;
|
|
}
|
|
}
|
|
|
|
catch( DWORD dwErr )
|
|
{
|
|
SetLastError( dwErr );
|
|
dwRet = false;
|
|
}
|
|
|
|
if( pDsSelList )
|
|
GlobalUnlock( stgmedium.hGlobal );
|
|
|
|
ReleaseStgMedium( &stgmedium );
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InitObjectPickerForGroups
|
|
//
|
|
// Synopsis: Call IDsObjectPicker::Initialize with arguments that will
|
|
// set it to allow the user to pick one or more groups.
|
|
//
|
|
// Arguments: [pDsObjectPicker] - object picker interface instance
|
|
//
|
|
// Returns: Result of calling IDsObjectPicker::Initialize.
|
|
//
|
|
// History: 10-14-1998 DavidMun Created
|
|
// 1-8-2000 SergeiA Adapted for IIS
|
|
// 9-6-2002 a-dsebes Adapted for UDDI
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT
|
|
InitObjectPickerForGroups( IDsObjectPicker *pDsObjectPicker,
|
|
BOOL fMultiselect,
|
|
LPCTSTR pszMachineName,
|
|
BOOL fWantSidPath )
|
|
{
|
|
//
|
|
// Prepare to initialize the object picker.
|
|
// Set up the array of scope initializer structures.
|
|
//
|
|
|
|
static const int SCOPE_INIT_COUNT = 5;
|
|
DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
|
|
|
|
ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
|
|
|
|
//
|
|
// Target computer scope. This adds a "Look In" entry for the
|
|
// target computer. Computer scopes are always treated as
|
|
// downlevel (i.e., they use the WinNT provider).
|
|
//
|
|
aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
|
|
aScopeInit[ 0 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
|
|
|
|
aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_BUILTIN_GROUPS;
|
|
aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS;
|
|
|
|
if( fWantSidPath )
|
|
{
|
|
aScopeInit[ 0 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
|
|
}
|
|
|
|
//
|
|
// The domain to which the target computer is joined. Note we're
|
|
// combining two scope types into flType here for convenience.
|
|
//
|
|
aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 1 ].flScope = 0;
|
|
aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN |
|
|
DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
|
|
|
|
aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
|
|
DSOP_FILTER_UNIVERSAL_GROUPS_SE |
|
|
DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
|
|
aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
|
|
|
|
if( fWantSidPath )
|
|
{
|
|
aScopeInit[ 1 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
|
|
}
|
|
|
|
//
|
|
// The domains in the same forest (enterprise) as the domain to which
|
|
// the target machine is joined. Note these can only be DS-aware
|
|
//
|
|
|
|
aScopeInit[ 2 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 2 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
|
|
aScopeInit[ 2 ].flScope = 0;
|
|
|
|
aScopeInit[ 2 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
|
|
DSOP_FILTER_UNIVERSAL_GROUPS_SE;
|
|
|
|
if( fWantSidPath )
|
|
{
|
|
aScopeInit[ 2 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
|
|
}
|
|
|
|
//
|
|
// Domains external to the enterprise but trusted directly by the
|
|
// domain to which the target machine is joined.
|
|
//
|
|
// If the target machine is joined to an NT4 domain, only the
|
|
// external downlevel domain scope applies, and it will cause
|
|
// all domains trusted by the joined domain to appear.
|
|
//
|
|
|
|
aScopeInit[ 3 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 3 ].flScope = 0;
|
|
aScopeInit[ 3 ].flType = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
|
|
DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
|
|
|
|
aScopeInit[ 3 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
|
|
DSOP_FILTER_UNIVERSAL_GROUPS_SE;
|
|
aScopeInit[ 3 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
|
|
|
|
if( fWantSidPath )
|
|
{
|
|
aScopeInit[ 3 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
|
|
}
|
|
|
|
//
|
|
// The Global Catalog
|
|
//
|
|
|
|
aScopeInit[ 4 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 4 ].flScope = 0;
|
|
aScopeInit[ 4 ].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
|
|
|
|
//
|
|
// Only native mode applies to gc scope.
|
|
//
|
|
aScopeInit[ 4 ].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_GLOBAL_GROUPS_SE |
|
|
DSOP_FILTER_UNIVERSAL_GROUPS_SE;
|
|
|
|
if( fWantSidPath )
|
|
{
|
|
aScopeInit[ 4 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
|
|
}
|
|
|
|
//
|
|
// Put the scope init array into the object picker init array
|
|
//
|
|
|
|
DSOP_INIT_INFO InitInfo;
|
|
ZeroMemory( &InitInfo, sizeof( InitInfo ) );
|
|
InitInfo.cbSize = sizeof( InitInfo );
|
|
|
|
//
|
|
// The pwzTargetComputer member allows the object picker to be
|
|
// retargetted to a different computer. It will behave as if it
|
|
// were being run ON THAT COMPUTER.
|
|
//
|
|
|
|
InitInfo.pwzTargetComputer = pszMachineName;
|
|
InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
|
|
InitInfo.aDsScopeInfos = aScopeInit;
|
|
InitInfo.flOptions = fMultiselect ? DSOP_FLAG_MULTISELECT : 0;
|
|
|
|
//
|
|
// Note object picker makes its own copy of InitInfo. Also note
|
|
// that Initialize may be called multiple times, last call wins.
|
|
//
|
|
|
|
HRESULT hr = pDsObjectPicker->Initialize( &InitInfo );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InitObjectPickerForGroups
|
|
//
|
|
// Synopsis: Call IDsObjectPicker::Initialize with arguments that will
|
|
// set it to allow the user to pick one or more groups.
|
|
//
|
|
// Arguments: [pDsObjectPicker] - object picker interface instance
|
|
//
|
|
// Returns: Result of calling IDsObjectPicker::Initialize.
|
|
//
|
|
// History: 9-6-2002 a-dsebes Created.
|
|
//
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT
|
|
InitObjectPickerForUsers( IDsObjectPicker *pDsObjectPicker,
|
|
BOOL fMultiselect,
|
|
LPCTSTR pszMachineName )
|
|
{
|
|
//
|
|
// Prepare to initialize the object picker.
|
|
// Set up the array of scope initializer structures.
|
|
//
|
|
|
|
static const int SCOPE_INIT_COUNT = 5;
|
|
DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
|
|
|
|
ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
|
|
|
|
//
|
|
// Target computer scope. This adds a "Look In" entry for the
|
|
// target computer. Computer scopes are always treated as
|
|
// downlevel (i.e., they use the WinNT provider).
|
|
//
|
|
aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
|
|
aScopeInit[ 0 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
|
|
|
|
aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
//
|
|
// The domain to which the target computer is joined. Note we're
|
|
// combining two scope types into flType here for convenience.
|
|
//
|
|
aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 1 ].flScope = 0;
|
|
aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN |
|
|
DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
|
|
|
|
aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
//
|
|
// The domains in the same forest (enterprise) as the domain to which
|
|
// the target machine is joined. Note these can only be DS-aware
|
|
//
|
|
aScopeInit[ 2 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 2 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
|
|
aScopeInit[ 2 ].flScope = 0;
|
|
|
|
aScopeInit[ 2 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
|
|
//
|
|
// Domains external to the enterprise but trusted directly by the
|
|
// domain to which the target machine is joined.
|
|
//
|
|
// If the target machine is joined to an NT4 domain, only the
|
|
// external downlevel domain scope applies, and it will cause
|
|
// all domains trusted by the joined domain to appear.
|
|
//
|
|
aScopeInit[ 3 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 3 ].flScope = 0;
|
|
aScopeInit[ 3 ].flType = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
|
|
DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
|
|
|
|
aScopeInit[ 3 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
|
|
aScopeInit[ 3 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
|
|
|
|
//
|
|
// The Global Catalog
|
|
//
|
|
aScopeInit[ 4 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 4 ].flScope = 0;
|
|
aScopeInit[ 4 ].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
|
|
|
|
//
|
|
// Only native mode applies to gc scope.
|
|
//
|
|
aScopeInit[ 4 ].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
|
|
|
|
//
|
|
// Put the scope init array into the object picker init array
|
|
//
|
|
DSOP_INIT_INFO InitInfo;
|
|
ZeroMemory( &InitInfo, sizeof( InitInfo ) );
|
|
InitInfo.cbSize = sizeof( InitInfo );
|
|
|
|
//
|
|
// The pwzTargetComputer member allows the object picker to be
|
|
// retargetted to a different computer. It will behave as if it
|
|
// were being run ON THAT COMPUTER.
|
|
//
|
|
InitInfo.pwzTargetComputer = pszMachineName;
|
|
InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
|
|
InitInfo.aDsScopeInfos = aScopeInit;
|
|
InitInfo.flOptions = fMultiselect ? DSOP_FLAG_MULTISELECT : 0;
|
|
|
|
//
|
|
// Note object picker makes its own copy of InitInfo. Also note
|
|
// that Initialize may be called multiple times, last call wins.
|
|
//
|
|
HRESULT hr = pDsObjectPicker->Initialize( &InitInfo );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InitObjectPickerForComputers
|
|
//
|
|
// Synopsis: Call IDsObjectPicker::Initialize with arguments that will
|
|
// set it to allow the user to pick a single computer object.
|
|
//
|
|
// Arguments: [pDsObjectPicker] - object picker interface instance
|
|
//
|
|
// Returns: Result of calling IDsObjectPicker::Initialize.
|
|
//
|
|
// History: 10-14-1998 DavidMun Created
|
|
// 08-06-2002 a-dsebes Adapted for UDDI.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
InitObjectPickerForComputers( IDsObjectPicker *pDsObjectPicker )
|
|
{
|
|
//
|
|
// Prepare to initialize the object picker.
|
|
// Set up the array of scope initializer structures.
|
|
//
|
|
|
|
static const int SCOPE_INIT_COUNT = 2;
|
|
DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
|
|
|
|
ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
|
|
|
|
//
|
|
// Build a scope init struct for everything except the joined domain.
|
|
//
|
|
|
|
aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
|
|
| DSOP_SCOPE_TYPE_GLOBAL_CATALOG
|
|
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
|
| DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
|
|
| DSOP_SCOPE_TYPE_WORKGROUP
|
|
| DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
|
|
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
|
|
|
|
aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
|
|
aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
|
|
|
|
|
|
//
|
|
// scope for the joined domain, make it the default
|
|
//
|
|
aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
|
|
aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
|
|
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
|
|
|
|
aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
|
|
aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
|
|
aScopeInit[ 1 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
|
|
|
|
//
|
|
// Put the scope init array into the object picker init array
|
|
//
|
|
|
|
DSOP_INIT_INFO InitInfo;
|
|
ZeroMemory( &InitInfo, sizeof( InitInfo ) );
|
|
|
|
InitInfo.cbSize = sizeof( InitInfo );
|
|
InitInfo.pwzTargetComputer = NULL; // NULL == local machine
|
|
InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
|
|
InitInfo.aDsScopeInfos = aScopeInit;
|
|
|
|
//
|
|
// Note object picker makes its own copy of InitInfo. Also note
|
|
// that Initialize may be called multiple times, last call wins.
|
|
//
|
|
|
|
return pDsObjectPicker->Initialize(&InitInfo);
|
|
}
|