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.

668 lines
18 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Windows NT Directory Service Administration SnapIn
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: toolbar.cpp
  9. //
  10. // Contents: DS App
  11. //
  12. // History: 30-apr-98 jimharr Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. #include "resource.h"
  17. #include "dsutil.h"
  18. #include "DSEvent.h"
  19. #include "DSdirect.h"
  20. #include "dsfilter.h"
  21. #include "dssnap.h"
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. MMCBUTTON g_DSAdmin_SnapinButtons[] =
  28. {
  29. { 2, dsNewUser, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  30. { 3, dsNewGroup, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  31. { 4, dsNewOU, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  32. { 1, dsFilter, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  33. { 0, dsFind, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  34. { 5, dsAddMember, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  35. };
  36. class CButtonStringsHolder
  37. {
  38. public:
  39. CButtonStringsHolder()
  40. {
  41. m_astr = NULL;
  42. }
  43. ~CButtonStringsHolder()
  44. {
  45. if (m_astr != NULL)
  46. delete[] m_astr;
  47. }
  48. CString* m_astr; // dynamic array of CStrings
  49. };
  50. CButtonStringsHolder g_astrButtonStrings;
  51. CONST INT cButtons = sizeof(g_DSAdmin_SnapinButtons)/sizeof(MMCBUTTON);
  52. /////////////////////////////////////////////////////////////////////////////////////////
  53. // IExtendControlbar
  54. HRESULT CDSEvent::SetControlbar (LPCONTROLBAR pControlbar)
  55. {
  56. HRESULT hr = S_OK;
  57. //
  58. // we are shutting down (get passed NULL)
  59. //
  60. if (pControlbar == NULL)
  61. {
  62. if (m_pControlbar != NULL)
  63. {
  64. //
  65. // assign to a variable on the stack to avoid
  66. // reentrancy problem: the Release() call might
  67. // cause another call in this function with null argument
  68. //
  69. LPCONTROLBAR pControlbarTemp = m_pControlbar;
  70. m_pControlbar = NULL;
  71. pControlbarTemp->Release();
  72. }
  73. return hr;
  74. }
  75. CBitmap bm;
  76. if (m_pComponentData->QuerySnapinType() == SNAPINTYPE_DS)
  77. {
  78. //
  79. // Store the control bar interface pointer
  80. //
  81. if (m_pControlbar == NULL)
  82. {
  83. m_pControlbar = pControlbar;
  84. TRACE(L"CDSEvent::SetControlbar() m_pControlbar->AddRef()\n",m_pControlbar);
  85. m_pControlbar->AddRef();
  86. }
  87. //
  88. // Create the toolbar if necessary
  89. //
  90. if (m_pToolbar == NULL)
  91. {
  92. hr = m_pControlbar->Create (TOOLBAR,
  93. this,
  94. (IUnknown **) &m_pToolbar);
  95. if (SUCCEEDED(hr))
  96. {
  97. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  98. bm.LoadBitmap (MAKEINTRESOURCE (IDB_BUTTONS));
  99. LoadToolbarStrings (g_DSAdmin_SnapinButtons);
  100. hr = m_pToolbar->AddBitmap (cButtons, (HBITMAP)bm, 16, 16, RGB(255,0,255));
  101. hr = m_pToolbar->AddButtons (cButtons, g_DSAdmin_SnapinButtons);
  102. }
  103. }
  104. else
  105. {
  106. hr = m_pControlbar->Attach (TOOLBAR, (IUnknown *) m_pToolbar);
  107. }
  108. m_UseSelectionParent = FALSE;
  109. }
  110. return hr;
  111. }
  112. HRESULT CDSEvent::LoadToolbarStrings (MMCBUTTON * Buttons)
  113. {
  114. if (g_astrButtonStrings.m_astr == NULL )
  115. {
  116. // load strings
  117. g_astrButtonStrings.m_astr = new CString[2*cButtons];
  118. for (UINT i = 0; i < cButtons; i++)
  119. {
  120. UINT iButtonTextId = 0, iTooltipTextId = 0;
  121. switch (Buttons[i].idCommand)
  122. {
  123. case dsNewUser:
  124. iButtonTextId = IDS_BUTTON_NEW_USER;
  125. iTooltipTextId = IDS_TOOLTIP_NEW_USER;
  126. break;
  127. case dsNewGroup:
  128. iButtonTextId = IDS_BUTTON_NEW_GROUP;
  129. iTooltipTextId = IDS_TOOLTIP_NEW_GROUP;
  130. break;
  131. case dsNewOU:
  132. iButtonTextId = IDS_BUTTON_NEW_OU;
  133. iTooltipTextId = IDS_TOOLTIP_NEW_OU;
  134. break;
  135. case dsFilter:
  136. iButtonTextId = IDS_BUTTON_FILTER;
  137. iTooltipTextId = IDS_TOOLTIP_FILTER;
  138. break;
  139. case dsFind:
  140. iButtonTextId = IDS_BUTTON_FIND;
  141. iTooltipTextId = IDS_TOOLTIP_FIND;
  142. break;
  143. case dsAddMember:
  144. iButtonTextId = IDS_BUTTON_ADD_MEMBER;
  145. iTooltipTextId = IDS_TOOLTIP_ADD_MEMBER;
  146. break;
  147. default:
  148. ASSERT(FALSE);
  149. break;
  150. }
  151. g_astrButtonStrings.m_astr[i*2].LoadString(iButtonTextId);
  152. Buttons[i].lpButtonText =
  153. const_cast<BSTR>((LPCTSTR)(g_astrButtonStrings.m_astr[i*2]));
  154. g_astrButtonStrings.m_astr[(i*2)+1].LoadString(iTooltipTextId);
  155. Buttons[i].lpTooltipText =
  156. const_cast<BSTR>((LPCTSTR)(g_astrButtonStrings.m_astr[(i*2)+1]));
  157. }
  158. }
  159. return S_OK;
  160. }
  161. HRESULT CDSEvent::ControlbarNotify (MMC_NOTIFY_TYPE event,
  162. LPARAM arg,
  163. LPARAM param)
  164. {
  165. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  166. CWaitCursor cwait;
  167. HRESULT hr = S_OK;
  168. if (m_pControlbar == NULL)
  169. {
  170. return hr;
  171. }
  172. BOOL bSelect;
  173. BOOL bScope;
  174. LPDATAOBJECT pDO = NULL;
  175. CDSCookie* pSelectedCookie = NULL;
  176. CDSCookie* pContainerCookie = NULL;
  177. CInternalFormatCracker dobjCracker;
  178. CUINode* pUINode = NULL, *pNode = NULL;
  179. switch (event)
  180. {
  181. case MMCN_SELECT:
  182. m_pControlbar->Attach (TOOLBAR,
  183. (IUnknown *) m_pToolbar);
  184. bSelect = HIWORD(arg);
  185. bScope = LOWORD(arg);
  186. if (bSelect)
  187. {
  188. pDO = (LPDATAOBJECT)param;
  189. dobjCracker.Extract(pDO);
  190. pUINode = dobjCracker.GetCookie();
  191. if (pUINode->IsSnapinRoot())
  192. {
  193. m_pToolbar->SetButtonState(dsNewUser,
  194. ENABLED,
  195. FALSE);
  196. m_pToolbar->SetButtonState(dsNewGroup,
  197. ENABLED,
  198. FALSE);
  199. m_pToolbar->SetButtonState(dsNewOU,
  200. ENABLED,
  201. FALSE);
  202. m_pToolbar->SetButtonState(dsFind,
  203. ENABLED,
  204. FALSE);
  205. m_pToolbar->SetButtonState(dsFilter,
  206. ENABLED,
  207. TRUE);
  208. m_pToolbar->SetButtonState(dsAddMember,
  209. ENABLED,
  210. FALSE);
  211. return hr;
  212. }
  213. if (IS_CLASS(pUINode, DS_UI_NODE))
  214. {
  215. pSelectedCookie = GetDSCookieFromUINode(pUINode);
  216. pContainerCookie = pSelectedCookie;
  217. pNode = pUINode;
  218. }
  219. else
  220. {
  221. //
  222. // Disable all buttons for non-DS nodes
  223. //
  224. m_pToolbar->SetButtonState (dsNewUser,
  225. ENABLED,
  226. FALSE);
  227. m_pToolbar->SetButtonState (dsNewGroup,
  228. ENABLED,
  229. FALSE);
  230. m_pToolbar->SetButtonState (dsNewOU,
  231. ENABLED,
  232. FALSE);
  233. m_pToolbar->SetButtonState (dsFind,
  234. ENABLED,
  235. FALSE);
  236. m_pToolbar->SetButtonState (dsFilter,
  237. ENABLED,
  238. FALSE);
  239. m_pToolbar->SetButtonState (dsAddMember,
  240. ENABLED,
  241. FALSE);
  242. return S_OK;
  243. }
  244. if (bScope)
  245. {
  246. pContainerCookie = pSelectedCookie;
  247. m_UseSelectionParent = FALSE;
  248. }
  249. else
  250. {
  251. pNode = pUINode->GetParent();
  252. if (IS_CLASS(pNode, DS_UI_NODE))
  253. {
  254. pContainerCookie = GetDSCookieFromUINode(pNode);
  255. }
  256. m_UseSelectionParent = TRUE;
  257. }
  258. if (pContainerCookie != NULL)
  259. {
  260. if (pNode->IsContainer())
  261. {
  262. int resultUser = -2, resultGroup = -2, resultOU = -2;
  263. resultUser = IsCreateAllowed (L"user", pContainerCookie);
  264. if ( resultUser != -2)
  265. {
  266. resultGroup = IsCreateAllowed(L"group", pContainerCookie);
  267. if (resultGroup != -2)
  268. {
  269. resultOU = IsCreateAllowed (L"organizationalUnit", pContainerCookie);
  270. }
  271. }
  272. m_pToolbar->SetButtonState (dsNewUser,
  273. ENABLED,
  274. resultUser >= 0);
  275. m_pToolbar->SetButtonState (dsNewGroup,
  276. ENABLED,
  277. resultGroup >= 0);
  278. m_pToolbar->SetButtonState (dsNewOU,
  279. ENABLED,
  280. resultOU >= 0);
  281. m_pToolbar->SetButtonState (dsFind,
  282. ENABLED,
  283. TRUE);
  284. m_pToolbar->SetButtonState (dsFilter,
  285. ENABLED,
  286. TRUE);
  287. }
  288. else
  289. {
  290. m_pToolbar->SetButtonState (dsNewUser,
  291. ENABLED,
  292. FALSE);
  293. m_pToolbar->SetButtonState (dsNewGroup,
  294. ENABLED,
  295. FALSE);
  296. m_pToolbar->SetButtonState (dsNewOU,
  297. ENABLED,
  298. FALSE);
  299. m_pToolbar->SetButtonState (dsFind,
  300. ENABLED,
  301. FALSE);
  302. }
  303. if ((wcscmp(pSelectedCookie->GetClass(), L"contact")==0) ||
  304. (wcscmp(pSelectedCookie->GetClass(), L"user")==0))
  305. {
  306. m_pToolbar->SetButtonState (dsAddMember,
  307. ENABLED,
  308. TRUE);
  309. }
  310. else
  311. {
  312. m_pToolbar->SetButtonState (dsAddMember,
  313. ENABLED,
  314. FALSE);
  315. }
  316. }
  317. else
  318. {
  319. m_UseSelectionParent = FALSE;
  320. }
  321. }
  322. break;
  323. case MMCN_BTN_CLICK:
  324. TRACE(_T("Button clicked. param is %d. pDataObj is %lx.\n"),
  325. param, arg);
  326. switch (param)
  327. {
  328. case dsNewUser:
  329. ToolbarCreateObject (CString (L"user"),
  330. (LPDATAOBJECT) arg);
  331. break;
  332. case dsNewGroup:
  333. ToolbarCreateObject (CString (L"group"),
  334. (LPDATAOBJECT) arg);
  335. break;
  336. case dsNewOU:
  337. ToolbarCreateObject (CString (L"organizationalUnit"),
  338. (LPDATAOBJECT) arg);
  339. break;
  340. case dsFilter:
  341. ToolbarFilter();
  342. break;
  343. case dsFind:
  344. ToolbarFind ((LPDATAOBJECT) arg);
  345. break;
  346. case dsAddMember:
  347. ToolbarAddMember((LPDATAOBJECT)arg);
  348. break;
  349. }
  350. break;
  351. }
  352. return hr;
  353. }
  354. bool CDSEvent::_ShouldUseParentContainer(CUINode* pUINode,
  355. CDSCookie* pDSNodeData)
  356. {
  357. bool result = false;
  358. // pUINode should never be NULL at this point or else we would
  359. // have had a failure by now
  360. ASSERT(pUINode);
  361. if (!pDSNodeData)
  362. {
  363. ASSERT(pDSNodeData);
  364. return result;
  365. }
  366. PCWSTR pszClass = pDSNodeData->GetClass();
  367. if (!pszClass)
  368. {
  369. ASSERT(pszClass);
  370. return result;
  371. }
  372. // NTRAID#NTBUG9-755184-2002/12/16-JeffJon
  373. // We need to have the same behavior whether or
  374. // not users, groups, and computers are shown as containers
  375. if (((!wcscmp(pszClass, L"computer")) ||
  376. (!wcscmp(pszClass, L"user")) ||
  377. #ifdef INETORGPERSON
  378. (!wcscmp(pszClass, L"inetOrgPerson")) ||
  379. #endif
  380. (!wcscmp(pszClass,L"group"))) &&
  381. m_pComponentData->ExpandComputers())
  382. {
  383. result = true;
  384. }
  385. else
  386. {
  387. if (!pUINode->IsContainer() &&
  388. m_UseSelectionParent)
  389. {
  390. result = true;
  391. }
  392. }
  393. return result;
  394. }
  395. HRESULT CDSEvent::ToolbarCreateObject (CString csClass,
  396. LPDATAOBJECT lpDataObj)
  397. {
  398. HRESULT hr = S_OK;
  399. CUINode* pSelectedUINode = NULL;
  400. CUINode* pUINode = NULL;
  401. CDSUINode* pDSUINode = NULL;
  402. CDSCookie * pCookie = NULL;
  403. int objIndex = 0;
  404. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  405. if (lpDataObj)
  406. {
  407. CInternalFormatCracker dobjCracker;
  408. VERIFY(SUCCEEDED(dobjCracker.Extract(lpDataObj)));
  409. pUINode = dobjCracker.GetCookie();
  410. }
  411. else
  412. {
  413. pUINode = m_pSelectedFolderNode;
  414. }
  415. //
  416. // Hold on to this so we can unselect it when we
  417. // create the new object
  418. //
  419. pSelectedUINode = pUINode;
  420. if (IS_CLASS(pUINode, DS_UI_NODE))
  421. {
  422. pCookie = GetDSCookieFromUINode(pUINode);
  423. pDSUINode = dynamic_cast<CDSUINode*>(pUINode);
  424. }
  425. ASSERT(pCookie != NULL && pDSUINode != NULL);
  426. if (pCookie == NULL || pDSUINode == NULL)
  427. {
  428. return E_INVALIDARG;
  429. }
  430. // If the selected node is a leaf, then we need to
  431. // use the parent container to create the new object
  432. // If "users, groups, and computers as containers" is
  433. // set, we need to use the parent container as well.
  434. // ShouldUserParentContainer() makes these decisions
  435. bool bUsingParent = false;
  436. if (_ShouldUseParentContainer(pUINode, pCookie))
  437. {
  438. // Set the UI node to be the parent container
  439. // and recalculate the DS node a cookie
  440. pUINode = pUINode->GetParent();
  441. bUsingParent = true;
  442. if (IS_CLASS(pUINode, DS_UI_NODE))
  443. {
  444. pCookie = GetDSCookieFromUINode(pUINode);
  445. pDSUINode = dynamic_cast<CDSUINode*>(pUINode);
  446. }
  447. ASSERT(pCookie != NULL && pDSUINode != NULL);
  448. if (pCookie == NULL || pDSUINode == NULL)
  449. {
  450. return E_INVALIDARG;
  451. }
  452. }
  453. // Now go on with the creation
  454. objIndex = IsCreateAllowed(csClass, pCookie);
  455. if (objIndex >= 0)
  456. {
  457. CDSUINode * pNewNode= NULL;
  458. hr = m_pComponentData->_CreateDSObject (pDSUINode,
  459. pCookie->GetChildListEntry(objIndex),
  460. NULL,
  461. &pNewNode);
  462. if (SUCCEEDED(hr) && (hr != S_FALSE) && (pNewNode != NULL))
  463. {
  464. m_pFrame->UpdateAllViews(lpDataObj,
  465. (LPARAM)pNewNode,
  466. (bUsingParent)
  467. ? DS_CREATE_OCCURRED_RESULT_PANE :
  468. DS_CREATE_OCCURRED);
  469. m_pFrame->UpdateAllViews(lpDataObj, (LPARAM)pSelectedUINode, DS_UNSELECT_OBJECT);
  470. }
  471. m_pFrame->UpdateAllViews(NULL, NULL, DS_UPDATE_OBJECT_COUNT);
  472. }
  473. return hr;
  474. }
  475. HRESULT CDSEvent::ToolbarAddMember(LPDATAOBJECT pDataObj)
  476. {
  477. HRESULT hr = S_OK;
  478. CObjectNamesFormatCracker objectNamesFormat;
  479. CInternalFormatCracker internalFormat;
  480. LPDATAOBJECT pDO = NULL;
  481. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  482. if (pDataObj)
  483. {
  484. pDO = internalFormat.ExtractMultiSelect(pDataObj);
  485. if (pDO == NULL)
  486. {
  487. pDO = pDataObj;
  488. }
  489. hr = objectNamesFormat.Extract(pDO);
  490. if (FAILED(hr))
  491. {
  492. return hr;
  493. }
  494. //
  495. // we need at least one object in the selection
  496. //
  497. ASSERT(objectNamesFormat.HasData());
  498. if (objectNamesFormat.GetCount() == 0)
  499. {
  500. TRACE (_T("DSToolbar::AddMember: can't find path\n"));
  501. return E_INVALIDARG;
  502. }
  503. }
  504. hr = AddDataObjListToGroup (&objectNamesFormat, m_hwnd, m_pComponentData);
  505. TRACE (_T("AddDataObjListToGroup returned hr = %lx\n"), hr);
  506. return hr;
  507. }
  508. HRESULT CDSEvent::ToolbarFilter()
  509. {
  510. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  511. if (m_pComponentData->CanRefreshAll())
  512. {
  513. if (m_pComponentData->m_pQueryFilter->EditFilteringOptions())
  514. {
  515. m_pComponentData->m_bDirty = TRUE;
  516. m_pComponentData->RefreshAll();
  517. }
  518. }
  519. return S_OK;
  520. }
  521. HRESULT CDSEvent::ToolbarFind(LPDATAOBJECT lpDataObj)
  522. {
  523. HRESULT hr = S_OK;
  524. CUINode* pUINode = NULL;
  525. CDSCookie * pCookie = NULL;
  526. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  527. if (lpDataObj)
  528. {
  529. CInternalFormatCracker dobjCracker;
  530. VERIFY(SUCCEEDED(dobjCracker.Extract(lpDataObj)));
  531. pUINode = dobjCracker.GetCookie();
  532. }
  533. else
  534. {
  535. pUINode = m_pSelectedFolderNode;
  536. }
  537. if (m_UseSelectionParent)
  538. {
  539. pUINode = pUINode->GetParent();
  540. }
  541. if (IS_CLASS(pUINode, DS_UI_NODE))
  542. {
  543. pCookie = GetDSCookieFromUINode(pUINode);
  544. }
  545. ASSERT(pCookie != NULL);
  546. if (pCookie == NULL)
  547. {
  548. return E_INVALIDARG;
  549. }
  550. m_pComponentData->m_ActiveDS->DSFind(m_pComponentData->GetHWnd(), pCookie->GetPath());
  551. return hr;
  552. }
  553. INT
  554. CDSEvent::IsCreateAllowed(CString csClass,
  555. CDSCookie * pContainer)
  556. {
  557. WCHAR ** ppChildren = NULL;
  558. HRESULT hr = S_OK;
  559. ppChildren = pContainer->GetChildList();
  560. if (ppChildren == NULL)
  561. {
  562. hr = m_pComponentData->FillInChildList(pContainer);
  563. if (hr == ERROR_DS_SERVER_DOWN)
  564. {
  565. return -2;
  566. }
  567. ppChildren = pContainer->GetChildList();
  568. }
  569. INT cChildClasses = pContainer->GetChildCount();
  570. INT i = 0;
  571. //
  572. // needs finishing
  573. //
  574. while (i < cChildClasses)
  575. {
  576. if (csClass == CString(ppChildren[i]))
  577. {
  578. return i;
  579. }
  580. else
  581. {
  582. i++;
  583. }
  584. }
  585. if (i == cChildClasses)
  586. {
  587. return -1;
  588. }
  589. return i;
  590. }