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.

761 lines
21 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 <iadsp.h> // IADsPathname
  8. #include <objsel.h>
  9. #include <adshlp.h>
  10. #include <winsock2.h>
  11. #include <comdef.h>
  12. #include "comprop.h"
  13. #include "objplus.h"
  14. #include "ipaddres.h"
  15. #include "objpick.h"
  16. #include "usrbrows.h"
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[]=__FILE__;
  20. #define new DEBUG_NEW
  21. #endif
  22. #define BREAK_ON_FAIL_HRESULT(hr) \
  23. if (FAILED(hr)) { TRACE(_T("line %u err 0x%x\n"), __LINE__, hr); break; }
  24. UINT g_cfDsObjectPicker = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
  25. HRESULT InitObjectPickerForGroups(IDsObjectPicker *pDsObjectPicker,
  26. BOOL fMultiselect,
  27. LPCTSTR pszMachineName,
  28. BOOL bUsersOnly);
  29. HRESULT InitObjectPickerForComputers(IDsObjectPicker *pDsObjectPicker);
  30. DWORD ObjPickGetHostName(DWORD dwIpAddr, CString & strHostName);
  31. DWORD ObjPickNameOrIpToHostname(CString & strNameOrIp, CString & strHostName);
  32. CAccessEntryArray::~CAccessEntryArray()
  33. {
  34. for (int i = 0; i < GetSize(); i++)
  35. delete GetAt(i);
  36. }
  37. //////////////////////////////////////////////////////////////////////
  38. // CGetUsers Class
  39. //////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////
  41. // Construction/Destruction
  42. //////////////////////////////////////////////////////////////////////
  43. void
  44. FormatName(LPCTSTR pszFullName, LPCTSTR pszDomainName, CString & strDisplay)
  45. {
  46. strDisplay.Format(_T("%s\\%s"), pszDomainName, pszFullName);
  47. }
  48. CGetUsers::CGetUsers(LPCTSTR pszMachineName, BOOL fMultiselect)
  49. : m_MachineName(pszMachineName),
  50. m_fMultiselect(fMultiselect)
  51. {
  52. }
  53. CGetUsers::~CGetUsers()
  54. {
  55. }
  56. BOOL
  57. CGetUsers::GetUsers(HWND hwndParent, BOOL bUsersOnly)
  58. {
  59. HRESULT hr = S_OK;
  60. IDsObjectPicker * pDsObjectPicker = NULL;
  61. IDataObject * pdo = NULL;
  62. BOOL fSuccess = TRUE;
  63. hr = CoInitialize(NULL);
  64. if (FAILED(hr))
  65. return FALSE;
  66. do
  67. {
  68. //
  69. // Create an instance of the object picker. The implementation in
  70. // objsel.dll is apartment model.
  71. //
  72. hr = CoCreateInstance(CLSID_DsObjectPicker,
  73. NULL,
  74. CLSCTX_INPROC_SERVER,
  75. IID_IDsObjectPicker,
  76. (void **) &pDsObjectPicker);
  77. BREAK_ON_FAIL_HRESULT(hr);
  78. hr = InitObjectPickerForGroups(
  79. pDsObjectPicker, m_fMultiselect, m_MachineName, bUsersOnly);
  80. BREAK_ON_FAIL_HRESULT(hr);
  81. //
  82. // Invoke the modal dialog.
  83. //
  84. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  85. BREAK_ON_FAIL_HRESULT(hr);
  86. //
  87. // If the user hit Cancel, hr == S_FALSE
  88. //
  89. if (hr == S_FALSE)
  90. {
  91. TRACE(_T("User canceled object picker dialog\n"));
  92. fSuccess = FALSE;
  93. break;
  94. }
  95. //
  96. // Process the user's selections
  97. //
  98. ASSERT(pdo);
  99. ProcessSelectedObjects(pdo);
  100. pdo->Release();
  101. pdo = NULL;
  102. } while (0);
  103. if (pDsObjectPicker)
  104. {
  105. pDsObjectPicker->Release();
  106. }
  107. CoUninitialize();
  108. if (FAILED(hr) || S_FALSE == hr)
  109. fSuccess = FALSE;
  110. return fSuccess;
  111. }
  112. void
  113. CGetUsers::ProcessSelectedObjects(IDataObject *pdo)
  114. {
  115. HRESULT hr = S_OK;
  116. STGMEDIUM stgmedium =
  117. {
  118. TYMED_HGLOBAL,
  119. NULL,
  120. NULL
  121. };
  122. FORMATETC formatetc =
  123. {
  124. (CLIPFORMAT)g_cfDsObjectPicker,
  125. NULL,
  126. DVASPECT_CONTENT,
  127. -1,
  128. TYMED_HGLOBAL
  129. };
  130. BOOL fGotStgMedium = FALSE;
  131. do
  132. {
  133. hr = pdo->GetData(&formatetc, &stgmedium);
  134. BREAK_ON_FAIL_HRESULT(hr);
  135. fGotStgMedium = TRUE;
  136. PDS_SELECTION_LIST pDsSelList =
  137. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  138. if (!pDsSelList)
  139. {
  140. TRACE(_T("GlobalLock error %u\n"), GetLastError());
  141. break;
  142. }
  143. // create the path name thing
  144. IADsPathname * pIADsPathname;
  145. hr = CoCreateInstance(CLSID_Pathname, NULL, CLSCTX_INPROC_SERVER,
  146. IID_IADsPathname, (PVOID *)&pIADsPathname);
  147. BREAK_ON_FAIL_HRESULT(hr);
  148. if (FAILED(hr = pIADsPathname->SetDisplayType(ADS_DISPLAY_VALUE_ONLY)))
  149. {
  150. pIADsPathname->Release();
  151. break;
  152. }
  153. for (UINT i = 0; i < pDsSelList->cItems; i++)
  154. {
  155. PSID psid = NULL;
  156. DS_SELECTION * pDsSel = &(pDsSelList->aDsSelection[i]);
  157. if (pDsSel->pvarFetchedAttributes != NULL)
  158. {
  159. HRESULT hr = SafeArrayAccessData(V_ARRAY(pDsSel->pvarFetchedAttributes), &psid);
  160. }
  161. if (psid != NULL)
  162. {
  163. LPWSTR pwzADsPath = pDsSel->pwzADsPath;
  164. CString name;
  165. if (pwzADsPath != NULL && *pwzADsPath != 0)
  166. {
  167. if (FAILED(hr = pIADsPathname->Set(pwzADsPath, ADS_SETTYPE_FULL)))
  168. continue;
  169. long lnNumPathElements = 0;
  170. if (FAILED(hr = pIADsPathname->GetNumElements(&lnNumPathElements)))
  171. continue;
  172. BSTR bstrUser = NULL, bstrDomain = NULL;
  173. if (FAILED(hr = pIADsPathname->GetElement(0, &bstrUser)))
  174. continue;
  175. switch (lnNumPathElements)
  176. {
  177. case 1:
  178. hr = pIADsPathname->Retrieve(ADS_FORMAT_SERVER, &bstrDomain);
  179. break;
  180. case 2: // nt4, nt5 domain
  181. case 3: // local domain
  182. hr = pIADsPathname->GetElement(1, &bstrDomain);
  183. break;
  184. default:
  185. ASSERT(FALSE);
  186. hr = E_FAIL;
  187. }
  188. if (FAILED(hr))
  189. continue;
  190. FormatName(bstrUser, bstrDomain, name);
  191. if (bstrDomain != NULL)
  192. SysFreeString(bstrDomain);
  193. if (bstrUser != NULL)
  194. SysFreeString(bstrUser);
  195. }
  196. else
  197. FormatName(pDsSel->pwzName, pDsSel->pwzADsPath, name);
  198. CAccessEntry * entry =
  199. new CAccessEntry(psid, name, pDsSel->pwzClass);
  200. Add(entry);
  201. }
  202. }
  203. pIADsPathname->Release();
  204. GlobalUnlock(stgmedium.hGlobal);
  205. } while (0);
  206. if (fGotStgMedium)
  207. {
  208. ReleaseStgMedium(&stgmedium);
  209. }
  210. }
  211. //////////////////////////////////////////////////////////////////////
  212. // CGetComputer Class
  213. //////////////////////////////////////////////////////////////////////
  214. //////////////////////////////////////////////////////////////////////
  215. // Construction/Destruction
  216. //////////////////////////////////////////////////////////////////////
  217. CGetComputer::CGetComputer()
  218. {
  219. }
  220. CGetComputer::~CGetComputer()
  221. {
  222. }
  223. BOOL
  224. CGetComputer::GetComputer(HWND hwndParent)
  225. {
  226. HRESULT hr = S_OK;
  227. IDsObjectPicker * pDsObjectPicker = NULL;
  228. IDataObject * pdo = NULL;
  229. BOOL fSuccess = TRUE;
  230. hr = CoInitialize(NULL);
  231. if (FAILED(hr))
  232. return FALSE;
  233. do
  234. {
  235. //
  236. // Create an instance of the object picker. The implementation in
  237. // objsel.dll is apartment model.
  238. //
  239. hr = CoCreateInstance(CLSID_DsObjectPicker,
  240. NULL,
  241. CLSCTX_INPROC_SERVER,
  242. IID_IDsObjectPicker,
  243. (void **) &pDsObjectPicker);
  244. BREAK_ON_FAIL_HRESULT(hr);
  245. //
  246. // Reinitialize the object picker to choose computers
  247. //
  248. hr = InitObjectPickerForComputers(pDsObjectPicker);
  249. BREAK_ON_FAIL_HRESULT(hr);
  250. //
  251. // Now pick a computer
  252. //
  253. hr = pDsObjectPicker->InvokeDialog(hwndParent, &pdo);
  254. BREAK_ON_FAIL_HRESULT(hr);
  255. //
  256. // If the user hit Cancel, hr == S_FALSE
  257. //
  258. if (hr == S_FALSE)
  259. {
  260. TRACE(_T("User canceled object picker dialog\n"));
  261. fSuccess = FALSE;
  262. break;
  263. }
  264. ASSERT(pdo);
  265. ProcessSelectedObjects(pdo);
  266. pdo->Release();
  267. pdo = NULL;
  268. } while (0);
  269. if (pDsObjectPicker)
  270. {
  271. pDsObjectPicker->Release();
  272. }
  273. CoUninitialize();
  274. if (FAILED(hr))
  275. fSuccess = FALSE;
  276. return fSuccess;
  277. }
  278. void
  279. CGetComputer::ProcessSelectedObjects(IDataObject *pdo)
  280. {
  281. HRESULT hr = S_OK;
  282. STGMEDIUM stgmedium =
  283. {
  284. TYMED_HGLOBAL,
  285. NULL,
  286. NULL
  287. };
  288. FORMATETC formatetc =
  289. {
  290. (CLIPFORMAT)g_cfDsObjectPicker,
  291. NULL,
  292. DVASPECT_CONTENT,
  293. -1,
  294. TYMED_HGLOBAL
  295. };
  296. BOOL fGotStgMedium = FALSE;
  297. do
  298. {
  299. hr = pdo->GetData(&formatetc, &stgmedium);
  300. BREAK_ON_FAIL_HRESULT(hr);
  301. fGotStgMedium = TRUE;
  302. PDS_SELECTION_LIST pDsSelList =
  303. (PDS_SELECTION_LIST) GlobalLock(stgmedium.hGlobal);
  304. if (!pDsSelList)
  305. {
  306. TRACE(_T("GlobalLock error %u\n"), GetLastError());
  307. break;
  308. }
  309. CString strTemp = pDsSelList->aDsSelection[0].pwzName;
  310. if (strTemp.Left(2) == _T("\\\\"))
  311. strTemp = pDsSelList->aDsSelection[0].pwzName[2];
  312. if (ERROR_SUCCESS != ObjPickNameOrIpToHostname(strTemp, m_strComputerName))
  313. {
  314. //we use the name from the object picker if we failed to convert it into hostname
  315. m_strComputerName = strTemp;
  316. }
  317. GlobalUnlock(stgmedium.hGlobal);
  318. } while (0);
  319. if (fGotStgMedium)
  320. {
  321. ReleaseStgMedium(&stgmedium);
  322. }
  323. }
  324. //+--------------------------------------------------------------------------
  325. //
  326. // Function: InitObjectPickerForGroups
  327. //
  328. // Synopsis: Call IDsObjectPicker::Initialize with arguments that will
  329. // set it to allow the user to pick one or more groups.
  330. //
  331. // Arguments: [pDsObjectPicker] - object picker interface instance
  332. //
  333. // Returns: Result of calling IDsObjectPicker::Initialize.
  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. }
  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. //Use WinSock to the host name based on the ip address
  559. DWORD
  560. ObjPickGetHostName
  561. (
  562. DWORD dwIpAddr,
  563. CString & strHostName
  564. )
  565. {
  566. CString strName;
  567. //
  568. // Call the Winsock API to get host name information.
  569. //
  570. strHostName.Empty();
  571. ULONG ulAddrInNetOrder = ::htonl( (ULONG) dwIpAddr ) ;
  572. HOSTENT * pHostInfo = ::gethostbyaddr( (CHAR *) & ulAddrInNetOrder,
  573. sizeof ulAddrInNetOrder,
  574. PF_INET ) ;
  575. if ( pHostInfo == NULL )
  576. {
  577. return ::WSAGetLastError();
  578. }
  579. // copy the name
  580. LPTSTR pBuf = strName.GetBuffer(256);
  581. ZeroMemory(pBuf, 256);
  582. ::MultiByteToWideChar(CP_ACP,
  583. MB_PRECOMPOSED,
  584. pHostInfo->h_name,
  585. -1,
  586. pBuf,
  587. 256);
  588. strName.ReleaseBuffer();
  589. strName.MakeUpper();
  590. int nDot = strName.Find(_T("."));
  591. if (nDot != -1)
  592. strHostName = strName.Left(nDot);
  593. else
  594. strHostName = strName;
  595. return NOERROR;
  596. }
  597. //Convert any valid name of a machine (IP address, NetBios name or fully qualified DNS name)
  598. //to the host name
  599. DWORD ObjPickNameOrIpToHostname(CString & strNameOrIp, CString & strHostName)
  600. {
  601. DWORD dwErr = ERROR_SUCCESS;
  602. CString strTemp;
  603. CIpAddress ia(strNameOrIp);
  604. if (!ia.IsValid())
  605. {
  606. dwErr = ObjPickGetHostName((LONG)ia, strTemp);
  607. }
  608. else
  609. {
  610. // just want the host name
  611. int nDot = strNameOrIp.Find('.');
  612. if (nDot != -1)
  613. {
  614. strTemp = strNameOrIp.Left(nDot);
  615. }
  616. else
  617. {
  618. strTemp = strNameOrIp;
  619. }
  620. }
  621. if (ERROR_SUCCESS == dwErr)
  622. {
  623. strHostName = strTemp;
  624. }
  625. return dwErr;
  626. }