Source code of Windows XP (NT5)
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.

586 lines
15 KiB

  1. #include "headers.hxx"
  2. #pragma hdrstop
  3. #include <compobj.h>
  4. #include <initguid.h>
  5. #include <objsel.h>
  6. PWSTR
  7. ScopeTypeStr(
  8. ULONG flType);
  9. LPWSTR
  10. VariantString(
  11. VARIANT *pvar);
  12. void
  13. VarArrayToStr(
  14. VARIANT *pvar,
  15. LPWSTR wzBuf,
  16. ULONG cchBuf);
  17. //
  18. // Helpful macros
  19. //
  20. #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
  21. #define DBG_OUT_HRESULT(hr) printf("error 0x%x at line %u\n", hr, __LINE__)
  22. #define BREAK_ON_FAIL_HRESULT(hr) \
  23. if (FAILED(hr)) \
  24. { \
  25. DBG_OUT_HRESULT(hr); \
  26. break; \
  27. }
  28. VOID
  29. DumpDsSelectedItemList(
  30. PDS_SELECTION_LIST pDsSelList,
  31. ULONG cRequestedAttributes,
  32. LPCTSTR *aptzRequestedAttributes)
  33. {
  34. if (!pDsSelList)
  35. {
  36. printf("List is empty\n");
  37. return;
  38. }
  39. ULONG i;
  40. PDS_SELECTION pCur = &pDsSelList->aDsSelection[0];
  41. for (i = 0; i < pDsSelList->cItems; i++, pCur++)
  42. {
  43. printf("ScopeType: %ws\n", ScopeTypeStr(pCur->flScopeType));
  44. printf("Name: %ws\n", pCur->pwzName);
  45. printf("Class: %ws\n", pCur->pwzClass);
  46. printf("Path: %ws\n", pCur->pwzADsPath);
  47. printf("UPN: %ws\n", pCur->pwzUPN);
  48. for (ULONG j = 0; j < cRequestedAttributes; j++)
  49. {
  50. printf("Attr %02u: %ws = %ws\n",
  51. j,
  52. aptzRequestedAttributes[j],
  53. VariantString(&pCur->pvarFetchedAttributes[j]));
  54. }
  55. printf("\n");
  56. }
  57. }
  58. PWSTR
  59. ScopeTypeStr(
  60. ULONG flType)
  61. {
  62. switch (flType)
  63. {
  64. case DSOP_SCOPE_TYPE_TARGET_COMPUTER:
  65. return L"DSOP_SCOPE_TYPE_TARGET_COMPUTER";
  66. case DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN:
  67. return L"DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN";
  68. case DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN:
  69. return L"DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN";
  70. case DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN:
  71. return L"DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN";
  72. case DSOP_SCOPE_TYPE_GLOBAL_CATALOG:
  73. return L"DSOP_SCOPE_TYPE_GLOBAL_CATALOG";
  74. case DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN:
  75. return L"DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN";
  76. case DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN:
  77. return L"DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN";
  78. case DSOP_SCOPE_TYPE_WORKGROUP:
  79. return L"DSOP_SCOPE_TYPE_WORKGROUP";
  80. case DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE:
  81. return L"DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE";
  82. case DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE:
  83. return L"DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE";
  84. default:
  85. return L"*** invalid scope type ***";
  86. }
  87. }
  88. LPWSTR
  89. VariantString(
  90. VARIANT *pvar)
  91. {
  92. static WCHAR wzBuf[1024];
  93. wzBuf[0] = L'\0';
  94. switch (pvar->vt)
  95. {
  96. case VT_EMPTY:
  97. lstrcpy(wzBuf, L"VT_EMPTY");
  98. break;
  99. case VT_NULL:
  100. lstrcpy(wzBuf, L"VT_NULL");
  101. break;
  102. case VT_I2:
  103. wsprintf(wzBuf, L"%d", V_I2(pvar));
  104. break;
  105. case VT_I4:
  106. wsprintf(wzBuf, L"%d", V_I4(pvar));
  107. break;
  108. case VT_R4:
  109. wsprintf(wzBuf, L"%f", V_R4(pvar));
  110. break;
  111. case VT_R8:
  112. wsprintf(wzBuf, L"%f", V_R8(pvar));
  113. break;
  114. case VT_CY:
  115. wsprintf(wzBuf, L"$%f", V_CY(pvar));
  116. break;
  117. case VT_DATE:
  118. wsprintf(wzBuf, L"date %f", V_DATE(pvar));
  119. break;
  120. case VT_BSTR:
  121. if (V_BSTR(pvar))
  122. {
  123. wsprintf(wzBuf, L"'%ws'", V_BSTR(pvar));
  124. }
  125. else
  126. {
  127. lstrcpy(wzBuf, L"VT_BSTR NULL");
  128. }
  129. break;
  130. case VT_DISPATCH:
  131. wsprintf(wzBuf, L"VT_DISPATCH 0x%x", V_DISPATCH(pvar));
  132. break;
  133. case VT_UNKNOWN:
  134. wsprintf(wzBuf, L"VT_UNKNOWN 0x%x", V_UNKNOWN(pvar));
  135. break;
  136. case VT_ERROR:
  137. case VT_HRESULT:
  138. wsprintf(wzBuf, L"hr 0x%x", V_ERROR(pvar));
  139. break;
  140. case VT_BOOL:
  141. wsprintf(wzBuf, L"%s", V_BOOL(pvar) ? "TRUE" : "FALSE");
  142. break;
  143. case VT_VARIANT:
  144. wsprintf(wzBuf, L"variant 0x%x", V_VARIANTREF(pvar));
  145. break;
  146. case VT_DECIMAL:
  147. lstrcpy(wzBuf, L"VT_DECIMAL");
  148. break;
  149. case VT_I1:
  150. wsprintf(wzBuf, L"%d", V_I1(pvar));
  151. break;
  152. case VT_UI1:
  153. wsprintf(wzBuf, L"%u", V_UI1(pvar));
  154. break;
  155. case VT_UI2:
  156. wsprintf(wzBuf, L"%u", V_UI2(pvar));
  157. break;
  158. case VT_UI4:
  159. wsprintf(wzBuf, L"%u", V_UI4(pvar));
  160. break;
  161. case VT_I8:
  162. lstrcpy(wzBuf, L"VT_I8");
  163. break;
  164. case VT_UI8:
  165. lstrcpy(wzBuf, L"VT_UI8");
  166. break;
  167. case VT_INT:
  168. wsprintf(wzBuf, L"%d", V_INT(pvar));
  169. break;
  170. case VT_UINT:
  171. wsprintf(wzBuf, L"%u", V_UINT(pvar));
  172. break;
  173. case VT_VOID:
  174. lstrcpy(wzBuf, L"VT_VOID");
  175. break;
  176. case VT_UI1 | VT_ARRAY:
  177. VarArrayToStr(pvar, wzBuf, ARRAYLEN(wzBuf));
  178. break;
  179. case VT_PTR:
  180. case VT_SAFEARRAY:
  181. case VT_CARRAY:
  182. case VT_USERDEFINED:
  183. case VT_LPSTR:
  184. case VT_LPWSTR:
  185. case VT_RECORD:
  186. case VT_FILETIME:
  187. case VT_BLOB:
  188. case VT_STREAM:
  189. case VT_STORAGE:
  190. case VT_STREAMED_OBJECT:
  191. case VT_STORED_OBJECT:
  192. case VT_BLOB_OBJECT:
  193. case VT_CF:
  194. case VT_CLSID:
  195. case VT_BSTR_BLOB:
  196. default:
  197. wsprintf(wzBuf, L"VT 0x%x", V_VT(pvar));
  198. break;
  199. }
  200. return wzBuf;
  201. }
  202. void
  203. VarArrayToStr(
  204. VARIANT *pvar,
  205. LPWSTR wzBuf,
  206. ULONG cchBuf)
  207. {
  208. ULONG i;
  209. LPWSTR pwzNext = wzBuf;
  210. LPWSTR pwzEnd = wzBuf + cchBuf;
  211. for (i = 0; i < pvar->parray->rgsabound[0].cElements && pwzNext < pwzEnd + 6; i++)
  212. {
  213. wsprintf(pwzNext, L"x%02x ", ((LPBYTE)(pvar->parray->pvData))[i]);
  214. pwzNext += lstrlen(pwzNext);
  215. }
  216. }
  217. //
  218. // This example allows the user to pick a single computer object
  219. // from any domain in the enterprise, the global catalog, or any
  220. // user-specified domain. If the target (local) computer is not
  221. // joined to a domain, it allows the user to choose a computer
  222. // object from the workgroup.
  223. //
  224. void func1(HWND hwndParent)
  225. {
  226. HRESULT hr;
  227. IDsObjectPicker *pDsObjectPicker;
  228. hr = CoCreateInstance(CLSID_DsObjectPicker,
  229. NULL,
  230. CLSCTX_INPROC_SERVER,
  231. IID_IDsObjectPicker,
  232. (void **) &pDsObjectPicker);
  233. DSOP_SCOPE_INIT_INFO aScopes[1];
  234. ZeroMemory(aScopes, sizeof(aScopes));
  235. aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  236. aScopes[0].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  237. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  238. | DSOP_SCOPE_TYPE_WORKGROUP
  239. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  240. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  241. aScopes[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  242. aScopes[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  243. DSOP_INIT_INFO InitInfo;
  244. ZeroMemory(&InitInfo, sizeof(InitInfo));
  245. InitInfo.cbSize = sizeof(InitInfo);
  246. InitInfo.cDsScopeInfos = 1;
  247. InitInfo.aDsScopeInfos = aScopes;
  248. hr = pDsObjectPicker->Initialize(&InitInfo);
  249. IDataObject *pdo = NULL;
  250. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  251. STGMEDIUM stgmedium =
  252. {
  253. TYMED_HGLOBAL,
  254. NULL
  255. };
  256. UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  257. FORMATETC formatetc =
  258. {
  259. cf,
  260. NULL,
  261. DVASPECT_CONTENT,
  262. -1,
  263. TYMED_HGLOBAL
  264. };
  265. hr = pdo->GetData(&formatetc, &stgmedium);
  266. PDS_SELECTION_LIST pDsSelList =
  267. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  268. ULONG i;
  269. for (i = 0; i < pDsSelList->cItems; i++)
  270. {
  271. printf("item %u: %ws\n", i + 1, pDsSelList->aDsSelection[i].pwzName);
  272. }
  273. GlobalUnlock(stgmedium.hGlobal);
  274. ReleaseStgMedium(&stgmedium);
  275. pdo->Release();
  276. pDsObjectPicker->Release();
  277. }
  278. //
  279. // This example allows the user to select one or more objects which may
  280. // legally be added to a security enabled global group. It will not
  281. // allow the user to specify objects which are contained in domains other
  282. // than those in the enterprise. The objectSid attribute is fetched for
  283. // all selected objects. The ADsPath of all selected objects is converted
  284. // to a form using the WinNT provider.
  285. //
  286. void func2(HWND hwndParent)
  287. {
  288. HRESULT hr;
  289. IDsObjectPicker *pDsObjectPicker;
  290. hr = CoCreateInstance(CLSID_DsObjectPicker,
  291. NULL,
  292. CLSCTX_INPROC_SERVER,
  293. IID_IDsObjectPicker,
  294. (void **) &pDsObjectPicker);
  295. PCWSTR apwzAttrs[] =
  296. {
  297. L"objectSid"
  298. };
  299. //
  300. // Specify the objects which should be displayed for the domain
  301. // to which the target computer is joined.
  302. //
  303. DSOP_SCOPE_INIT_INFO aScopes[2];
  304. ZeroMemory(aScopes, sizeof(aScopes));
  305. aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  306. aScopes[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  307. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  308. aScopes[0].FilterFlags.Uplevel.flBothModes =
  309. DSOP_FILTER_USERS
  310. | DSOP_FILTER_CONTACTS
  311. | DSOP_FILTER_COMPUTERS;
  312. aScopes[0].FilterFlags.Uplevel.flNativeModeOnly =
  313. DSOP_FILTER_GLOBAL_GROUPS_DL
  314. | DSOP_FILTER_GLOBAL_GROUPS_SE;
  315. aScopes[0].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  316. // include downlevel filter in case target computer is joined to
  317. // an NT4 domain
  318. aScopes[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  319. //
  320. // Specify the objects which should be displayed for all other
  321. // domains in the enterprise.
  322. //
  323. aScopes[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  324. aScopes[1].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  325. aScopes[1].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_CONTACTS;
  326. aScopes[1].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  327. DSOP_INIT_INFO InitInfo;
  328. ZeroMemory(&InitInfo, sizeof(InitInfo));
  329. InitInfo.cbSize = sizeof(InitInfo);
  330. InitInfo.cDsScopeInfos = 2;
  331. InitInfo.aDsScopeInfos = aScopes;
  332. InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
  333. hr = pDsObjectPicker->Initialize(&InitInfo);
  334. IDataObject *pdo = NULL;
  335. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  336. }
  337. #include <initguid.h>
  338. #include <objselp.h>
  339. int _cdecl
  340. main(int argc, char * argv[])
  341. {
  342. HRESULT hr;
  343. IDsObjectPicker *pDsObjectPicker = NULL;
  344. do
  345. {
  346. hr = CoInitialize(NULL);
  347. BREAK_ON_FAIL_HRESULT(hr);
  348. hr = CoCreateInstance(CLSID_DsObjectPicker,
  349. NULL,
  350. CLSCTX_INPROC_SERVER,
  351. IID_IDsObjectPickerEx,
  352. (void **) &pDsObjectPicker);
  353. BREAK_ON_FAIL_HRESULT(hr);
  354. DSOP_SCOPE_INIT_INFO aScopes[1];
  355. ZeroMemory(aScopes, sizeof(aScopes));
  356. aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  357. aScopes[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN;
  358. aScopes[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  359. aScopes[0].FilterFlags.Uplevel.flBothModes =
  360. DSOP_FILTER_WELL_KNOWN_PRINCIPALS
  361. | DSOP_FILTER_USERS;
  362. aScopes[0].FilterFlags.flDownlevel =
  363. DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS;
  364. #if 0
  365. aScopes[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  366. aScopes[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  367. aScopes[0].flType =
  368. DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  369. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  370. aScopes[0].FilterFlags.Uplevel.flMixedModeOnly =
  371. DSOP_FILTER_INCLUDE_ADVANCED_VIEW
  372. | DSOP_FILTER_USERS
  373. | DSOP_FILTER_BUILTIN_GROUPS
  374. | DSOP_FILTER_WELL_KNOWN_PRINCIPALS
  375. | DSOP_FILTER_GLOBAL_GROUPS_SE
  376. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE
  377. | DSOP_FILTER_COMPUTERS;
  378. aScopes[0].FilterFlags.Uplevel.flNativeModeOnly =
  379. DSOP_FILTER_INCLUDE_ADVANCED_VIEW
  380. | DSOP_FILTER_USERS
  381. | DSOP_FILTER_BUILTIN_GROUPS
  382. | DSOP_FILTER_WELL_KNOWN_PRINCIPALS
  383. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  384. | DSOP_FILTER_GLOBAL_GROUPS_SE
  385. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE
  386. | DSOP_FILTER_COMPUTERS;
  387. aScopes[0].FilterFlags.flDownlevel = 0x800079fd;
  388. aScopes[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  389. aScopes[1].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  390. aScopes[1].flScope = 0;
  391. aScopes[1].FilterFlags.Uplevel.flBothModes = 0x8a3;
  392. aScopes[2].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  393. aScopes[2].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  394. aScopes[2].flScope = 0;
  395. aScopes[2].FilterFlags.Uplevel.flBothModes = 0x8a3;
  396. aScopes[2].FilterFlags.flDownlevel = 0x80000005;
  397. aScopes[3].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  398. aScopes[3].flType =
  399. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  400. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  401. aScopes[3].flScope = 0;
  402. aScopes[3].FilterFlags.Uplevel.flBothModes = 0x8a3;
  403. aScopes[3].FilterFlags.flDownlevel = 0x80000005;
  404. #endif
  405. DSOP_INIT_INFO InitInfo;
  406. ZeroMemory(&InitInfo, sizeof(InitInfo));
  407. PCWSTR apwzAttributeNames[] = {
  408. L"ObjectSid"
  409. };
  410. InitInfo.cbSize = sizeof(InitInfo);
  411. InitInfo.pwzTargetComputer = NULL;
  412. //InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
  413. InitInfo.cDsScopeInfos = ARRAYLEN(aScopes);
  414. InitInfo.aDsScopeInfos = aScopes;
  415. InitInfo.cAttributesToFetch = ARRAYLEN(apwzAttributeNames);
  416. InitInfo.apwzAttributeNames = apwzAttributeNames;
  417. hr = pDsObjectPicker->Initialize(&InitInfo);
  418. BREAK_ON_FAIL_HRESULT(hr);
  419. IDataObject *pdo = NULL;
  420. hr = pDsObjectPicker->InvokeDialog(NULL, &pdo);
  421. BREAK_ON_FAIL_HRESULT(hr);
  422. if (hr == S_FALSE)
  423. {
  424. printf("User cancelled dialog\n");
  425. break;
  426. }
  427. STGMEDIUM stgmedium =
  428. {
  429. TYMED_HGLOBAL,
  430. NULL
  431. };
  432. UINT cf = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  433. FORMATETC formatetc =
  434. {
  435. cf,
  436. NULL,
  437. DVASPECT_CONTENT,
  438. -1,
  439. TYMED_HGLOBAL
  440. };
  441. hr = pdo->GetData(&formatetc, &stgmedium);
  442. BREAK_ON_FAIL_HRESULT(hr);
  443. PDS_SELECTION_LIST pDsSelList =
  444. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  445. DumpDsSelectedItemList(
  446. pDsSelList,
  447. InitInfo.cAttributesToFetch,
  448. InitInfo.apwzAttributeNames);
  449. GlobalUnlock(stgmedium.hGlobal);
  450. ReleaseStgMedium(&stgmedium);
  451. pdo->Release();
  452. } while (0);
  453. if (pDsObjectPicker)
  454. {
  455. pDsObjectPicker->Release();
  456. }
  457. OutputDebugString(L"main.cxx: uninitializing OLE\n");
  458. CoUninitialize();
  459. return 0;
  460. }