#include "headers.hxx" #pragma hdrstop #include #include #include PWSTR ScopeTypeStr( ULONG flType); LPWSTR VariantString( VARIANT *pvar); void VarArrayToStr( VARIANT *pvar, LPWSTR wzBuf, ULONG cchBuf); // // Helpful macros // #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0])) #define DBG_OUT_HRESULT(hr) printf("error 0x%x at line %u\n", hr, __LINE__) #define BREAK_ON_FAIL_HRESULT(hr) \ if (FAILED(hr)) \ { \ DBG_OUT_HRESULT(hr); \ break; \ } VOID DumpDsSelectedItemList( PDS_SELECTION_LIST pDsSelList, ULONG cRequestedAttributes, LPCTSTR *aptzRequestedAttributes) { if (!pDsSelList) { printf("List is empty\n"); return; } ULONG i; PDS_SELECTION pCur = &pDsSelList->aDsSelection[0]; for (i = 0; i < pDsSelList->cItems; i++, pCur++) { printf("ScopeType: %ws\n", ScopeTypeStr(pCur->flScopeType)); printf("Name: %ws\n", pCur->pwzName); printf("Class: %ws\n", pCur->pwzClass); printf("Path: %ws\n", pCur->pwzADsPath); printf("UPN: %ws\n", pCur->pwzUPN); for (ULONG j = 0; j < cRequestedAttributes; j++) { printf("Attr %02u: %ws = %ws\n", j, aptzRequestedAttributes[j], VariantString(&pCur->pvarFetchedAttributes[j])); } printf("\n"); } } PWSTR ScopeTypeStr( ULONG flType) { switch (flType) { case DSOP_SCOPE_TYPE_TARGET_COMPUTER: return L"DSOP_SCOPE_TYPE_TARGET_COMPUTER"; case DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN: return L"DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN"; case DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN: return L"DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN"; case DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN: return L"DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN"; case DSOP_SCOPE_TYPE_GLOBAL_CATALOG: return L"DSOP_SCOPE_TYPE_GLOBAL_CATALOG"; case DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN: return L"DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN"; case DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN: return L"DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN"; case DSOP_SCOPE_TYPE_WORKGROUP: return L"DSOP_SCOPE_TYPE_WORKGROUP"; case DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE: return L"DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE"; case DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE: return L"DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE"; default: return L"*** invalid scope type ***"; } } LPWSTR VariantString( VARIANT *pvar) { static WCHAR wzBuf[1024]; wzBuf[0] = L'\0'; switch (pvar->vt) { case VT_EMPTY: lstrcpy(wzBuf, L"VT_EMPTY"); break; case VT_NULL: lstrcpy(wzBuf, L"VT_NULL"); break; case VT_I2: wsprintf(wzBuf, L"%d", V_I2(pvar)); break; case VT_I4: wsprintf(wzBuf, L"%d", V_I4(pvar)); break; case VT_R4: wsprintf(wzBuf, L"%f", V_R4(pvar)); break; case VT_R8: wsprintf(wzBuf, L"%f", V_R8(pvar)); break; case VT_CY: wsprintf(wzBuf, L"$%f", V_CY(pvar)); break; case VT_DATE: wsprintf(wzBuf, L"date %f", V_DATE(pvar)); break; case VT_BSTR: if (V_BSTR(pvar)) { wsprintf(wzBuf, L"'%ws'", V_BSTR(pvar)); } else { lstrcpy(wzBuf, L"VT_BSTR NULL"); } break; case VT_DISPATCH: wsprintf(wzBuf, L"VT_DISPATCH 0x%x", V_DISPATCH(pvar)); break; case VT_UNKNOWN: wsprintf(wzBuf, L"VT_UNKNOWN 0x%x", V_UNKNOWN(pvar)); break; case VT_ERROR: case VT_HRESULT: wsprintf(wzBuf, L"hr 0x%x", V_ERROR(pvar)); break; case VT_BOOL: wsprintf(wzBuf, L"%s", V_BOOL(pvar) ? "TRUE" : "FALSE"); break; case VT_VARIANT: wsprintf(wzBuf, L"variant 0x%x", V_VARIANTREF(pvar)); break; case VT_DECIMAL: lstrcpy(wzBuf, L"VT_DECIMAL"); break; case VT_I1: wsprintf(wzBuf, L"%d", V_I1(pvar)); break; case VT_UI1: wsprintf(wzBuf, L"%u", V_UI1(pvar)); break; case VT_UI2: wsprintf(wzBuf, L"%u", V_UI2(pvar)); break; case VT_UI4: wsprintf(wzBuf, L"%u", V_UI4(pvar)); break; case VT_I8: lstrcpy(wzBuf, L"VT_I8"); break; case VT_UI8: lstrcpy(wzBuf, L"VT_UI8"); break; case VT_INT: wsprintf(wzBuf, L"%d", V_INT(pvar)); break; case VT_UINT: wsprintf(wzBuf, L"%u", V_UINT(pvar)); break; case VT_VOID: lstrcpy(wzBuf, L"VT_VOID"); break; case VT_UI1 | VT_ARRAY: VarArrayToStr(pvar, wzBuf, ARRAYLEN(wzBuf)); break; case VT_PTR: case VT_SAFEARRAY: case VT_CARRAY: case VT_USERDEFINED: case VT_LPSTR: case VT_LPWSTR: case VT_RECORD: case VT_FILETIME: case VT_BLOB: case VT_STREAM: case VT_STORAGE: case VT_STREAMED_OBJECT: case VT_STORED_OBJECT: case VT_BLOB_OBJECT: case VT_CF: case VT_CLSID: case VT_BSTR_BLOB: default: wsprintf(wzBuf, L"VT 0x%x", V_VT(pvar)); break; } return wzBuf; } void VarArrayToStr( VARIANT *pvar, LPWSTR wzBuf, ULONG cchBuf) { ULONG i; LPWSTR pwzNext = wzBuf; LPWSTR pwzEnd = wzBuf + cchBuf; for (i = 0; i < pvar->parray->rgsabound[0].cElements && pwzNext < pwzEnd + 6; i++) { wsprintf(pwzNext, L"x%02x ", ((LPBYTE)(pvar->parray->pvData))[i]); pwzNext += lstrlen(pwzNext); } } // // This example allows the user to pick a single computer object // from any domain in the enterprise, the global catalog, or any // user-specified domain. If the target (local) computer is not // joined to a domain, it allows the user to choose a computer // object from the workgroup. // void func1(HWND hwndParent) { HRESULT hr; IDsObjectPicker *pDsObjectPicker; hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void **) &pDsObjectPicker); DSOP_SCOPE_INIT_INFO aScopes[1]; ZeroMemory(aScopes, sizeof(aScopes)); aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[0].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN | DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_WORKGROUP | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE; aScopes[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS; aScopes[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS; DSOP_INIT_INFO InitInfo; ZeroMemory(&InitInfo, sizeof(InitInfo)); InitInfo.cbSize = sizeof(InitInfo); InitInfo.cDsScopeInfos = 1; InitInfo.aDsScopeInfos = aScopes; hr = pDsObjectPicker->Initialize(&InitInfo); IDataObject *pdo = NULL; hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo); STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL }; UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST); FORMATETC formatetc = { cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hr = pdo->GetData(&formatetc, &stgmedium); PDS_SELECTION_LIST pDsSelList = (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal); ULONG i; for (i = 0; i < pDsSelList->cItems; i++) { printf("item %u: %ws\n", i + 1, pDsSelList->aDsSelection[i].pwzName); } GlobalUnlock(stgmedium.hGlobal); ReleaseStgMedium(&stgmedium); pdo->Release(); pDsObjectPicker->Release(); } // // This example allows the user to select one or more objects which may // legally be added to a security enabled global group. It will not // allow the user to specify objects which are contained in domains other // than those in the enterprise. The objectSid attribute is fetched for // all selected objects. The ADsPath of all selected objects is converted // to a form using the WinNT provider. // void func2(HWND hwndParent) { HRESULT hr; IDsObjectPicker *pDsObjectPicker; hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void **) &pDsObjectPicker); PCWSTR apwzAttrs[] = { L"objectSid" }; // // Specify the objects which should be displayed for the domain // to which the target computer is joined. // DSOP_SCOPE_INIT_INFO aScopes[2]; ZeroMemory(aScopes, sizeof(aScopes)); aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN; aScopes[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS | DSOP_FILTER_CONTACTS | DSOP_FILTER_COMPUTERS; aScopes[0].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_GLOBAL_GROUPS_DL | DSOP_FILTER_GLOBAL_GROUPS_SE; aScopes[0].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT; // include downlevel filter in case target computer is joined to // an NT4 domain aScopes[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS; // // Specify the objects which should be displayed for all other // domains in the enterprise. // aScopes[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[1].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN; aScopes[1].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_CONTACTS; aScopes[1].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT; DSOP_INIT_INFO InitInfo; ZeroMemory(&InitInfo, sizeof(InitInfo)); InitInfo.cbSize = sizeof(InitInfo); InitInfo.cDsScopeInfos = 2; InitInfo.aDsScopeInfos = aScopes; InitInfo.flOptions = DSOP_FLAG_MULTISELECT; hr = pDsObjectPicker->Initialize(&InitInfo); IDataObject *pdo = NULL; hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo); } #include #include int _cdecl main(int argc, char * argv[]) { HRESULT hr; IDsObjectPicker *pDsObjectPicker = NULL; do { hr = CoInitialize(NULL); BREAK_ON_FAIL_HRESULT(hr); hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPickerEx, (void **) &pDsObjectPicker); BREAK_ON_FAIL_HRESULT(hr); DSOP_SCOPE_INIT_INFO aScopes[1]; ZeroMemory(aScopes, sizeof(aScopes)); aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN; aScopes[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE; aScopes[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_WELL_KNOWN_PRINCIPALS | DSOP_FILTER_USERS; aScopes[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS; #if 0 aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE; aScopes[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN; aScopes[0].FilterFlags.Uplevel.flMixedModeOnly = DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_BUILTIN_GROUPS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE | DSOP_FILTER_COMPUTERS; aScopes[0].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_BUILTIN_GROUPS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE | DSOP_FILTER_COMPUTERS; aScopes[0].FilterFlags.flDownlevel = 0x800079fd; aScopes[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[1].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG; aScopes[1].flScope = 0; aScopes[1].FilterFlags.Uplevel.flBothModes = 0x8a3; aScopes[2].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[2].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN; aScopes[2].flScope = 0; aScopes[2].FilterFlags.Uplevel.flBothModes = 0x8a3; aScopes[2].FilterFlags.flDownlevel = 0x80000005; aScopes[3].cbSize = sizeof(DSOP_SCOPE_INIT_INFO); aScopes[3].flType = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN; aScopes[3].flScope = 0; aScopes[3].FilterFlags.Uplevel.flBothModes = 0x8a3; aScopes[3].FilterFlags.flDownlevel = 0x80000005; #endif DSOP_INIT_INFO InitInfo; ZeroMemory(&InitInfo, sizeof(InitInfo)); PCWSTR apwzAttributeNames[] = { L"ObjectSid" }; InitInfo.cbSize = sizeof(InitInfo); InitInfo.pwzTargetComputer = NULL; //InitInfo.flOptions = DSOP_FLAG_MULTISELECT; InitInfo.cDsScopeInfos = ARRAYLEN(aScopes); InitInfo.aDsScopeInfos = aScopes; InitInfo.cAttributesToFetch = ARRAYLEN(apwzAttributeNames); InitInfo.apwzAttributeNames = apwzAttributeNames; hr = pDsObjectPicker->Initialize(&InitInfo); BREAK_ON_FAIL_HRESULT(hr); IDataObject *pdo = NULL; hr = pDsObjectPicker->InvokeDialog(NULL, &pdo); BREAK_ON_FAIL_HRESULT(hr); if (hr == S_FALSE) { printf("User cancelled dialog\n"); break; } STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL }; UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST); FORMATETC formatetc = { cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; hr = pdo->GetData(&formatetc, &stgmedium); BREAK_ON_FAIL_HRESULT(hr); PDS_SELECTION_LIST pDsSelList = (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal); DumpDsSelectedItemList( pDsSelList, InitInfo.cAttributesToFetch, InitInfo.apwzAttributeNames); GlobalUnlock(stgmedium.hGlobal); ReleaseStgMedium(&stgmedium); pdo->Release(); } while (0); if (pDsObjectPicker) { pDsObjectPicker->Release(); } OutputDebugString(L"main.cxx: uninitializing OLE\n"); CoUninitialize(); return 0; }