Leaked source code of windows server 2003
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

  1. //--------------------------------------------------------------------------
  2. #ifndef _WIN32_WINNT
  3. #define _WIN32_WINNT 0x0510
  4. #endif
  5. #ifndef WIN32_LEAN_AND_MEAN
  6. #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
  7. #endif
  8. #define SECURITY_WIN32
  9. #include <windows.h>
  10. #include <tchar.h>
  11. #include <assert.h>
  12. #include <objbase.h>
  13. #include <objsel.h>
  14. #include <Security.h>
  15. #include <sddl.h>
  16. #include <Secext.h>
  17. #include "objectpicker.h"
  18. #define OP_GENERIC_EXCEPTION ( ( DWORD ) 1 )
  19. //--------------------------------------------------------------------------
  20. UINT g_cfDsObjectPicker = RegisterClipboardFormat( CFSTR_DSOP_DS_SELECTION_LIST );
  21. static HRESULT InitObjectPicker( ObjectType oType,
  22. IDsObjectPicker *pDsObjectPicker,
  23. PTCHAR szTarget );
  24. static HRESULT InitObjectPickerForComputers( IDsObjectPicker *pDsObjectPicker );
  25. static HRESULT InitObjectPickerForGroups( IDsObjectPicker *pDsObjectPicker,
  26. BOOL fMultiselect,
  27. LPCTSTR pszMachineName,
  28. BOOL fWantSidPath );
  29. static HRESULT InitObjectPickerForUsers( IDsObjectPicker *pDsObjectPicker,
  30. BOOL fMultiselect,
  31. LPCTSTR pszMachineName );
  32. static bool ProcessSelectedObjects( IDataObject *pdo,
  33. ObjectType oType,
  34. PTCHAR szObjectName,
  35. ULONG uBufSize );
  36. //--------------------------------------------------------------------------
  37. // returns true if no errors, false otherwise
  38. // use GetLastError() to get error code
  39. //
  40. bool
  41. ObjectPicker( HWND hwndParent,
  42. ObjectType oType,
  43. PTCHAR szObjectName,
  44. ULONG uBufSize,
  45. PTCHAR szTarget )
  46. {
  47. IDsObjectPicker *pDsObjectPicker = NULL;
  48. IDataObject *pdo = NULL;
  49. bool bRet = true; // assume no errors
  50. try
  51. {
  52. HRESULT hr = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  53. if( FAILED( hr ) )
  54. {
  55. throw (DWORD)HRESULT_CODE( hr );
  56. }
  57. //
  58. // Create an instance of the object picker.
  59. //
  60. hr = CoCreateInstance( CLSID_DsObjectPicker,
  61. NULL,
  62. CLSCTX_INPROC_SERVER,
  63. IID_IDsObjectPicker,
  64. reinterpret_cast<void **>( &pDsObjectPicker ) );
  65. if( FAILED( hr ) )
  66. {
  67. throw (DWORD)HRESULT_CODE(hr);
  68. }
  69. //
  70. // Initialize the object picker instance.
  71. //
  72. hr = InitObjectPicker( oType, pDsObjectPicker, szTarget );
  73. if( FAILED( hr ) )
  74. {
  75. throw (DWORD)HRESULT_CODE(hr);
  76. }
  77. //
  78. // Invoke the modal dialog.
  79. //
  80. hr = pDsObjectPicker->InvokeDialog( hwndParent, &pdo );
  81. if( S_OK == hr )
  82. {
  83. if( !ProcessSelectedObjects( pdo, oType, szObjectName, uBufSize ))
  84. {
  85. throw GetLastError();
  86. }
  87. }
  88. else if( S_FALSE == hr ) // user pressed cancel
  89. {
  90. throw (DWORD)OP_GENERIC_EXCEPTION;
  91. }
  92. else
  93. {
  94. throw (DWORD)HRESULT_CODE(hr);
  95. }
  96. }
  97. catch( DWORD dwErr )
  98. {
  99. SetLastError( dwErr );
  100. bRet = false;
  101. }
  102. catch( ... )
  103. {
  104. bRet = false;
  105. }
  106. //
  107. // Cleanup.
  108. //
  109. if( pdo )
  110. pdo->Release();
  111. if( pDsObjectPicker )
  112. pDsObjectPicker->Release();
  113. CoUninitialize();
  114. return bRet;
  115. }
  116. static HRESULT
  117. InitObjectPicker( ObjectType oType, IDsObjectPicker *pDsObjectPicker, PTCHAR szTarget )
  118. {
  119. if( NULL == pDsObjectPicker )
  120. {
  121. return E_INVALIDARG;
  122. }
  123. HRESULT hr = E_FAIL;
  124. if( OT_Computer == oType )
  125. {
  126. hr = InitObjectPickerForComputers( pDsObjectPicker );
  127. }
  128. else if( OT_User == oType )
  129. {
  130. hr = InitObjectPickerForUsers( pDsObjectPicker, FALSE, szTarget );
  131. }
  132. else if( OT_Group == oType )
  133. {
  134. hr = InitObjectPickerForGroups( pDsObjectPicker, FALSE, szTarget, FALSE );
  135. }
  136. else if( OT_GroupSID == oType )
  137. {
  138. hr = InitObjectPickerForGroups( pDsObjectPicker, FALSE, szTarget, TRUE );
  139. }
  140. return hr;
  141. }
  142. static bool
  143. ProcessSelectedObjects( IDataObject *pdo, ObjectType oType, PTCHAR szObjectName, ULONG uBufSize )
  144. {
  145. PDS_SELECTION_LIST pDsSelList = NULL;
  146. bool dwRet = true; // assume ok
  147. STGMEDIUM stgmedium =
  148. {
  149. TYMED_HGLOBAL,
  150. NULL,
  151. NULL
  152. };
  153. FORMATETC formatetc =
  154. {
  155. ( CLIPFORMAT ) g_cfDsObjectPicker,
  156. NULL,
  157. DVASPECT_CONTENT,
  158. -1,
  159. TYMED_HGLOBAL
  160. };
  161. try
  162. {
  163. //
  164. // Get the global memory block containing a user's selections.
  165. //
  166. HRESULT hr = pdo->GetData( &formatetc, &stgmedium );
  167. if( FAILED( hr ) )
  168. throw HRESULT_CODE( hr );
  169. //
  170. // Retrieve pointer to DS_SELECTION_LIST structure.
  171. //
  172. pDsSelList = ( PDS_SELECTION_LIST ) GlobalLock( stgmedium.hGlobal );
  173. if( !pDsSelList )
  174. {
  175. throw GetLastError();
  176. }
  177. //
  178. // assume there is only 1 item returned because
  179. // we have multi-select turned off
  180. //
  181. if( pDsSelList->cItems != 1 )
  182. {
  183. assert( false );
  184. throw OP_GENERIC_EXCEPTION;
  185. }
  186. UINT i = 0;
  187. //
  188. // did we request a computer name? If so, we get it directly in the pwzName field
  189. //
  190. if( 0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "computer" )) )
  191. {
  192. assert( uBufSize > _tcslen( pDsSelList->aDsSelection[i].pwzName ) );
  193. _tcsncpy( szObjectName, pDsSelList->aDsSelection[i].pwzName, uBufSize - 1 );
  194. szObjectName[ uBufSize - 1 ] = NULL;
  195. }
  196. //
  197. // user name or group takes some post-processsing...
  198. //
  199. else if( 0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "user" ) ) ||
  200. 0 == _tcsicmp( pDsSelList->aDsSelection[i].pwzClass, TEXT( "group" ) ) )
  201. {
  202. //
  203. // user names from the domain begin with "LDAP:"
  204. // strip off the prefix info, up to the first "cn="
  205. // then use the TranslateName API to get the form "domain\user" or "domain\group"
  206. //
  207. if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "LDAP:" ), 5 ) )
  208. {
  209. if( OT_Group == oType )
  210. {
  211. PTCHAR p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "CN=" ) );
  212. if( NULL == p )
  213. p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "cn=" ) );
  214. if( NULL == p )
  215. {
  216. assert( false );
  217. throw OP_GENERIC_EXCEPTION;
  218. }
  219. if( !TranslateName( p, NameFullyQualifiedDN, NameSamCompatible, szObjectName, &uBufSize ) )
  220. throw GetLastError();
  221. }
  222. else if( OT_GroupSID == oType )
  223. {
  224. //
  225. // If we are here, then we should expect a string LDAP://SID=<xxxxx>
  226. //
  227. if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "LDAP:" ), 5 ) )
  228. {
  229. LPTSTR p = _tcsstr( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "=" ) );
  230. if( p )
  231. {
  232. p++;
  233. p[ _tcslen( p ) - 1 ] = NULL;
  234. LPTSTR szSID = NULL;
  235. BYTE sidArray[ 512 ];
  236. TCHAR szDigit[ 3 ];
  237. ZeroMemory( sidArray, sizeof sidArray );
  238. ZeroMemory( szDigit, sizeof szDigit );
  239. size_t len = _tcslen(p) / 2;
  240. for (size_t j=0; j < len; j++)
  241. {
  242. _tcsncpy( szDigit, p, 2 );
  243. LPTSTR stopPtr = NULL;
  244. sidArray[ j ] = (BYTE)_tcstoul( szDigit, &stopPtr, 16 );
  245. p+=2;
  246. }
  247. if( !ConvertSidToStringSid( sidArray, &szSID ) )
  248. {
  249. assert( false );
  250. throw OP_GENERIC_EXCEPTION;
  251. }
  252. else
  253. {
  254. _tcsncpy( szObjectName, szSID, uBufSize - 1 );
  255. LocalFree( szSID );
  256. }
  257. }
  258. else
  259. {
  260. assert( false );
  261. throw OP_GENERIC_EXCEPTION;
  262. }
  263. }
  264. else
  265. {
  266. assert( false );
  267. throw OP_GENERIC_EXCEPTION;
  268. }
  269. }
  270. else
  271. {
  272. assert( false );
  273. throw OP_GENERIC_EXCEPTION;
  274. }
  275. }
  276. //
  277. // otherwise, names on the local box begin with "winnt:"
  278. // and we are only interested in the last two sections of the string,
  279. // delimited by "/"
  280. //
  281. else if( 0 == _tcsnicmp( pDsSelList->aDsSelection[i].pwzADsPath, TEXT( "WINNT:" ), 6 ) )
  282. {
  283. PTCHAR p = pDsSelList->aDsSelection[i].pwzADsPath;
  284. PTCHAR pend = p + _tcslen( p );
  285. UINT uCount = 0;
  286. while( pend > p )
  287. {
  288. if( '/' == *pend )
  289. {
  290. *pend = '\\';
  291. uCount++;
  292. if( uCount == 2 )
  293. {
  294. p = pend + 1;
  295. break;
  296. }
  297. }
  298. pend--;
  299. }
  300. //
  301. // if this fails, assert during debug but do not stop
  302. //
  303. if( p == pend )
  304. assert( false );
  305. assert( uBufSize > _tcslen( p ) );
  306. _tcsncpy( szObjectName, p, uBufSize - 1 );
  307. szObjectName[ uBufSize - 1 ] = NULL;
  308. }
  309. else
  310. {
  311. assert( false );
  312. throw OP_GENERIC_EXCEPTION;
  313. }
  314. }
  315. else
  316. {
  317. assert( false );
  318. throw OP_GENERIC_EXCEPTION;
  319. }
  320. }
  321. catch( DWORD dwErr )
  322. {
  323. SetLastError( dwErr );
  324. dwRet = false;
  325. }
  326. if( pDsSelList )
  327. GlobalUnlock( stgmedium.hGlobal );
  328. ReleaseStgMedium( &stgmedium );
  329. return dwRet;
  330. }
  331. //+--------------------------------------------------------------------------
  332. //
  333. // Function: InitObjectPickerForGroups
  334. //
  335. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  336. // set it to allow the user to pick one or more groups.
  337. //
  338. // Arguments: [pDsObjectPicker] - object picker interface instance
  339. //
  340. // Returns: Result of calling IDsObjectPicker::Initialize.
  341. //
  342. // History: 10-14-1998 DavidMun Created
  343. // 1-8-2000 SergeiA Adapted for IIS
  344. // 9-6-2002 a-dsebes Adapted for UDDI
  345. //
  346. //---------------------------------------------------------------------------
  347. HRESULT
  348. InitObjectPickerForGroups( IDsObjectPicker *pDsObjectPicker,
  349. BOOL fMultiselect,
  350. LPCTSTR pszMachineName,
  351. BOOL fWantSidPath )
  352. {
  353. //
  354. // Prepare to initialize the object picker.
  355. // Set up the array of scope initializer structures.
  356. //
  357. static const int SCOPE_INIT_COUNT = 5;
  358. DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
  359. ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
  360. //
  361. // Target computer scope. This adds a "Look In" entry for the
  362. // target computer. Computer scopes are always treated as
  363. // downlevel (i.e., they use the WinNT provider).
  364. //
  365. aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  366. aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  367. aScopeInit[ 0 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  368. aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_BUILTIN_GROUPS;
  369. aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS;
  370. if( fWantSidPath )
  371. {
  372. aScopeInit[ 0 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
  373. }
  374. //
  375. // The domain to which the target computer is joined. Note we're
  376. // combining two scope types into flType here for convenience.
  377. //
  378. aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  379. aScopeInit[ 1 ].flScope = 0;
  380. aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN |
  381. DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  382. aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
  383. DSOP_FILTER_UNIVERSAL_GROUPS_SE |
  384. DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  385. aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  386. if( fWantSidPath )
  387. {
  388. aScopeInit[ 1 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
  389. }
  390. //
  391. // The domains in the same forest (enterprise) as the domain to which
  392. // the target machine is joined. Note these can only be DS-aware
  393. //
  394. aScopeInit[ 2 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  395. aScopeInit[ 2 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  396. aScopeInit[ 2 ].flScope = 0;
  397. aScopeInit[ 2 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
  398. DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  399. if( fWantSidPath )
  400. {
  401. aScopeInit[ 2 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
  402. }
  403. //
  404. // Domains external to the enterprise but trusted directly by the
  405. // domain to which the target machine is joined.
  406. //
  407. // If the target machine is joined to an NT4 domain, only the
  408. // external downlevel domain scope applies, and it will cause
  409. // all domains trusted by the joined domain to appear.
  410. //
  411. aScopeInit[ 3 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  412. aScopeInit[ 3 ].flScope = 0;
  413. aScopeInit[ 3 ].flType = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
  414. DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  415. aScopeInit[ 3 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_GLOBAL_GROUPS_SE |
  416. DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  417. aScopeInit[ 3 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  418. if( fWantSidPath )
  419. {
  420. aScopeInit[ 3 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
  421. }
  422. //
  423. // The Global Catalog
  424. //
  425. aScopeInit[ 4 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  426. aScopeInit[ 4 ].flScope = 0;
  427. aScopeInit[ 4 ].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  428. //
  429. // Only native mode applies to gc scope.
  430. //
  431. aScopeInit[ 4 ].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_GLOBAL_GROUPS_SE |
  432. DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  433. if( fWantSidPath )
  434. {
  435. aScopeInit[ 4 ].flScope |= DSOP_SCOPE_FLAG_WANT_SID_PATH;
  436. }
  437. //
  438. // Put the scope init array into the object picker init array
  439. //
  440. DSOP_INIT_INFO InitInfo;
  441. ZeroMemory( &InitInfo, sizeof( InitInfo ) );
  442. InitInfo.cbSize = sizeof( InitInfo );
  443. //
  444. // The pwzTargetComputer member allows the object picker to be
  445. // retargetted to a different computer. It will behave as if it
  446. // were being run ON THAT COMPUTER.
  447. //
  448. InitInfo.pwzTargetComputer = pszMachineName;
  449. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  450. InitInfo.aDsScopeInfos = aScopeInit;
  451. InitInfo.flOptions = fMultiselect ? DSOP_FLAG_MULTISELECT : 0;
  452. //
  453. // Note object picker makes its own copy of InitInfo. Also note
  454. // that Initialize may be called multiple times, last call wins.
  455. //
  456. HRESULT hr = pDsObjectPicker->Initialize( &InitInfo );
  457. return hr;
  458. }
  459. //+--------------------------------------------------------------------------
  460. //
  461. // Function: InitObjectPickerForGroups
  462. //
  463. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  464. // set it to allow the user to pick one or more groups.
  465. //
  466. // Arguments: [pDsObjectPicker] - object picker interface instance
  467. //
  468. // Returns: Result of calling IDsObjectPicker::Initialize.
  469. //
  470. // History: 9-6-2002 a-dsebes Created.
  471. //
  472. //
  473. //---------------------------------------------------------------------------
  474. HRESULT
  475. InitObjectPickerForUsers( IDsObjectPicker *pDsObjectPicker,
  476. BOOL fMultiselect,
  477. LPCTSTR pszMachineName )
  478. {
  479. //
  480. // Prepare to initialize the object picker.
  481. // Set up the array of scope initializer structures.
  482. //
  483. static const int SCOPE_INIT_COUNT = 5;
  484. DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
  485. ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
  486. //
  487. // Target computer scope. This adds a "Look In" entry for the
  488. // target computer. Computer scopes are always treated as
  489. // downlevel (i.e., they use the WinNT provider).
  490. //
  491. aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  492. aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  493. aScopeInit[ 0 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  494. aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  495. aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  496. //
  497. // The domain to which the target computer is joined. Note we're
  498. // combining two scope types into flType here for convenience.
  499. //
  500. aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  501. aScopeInit[ 1 ].flScope = 0;
  502. aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN |
  503. DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  504. aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  505. aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  506. //
  507. // The domains in the same forest (enterprise) as the domain to which
  508. // the target machine is joined. Note these can only be DS-aware
  509. //
  510. aScopeInit[ 2 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  511. aScopeInit[ 2 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  512. aScopeInit[ 2 ].flScope = 0;
  513. aScopeInit[ 2 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  514. //
  515. // Domains external to the enterprise but trusted directly by the
  516. // domain to which the target machine is joined.
  517. //
  518. // If the target machine is joined to an NT4 domain, only the
  519. // external downlevel domain scope applies, and it will cause
  520. // all domains trusted by the joined domain to appear.
  521. //
  522. aScopeInit[ 3 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  523. aScopeInit[ 3 ].flScope = 0;
  524. aScopeInit[ 3 ].flType = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
  525. DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  526. aScopeInit[ 3 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  527. aScopeInit[ 3 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  528. //
  529. // The Global Catalog
  530. //
  531. aScopeInit[ 4 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  532. aScopeInit[ 4 ].flScope = 0;
  533. aScopeInit[ 4 ].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  534. //
  535. // Only native mode applies to gc scope.
  536. //
  537. aScopeInit[ 4 ].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
  538. //
  539. // Put the scope init array into the object picker init array
  540. //
  541. DSOP_INIT_INFO InitInfo;
  542. ZeroMemory( &InitInfo, sizeof( InitInfo ) );
  543. InitInfo.cbSize = sizeof( InitInfo );
  544. //
  545. // The pwzTargetComputer member allows the object picker to be
  546. // retargetted to a different computer. It will behave as if it
  547. // were being run ON THAT COMPUTER.
  548. //
  549. InitInfo.pwzTargetComputer = pszMachineName;
  550. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  551. InitInfo.aDsScopeInfos = aScopeInit;
  552. InitInfo.flOptions = fMultiselect ? DSOP_FLAG_MULTISELECT : 0;
  553. //
  554. // Note object picker makes its own copy of InitInfo. Also note
  555. // that Initialize may be called multiple times, last call wins.
  556. //
  557. HRESULT hr = pDsObjectPicker->Initialize( &InitInfo );
  558. return hr;
  559. }
  560. //+--------------------------------------------------------------------------
  561. //
  562. // Function: InitObjectPickerForComputers
  563. //
  564. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  565. // set it to allow the user to pick a single computer object.
  566. //
  567. // Arguments: [pDsObjectPicker] - object picker interface instance
  568. //
  569. // Returns: Result of calling IDsObjectPicker::Initialize.
  570. //
  571. // History: 10-14-1998 DavidMun Created
  572. // 08-06-2002 a-dsebes Adapted for UDDI.
  573. //
  574. //---------------------------------------------------------------------------
  575. HRESULT
  576. InitObjectPickerForComputers( IDsObjectPicker *pDsObjectPicker )
  577. {
  578. //
  579. // Prepare to initialize the object picker.
  580. // Set up the array of scope initializer structures.
  581. //
  582. static const int SCOPE_INIT_COUNT = 2;
  583. DSOP_SCOPE_INIT_INFO aScopeInit[ SCOPE_INIT_COUNT ];
  584. ZeroMemory( aScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * SCOPE_INIT_COUNT );
  585. //
  586. // Build a scope init struct for everything except the joined domain.
  587. //
  588. aScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  589. aScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  590. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  591. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  592. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
  593. | DSOP_SCOPE_TYPE_WORKGROUP
  594. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  595. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  596. aScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  597. aScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  598. //
  599. // scope for the joined domain, make it the default
  600. //
  601. aScopeInit[ 1 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  602. aScopeInit[ 1 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  603. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  604. aScopeInit[ 1 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  605. aScopeInit[ 1 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  606. aScopeInit[ 1 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  607. //
  608. // Put the scope init array into the object picker init array
  609. //
  610. DSOP_INIT_INFO InitInfo;
  611. ZeroMemory( &InitInfo, sizeof( InitInfo ) );
  612. InitInfo.cbSize = sizeof( InitInfo );
  613. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  614. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  615. InitInfo.aDsScopeInfos = aScopeInit;
  616. //
  617. // Note object picker makes its own copy of InitInfo. Also note
  618. // that Initialize may be called multiple times, last call wins.
  619. //
  620. return pDsObjectPicker->Initialize(&InitInfo);
  621. }