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.

628 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: dsutil.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef __DSUTIL_H_
  11. #define __DSUTIL_H_
  12. #include "util.h"
  13. #include "uiutil.h"
  14. #include "dssnap.h"
  15. #include "query.h"
  16. //
  17. // Common DS strings
  18. //
  19. extern PCWSTR g_pszAllowedAttributesEffective;
  20. extern PCWSTR g_pszPwdLastSet;
  21. HRESULT DSAdminOpenObject(PCWSTR pszPath,
  22. REFIID refIID,
  23. PVOID* ppInterface,
  24. BOOL bServer = FALSE);
  25. /////////////////////////////////////////////////////////////////////////////////
  26. // ADSI path helpers
  27. //
  28. HRESULT GetServerFromLDAPPath(IN LPCWSTR lpszLdapPath, OUT BSTR* pbstrServerName);
  29. BOOL StripADsIPath(LPCWSTR lpszPath, CString& strref, bool bUseEscapedMode = true);
  30. // remove escape characters from a path
  31. // Arguments:
  32. // lpszPath = path to be escaped
  33. // bDN = if TRUE, the path os a distinguished name, if FALSE is an LDAP path
  34. // bstrUnescaped = returned unescaped path
  35. //
  36. inline HRESULT UnescapePath(IN LPCWSTR lpszPath, IN BOOL bDN, OUT CComBSTR& bstrUnescaped)
  37. {
  38. CPathCracker pathCracker;
  39. pathCracker.Set((LPWSTR)lpszPath, bDN ? ADS_SETTYPE_DN : ADS_SETTYPE_FULL);
  40. pathCracker.put_EscapedMode(ADS_ESCAPEDMODE_OFF);
  41. bstrUnescaped = (LPCWSTR)NULL;
  42. HRESULT hr = pathCracker.Retrieve(bDN ? ADS_FORMAT_X500_DN : ADS_FORMAT_X500, &bstrUnescaped);
  43. return hr;
  44. }
  45. class CObjectNamesFormatCracker; // fwd decl
  46. HRESULT AddDataObjListToGroup(CObjectNamesFormatCracker * pNames,
  47. HWND hwnd,
  48. CDSComponentData* pComponentData);
  49. HRESULT AddDataObjListToGivenGroup(CObjectNamesFormatCracker * pNames,
  50. LPCWSTR lpszGroup,
  51. LPCWSTR lpszGroupName,
  52. HWND hwnd,
  53. CDSComponentData* pComponentData);
  54. BOOL IsValidSiteName( LPCTSTR lpctszSiteName, BOOL* pfNonRfc = NULL );
  55. BOOL IsLocalLogin( void );
  56. BOOL IsThisUserLoggedIn( LPCTSTR pwszUserDN );
  57. BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
  58. BOOL IsHomogenousDSSelection(LPDATAOBJECT pDataObject, CString& szClassName);
  59. BOOL CALLBACK AddPageProc(HPROPSHEETPAGE hPage, LPARAM pCall);
  60. HRESULT GetDisplaySpecifierProperty(PCWSTR pszClassName,
  61. PCWSTR pszDisplayProperty,
  62. MyBasePathsInfo* pBasePathsInfo,
  63. CStringList& strListRef,
  64. bool bEnglishOnly = false);
  65. HRESULT TabCollect_GetDisplayGUIDs(LPCWSTR lpszClassName,
  66. LPCWSTR lpszDisplayProperty,
  67. MyBasePathsInfo* pBasePathsInfo,
  68. UINT* pnCount,
  69. GUID** ppGuids);
  70. BOOL FindCookieInSubtree(IN CUINode* pContainerNode,
  71. IN LPCWSTR lpszCookieDN,
  72. IN SnapinType snapinType,
  73. OUT CUINode** ppUINode);
  74. bool CanUserChangePassword(IN IDirectoryObject* pDirObject);
  75. /////////////////////////////////////////////////////////////////////
  76. // CChangePasswordPrivilegeAction
  77. // helper class to handle the revoking and the reading of the
  78. // change password control right on user objects
  79. class CChangePasswordPrivilegeAction
  80. {
  81. public:
  82. CChangePasswordPrivilegeAction() : m_pDacl(NULL)
  83. {
  84. }
  85. HRESULT Load(IADs * pIADs);
  86. HRESULT Read(BOOL* pbPasswordCannotChange);
  87. HRESULT Revoke();
  88. private:
  89. HRESULT _SetSids();
  90. CComBSTR m_bstrObjectLdapPath;
  91. CSimpleSecurityDescriptorHolder m_SDHolder;
  92. PACL m_pDacl;
  93. CSidHolder m_SelfSid;
  94. CSidHolder m_WorldSid;
  95. };
  96. /////////////////////////////////////////////////////////////////////
  97. // CDSNotifyHandlerTransaction
  98. class CDSNotifyHandlerManager; // fwd decl
  99. class CDSComponentData;
  100. class CDSNotifyHandlerTransaction
  101. {
  102. public:
  103. CDSNotifyHandlerTransaction(CDSComponentData* pCD);
  104. ~CDSNotifyHandlerTransaction()
  105. {
  106. if (m_bStarted)
  107. End();
  108. }
  109. void SetEventType(ULONG uEvent)
  110. {
  111. ASSERT(m_uEvent == 0);
  112. ASSERT(uEvent != 0);
  113. m_uEvent = uEvent;
  114. }
  115. // state veriables check
  116. UINT NeedNotifyCount();
  117. // handlers for visualization in confirnation dialog
  118. void SetCheckListBox(CCheckListBox* pCheckListBox);
  119. void ReadFromCheckListBox(CCheckListBox* pCheckListBox);
  120. // interfaces for transacted protocol
  121. HRESULT Begin(LPCWSTR lpszArg1Path, LPCWSTR lpszArg1Class, BOOL bArg1Cont,
  122. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  123. HRESULT Begin(CDSCookie* pArg1Cookie,
  124. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  125. HRESULT Begin(IDataObject* pArg1,
  126. LPCWSTR lpszArg2Path, LPCWSTR lpszArg2Class, BOOL bArg2Cont);
  127. void Notify(ULONG nItem);
  128. void End();
  129. static HRESULT BuildTransactionDataObject(LPCWSTR lpszArgPath,
  130. LPCWSTR lpszArgClass,
  131. BOOL bContainer,
  132. CDSComponentData* pCD,
  133. IDataObject** ppArg);
  134. private:
  135. HRESULT _BuildDataObject(LPCWSTR lpszArgPath,
  136. LPCWSTR lpszArgClass,
  137. BOOL bContainer,
  138. IDataObject** ppArg);
  139. BOOL m_bStarted;
  140. CDSComponentData* m_pCD;
  141. CDSNotifyHandlerManager* m_pMgr;
  142. ULONG m_uEvent;
  143. CComPtr<IDataObject> m_spArg1;
  144. CComPtr<IDataObject> m_spArg2;
  145. };
  146. ///////////////////////////////////////////////////////////////////////////
  147. // CUIOperationHandlerBase
  148. class CUIOperationHandlerBase
  149. {
  150. public:
  151. CUIOperationHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  152. : m_transaction(pComponentData)
  153. {
  154. m_pComponentData = pComponentData;
  155. m_hWndFrame = m_hWndParent = hwnd;
  156. }
  157. virtual ~CUIOperationHandlerBase(){}
  158. protected:
  159. // accessor functions
  160. HWND GetParentHwnd() { return m_hWndParent;}
  161. void SetParentHwnd(HWND hwnd) { m_hWndParent = hwnd;}
  162. CDSComponentData* GetComponentData() { return m_pComponentData;}
  163. CDSNotifyHandlerTransaction* GetTransaction() { return &m_transaction;}
  164. // JonN 6/2/00 99382
  165. // SITEREPL: Run interference when administrator attempts to
  166. // delete critical object (NTDS Settings)
  167. // reports own errors, returns true iff deletion should proceed
  168. /* bool CheckForNTDSDSAInSubtree(
  169. LPCTSTR lpszX500Path,
  170. LPCTSTR lpszItemName);
  171. */
  172. //
  173. // JeffJon 8/10/00 27377
  174. // Check for critical system objects in the subtree before
  175. // attempting a subtree delete. This includes objects with
  176. // isCriticalSystemObject=TRUE and NTDS Settings objects
  177. //
  178. bool CheckForCriticalSystemObjectInSubtree(
  179. LPCTSTR lpszX500Path,
  180. LPCTSTR lpszItemName);
  181. // JonN 6/15/00 13574
  182. // Centralizes the checks to make sure this is an OK object to delete
  183. // returns HRESULT_FROM_WIN32(ERROR_CANCELLED) on cancellation
  184. // returns fAlternateDeleteMethod=true iff ObjectDeletionCheck already
  185. // attempted an alternate deletion method (e.g. DsRemoveDsServer).
  186. HRESULT ObjectDeletionCheck(
  187. LPCTSTR lpszADsPath,
  188. LPCTSTR lpszName, // shortname to display to user, may be NULL
  189. LPCTSTR lpszClass,
  190. bool& fAlternateDeleteMethod );
  191. private:
  192. CDSComponentData* m_pComponentData;
  193. CDSNotifyHandlerTransaction m_transaction;
  194. HWND m_hWndFrame; // MMC frame window
  195. HWND m_hWndParent; // window to parent any UI created in the handler
  196. };
  197. ///////////////////////////////////////////////////////////////////////////
  198. // CSingleDeleteHandlerBase
  199. class CSingleDeleteHandlerBase : public CUIOperationHandlerBase
  200. {
  201. public:
  202. CSingleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  203. : CUIOperationHandlerBase(pComponentData, hwnd)
  204. {
  205. GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
  206. }
  207. HRESULT Delete();
  208. protected:
  209. // hooks for customization
  210. virtual HRESULT BeginTransaction() = 0;
  211. virtual HRESULT DeleteObject() = 0;
  212. virtual HRESULT DeleteSubtree() = 0;
  213. virtual void GetItemName(OUT CString& szName) = 0;
  214. virtual LPCWSTR GetItemClass() = 0;
  215. virtual LPCWSTR GetItemPath() = 0;
  216. };
  217. ///////////////////////////////////////////////////////////////////////////
  218. // CMultipleDeleteHandlerBase
  219. class CMultipleDeleteHandlerBase : public CUIOperationHandlerBase
  220. {
  221. public:
  222. CMultipleDeleteHandlerBase(CDSComponentData* pComponentData, HWND hwnd)
  223. : CUIOperationHandlerBase(pComponentData, hwnd)
  224. {
  225. GetTransaction()->SetEventType(DSA_NOTIFY_DEL);
  226. }
  227. void Delete();
  228. protected:
  229. // hooks for customization
  230. virtual UINT GetItemCount() = 0;
  231. virtual HRESULT BeginTransaction() = 0;
  232. virtual HRESULT DeleteObject(UINT i) = 0;
  233. virtual HRESULT DeleteSubtree(UINT i) = 0;
  234. virtual void OnItemDeleted(UINT) {}
  235. virtual void GetItemName(IN UINT i, OUT CString& szName) = 0;
  236. virtual void GetItemPath(UINT i, CString& szPath) = 0;
  237. virtual PCWSTR GetItemClass(UINT i) = 0;
  238. private:
  239. CMultipleDeletionConfirmationUI m_confirmationUI;
  240. void OnStart(HWND hwnd);
  241. HRESULT OnDeleteStep(UINT i,
  242. BOOL* pbContinue,
  243. CString& strrefPath,
  244. CString& strrefClass,
  245. BOOL bSilent = TRUE);
  246. friend class CMultipleDeleteProgressDialog; // for m_confirmationUI
  247. };
  248. ///////////////////////////////////////////////////////////////////////////
  249. // CMoveHandlerBase
  250. class CMultipleMoveProgressDialog; // fwd decl
  251. class CMoveHandlerBase : public CUIOperationHandlerBase
  252. {
  253. public:
  254. CMoveHandlerBase(CDSComponentData* pComponentData, HWND hwnd,
  255. LPCWSTR lpszBrowseRootPath)
  256. : CUIOperationHandlerBase(pComponentData, hwnd)
  257. {
  258. m_lpszBrowseRootPath = lpszBrowseRootPath;
  259. GetTransaction()->SetEventType(DSA_NOTIFY_MOV);
  260. }
  261. HRESULT Move(LPCWSTR lpszDestinationPath = NULL);
  262. protected:
  263. // hooks for customization
  264. virtual UINT GetItemCount() = 0;
  265. virtual HRESULT BeginTransaction() = 0;
  266. virtual void GetNewPath(UINT i, CString& szNewPath) = 0;
  267. virtual void GetName(UINT i, CString& strref) = 0;
  268. virtual HRESULT OnItemMoved(UINT i, IADs* pIADs) = 0;
  269. virtual void GetClassOfMovedItem(CString& szClass) = 0;
  270. virtual void GetItemPath(UINT i, CString& szPath) = 0;
  271. virtual PCWSTR GetItemClass(UINT i) = 0;
  272. LPCWSTR GetDestPath() { return m_szDestPath;}
  273. LPCWSTR GetDestClass() { return m_szDestClass;}
  274. BOOL IsDestContainer() { return m_bDestContainer; }
  275. private:
  276. LPCWSTR m_lpszBrowseRootPath; // LDAP path where to point the browser dialog
  277. CComPtr<IADsContainer> m_spDSDestination;
  278. CString m_szDestPath;
  279. CString m_szDestClass;
  280. BOOL m_bDestContainer;
  281. BOOL _ReportFailure(BOOL bLast, HRESULT hr, LPCWSTR lpszName);
  282. HRESULT _BrowseForDestination(LPCWSTR lpszDestinationPath);
  283. BOOL _BeginTransactionAndConfirmOperation();
  284. HRESULT _MoveSingleSel(PCWSTR pszNewName);
  285. HRESULT _MoveMultipleSel();
  286. HRESULT _OnMoveStep(IN UINT i,
  287. OUT BOOL* pbCanContinue,
  288. OUT CString& strrefPath,
  289. OUT CString& strrefClass);
  290. friend class CMultipleMoveProgressDialog;
  291. };
  292. ///////////////////////////////////////////////////////////////////////////
  293. // CMultiselectMoveHandler
  294. class CMultiselectMoveHandler : public CMoveHandlerBase
  295. {
  296. private:
  297. struct CMovedState
  298. {
  299. CMovedState()
  300. {
  301. m_bMoved = FALSE;
  302. }
  303. BOOL m_bMoved;
  304. CString m_szNewPath;
  305. };
  306. public:
  307. CMultiselectMoveHandler(CDSComponentData* pComponentData, HWND hwnd,
  308. LPCWSTR lpszBrowseRootPath)
  309. : CMoveHandlerBase(pComponentData, hwnd, lpszBrowseRootPath)
  310. {
  311. m_pMovedArr = NULL;
  312. }
  313. virtual ~CMultiselectMoveHandler()
  314. {
  315. if (m_pMovedArr != NULL)
  316. delete[] m_pMovedArr;
  317. }
  318. BOOL WasItemMoved(UINT i)
  319. {
  320. ASSERT(i < GetItemCount());
  321. return m_pMovedArr[i].m_bMoved;
  322. }
  323. LPCWSTR GetNewItemPath(UINT i)
  324. {
  325. ASSERT(WasItemMoved(i));
  326. return m_pMovedArr[i].m_szNewPath;
  327. }
  328. HRESULT Initialize(IDataObject* pDataObject,
  329. CObjectNamesFormatCracker* pObjectNamesFormatCracker,
  330. CInternalFormatCracker* pInternalFormatCracker)
  331. {
  332. if ((pDataObject == NULL) || (pObjectNamesFormatCracker == NULL))
  333. {
  334. ASSERT(FALSE);
  335. return E_INVALIDARG;
  336. }
  337. m_pDataObject = pDataObject;
  338. m_pInternalFormatCracker = pInternalFormatCracker;
  339. m_pObjectNamesFormatCracker = pObjectNamesFormatCracker;
  340. if (m_pObjectNamesFormatCracker->GetCount() < 1)
  341. {
  342. ASSERT(FALSE); // something is just wrong...
  343. return E_INVALIDARG;
  344. }
  345. // allocate an array of CMovedState structs to keep track of what actually got moved
  346. // and what the new name is
  347. m_pMovedArr = new CMovedState[GetItemCount()];
  348. return S_OK;
  349. }
  350. protected:
  351. virtual UINT GetItemCount() { return m_pObjectNamesFormatCracker->GetCount();}
  352. virtual HRESULT BeginTransaction()
  353. {
  354. return GetTransaction()->Begin(m_pDataObject,
  355. GetDestPath(), GetDestClass(), IsDestContainer());
  356. }
  357. virtual void GetNewPath(UINT i, CString& szNewPath)
  358. {
  359. szNewPath = m_pObjectNamesFormatCracker->GetName(i);
  360. }
  361. virtual void GetName(UINT i, CString& strref)
  362. {
  363. HRESULT hr = S_OK;
  364. if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
  365. {
  366. CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
  367. CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
  368. strref = pCookie->GetName();
  369. }
  370. else
  371. {
  372. // REVIEW_MARCOC_PORT: this might be inefficent, need to make a member variable
  373. CPathCracker pathCracker;
  374. hr = pathCracker.Set((LPWSTR)m_pObjectNamesFormatCracker->GetName(i),
  375. ADS_SETTYPE_FULL);
  376. hr = pathCracker.SetDisplayType(ADS_DISPLAY_VALUE_ONLY);
  377. CComBSTR DestName;
  378. hr = pathCracker.GetElement( 0, &DestName );
  379. strref = DestName;
  380. }
  381. }
  382. virtual void GetItemPath(UINT i, CString& szPath)
  383. {
  384. szPath = m_pObjectNamesFormatCracker->GetName(i);
  385. }
  386. virtual PCWSTR GetItemClass(UINT i)
  387. {
  388. return m_pObjectNamesFormatCracker->GetClass(i);
  389. }
  390. virtual HRESULT OnItemMoved(UINT i, IADs* pIADs)
  391. {
  392. HRESULT hr = S_OK;
  393. m_pMovedArr[i].m_bMoved = TRUE;
  394. CComBSTR bsPath;
  395. hr = pIADs->get_ADsPath(&bsPath);
  396. if (SUCCEEDED(hr))
  397. {
  398. // save the new LDAP path in the array
  399. m_pMovedArr[i].m_szNewPath = bsPath;
  400. }
  401. if ((m_pInternalFormatCracker != NULL) && m_pInternalFormatCracker->HasData())
  402. {
  403. CUINode* pUINode = m_pInternalFormatCracker->GetCookie(i);
  404. CDSCookie* pCookie = GetDSCookieFromUINode(pUINode);
  405. pUINode->SetExtOp(OPCODE_MOVE);
  406. if (SUCCEEDED(hr))
  407. {
  408. CUINode* pParentNode = pUINode->GetParent();
  409. if (pParentNode != NULL)
  410. {
  411. if (!IS_CLASS(*pParentNode, CSavedQueryNode))
  412. {
  413. //
  414. // set the new DN in the cookie
  415. //
  416. CString szPath;
  417. StripADsIPath(bsPath, szPath);
  418. pCookie->SetPath(szPath);
  419. }
  420. }
  421. }
  422. }
  423. return hr;
  424. }
  425. virtual void GetClassOfMovedItem(CString& szClass)
  426. {
  427. szClass.Empty();
  428. if (NULL == m_pObjectNamesFormatCracker)
  429. return;
  430. UINT nCount = GetItemCount();
  431. if (0 == nCount)
  432. return;
  433. szClass = m_pObjectNamesFormatCracker->GetClass(0);
  434. for (UINT i = 1; i < nCount; i++)
  435. {
  436. if (0 != szClass.CompareNoCase( m_pObjectNamesFormatCracker->GetClass(i) ))
  437. {
  438. szClass.Empty();
  439. return;
  440. }
  441. }
  442. }
  443. protected:
  444. CMovedState* m_pMovedArr;
  445. CInternalFormatCracker* m_pInternalFormatCracker;
  446. private:
  447. IDataObject* m_pDataObject;
  448. CObjectNamesFormatCracker* m_pObjectNamesFormatCracker;
  449. };
  450. ///////////////////////////////////////////////////////////////////////////
  451. // CMultiselectMoveDataObject
  452. class CMultiselectMoveDataObject : public IDataObject, public CComObjectRoot
  453. {
  454. // ATL Maps
  455. DECLARE_NOT_AGGREGATABLE(CMultiselectMoveDataObject)
  456. BEGIN_COM_MAP(CMultiselectMoveDataObject)
  457. COM_INTERFACE_ENTRY(IDataObject)
  458. END_COM_MAP()
  459. // Construction/Destruction
  460. CMultiselectMoveDataObject()
  461. {
  462. m_pDSObjCached = NULL;
  463. m_nDSObjCachedBytes = 0;
  464. }
  465. ~CMultiselectMoveDataObject()
  466. {
  467. _Clear();
  468. }
  469. // Standard IDataObject methods
  470. public:
  471. // Implemented
  472. STDMETHOD(GetData)(FORMATETC * pformatetcIn, STGMEDIUM * pmedium);
  473. // Not Implemented
  474. private:
  475. STDMETHOD(GetDataHere)(FORMATETC*, STGMEDIUM*) { return E_NOTIMPL; };
  476. STDMETHOD(EnumFormatEtc)(DWORD, IEnumFORMATETC**) { return E_NOTIMPL; };
  477. STDMETHOD(SetData)(FORMATETC*, STGMEDIUM*,BOOL) { return E_NOTIMPL; };
  478. STDMETHOD(QueryGetData)(FORMATETC*) { return E_NOTIMPL; };
  479. STDMETHOD(GetCanonicalFormatEtc)(FORMATETC*, FORMATETC*) { return E_NOTIMPL; };
  480. STDMETHOD(DAdvise)(FORMATETC*, DWORD, IAdviseSink*, DWORD*) { return E_NOTIMPL; };
  481. STDMETHOD(DUnadvise)(DWORD) { return E_NOTIMPL; };
  482. STDMETHOD(EnumDAdvise)(IEnumSTATDATA**) { return E_NOTIMPL; };
  483. public:
  484. // Property Page Clipboard formats
  485. static CLIPFORMAT m_cfDsObjectNames;
  486. static HRESULT BuildPastedDataObject(
  487. IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
  488. IN CMultiselectMoveHandler* pMoveHandler,
  489. IN CDSComponentData* pCD,
  490. OUT IDataObject** ppSuccesfullyPastedDataObject);
  491. protected:
  492. // initialization
  493. HRESULT Init(IN CObjectNamesFormatCracker* pObjectNamesFormatPaste,
  494. IN CMultiselectMoveHandler* pMoveHandler,
  495. IN CDSComponentData* pCD);
  496. // Implementation
  497. private:
  498. void _Clear()
  499. {
  500. if (m_pDSObjCached != NULL)
  501. {
  502. ::free(m_pDSObjCached);
  503. m_pDSObjCached = NULL;
  504. m_nDSObjCachedBytes = 0;
  505. }
  506. }
  507. // chunk of memory with the clpboard format already computed
  508. LPDSOBJECTNAMES m_pDSObjCached;
  509. DWORD m_nDSObjCachedBytes;
  510. };
  511. ////////////////////////////////////////////////////////////////////////
  512. void EscapeFilterElement(PCWSTR pszElement, CString& refszEscapedElement);
  513. #endif // __DSUTIL_H_