windows-nt/Source/XPSP1/NT/admin/select/sample/sample.cxx
2020-09-26 16:20:57 +08:00

413 lines
11 KiB
C++

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1998.
//
// File: sample.cxx
//
// Contents: Sample DS object picker client.
//
//---------------------------------------------------------------------------
#define INC_OLE2
#include <windows.h>
#include <stdio.h>
#include <objsel.h>
#define BREAK_ON_FAIL_HRESULT(hr) \
if (FAILED(hr)) { printf("line %u err 0x%x\n", __LINE__, hr); break; }
#undef ASSERT
#define ASSERT(x) \
if (!(x)) printf("line %u assert failed\n", __LINE__)
UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
//+--------------------------------------------------------------------------
//
// 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.
//
//---------------------------------------------------------------------------
HRESULT
InitObjectPickerForGroups(
IDsObjectPicker *pDsObjectPicker)
{
//
// 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.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].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
aScopeInit[1].FilterFlags.Uplevel.flNativeModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE
| DSOP_FILTER_UNIVERSAL_GROUPS_SE
| DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
aScopeInit[1].FilterFlags.Uplevel.flMixedModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE;
aScopeInit[1].FilterFlags.flDownlevel =
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
//
// 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].FilterFlags.Uplevel.flNativeModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE
| DSOP_FILTER_UNIVERSAL_GROUPS_SE;
aScopeInit[2].FilterFlags.Uplevel.flMixedModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE;
//
// 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].flType =
DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
aScopeInit[3].FilterFlags.Uplevel.flNativeModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE
| DSOP_FILTER_UNIVERSAL_GROUPS_SE;
aScopeInit[3].FilterFlags.Uplevel.flMixedModeOnly =
DSOP_FILTER_GLOBAL_GROUPS_SE;
aScopeInit[3].FilterFlags.flDownlevel =
DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
//
// The Global Catalog
//
aScopeInit[4].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
aScopeInit[4].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
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
| DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
//
// 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 = NULL; // NULL == local machine
InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
InitInfo.aDsScopeInfos = aScopeInit;
InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
//
// 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);
if (FAILED(hr))
{
ULONG i;
for (i = 0; i < SCOPE_INIT_COUNT; i++)
{
if (FAILED(InitInfo.aDsScopeInfos[i].hr))
{
printf("Initialization failed because of scope %u\n", i);
}
}
}
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.
//
//---------------------------------------------------------------------------
HRESULT
InitObjectPickerForComputers(
IDsObjectPicker *pDsObjectPicker)
{
//
// Prepare to initialize the object picker.
// Set up the array of scope initializer structures.
//
static const int SCOPE_INIT_COUNT = 1;
DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
//
// Since we just want computer objects from every scope, combine them
// all in a single scope initializer.
//
aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
aScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
| 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;
//
// 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);
}
//+--------------------------------------------------------------------------
//
// Function: ProcessSelectedObjects
//
// Synopsis: Retrieve the list of selected items from the data object
// created by the object picker and print out each one.
//
// Arguments: [pdo] - data object returned by object picker
//
//---------------------------------------------------------------------------
void
ProcessSelectedObjects(
IDataObject *pdo)
{
HRESULT hr = S_OK;
STGMEDIUM stgmedium =
{
TYMED_HGLOBAL,
NULL,
NULL
};
FORMATETC formatetc =
{
g_cfDsObjectPicker,
NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
bool fGotStgMedium = false;
do
{
hr = pdo->GetData(&formatetc, &stgmedium);
BREAK_ON_FAIL_HRESULT(hr);
fGotStgMedium = true;
PDS_SELECTION_LIST pDsSelList =
(PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
if (!pDsSelList)
{
printf("GlobalLock error %u\n", GetLastError());
break;
}
ULONG i;
for (i = 0; i < pDsSelList->cItems; i++)
{
printf("Object %u'\n", i);
printf(" Name '%ws'\n", pDsSelList->aDsSelection[i].pwzName);
printf(" Class '%ws'\n", pDsSelList->aDsSelection[i].pwzClass);
printf(" Path '%ws'\n", pDsSelList->aDsSelection[i].pwzADsPath);
printf(" UPN '%ws'\n", pDsSelList->aDsSelection[i].pwzUPN);
}
GlobalUnlock(stgmedium.hGlobal);
} while (0);
if (fGotStgMedium)
{
ReleaseStgMedium(&stgmedium);
}
}
//+--------------------------------------------------------------------------
//
// Function: main
//
// Synopsis: Demonstrate use of DS object picker.
//
//---------------------------------------------------------------------------
void _cdecl
main(int argc, char * argv[])
{
HRESULT hr = S_OK;
IDsObjectPicker *pDsObjectPicker = NULL;
IDataObject *pdo = NULL;
hr = CoInitialize(NULL);
if (FAILED(hr)) return;
do
{
//
// Create an instance of the object picker.
//
hr = CoCreateInstance(CLSID_DsObjectPicker,
NULL,
CLSCTX_INPROC_SERVER,
IID_IDsObjectPicker,
(void **) &pDsObjectPicker);
BREAK_ON_FAIL_HRESULT(hr);
hr = InitObjectPickerForGroups(pDsObjectPicker);
//
// Invoke the modal dialog.
//
HWND hwndParent = NULL; // supply a window handle to your app
hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
BREAK_ON_FAIL_HRESULT(hr);
//
// If the user hit Cancel, hr == S_FALSE
//
if (hr == S_FALSE)
{
printf("User canceled object picker dialog\n");
break;
}
//
// Process the user's selections
//
ASSERT(pdo);
ProcessSelectedObjects(pdo);
pdo->Release();
pdo = NULL;
//
// Reinitialize the object picker to choose computers
//
hr = InitObjectPickerForComputers(pDsObjectPicker);
BREAK_ON_FAIL_HRESULT(hr);
//
// Now pick a computer
//
hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
BREAK_ON_FAIL_HRESULT(hr);
ASSERT(pdo);
ProcessSelectedObjects(pdo);
pdo->Release();
pdo = NULL;
} while (0);
if (pDsObjectPicker)
{
pDsObjectPicker->Release();
}
CoUninitialize();
}