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.

787 lines
22 KiB

  1. // objpick.cpp: implementation of the CGetUser class and the
  2. // CGetComputer class using the object picker
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #include "stdafx.h"
  6. #include <iads.h>
  7. #include <objsel.h>
  8. #include <adshlp.h>
  9. #include <winsock2.h>
  10. #include <comdef.h>
  11. #include "common.h"
  12. #include "objpick.h"
  13. #include "accentry.h"
  14. #include "util.h"
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char THIS_FILE[]=__FILE__;
  18. #define new DEBUG_NEW
  19. #endif
  20. #define BREAK_ON_FAIL_HRESULT(hr) \
  21. if (FAILED(hr)) { TRACE(_T("line %u err 0x%x\n"), __LINE__, hr); break; }
  22. UINT g_cfDsObjectPicker; // = ::RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  23. HRESULT InitObjectPickerForGroups(IDsObjectPicker *pDsObjectPicker,
  24. BOOL fMultiselect,
  25. LPCTSTR pszMachineName,
  26. BOOL bUsersOnly);
  27. HRESULT InitObjectPickerForComputers(IDsObjectPicker *pDsObjectPicker);
  28. CAccessEntryArray::~CAccessEntryArray()
  29. {
  30. for (int i = 0; i < GetSize(); i++)
  31. delete GetAt(i);
  32. }
  33. //////////////////////////////////////////////////////////////////////
  34. // CGetUsers Class
  35. //////////////////////////////////////////////////////////////////////
  36. //////////////////////////////////////////////////////////////////////
  37. // Construction/Destruction
  38. //////////////////////////////////////////////////////////////////////
  39. void
  40. FormatName(LPCTSTR pszFullName, LPCTSTR pszDomainName, CString & strDisplay)
  41. {
  42. strDisplay.Format(_T("%s\\%s"), pszDomainName, pszFullName);
  43. }
  44. CGetUsers::CGetUsers(LPCTSTR pszMachineName, BOOL fMultiselect)
  45. : m_MachineName(pszMachineName),
  46. m_fMultiselect(fMultiselect)
  47. {
  48. }
  49. CGetUsers::~CGetUsers()
  50. {
  51. }
  52. BOOL
  53. CGetUsers::GetUsers(HWND hwndParent, BOOL bUsersOnly)
  54. {
  55. HRESULT hr = S_OK;
  56. IDsObjectPicker * pDsObjectPicker = NULL;
  57. IDataObject * pdo = NULL;
  58. BOOL fSuccess = TRUE;
  59. hr = CoInitialize(NULL);
  60. if (FAILED(hr))
  61. return FALSE;
  62. do
  63. {
  64. //
  65. // Create an instance of the object picker. The implementation in
  66. // objsel.dll is apartment model.
  67. //
  68. hr = CoCreateInstance(CLSID_DsObjectPicker,
  69. NULL,
  70. CLSCTX_INPROC_SERVER,
  71. IID_IDsObjectPicker,
  72. (void **) &pDsObjectPicker);
  73. BREAK_ON_FAIL_HRESULT(hr);
  74. hr = InitObjectPickerForGroups(pDsObjectPicker, m_fMultiselect, m_MachineName, bUsersOnly);
  75. BREAK_ON_FAIL_HRESULT(hr);
  76. //
  77. // Invoke the modal dialog.
  78. //
  79. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  80. BREAK_ON_FAIL_HRESULT(hr);
  81. //
  82. // If the user hit Cancel, hr == S_FALSE
  83. //
  84. if (hr == S_FALSE)
  85. {
  86. TRACE(_T("User canceled object picker dialog\n"));
  87. fSuccess = FALSE;
  88. break;
  89. }
  90. //
  91. // Process the user's selections
  92. //
  93. ASSERT(pdo);
  94. ProcessSelectedObjects(pdo);
  95. pdo->Release();
  96. pdo = NULL;
  97. } while (0);
  98. if (pDsObjectPicker)
  99. {
  100. pDsObjectPicker->Release();
  101. }
  102. CoUninitialize();
  103. if (FAILED(hr) || S_FALSE == hr)
  104. fSuccess = FALSE;
  105. return fSuccess;
  106. }
  107. void
  108. CGetUsers::ProcessSelectedObjects(IDataObject *pdo)
  109. {
  110. HRESULT hr = S_OK;
  111. STGMEDIUM stgmedium =
  112. {
  113. TYMED_HGLOBAL,
  114. NULL,
  115. NULL
  116. };
  117. if (g_cfDsObjectPicker == 0)
  118. g_cfDsObjectPicker = ::RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  119. ASSERT(g_cfDsObjectPicker != 0);
  120. FORMATETC formatetc =
  121. {
  122. (CLIPFORMAT)g_cfDsObjectPicker,
  123. NULL,
  124. DVASPECT_CONTENT,
  125. -1,
  126. TYMED_HGLOBAL
  127. };
  128. BOOL fGotStgMedium = FALSE;
  129. do
  130. {
  131. hr = pdo->GetData(&formatetc, &stgmedium);
  132. BREAK_ON_FAIL_HRESULT(hr);
  133. fGotStgMedium = TRUE;
  134. PDS_SELECTION_LIST pDsSelList =
  135. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  136. if (!pDsSelList)
  137. {
  138. TRACE(_T("GlobalLock error %u\n"), GetLastError());
  139. break;
  140. }
  141. // create the path name thing
  142. IADsPathname * pIADsPathname;
  143. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  144. IID_IADsPathname, (PVOID *)&pIADsPathname);
  145. BREAK_ON_FAIL_HRESULT(hr);
  146. if (FAILED(hr = pIADsPathname->SetDisplayType(ADS_DISPLAY_VALUE_ONLY)))
  147. {
  148. pIADsPathname->Release();
  149. break;
  150. }
  151. for (UINT i = 0; i < pDsSelList->cItems; i++)
  152. {
  153. PSID psid = NULL;
  154. DS_SELECTION * pDsSel = &(pDsSelList->aDsSelection[i]);
  155. if (pDsSel->pvarFetchedAttributes != NULL)
  156. {
  157. hr = SafeArrayAccessData(V_ARRAY(pDsSel->pvarFetchedAttributes), &psid);
  158. }
  159. if (psid != NULL)
  160. {
  161. LPWSTR pwzADsPath = pDsSel->pwzADsPath;
  162. if (FAILED(hr = pIADsPathname->Set(pwzADsPath, ADS_SETTYPE_FULL)))
  163. continue;
  164. long lnNumPathElements = 0;
  165. if (FAILED(hr = pIADsPathname->GetNumElements(&lnNumPathElements)))
  166. continue;
  167. BSTR bstrUser = NULL, bstrDomain = NULL;
  168. if (FAILED(hr = pIADsPathname->GetElement(0, &bstrUser)))
  169. continue;
  170. switch (lnNumPathElements)
  171. {
  172. case 1:
  173. hr = pIADsPathname->Retrieve(ADS_FORMAT_SERVER, &bstrDomain);
  174. break;
  175. case 2: // nt4, nt5 domain
  176. case 3: // local domain
  177. hr = pIADsPathname->GetElement(1, &bstrDomain);
  178. break;
  179. default:
  180. ASSERT(FALSE);
  181. hr = E_FAIL;
  182. }
  183. if (FAILED(hr))
  184. continue;
  185. CString name;
  186. FormatName(bstrUser, bstrDomain, name);
  187. if (bstrDomain != NULL)
  188. SysFreeString(bstrDomain);
  189. if (bstrUser != NULL)
  190. SysFreeString(bstrUser);
  191. CAccessEntry * entry =
  192. new CAccessEntry(psid, name, pDsSel->pwzClass);
  193. Add(entry);
  194. }
  195. }
  196. pIADsPathname->Release();
  197. GlobalUnlock(stgmedium.hGlobal);
  198. } while (0);
  199. if (fGotStgMedium)
  200. {
  201. ReleaseStgMedium(&stgmedium);
  202. }
  203. }
  204. //////////////////////////////////////////////////////////////////////
  205. // CGetComputer Class
  206. //////////////////////////////////////////////////////////////////////
  207. //////////////////////////////////////////////////////////////////////
  208. // Construction/Destruction
  209. //////////////////////////////////////////////////////////////////////
  210. CGetComputer::CGetComputer()
  211. {
  212. }
  213. CGetComputer::~CGetComputer()
  214. {
  215. }
  216. BOOL
  217. CGetComputer::GetComputer(HWND hwndParent)
  218. {
  219. HRESULT hr = S_OK;
  220. IDsObjectPicker * pDsObjectPicker = NULL;
  221. IDataObject * pdo = NULL;
  222. BOOL fSuccess = TRUE;
  223. hr = CoInitialize(NULL);
  224. if (FAILED(hr))
  225. return FALSE;
  226. do
  227. {
  228. //
  229. // Create an instance of the object picker. The implementation in
  230. // objsel.dll is apartment model.
  231. //
  232. hr = CoCreateInstance(CLSID_DsObjectPicker,
  233. NULL,
  234. CLSCTX_INPROC_SERVER,
  235. IID_IDsObjectPicker,
  236. (void **) &pDsObjectPicker);
  237. BREAK_ON_FAIL_HRESULT(hr);
  238. //
  239. // Reinitialize the object picker to choose computers
  240. //
  241. hr = InitObjectPickerForComputers(pDsObjectPicker);
  242. BREAK_ON_FAIL_HRESULT(hr);
  243. //
  244. // Now pick a computer
  245. //
  246. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  247. BREAK_ON_FAIL_HRESULT(hr);
  248. //
  249. // If the user hit Cancel, hr == S_FALSE
  250. //
  251. if (hr == S_FALSE)
  252. {
  253. TRACE(_T("User canceled object picker dialog\n"));
  254. fSuccess = FALSE;
  255. break;
  256. }
  257. ASSERT(pdo);
  258. ProcessSelectedObjects(pdo);
  259. pdo->Release();
  260. pdo = NULL;
  261. } while (0);
  262. if (pDsObjectPicker)
  263. {
  264. pDsObjectPicker->Release();
  265. }
  266. CoUninitialize();
  267. if (FAILED(hr))
  268. fSuccess = FALSE;
  269. return fSuccess;
  270. }
  271. void
  272. CGetComputer::ProcessSelectedObjects(IDataObject *pdo)
  273. {
  274. HRESULT hr = S_OK;
  275. STGMEDIUM stgmedium =
  276. {
  277. TYMED_HGLOBAL,
  278. NULL,
  279. NULL
  280. };
  281. if (g_cfDsObjectPicker == 0)
  282. g_cfDsObjectPicker = ::RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  283. ASSERT(g_cfDsObjectPicker != 0);
  284. FORMATETC formatetc =
  285. {
  286. (CLIPFORMAT)g_cfDsObjectPicker,
  287. NULL,
  288. DVASPECT_CONTENT,
  289. -1,
  290. TYMED_HGLOBAL
  291. };
  292. BOOL fGotStgMedium = FALSE;
  293. do
  294. {
  295. hr = pdo->GetData(&formatetc, &stgmedium);
  296. BREAK_ON_FAIL_HRESULT(hr);
  297. fGotStgMedium = TRUE;
  298. PDS_SELECTION_LIST pDsSelList =
  299. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  300. if (!pDsSelList)
  301. {
  302. TRACE(_T("GlobalLock error %u\n"), GetLastError());
  303. break;
  304. }
  305. CString strTemp = pDsSelList->aDsSelection[0].pwzName;
  306. if (strTemp.Left(2) == _T("\\\\"))
  307. strTemp = pDsSelList->aDsSelection[0].pwzName[2];
  308. if (ERROR_SUCCESS != ObjPickNameOrIpToHostname(strTemp, m_strComputerName))
  309. {
  310. //we use the name from the object picker if we failed to convert it into hostname
  311. m_strComputerName = strTemp;
  312. }
  313. GlobalUnlock(stgmedium.hGlobal);
  314. } while (0);
  315. if (fGotStgMedium)
  316. {
  317. ReleaseStgMedium(&stgmedium);
  318. }
  319. }
  320. //+--------------------------------------------------------------------------
  321. //
  322. // Function: InitObjectPickerForGroups
  323. //
  324. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  325. // set it to allow the user to pick one or more groups.
  326. //
  327. // Arguments: [pDsObjectPicker] - object picker interface instance
  328. //
  329. // Returns: Result of calling IDsObjectPicker::Initialize.
  330. //
  331. // History: 10-14-1998 DavidMun Created
  332. // 1-8-2000 SergeiA Adapted for IIS
  333. //
  334. //---------------------------------------------------------------------------
  335. HRESULT
  336. InitObjectPickerForGroups(IDsObjectPicker *pDsObjectPicker,
  337. BOOL fMultiselect,
  338. LPCTSTR pszMachineName,
  339. BOOL bUsersOnly)
  340. {
  341. //
  342. // Prepare to initialize the object picker.
  343. // Set up the array of scope initializer structures.
  344. //
  345. static const int SCOPE_INIT_COUNT = 5;
  346. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  347. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  348. //
  349. // Target computer scope. This adds a "Look In" entry for the
  350. // target computer. Computer scopes are always treated as
  351. // downlevel (i.e., they use the WinNT provider).
  352. //
  353. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  354. aScopeInit[0].flType = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
  355. aScopeInit[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  356. aScopeInit[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_USERS;
  357. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  358. if (!bUsersOnly)
  359. {
  360. aScopeInit[0].FilterFlags.flDownlevel |=
  361. // DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS;
  362. DSOP_DOWNLEVEL_FILTER_LOCAL_GROUPS;
  363. }
  364. //
  365. // The domain to which the target computer is joined. Note we're
  366. // combining two scope types into flType here for convenience.
  367. //
  368. aScopeInit[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  369. aScopeInit[1].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  370. aScopeInit[1].flType =
  371. DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  372. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  373. aScopeInit[1].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
  374. if (!bUsersOnly)
  375. {
  376. aScopeInit[1].FilterFlags.Uplevel.flNativeModeOnly |=
  377. DSOP_FILTER_GLOBAL_GROUPS_SE
  378. | DSOP_FILTER_UNIVERSAL_GROUPS_SE
  379. | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE;
  380. }
  381. aScopeInit[1].FilterFlags.Uplevel.flMixedModeOnly = DSOP_FILTER_USERS;
  382. if (!bUsersOnly)
  383. {
  384. aScopeInit[1].FilterFlags.Uplevel.flMixedModeOnly |= DSOP_FILTER_GLOBAL_GROUPS_SE;
  385. }
  386. aScopeInit[1].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  387. if (!bUsersOnly)
  388. {
  389. aScopeInit[1].FilterFlags.flDownlevel |= DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  390. }
  391. //
  392. // The domains in the same forest (enterprise) as the domain to which
  393. // the target machine is joined. Note these can only be DS-aware
  394. //
  395. aScopeInit[2].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  396. aScopeInit[2].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN;
  397. aScopeInit[2].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  398. aScopeInit[2].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
  399. if (!bUsersOnly)
  400. {
  401. aScopeInit[2].FilterFlags.Uplevel.flNativeModeOnly |=
  402. DSOP_FILTER_GLOBAL_GROUPS_SE
  403. | DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  404. }
  405. aScopeInit[2].FilterFlags.Uplevel.flMixedModeOnly = DSOP_FILTER_USERS;
  406. if (!bUsersOnly)
  407. {
  408. aScopeInit[2].FilterFlags.Uplevel.flMixedModeOnly |=
  409. DSOP_FILTER_GLOBAL_GROUPS_SE;
  410. }
  411. //
  412. // Domains external to the enterprise but trusted directly by the
  413. // domain to which the target machine is joined.
  414. //
  415. // If the target machine is joined to an NT4 domain, only the
  416. // external downlevel domain scope applies, and it will cause
  417. // all domains trusted by the joined domain to appear.
  418. //
  419. aScopeInit[3].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  420. aScopeInit[3].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  421. aScopeInit[3].flType =
  422. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  423. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN;
  424. aScopeInit[3].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
  425. if (!bUsersOnly)
  426. {
  427. aScopeInit[3].FilterFlags.Uplevel.flNativeModeOnly |=
  428. DSOP_FILTER_GLOBAL_GROUPS_SE
  429. | DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  430. }
  431. aScopeInit[3].FilterFlags.Uplevel.flMixedModeOnly = DSOP_FILTER_USERS;
  432. if (!bUsersOnly)
  433. {
  434. aScopeInit[3].FilterFlags.Uplevel.flMixedModeOnly |=
  435. DSOP_FILTER_GLOBAL_GROUPS_SE;
  436. }
  437. aScopeInit[3].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_USERS;
  438. if (!bUsersOnly)
  439. {
  440. aScopeInit[3].FilterFlags.flDownlevel |=
  441. DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS;
  442. }
  443. //
  444. // The Global Catalog
  445. //
  446. aScopeInit[4].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  447. aScopeInit[4].flScope = DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT;
  448. aScopeInit[4].flType = DSOP_SCOPE_TYPE_GLOBAL_CATALOG;
  449. // Only native mode applies to gc scope.
  450. aScopeInit[4].FilterFlags.Uplevel.flNativeModeOnly = DSOP_FILTER_USERS;
  451. if (!bUsersOnly)
  452. {
  453. aScopeInit[4].FilterFlags.Uplevel.flNativeModeOnly |=
  454. DSOP_FILTER_GLOBAL_GROUPS_SE
  455. | DSOP_FILTER_UNIVERSAL_GROUPS_SE;
  456. }
  457. //
  458. // Put the scope init array into the object picker init array
  459. //
  460. DSOP_INIT_INFO InitInfo;
  461. ZeroMemory(&InitInfo, sizeof(InitInfo));
  462. InitInfo.cbSize = sizeof(InitInfo);
  463. //
  464. // The pwzTargetComputer member allows the object picker to be
  465. // retargetted to a different computer. It will behave as if it
  466. // were being run ON THAT COMPUTER.
  467. //
  468. InitInfo.pwzTargetComputer = pszMachineName;
  469. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  470. InitInfo.aDsScopeInfos = aScopeInit;
  471. InitInfo.flOptions = (fMultiselect) ? DSOP_FLAG_MULTISELECT : 0;
  472. LPCTSTR attrs[] = {_T("ObjectSid")};
  473. InitInfo.cAttributesToFetch = sizeof(attrs) / sizeof(attrs[0]);
  474. InitInfo.apwzAttributeNames = attrs;
  475. //
  476. // Note object picker makes its own copy of InitInfo. Also note
  477. // that Initialize may be called multiple times, last call wins.
  478. //
  479. HRESULT hr = pDsObjectPicker->Initialize(&InitInfo);
  480. #ifdef _DEBUG
  481. if (FAILED(hr))
  482. {
  483. ULONG i;
  484. for (i = 0; i < SCOPE_INIT_COUNT; i++)
  485. {
  486. if (FAILED(InitInfo.aDsScopeInfos[i].hr))
  487. {
  488. TRACE(_T("Initialization failed because of scope %u\n"), i);
  489. }
  490. }
  491. }
  492. #endif
  493. return hr;
  494. }
  495. //+--------------------------------------------------------------------------
  496. //
  497. // Function: InitObjectPickerForComputers
  498. //
  499. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  500. // set it to allow the user to pick a single computer object.
  501. //
  502. // Arguments: [pDsObjectPicker] - object picker interface instance
  503. //
  504. // Returns: Result of calling IDsObjectPicker::Initialize.
  505. //
  506. // History: 10-14-1998 DavidMun Created
  507. //
  508. //---------------------------------------------------------------------------
  509. HRESULT
  510. InitObjectPickerForComputers(IDsObjectPicker *pDsObjectPicker)
  511. {
  512. //
  513. // Prepare to initialize the object picker.
  514. // Set up the array of scope initializer structures.
  515. //
  516. static const int SCOPE_INIT_COUNT = 2;
  517. DSOP_SCOPE_INIT_INFO aScopeInit[SCOPE_INIT_COUNT];
  518. ZeroMemory(aScopeInit, sizeof(DSOP_SCOPE_INIT_INFO) * SCOPE_INIT_COUNT);
  519. //
  520. // Build a scope init struct for everything except the joined domain.
  521. //
  522. aScopeInit[0].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  523. aScopeInit[0].flType = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN
  524. | DSOP_SCOPE_TYPE_GLOBAL_CATALOG
  525. | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
  526. | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
  527. | DSOP_SCOPE_TYPE_WORKGROUP
  528. | DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
  529. | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE;
  530. aScopeInit[0].FilterFlags.Uplevel.flBothModes =
  531. DSOP_FILTER_COMPUTERS;
  532. aScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  533. //
  534. // scope for the joined domain, make it the default
  535. //
  536. aScopeInit[1].cbSize = sizeof(DSOP_SCOPE_INIT_INFO);
  537. aScopeInit[1].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
  538. | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  539. aScopeInit[1].FilterFlags.Uplevel.flBothModes =
  540. DSOP_FILTER_COMPUTERS;
  541. aScopeInit[1].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  542. aScopeInit[1].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  543. //
  544. // Put the scope init array into the object picker init array
  545. //
  546. DSOP_INIT_INFO InitInfo;
  547. ZeroMemory(&InitInfo, sizeof(InitInfo));
  548. InitInfo.cbSize = sizeof(InitInfo);
  549. InitInfo.pwzTargetComputer = NULL; // NULL == local machine
  550. InitInfo.cDsScopeInfos = SCOPE_INIT_COUNT;
  551. InitInfo.aDsScopeInfos = aScopeInit;
  552. //
  553. // Note object picker makes its own copy of InitInfo. Also note
  554. // that Initialize may be called multiple times, last call wins.
  555. //
  556. return pDsObjectPicker->Initialize(&InitInfo);
  557. }
  558. //Convert any valid name of a machine (IP address, NetBios name or fully qualified DNS name)
  559. //to the host name
  560. DWORD ObjPickNameOrIpToHostname(CString & strNameOrIp, CString & strHostName)
  561. {
  562. DWORD dwErr = ERROR_SUCCESS;
  563. CString strTemp;
  564. CIPAddress ia(strNameOrIp);
  565. if (!ia.IsValid())
  566. {
  567. dwErr = MyGetHostName((DWORD)ia, strTemp);
  568. }
  569. else
  570. {
  571. // just want the host name
  572. int nDot = strNameOrIp.Find('.');
  573. if (nDot != -1)
  574. {
  575. strTemp = strNameOrIp.Left(nDot);
  576. }
  577. else
  578. {
  579. strTemp = strNameOrIp;
  580. }
  581. }
  582. if (ERROR_SUCCESS == dwErr)
  583. {
  584. strHostName = strTemp;
  585. }
  586. return dwErr;
  587. }
  588. BOOL
  589. GetIUsrAccount(
  590. IN LPCTSTR lpstrServer,
  591. IN CWnd * pParent, OPTIONAL
  592. OUT CString & str
  593. )
  594. /*++
  595. Routine Description:
  596. Helper function to browse for IUSR Account
  597. Arguments:
  598. LPCTSTR lpstrServer : Server
  599. CWnd * pParent : Parent window
  600. CString & str : Will contain the selected account
  601. Return Value:
  602. TRUE if an account was selected FALSE if not
  603. --*/
  604. {
  605. CGetUsers usrBrowser(lpstrServer);
  606. BOOL bRes = usrBrowser.GetUsers(pParent->GetSafeHwnd(), TRUE);
  607. if (bRes)
  608. {
  609. if (usrBrowser.GetSize() != 0)
  610. {
  611. str = usrBrowser.GetAt(0)->QueryUserName();
  612. }
  613. else
  614. bRes = FALSE;
  615. }
  616. return bRes;
  617. }
  618. BOOL
  619. GetIUsrAccount(
  620. LPCTSTR lpstrServer,
  621. CWnd * pParent,
  622. TCHAR * pBuffer,
  623. int size
  624. )
  625. /*++
  626. Routine Description:
  627. Helper function to browse for IUSR Account
  628. Arguments:
  629. LPCTSTR lpstrServer : Server
  630. CWnd * pParent : Parent window
  631. CString & str : Will contain the selected account
  632. Return Value:
  633. TRUE if an account was selected FALSE if not
  634. --*/
  635. {
  636. CGetUsers usrBrowser(lpstrServer);
  637. BOOL bRes = usrBrowser.GetUsers(pParent->GetSafeHwnd(), TRUE);
  638. if (bRes)
  639. {
  640. if (usrBrowser.GetSize() != 0)
  641. {
  642. lstrcpyn(pBuffer, usrBrowser.GetAt(0)->QueryUserName(), size - 1);
  643. }
  644. else
  645. bRes = FALSE;
  646. }
  647. return bRes;
  648. }