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.

854 lines
18 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: scope.hxx
  7. //
  8. // Contents: Implementation of CScope
  9. //
  10. // Classes: CScope
  11. // CInvalidScope
  12. // CAdsiScope
  13. // CWinNtScope
  14. // CTargetComputerScope
  15. // CWorkgroupScope
  16. // CLdapContainerScope
  17. // CGcScope
  18. // CLdapDomainScope
  19. //
  20. // History: 01-21-2000 davidmun Created
  21. //
  22. //---------------------------------------------------------------------------
  23. class CObjectPicker;
  24. class CScope;
  25. typedef RefCountPointer<CScope> RpScope;
  26. //
  27. // SCOPE_VISIBILITY - user-entered scopes are stored along with regular
  28. // scopes, but should not be displayed in the Look In dialog. They are
  29. // marked as hidden using the SCOPE_HIDDEN value.
  30. //
  31. // User-entered scopes are created when: the user types in dom\obj or obj@dom
  32. // AND "dom" is not found among the domain scopes AND caller set the flag(s)
  33. // DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE or
  34. // DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE AND binding to "dom" for the
  35. // IADsContainer interface succeeded AND retrieving "obj" using that interface
  36. // succeeded. See dsobject.cxx.
  37. //
  38. enum SCOPE_VISIBILITY
  39. {
  40. SCOPE_VISIBLE,
  41. SCOPE_HIDDEN
  42. };
  43. //
  44. // SCOPE_TYPE - The main reason this enum exists is to make life easier when
  45. // debugging with VC; it will display enumeration values as symbols,
  46. // whereas defines (the DSOP_SCOPE_TYPE_* values) are displayed as hex.
  47. //
  48. // Another reason for the enum is that the SCOPE_TYPEs are a superset of the
  49. // public DSOP_SCOPE_TYPE_* values; the enum contains some values that are
  50. // implementation details.
  51. //
  52. enum SCOPE_TYPE
  53. {
  54. ST_INVALID = 0,
  55. ST_TARGET_COMPUTER = DSOP_SCOPE_TYPE_TARGET_COMPUTER,
  56. ST_UPLEVEL_JOINED_DOMAIN = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN,
  57. ST_DOWNLEVEL_JOINED_DOMAIN = DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
  58. ST_ENTERPRISE_DOMAIN = DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN,
  59. ST_GLOBAL_CATALOG = DSOP_SCOPE_TYPE_GLOBAL_CATALOG,
  60. ST_EXTERNAL_UPLEVEL_DOMAIN = DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN,
  61. ST_EXTERNAL_DOWNLEVEL_DOMAIN = DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN,
  62. ST_WORKGROUP = DSOP_SCOPE_TYPE_WORKGROUP,
  63. ST_USER_ENTERED_UPLEVEL_SCOPE = DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE,
  64. ST_USER_ENTERED_DOWNLEVEL_SCOPE = DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE,
  65. ST_LDAP_CONTAINER = 0x00000400
  66. };
  67. //
  68. // Structures used for creating a scope
  69. //
  70. enum DOMAIN_MODE
  71. {
  72. DM_UNDETERMINED,
  73. DM_MIXED,
  74. DM_NATIVE
  75. };
  76. struct DOMAIN_SCOPE_INIT
  77. {
  78. String strScopeName;
  79. String strFlatName;
  80. String strADsPath;
  81. DOMAIN_MODE Mode;
  82. BOOL fPathIsDc;
  83. DOMAIN_SCOPE_INIT():
  84. Mode(DM_UNDETERMINED),
  85. fPathIsDc(FALSE)
  86. {
  87. }
  88. };
  89. struct GLOBAL_CATALOG_SCOPE_INIT
  90. {
  91. String strADsPath;
  92. };
  93. struct SEPARATOR_SCOPE_INIT
  94. {
  95. ULONG idsMessage;
  96. SEPARATOR_SCOPE_INIT(): idsMessage(0) {}
  97. };
  98. struct COMPUTER_SCOPE_INIT
  99. {
  100. String strComputerName;
  101. BOOL fIsLocalComputer;
  102. COMPUTER_SCOPE_INIT(): fIsLocalComputer(FALSE) {}
  103. };
  104. struct ADD_SCOPE_INFO
  105. {
  106. ULONG flType;
  107. ULONG flScope;
  108. DSOP_FILTER_FLAGS FilterFlags;
  109. ULONG ulIndentLevel;
  110. SCOPE_VISIBILITY Visibility;
  111. SEPARATOR_SCOPE_INIT Separator;
  112. COMPUTER_SCOPE_INIT Computer;
  113. DOMAIN_SCOPE_INIT Domain;
  114. GLOBAL_CATALOG_SCOPE_INIT GlobalCatalog;
  115. ADD_SCOPE_INFO():
  116. flType(0),
  117. flScope(0),
  118. ulIndentLevel(0),
  119. Visibility(SCOPE_VISIBLE)
  120. {
  121. ZeroMemory(&FilterFlags, sizeof FilterFlags);
  122. }
  123. bool
  124. operator< (const ADD_SCOPE_INFO &rhs) const
  125. {
  126. return lstrcmpi(Domain.strScopeName.c_str(),
  127. rhs.Domain.strScopeName.c_str()) < 0;
  128. }
  129. };
  130. //
  131. // SScopeParameters - used to hold a copy of the initialization info the
  132. // caller supplied for a particular scope type.
  133. //
  134. struct SScopeParameters
  135. {
  136. SScopeParameters():
  137. flType(0),
  138. flScope(0)
  139. {
  140. ASSERT(0 &&
  141. "ctor required to compile STL, not expected to be used at runtime");
  142. ZeroMemory(&FilterFlags, sizeof FilterFlags);
  143. }
  144. SScopeParameters(
  145. const DSOP_SCOPE_INIT_INFO &sii,
  146. ULONG flLegalScopes);
  147. SScopeParameters(
  148. const SScopeParameters &rhs)
  149. {
  150. SScopeParameters::operator =(rhs);
  151. }
  152. SScopeParameters &
  153. operator =(
  154. const SScopeParameters &rhs)
  155. {
  156. flType = rhs.flType;
  157. flScope = rhs.flScope;
  158. FilterFlags = rhs.FilterFlags;
  159. strDcName = rhs.strDcName;
  160. return *this;
  161. }
  162. ULONG flType;
  163. ULONG flScope;
  164. DSOP_FILTER_FLAGS FilterFlags;
  165. String strDcName;
  166. };
  167. //+--------------------------------------------------------------------------
  168. //
  169. // Class: CScope
  170. //
  171. // Purpose: Abstract base class for a scope.
  172. //
  173. // History: 06-23-2000 DavidMun Created
  174. //
  175. // Notes: A "Scope" is a container of objects. "Uplevel" scopes are
  176. // those that support LDAP (i.e. Win2K domains and the GC).
  177. // "Downlevel" scopes are those which are accessed through
  178. // ADSI's WinNT provider (individual computers, NT4 domains,
  179. // and workgroups).
  180. //
  181. //---------------------------------------------------------------------------
  182. class CScope: public IDsObjectPickerScope
  183. {
  184. public:
  185. //
  186. // IDsObjectPickerScope is a legacy interface. Hopefully
  187. // support for this can be dropped soon.
  188. //
  189. // Except for AddRef and Release, all the following are
  190. // legacy methods.
  191. //
  192. virtual ULONG STDMETHODCALLTYPE
  193. AddRef();
  194. virtual ULONG STDMETHODCALLTYPE
  195. Release();
  196. virtual HRESULT STDMETHODCALLTYPE
  197. QueryInterface(REFIID riid, LPVOID * ppv);
  198. STDMETHOD_(HWND, GetHwnd)();
  199. virtual HRESULT STDMETHODCALLTYPE
  200. SetHwnd(HWND hwndScopeDialog);
  201. STDMETHOD_(ULONG,GetType)();
  202. virtual HRESULT STDMETHODCALLTYPE
  203. GetQueryInfo(PDSQUERYINFO *ppqi);
  204. virtual BOOL STDMETHODCALLTYPE
  205. IsUplevel();
  206. virtual BOOL STDMETHODCALLTYPE
  207. IsDownlevel();
  208. virtual BOOL STDMETHODCALLTYPE
  209. IsExternalDomain();
  210. virtual HRESULT STDMETHODCALLTYPE
  211. GetADsPath(PWSTR *ppwzADsPath);
  212. //
  213. // Nonlegacy methods:
  214. //
  215. virtual void
  216. Expand(
  217. HWND hwndBaseDlg,
  218. vector<RpScope>::const_iterator *pitBeginNew,
  219. vector<RpScope>::const_iterator *pitEndNew) const = 0;
  220. virtual HRESULT
  221. GetResultantFilterFlags(
  222. HWND hwndDlg,
  223. ULONG *pulFlags) const = 0;
  224. ULONG
  225. GetScopeFlags() const;
  226. HRESULT
  227. GetResultantDefaultFilterFlags(
  228. HWND hwndDlg,
  229. ULONG *pulFlags) const;
  230. virtual BOOL
  231. MightHaveChildScopes() const
  232. {
  233. return TRUE;
  234. }
  235. virtual BOOL
  236. MightHaveAdditionalChildScopes() const
  237. {
  238. return FALSE; // might have more scopes on next expand
  239. }
  240. size_t
  241. GetCurrentImmediateChildCount() const
  242. {
  243. return m_vrpChildren.size();
  244. }
  245. SCOPE_TYPE
  246. Type() const
  247. {
  248. return m_Type;
  249. }
  250. virtual const String &
  251. GetDisplayName() const
  252. {
  253. return m_strDisplayName;
  254. }
  255. ULONG
  256. GetID() const
  257. {
  258. return m_id;
  259. }
  260. const CScope *
  261. GetParent() const
  262. {
  263. return m_pParent;
  264. }
  265. void
  266. GetChildScopeIterators(
  267. vector<RpScope>::const_iterator *pitBegin,
  268. vector<RpScope>::const_iterator *pitEnd) const
  269. {
  270. *pitBegin = m_vrpChildren.begin();
  271. *pitEnd = m_vrpChildren.end();
  272. }
  273. protected:
  274. CScope(
  275. SCOPE_TYPE eType,
  276. const CObjectPicker &rop):
  277. m_cRefs(1),
  278. m_Type(eType),
  279. m_fExpanded(FALSE),
  280. m_pParent(NULL),
  281. m_rop(rop),
  282. m_id(InterlockedIncrement((LPLONG)&s_ulNextID))
  283. {
  284. // note this is pre-increment, so ID 0 is reserved as invalid
  285. }
  286. // this is a refcounted class, cannot explicitly delete
  287. virtual
  288. ~CScope()
  289. {
  290. ASSERT(!m_cRefs);
  291. m_Type = ST_INVALID;
  292. m_pParent = NULL;
  293. }
  294. vector<RpScope> m_vrpChildren;
  295. String m_strDisplayName;
  296. ULONG m_cRefs;
  297. const ULONG m_id;
  298. SCOPE_TYPE m_Type;
  299. mutable BOOL m_fExpanded;
  300. const CScope *m_pParent;
  301. const CObjectPicker &m_rop;
  302. private:
  303. CScope &operator=(const CScope &);
  304. static ULONG s_ulNextID;
  305. };
  306. BOOL
  307. IsUplevel(
  308. SCOPE_TYPE Type);
  309. BOOL
  310. IsDownlevel(
  311. SCOPE_TYPE Type);
  312. inline BOOL
  313. IsUplevel(
  314. const CScope *pScope)
  315. {
  316. return IsUplevel(pScope->Type());
  317. }
  318. inline BOOL
  319. IsUplevel(
  320. const CScope &rScope)
  321. {
  322. return IsUplevel(rScope.Type());
  323. }
  324. inline BOOL
  325. IsDownlevel(
  326. const CScope *pScope)
  327. {
  328. return IsDownlevel(pScope->Type());
  329. }
  330. inline BOOL
  331. IsDownlevel(
  332. const CScope &rScope)
  333. {
  334. return IsDownlevel(rScope.Type());
  335. }
  336. inline BOOL
  337. IsInvalid(
  338. const CScope &rScope)
  339. {
  340. return rScope.Type() == ST_INVALID;
  341. }
  342. //+--------------------------------------------------------------------------
  343. //
  344. // Class: CInvalidScope
  345. //
  346. // Purpose: References to objects of this class are returned to indicate
  347. // no valid scope could be found or created.
  348. //
  349. // History: 06-23-2000 DavidMun Created
  350. //
  351. //---------------------------------------------------------------------------
  352. class CInvalidScope: public CScope
  353. {
  354. public:
  355. CInvalidScope(
  356. const CObjectPicker &rop):
  357. CScope(ST_INVALID, rop)
  358. {
  359. }
  360. virtual void
  361. Expand(
  362. HWND hwndBaseDlg,
  363. vector<RpScope>:: const_iterator *pitBeginNew,
  364. vector<RpScope>:: const_iterator *pitEndNew) const
  365. {
  366. }
  367. virtual HRESULT
  368. GetResultantFilterFlags(
  369. HWND hwndDlg,
  370. ULONG *pulFlags) const
  371. {
  372. ASSERT(pulFlags);
  373. if (!pulFlags)
  374. {
  375. return E_POINTER;
  376. }
  377. *pulFlags = 0;
  378. return S_OK;
  379. }
  380. };
  381. //+--------------------------------------------------------------------------
  382. //
  383. // Class: CAdsiScope
  384. //
  385. // Purpose: Base class for scopes accessed through ADSI.
  386. //
  387. // History: 06-23-2000 DavidMun Created
  388. //
  389. //---------------------------------------------------------------------------
  390. class CAdsiScope: public CScope
  391. {
  392. public:
  393. virtual HRESULT
  394. GetADsPath(
  395. HWND hwnd,
  396. String *pstrPath) const
  397. {
  398. *pstrPath = m_strADsPath;
  399. return S_OK;
  400. }
  401. protected:
  402. CAdsiScope(
  403. SCOPE_TYPE eType,
  404. const CObjectPicker &rop,
  405. const CScope *pParent):
  406. CScope(eType, rop)
  407. {
  408. m_pParent = pParent;
  409. }
  410. virtual
  411. ~CAdsiScope()
  412. {
  413. }
  414. mutable String m_strADsPath;
  415. };
  416. //+--------------------------------------------------------------------------
  417. //
  418. // Class: CWinNtScope
  419. //
  420. // Purpose: Represent a scope which is accessed via the ADSI WinNT
  421. // provider.
  422. //
  423. // History: 06-23-2000 DavidMun Created
  424. //
  425. //---------------------------------------------------------------------------
  426. class CWinNtScope: public CAdsiScope
  427. {
  428. public:
  429. virtual void
  430. Expand(
  431. HWND hwndBaseDlg,
  432. vector<RpScope>::const_iterator *pitBeginNew,
  433. vector<RpScope>::const_iterator *pitEndNew) const
  434. {
  435. GetChildScopeIterators(pitBeginNew, pitEndNew);
  436. }
  437. virtual BOOL
  438. MightHaveChildScopes() const
  439. {
  440. return FALSE;
  441. }
  442. virtual HRESULT
  443. GetResultantFilterFlags(
  444. HWND hwndDlg,
  445. ULONG *pulFlags) const;
  446. protected:
  447. CWinNtScope(
  448. SCOPE_TYPE eType,
  449. const CObjectPicker &rop):
  450. CAdsiScope(eType, rop, NULL)
  451. {
  452. }
  453. virtual
  454. ~CWinNtScope()
  455. {
  456. }
  457. };
  458. //+--------------------------------------------------------------------------
  459. //
  460. // Class: CTargetComputerScope
  461. //
  462. // Purpose: A scope which represents the contents of a single computer.
  463. //
  464. // History: 06-23-2000 DavidMun Created
  465. //
  466. //---------------------------------------------------------------------------
  467. class CTargetComputerScope: public CWinNtScope
  468. {
  469. public:
  470. CTargetComputerScope(
  471. const CObjectPicker &rop);
  472. private:
  473. ~CTargetComputerScope()
  474. {
  475. TRACE_DESTRUCTOR(CTargetComputerScope);
  476. }
  477. };
  478. //+--------------------------------------------------------------------------
  479. //
  480. // Class: CWorkgroupScope
  481. //
  482. // Purpose: Represent a workgroup
  483. //
  484. // History: 06-23-2000 DavidMun Created
  485. //
  486. //---------------------------------------------------------------------------
  487. class CWorkgroupScope: public CWinNtScope
  488. {
  489. public:
  490. CWorkgroupScope(
  491. const CObjectPicker &rop):
  492. m_fInitialized(FALSE),
  493. CWinNtScope(ST_WORKGROUP, rop)
  494. {
  495. TRACE_CONSTRUCTOR(CWorkgroupScope);
  496. }
  497. virtual HRESULT
  498. GetADsPath(
  499. HWND hwnd,
  500. String *pstrPath) const;
  501. virtual const String&
  502. GetDisplayName() const;
  503. private:
  504. ~CWorkgroupScope()
  505. {
  506. TRACE_DESTRUCTOR(CWorkgroupScope);
  507. }
  508. void
  509. _Initialize();
  510. BOOL m_fInitialized;
  511. };
  512. //+--------------------------------------------------------------------------
  513. //
  514. // Class: CWinNtDomainScope
  515. //
  516. // Purpose: Represent a downlevel domain
  517. //
  518. // History: 06-23-2000 DavidMun Created
  519. //
  520. //---------------------------------------------------------------------------
  521. class CWinNtDomainScope: public CWinNtScope
  522. {
  523. public:
  524. CWinNtDomainScope(
  525. const CObjectPicker &rop,
  526. const ADD_SCOPE_INFO &asi);
  527. private:
  528. ~CWinNtDomainScope()
  529. {
  530. TRACE_DESTRUCTOR(CWinNtDomainScope);
  531. }
  532. // flat (netbios) name is display name
  533. };
  534. //+--------------------------------------------------------------------------
  535. //
  536. // Class: CLdapContainerScope
  537. //
  538. // Purpose: Represent an uplevel scope
  539. //
  540. // History: 06-23-2000 DavidMun Created
  541. //
  542. // Notes: Used as base class for classes representing uplevel
  543. // domains and the GC, and directly for OUs.
  544. //
  545. //---------------------------------------------------------------------------
  546. class CLdapContainerScope: public CAdsiScope
  547. {
  548. public:
  549. virtual void
  550. AddChild(const RpScope &ChildScope)
  551. {
  552. m_vrpChildren.push_back(ChildScope);
  553. }
  554. virtual void
  555. Expand(
  556. HWND hwndBaseDlg,
  557. vector<RpScope>::const_iterator *pitBeginNew,
  558. vector<RpScope>::const_iterator *pitEndNew) const;
  559. virtual BOOL
  560. MightHaveAdditionalChildScopes() const
  561. {
  562. return !m_fExpanded;
  563. }
  564. const RpScope &
  565. back()
  566. {
  567. return m_vrpChildren.back();
  568. }
  569. CLdapContainerScope(
  570. SCOPE_TYPE eType,
  571. const String &strDisplayName,
  572. const String &strADsPath,
  573. const CObjectPicker &rop,
  574. const CScope *pParent):
  575. CAdsiScope(eType, rop, pParent)
  576. {
  577. TRACE_CONSTRUCTOR(CLdapContainerScope);
  578. m_strDisplayName = strDisplayName;
  579. m_strADsPath = strADsPath;
  580. m_pParent = pParent;
  581. m_DomainMode = DM_UNDETERMINED;
  582. }
  583. virtual HRESULT
  584. GetResultantFilterFlags(
  585. HWND hwndDlg,
  586. ULONG *pulFlags) const;
  587. protected:
  588. //
  589. // this constructor is for use by derived classes which are specialized
  590. // types of ldap containers. they may need to demand-initialize members
  591. // other than m_Type and m_rop.
  592. //
  593. CLdapContainerScope(
  594. SCOPE_TYPE eType,
  595. const CObjectPicker &rop,
  596. const CScope *pParent):
  597. CAdsiScope(eType, rop, pParent),
  598. m_DomainMode(DM_UNDETERMINED)
  599. {
  600. }
  601. virtual
  602. ~CLdapContainerScope()
  603. {
  604. }
  605. mutable DOMAIN_MODE m_DomainMode;
  606. };
  607. //+--------------------------------------------------------------------------
  608. //
  609. // Class: CGcScope
  610. //
  611. // Purpose: Represent the Global Catalog
  612. //
  613. // History: 06-23-2000 DavidMun Created
  614. //
  615. //---------------------------------------------------------------------------
  616. class CGcScope: public CLdapContainerScope
  617. {
  618. public:
  619. CGcScope(
  620. const CObjectPicker &rop);
  621. void
  622. CGcScope::Clone(
  623. const CGcScope &rgc);
  624. virtual void
  625. Expand(
  626. HWND hwndBaseDlg,
  627. vector<RpScope>::const_iterator *pitBeginNew,
  628. vector<RpScope>::const_iterator *pitEndNew) const;
  629. virtual HRESULT
  630. GetResultantFilterFlags(
  631. HWND hwndDlg,
  632. ULONG *pulFlags) const;
  633. virtual HRESULT
  634. GetADsPath(
  635. HWND hwnd,
  636. String *pstrPath) const;
  637. STDMETHOD(GetADsPath)(PWSTR *ppwzADsPath);
  638. private:
  639. virtual
  640. ~CGcScope()
  641. {
  642. TRACE_DESTRUCTOR(CGcScope);
  643. }
  644. };
  645. //+--------------------------------------------------------------------------
  646. //
  647. // Class: CLdapDomainScope
  648. //
  649. // Purpose: Represent uplevel (Win2K and later) domains.
  650. //
  651. // History: 06-23-2000 DavidMun Created
  652. //
  653. //---------------------------------------------------------------------------
  654. class CLdapDomainScope: public CLdapContainerScope
  655. {
  656. public:
  657. CLdapDomainScope(
  658. const CObjectPicker &rop,
  659. const ADD_SCOPE_INFO &asi,
  660. const CScope *pParent);
  661. virtual HRESULT
  662. GetResultantFilterFlags(
  663. HWND hwndDlg,
  664. ULONG *pulFlags) const;
  665. const String &
  666. GetFlatName() const
  667. {
  668. return m_strFlatName;
  669. }
  670. BOOL
  671. PathIsDc() const { return m_fPathIsDc; }
  672. VOID SetXForest(){m_bXForest = TRUE; }
  673. BOOL
  674. IsXForest() const {return m_bXForest; }
  675. private:
  676. virtual
  677. ~CLdapDomainScope()
  678. {
  679. TRACE_DESTRUCTOR(CLdapDomainScope);
  680. }
  681. String m_strFlatName;
  682. BOOL m_fPathIsDc;
  683. BOOL m_bXForest;
  684. };