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.

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