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.

412 lines
11 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: sample.cxx
  7. //
  8. // Contents: Sample DS object picker client.
  9. //
  10. //---------------------------------------------------------------------------
  11. #define INC_OLE2
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <objsel.h>
  15. #define BREAK_ON_FAIL_HRESULT(hr) \
  16. if (FAILED(hr)) { printf("line %u err 0x%x\n", __LINE__, hr); break; }
  17. #undef ASSERT
  18. #define ASSERT(x) \
  19. if (!(x)) printf("line %u assert failed\n", __LINE__)
  20. UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  21. //+--------------------------------------------------------------------------
  22. //
  23. // Function: InitObjectPickerForGroups
  24. //
  25. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  26. // set it to allow the user to pick one or more groups.
  27. //
  28. // Arguments: [pDsObjectPicker] - object picker interface instance
  29. //
  30. // Returns: Result of calling IDsObjectPicker::Initialize.
  31. //
  32. //---------------------------------------------------------------------------
  33. HRESULT
  34. InitObjectPickerForGroups(
  35. IDsObjectPicker *pDsObjectPicker)
  36. {
  37. //
  38. // Prepare to initialize the object picker.
  39. // Set up the array of scope initializer structures.
  40. //
  41. static const int SCOPE_INIT_COUNT = 5;
  42. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  43. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  44. //
  45. // Target computer scope. This adds a "Look In" entry for the
  46. // target computer. Computer scopes are always treated as
  47. // downlevel (i.e., they use the WinNT provider).
  48. //
  49. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  50. aScopeInit[0].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  51. aScopeInit[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  52. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  53. //
  54. // The domain to which the target computer is joined. Note we're
  55. // combining two scope types into flType here for convenience.
  56. //
  57. aScopeInit[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  58. aScopeInit[1].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  59. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  60. aScopeInit[1].FilterFlags.Uplevel.flNativeModeOnly =
  61. DSOP_FILTER_GLOBAL_GROUPS_SE
  62. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  63. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  64. aScopeInit[1].FilterFlags.Uplevel.flMixedModeOnly =
  65. DSOP_FILTER_GLOBAL_GROUPS_SE;
  66. aScopeInit[1].FilterFlags.flDownlevel =
  67. DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  68. //
  69. // The domains in the same forest (enterprise) as the domain to which
  70. // the target machine is joined. Note these can only be DS-aware
  71. //
  72. aScopeInit[2].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  73. aScopeInit[2].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  74. aScopeInit[2].FilterFlags.Uplevel.flNativeModeOnly =
  75. DSOP_FILTER_GLOBAL_GROUPS_SE
  76. | DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  77. aScopeInit[2].FilterFlags.Uplevel.flMixedModeOnly =
  78. DSOP_FILTER_GLOBAL_GROUPS_SE;
  79. //
  80. // Domains external to the enterprise but trusted directly by the
  81. // domain to which the target machine is joined.
  82. //
  83. // If the target machine is joined to an NT4 domain, only the
  84. // external downlevel domain scope applies, and it will cause
  85. // all domains trusted by the joined domain to appear.
  86. //
  87. aScopeInit[3].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  88. aScopeInit[3].flType =
  89. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  90. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  91. aScopeInit[3].FilterFlags.Uplevel.flNativeModeOnly =
  92. DSOP_FILTER_GLOBAL_GROUPS_SE
  93. | DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  94. aScopeInit[3].FilterFlags.Uplevel.flMixedModeOnly =
  95. DSOP_FILTER_GLOBAL_GROUPS_SE;
  96. aScopeInit[3].FilterFlags.flDownlevel =
  97. DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  98. //
  99. // The Global Catalog
  100. //
  101. aScopeInit[4].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  102. aScopeInit[4].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  103. aScopeInit[4].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  104. // Only native mode applies to gc scope.
  105. aScopeInit[4].FilterFlags.Uplevel.flNativeModeOnly =
  106. DSOP_FILTER_GLOBAL_GROUPS_SE
  107. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  108. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  109. //
  110. // Put the scope init array into the object picker init array
  111. //
  112. DSOP_INIT_INFO InitInfo;
  113. ZeroMemory(&InitInfo, sizeof(InitInfo));
  114. InitInfo.cbSize = sizeof(InitInfo);
  115. //
  116. // The pwzTargetComputer member allows the object picker to be
  117. // retargetted to a different computer. It will behave as if it
  118. // were being run ON THAT COMPUTER.
  119. //
  120. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  121. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  122. InitInfo.aDsScopeInfos = aScopeInit;
  123. InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
  124. //
  125. // Note object picker makes its own copy of InitInfo. Also note
  126. // that Initialize may be called multiple times, last call wins.
  127. //
  128. HRESULT hr = pDsObjectPicker->Initialize(&InitInfo);
  129. if (FAILED(hr))
  130. {
  131. ULONG i;
  132. for (i = 0; i < SCOPE_INIT_COUNT; i++)
  133. {
  134. if (FAILED(InitInfo.aDsScopeInfos[i].hr))
  135. {
  136. printf("Initialization failed because of scope %u\n", i);
  137. }
  138. }
  139. }
  140. return hr;
  141. }
  142. //+--------------------------------------------------------------------------
  143. //
  144. // Function: InitObjectPickerForComputers
  145. //
  146. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  147. // set it to allow the user to pick a single computer object.
  148. //
  149. // Arguments: [pDsObjectPicker] - object picker interface instance
  150. //
  151. // Returns: Result of calling IDsObjectPicker::Initialize.
  152. //
  153. //---------------------------------------------------------------------------
  154. HRESULT
  155. InitObjectPickerForComputers(
  156. IDsObjectPicker *pDsObjectPicker)
  157. {
  158. //
  159. // Prepare to initialize the object picker.
  160. // Set up the array of scope initializer structures.
  161. //
  162. static const int SCOPE_INIT_COUNT = 1;
  163. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  164. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  165. //
  166. // Since we just want computer objects from every scope, combine them
  167. // all in a single scope initializer.
  168. //
  169. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  170. aScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  171. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
  172. | DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  173. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  174. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  175. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
  176. | DSOP_SCOPE_TYPE_WORKGROUP
  177. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  178. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  179. aScopeInit[0].FilterFlags.Uplevel.flBothModes =
  180. DSOP_FILTER_COMPUTERS;
  181. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  182. //
  183. // Put the scope init array into the object picker init array
  184. //
  185. DSOP_INIT_INFO InitInfo;
  186. ZeroMemory(&InitInfo, sizeof(InitInfo));
  187. InitInfo.cbSize = sizeof(InitInfo);
  188. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  189. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  190. InitInfo.aDsScopeInfos = aScopeInit;
  191. //
  192. // Note object picker makes its own copy of InitInfo. Also note
  193. // that Initialize may be called multiple times, last call wins.
  194. //
  195. return pDsObjectPicker->Initialize(&InitInfo);
  196. }
  197. //+--------------------------------------------------------------------------
  198. //
  199. // Function: ProcessSelectedObjects
  200. //
  201. // Synopsis: Retrieve the list of selected items from the data object
  202. // created by the object picker and print out each one.
  203. //
  204. // Arguments: [pdo] - data object returned by object picker
  205. //
  206. //---------------------------------------------------------------------------
  207. void
  208. ProcessSelectedObjects(
  209. IDataObject *pdo)
  210. {
  211. HRESULT hr = S_OK;
  212. STGMEDIUM stgmedium =
  213. {
  214. TYMED_HGLOBAL,
  215. NULL,
  216. NULL
  217. };
  218. FORMATETC formatetc =
  219. {
  220. g_cfDsObjectPicker,
  221. NULL,
  222. DVASPECT_CONTENT,
  223. -1,
  224. TYMED_HGLOBAL
  225. };
  226. bool fGotStgMedium = false;
  227. do
  228. {
  229. hr = pdo->GetData(&formatetc, &stgmedium);
  230. BREAK_ON_FAIL_HRESULT(hr);
  231. fGotStgMedium = true;
  232. PDS_SELECTION_LIST pDsSelList =
  233. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  234. if (!pDsSelList)
  235. {
  236. printf("GlobalLock error %u\n", GetLastError());
  237. break;
  238. }
  239. ULONG i;
  240. for (i = 0; i < pDsSelList->cItems; i++)
  241. {
  242. printf("Object %u'\n", i);
  243. printf(" Name '%ws'\n", pDsSelList->aDsSelection[i].pwzName);
  244. printf(" Class '%ws'\n", pDsSelList->aDsSelection[i].pwzClass);
  245. printf(" Path '%ws'\n", pDsSelList->aDsSelection[i].pwzADsPath);
  246. printf(" UPN '%ws'\n", pDsSelList->aDsSelection[i].pwzUPN);
  247. }
  248. GlobalUnlock(stgmedium.hGlobal);
  249. } while (0);
  250. if (fGotStgMedium)
  251. {
  252. ReleaseStgMedium(&stgmedium);
  253. }
  254. }
  255. //+--------------------------------------------------------------------------
  256. //
  257. // Function: main
  258. //
  259. // Synopsis: Demonstrate use of DS object picker.
  260. //
  261. //---------------------------------------------------------------------------
  262. void _cdecl
  263. main(int argc, char * argv[])
  264. {
  265. HRESULT hr = S_OK;
  266. IDsObjectPicker *pDsObjectPicker = NULL;
  267. IDataObject *pdo = NULL;
  268. hr = CoInitialize(NULL);
  269. if (FAILED(hr)) return;
  270. do
  271. {
  272. //
  273. // Create an instance of the object picker.
  274. //
  275. hr = CoCreateInstance(CLSID_DsObjectPicker,
  276. NULL,
  277. CLSCTX_INPROC_SERVER,
  278. IID_IDsObjectPicker,
  279. (void **) &pDsObjectPicker);
  280. BREAK_ON_FAIL_HRESULT(hr);
  281. hr = InitObjectPickerForGroups(pDsObjectPicker);
  282. //
  283. // Invoke the modal dialog.
  284. //
  285. HWND hwndParent = NULL; // supply a window handle to your app
  286. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  287. BREAK_ON_FAIL_HRESULT(hr);
  288. //
  289. // If the user hit Cancel, hr == S_FALSE
  290. //
  291. if (hr == S_FALSE)
  292. {
  293. printf("User canceled object picker dialog\n");
  294. break;
  295. }
  296. //
  297. // Process the user's selections
  298. //
  299. ASSERT(pdo);
  300. ProcessSelectedObjects(pdo);
  301. pdo->Release();
  302. pdo = NULL;
  303. //
  304. // Reinitialize the object picker to choose computers
  305. //
  306. hr = InitObjectPickerForComputers(pDsObjectPicker);
  307. BREAK_ON_FAIL_HRESULT(hr);
  308. //
  309. // Now pick a computer
  310. //
  311. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  312. BREAK_ON_FAIL_HRESULT(hr);
  313. ASSERT(pdo);
  314. ProcessSelectedObjects(pdo);
  315. pdo->Release();
  316. pdo = NULL;
  317. } while (0);
  318. if (pDsObjectPicker)
  319. {
  320. pDsObjectPicker->Release();
  321. }
  322. CoUninitialize();
  323. }