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.

2110 lines
57 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: delegwiz.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "pch.h"
  11. #include "wizbase.h"
  12. #include "util.h"
  13. #include <initguid.h>
  14. #include <cmnquery.h> // ICommonQuery
  15. #include <dsquery.h>
  16. #include <dsclient.h>
  17. #include "resource.h"
  18. #include "dsuiwiz.h"
  19. #include "delegWiz.h"
  20. #define GET_OU_WIZARD() ((CDelegWiz*)GetWizard())
  21. /////////////////////////////////////////////////////////////////////////////
  22. void InitBigBoldFont(HWND hWnd, HFONT& hFont)
  23. {
  24. ASSERT(::IsWindow(hWnd));
  25. NONCLIENTMETRICS ncm;
  26. memset(&ncm, 0, sizeof(ncm));
  27. ncm.cbSize = sizeof(ncm);
  28. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  29. LOGFONT boldLogFont = ncm.lfMessageFont;
  30. boldLogFont.lfWeight = FW_BOLD;
  31. // load big font definition from resources
  32. WCHAR szFontName[LF_FACESIZE];
  33. if (0 == ::LoadString(_Module.GetResourceInstance(), IDS_BIG_BOLD_FONT_NAME,
  34. boldLogFont.lfFaceName, LF_FACESIZE))
  35. {
  36. // set to default of failed to load
  37. wcscpy(boldLogFont.lfFaceName, L"Verdana Bold"); // LF_FACESIZE == 32
  38. }
  39. WCHAR szFontSize[128];
  40. int nFontSize = 0;
  41. if (0 != ::LoadString(_Module.GetResourceInstance(), IDS_BIG_BOLD_FONT_SIZE,
  42. szFontSize, sizeof(szFontSize)/sizeof(WCHAR)))
  43. {
  44. nFontSize = _wtoi(szFontSize);
  45. }
  46. if (nFontSize == 0)
  47. nFontSize = 12; // default
  48. HDC hdc = ::GetDC(hWnd);
  49. //Bug fix 447884
  50. if( hdc )
  51. {
  52. boldLogFont.lfHeight =
  53. 0 - (::GetDeviceCaps(hdc, LOGPIXELSY) * nFontSize / 72);
  54. hFont = ::CreateFontIndirect((const LOGFONT*)(&boldLogFont));
  55. ::ReleaseDC(hWnd, hdc);
  56. }
  57. }
  58. void SetLargeFont(HWND hWndDialog, int nControlID)
  59. {
  60. ASSERT(::IsWindow(hWndDialog));
  61. ASSERT(nControlID);
  62. static HFONT boldLogFont = 0;
  63. if (boldLogFont == 0)
  64. {
  65. InitBigBoldFont(hWndDialog, boldLogFont);
  66. }
  67. HWND hWndControl = ::GetDlgItem(hWndDialog, nControlID);
  68. if (hWndControl)
  69. {
  70. ::SendMessage(hWndControl, WM_SETFONT, (WPARAM)boldLogFont, MAKELPARAM(TRUE, 0));
  71. }
  72. }
  73. ////////////////////////////////////////////////////////////////////////////
  74. // CDelegWiz_StartPage
  75. BOOL CDelegWiz_StartPage::OnSetActive()
  76. {
  77. CDelegWiz* pWizard = GET_OU_WIZARD();
  78. pWizard->SetWizardButtonsFirst(TRUE);
  79. return TRUE;
  80. }
  81. LRESULT CDelegWiz_StartPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  82. LPARAM lParam, BOOL& bHandled)
  83. {
  84. LRESULT lRes = 1;
  85. SetLargeFont(m_hWnd, IDC_STATIC_WELCOME);
  86. return lRes;
  87. }
  88. #ifdef _SKIP_NAME_PAGE
  89. LRESULT CDelegWiz_StartPage::OnWizardNext()
  90. {
  91. BOOL bSuccess = TRUE;
  92. HRESULT hr = S_OK;
  93. CDelegWiz* pWiz = GET_OU_WIZARD();
  94. // if we do not have an object, we will browse from the next page
  95. if (!pWiz->CanChangeName() && !m_bBindOK)
  96. {
  97. // make sure it exists and it is of the right type
  98. {
  99. // scope to restore cursor
  100. CWaitCursor wait;
  101. hr = pWiz->GetObjectInfo();
  102. }
  103. if (FAILED(hr))
  104. {
  105. WCHAR szFmt[256];
  106. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256);
  107. WCHAR szMsg[512];
  108. wsprintf(szMsg, szFmt, pWiz->GetCanonicalName());
  109. pWiz->WizReportHRESULTError(szMsg, hr);
  110. goto error;
  111. }
  112. {
  113. // scope to restore cursor
  114. CWaitCursor wait;
  115. hr = pWiz->GetClassInfoFromSchema();
  116. }
  117. if (FAILED(hr))
  118. {
  119. WCHAR szFmt[256];
  120. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_INFO, szFmt, 256);
  121. WCHAR szMsg[512];
  122. wsprintf(szMsg, szFmt, pWiz->GetCanonicalName());
  123. pWiz->WizReportHRESULTError(szMsg, hr);
  124. goto error;
  125. }
  126. // all fine, we do not need to do it anymore
  127. m_bBindOK = TRUE;
  128. }
  129. OnWizardNextHelper();
  130. return 0; // all fine, go to next page
  131. error:
  132. pWiz->SetWizardButtonsFirst(FALSE);
  133. return -1; // do not advance
  134. }
  135. #endif
  136. ////////////////////////////////////////////////////////////////////////////
  137. // CDelegWiz_NamePage
  138. LRESULT CDelegWiz_NamePage::OnInitDialog(UINT uMsg, WPARAM wParam,
  139. LPARAM lParam, BOOL& bHandled)
  140. {
  141. LRESULT lRes = 1;
  142. CDelegWiz* pWiz = GET_OU_WIZARD();
  143. m_hwndNameEdit = GetDlgItem(IDC_OBJ_NAME_EDIT);
  144. if (!pWiz->CanChangeName()) // called on a given object
  145. {
  146. // hide static text that gives instructions
  147. HWND hwndNameStatic = GetDlgItem(IDC_OBJ_NAME_STATIC);
  148. ::ShowWindow(hwndNameStatic, FALSE);
  149. // change text to the editbox
  150. HWND hwndNameEditStatic = GetDlgItem(IDC_OBJ_NAME_EDIT_STATIC);
  151. CWString szLabel;
  152. szLabel.LoadFromResource(IDS_OBJ_NAME_EDIT_STATIC);
  153. ::SendMessage(hwndNameEditStatic, WM_SETTEXT,0 , (LPARAM)(LPCWSTR)szLabel);
  154. // remove the tabstop flag from the Edit Box
  155. LONG style = ::GetWindowLong(m_hwndNameEdit, GWL_STYLE);
  156. style &= ~WS_TABSTOP;
  157. ::SetWindowLong(m_hwndNameEdit, GWL_STYLE, style);
  158. // make the Edit Box Read Only
  159. ::SendMessage(m_hwndNameEdit, EM_SETREADONLY, TRUE, 0L);
  160. // disable and hide the Browse Button
  161. HWND hWndBrowseButton = GetDlgItem(IDC_BROWSE_BUTTON);
  162. ::EnableWindow(hWndBrowseButton, FALSE);
  163. ::ShowWindow(hWndBrowseButton, FALSE);
  164. lRes = 0;
  165. }
  166. return lRes;
  167. }
  168. LRESULT CDelegWiz_NamePage::OnBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  169. {
  170. // load resources to customize dialog
  171. TCHAR szCaption[256];
  172. LoadStringHelper(IDS_DELEGWIZ_BROWSE_CONTAINER_CAPTION, szCaption, ARRAYSIZE(szCaption));
  173. TCHAR szTitle[256];
  174. LoadStringHelper(IDS_DELEGWIZ_BROWSE_CONTAINER_TITLE, szTitle, ARRAYSIZE(szTitle));
  175. // set dialog struct
  176. TCHAR szPath[MAX_PATH+1];
  177. szPath[0] = NULL;
  178. DSBROWSEINFO dsbi;
  179. ::ZeroMemory( &dsbi, sizeof(dsbi) );
  180. dsbi.cbStruct = sizeof(DSBROWSEINFO);
  181. dsbi.hwndOwner = m_hWnd;
  182. dsbi.pszCaption = szCaption;
  183. dsbi.pszTitle = szTitle;
  184. dsbi.pszRoot = NULL; // ADS path to root (NULL == root of DS namespace)
  185. dsbi.pszPath = szPath;
  186. dsbi.cchPath = (sizeof(szPath) / sizeof(TCHAR));
  187. dsbi.dwFlags = DSBI_ENTIREDIRECTORY;
  188. // REVIEW_MARCOC: need to determine how to show/hide hidden folders
  189. dsbi.dwFlags |= DSBI_INCLUDEHIDDEN; //m_fBrowseHiddenFolders ? DSBI_INCLUDEHIDDEN : 0;
  190. dsbi.pfnCallback = NULL;
  191. dsbi.lParam = 0;
  192. // make the call to the dialog
  193. int iRet = ::DsBrowseForContainer( &dsbi );
  194. if ( IDOK == iRet )
  195. { // returns -1, 0, IDOK or IDCANCEL
  196. // get path from BROWSEINFO struct, put in text edit field
  197. //TRACE(_T("returned from DS Browse successfully with:\n %s\n"),
  198. // dsbi.pszPath);
  199. ::SetWindowText(m_hwndNameEdit, szPath);
  200. }
  201. return 1;
  202. }
  203. BOOL CDelegWiz_NamePage::OnSetActive()
  204. {
  205. CDelegWiz* pWiz = GET_OU_WIZARD();
  206. #ifdef _SKIP_NAME_PAGE
  207. if (!pWiz->CanChangeName())
  208. {
  209. // just cause the page to fail, so that we skip it
  210. return FALSE;
  211. }
  212. #endif
  213. HRESULT hr = S_OK;
  214. if (pWiz->m_bFwd && !pWiz->CanChangeName()) // called on a given object
  215. {
  216. // need to bind now to get the needed data
  217. hr = pWiz->GetObjectInfo();
  218. if (SUCCEEDED(hr))
  219. {
  220. // set the name of the object in the Edit Box
  221. ::SendMessage(m_hwndNameEdit, WM_SETTEXT, 0, (LPARAM)pWiz->GetCanonicalName());
  222. }
  223. else
  224. {
  225. WCHAR szFmt[256];
  226. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256);
  227. WCHAR szMsg[512];
  228. wsprintf(szMsg, szFmt, pWiz->GetCanonicalName());
  229. pWiz->WizReportHRESULTError(szMsg, hr);
  230. }
  231. }
  232. pWiz->SetWizardButtonsMiddle(SUCCEEDED(hr));
  233. return TRUE;
  234. }
  235. LRESULT CDelegWiz_NamePage::OnWizardNext()
  236. {
  237. BOOL bSuccess = TRUE;
  238. HRESULT hr = S_OK;
  239. CDelegWiz* pWiz = GET_OU_WIZARD();
  240. if (pWiz->CanChangeName())
  241. {
  242. // retrieve name from the edit control
  243. int nEditTextLen = ::SendMessage(m_hwndNameEdit, WM_GETTEXTLENGTH,0,0) + 1;// count NULL
  244. TCHAR* lpszName = (TCHAR*)alloca(sizeof(TCHAR)*(nEditTextLen));
  245. ::SendMessage(m_hwndNameEdit, WM_GETTEXT, (WPARAM)nEditTextLen, (LPARAM)lpszName);
  246. // this will get the equivalent LDAP path
  247. pWiz->SetName(lpszName);
  248. // make sure it exists and it is of the right type
  249. {
  250. // scope to restore cursor
  251. CWaitCursor wait;
  252. hr = pWiz->GetObjectInfo();
  253. }
  254. if (FAILED(hr))
  255. {
  256. WCHAR szFmt[256];
  257. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256);
  258. WCHAR szMsg[512];
  259. wsprintf(szMsg, szFmt, pWiz->GetCanonicalName());
  260. pWiz->WizReportHRESULTError(szMsg, hr);
  261. goto error;
  262. }
  263. } // if can change name
  264. {
  265. // scope to restore cursor
  266. CWaitCursor wait;
  267. hr = pWiz->GetClassInfoFromSchema();
  268. }
  269. if (FAILED(hr))
  270. {
  271. WCHAR szFmt[256];
  272. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_INFO, szFmt, 256);
  273. WCHAR szMsg[512];
  274. wsprintf(szMsg, szFmt, pWiz->GetCanonicalName());
  275. pWiz->WizReportHRESULTError(szMsg, hr);
  276. goto error;
  277. }
  278. OnWizardNextHelper();
  279. return 0; // all fine, go to next page
  280. error:
  281. pWiz->SetWizardButtonsMiddle(FALSE);
  282. return -1; // do not advance
  283. }
  284. ////////////////////////////////////////////////////////////////////////////
  285. // CDelegWiz_DelegationTemplateSelectionPage
  286. LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  287. LPARAM lParam, BOOL& bHandled)
  288. {
  289. m_delegationTemplatesListView.Initialize(IDC_DELEGATE_TEMPLATE_LIST, m_hWnd);
  290. // set the correct value for radiobuttons text
  291. m_hwndDelegateTemplateRadio = GetDlgItem(IDC_DELEGATE_TEMPLATE_RADIO);
  292. _ASSERTE(m_hwndDelegateTemplateRadio != NULL);
  293. m_hwndDelegateCustomRadio = GetDlgItem(IDC_DELEGATE_CUSTOM_RADIO);
  294. _ASSERTE(m_hwndDelegateCustomRadio != NULL);
  295. // set default setting
  296. ::SendMessage(m_hwndDelegateTemplateRadio, BM_SETCHECK, BST_CHECKED, 0);
  297. return 1;
  298. }
  299. LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnDelegateTypeRadioChange(WORD wNotifyCode, WORD wID,
  300. HWND hWndCtl, BOOL& bHandled)
  301. {
  302. SyncControlsHelper(IDC_DELEGATE_CUSTOM_RADIO == wID);
  303. return 1;
  304. }
  305. LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  306. {
  307. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh;
  308. if (CCheckListViewHelper::CheckChanged(pNMListView))
  309. {
  310. int nSelCount = m_delegationTemplatesListView.GetCheckCount();
  311. GET_OU_WIZARD()->SetWizardButtonsMiddle(nSelCount > 0);
  312. }
  313. return 1;
  314. }
  315. BOOL CDelegWiz_DelegationTemplateSelectionPage::OnSetActive()
  316. {
  317. CDelegWiz* pWizard = GET_OU_WIZARD();
  318. BOOL bRetVal = TRUE;
  319. BOOL bDelegateCustom =
  320. (BST_CHECKED == ::SendMessage(m_hwndDelegateCustomRadio, BM_GETCHECK,0,0));
  321. if (pWizard->m_bFwd)
  322. {
  323. // need to fill in with data
  324. BOOL bHaveTemplates =
  325. pWizard->m_templateAccessPermissionsHolderManager.FillTemplatesListView(
  326. &m_delegationTemplatesListView, pWizard->GetClass())> 0;
  327. if (!bDelegateCustom && !bHaveTemplates)
  328. {
  329. ::SendMessage(m_hwndDelegateCustomRadio, BM_SETCHECK,BST_CHECKED,0);
  330. ::SendMessage(m_hwndDelegateTemplateRadio, BM_SETCHECK,BST_UNCHECKED,0);
  331. bDelegateCustom = TRUE;
  332. }
  333. SyncControlsHelper(bDelegateCustom);
  334. }
  335. else
  336. {
  337. // data already in, just coming back from next page
  338. if (bDelegateCustom)
  339. {
  340. pWizard->SetWizardButtonsMiddle(TRUE);
  341. }
  342. else
  343. {
  344. int nSelCount = m_delegationTemplatesListView.GetCheckCount();
  345. pWizard->SetWizardButtonsMiddle(nSelCount > 0);
  346. }
  347. }
  348. return TRUE;
  349. }
  350. LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnWizardNext()
  351. {
  352. HRESULT hr = S_OK;
  353. int nSelCount = -1;
  354. int* nSelArray = NULL;
  355. BOOL bCanAdvance = FALSE;
  356. CDelegWiz* pWiz = GET_OU_WIZARD();
  357. // check if the delegation is on all objects
  358. BOOL bCustom = TRUE;
  359. UINT nNextPageID = 0;
  360. if (BST_CHECKED == ::SendMessage(m_hwndDelegateCustomRadio, BM_GETCHECK,0,0))
  361. {
  362. nSelCount = 0;
  363. nSelArray = NULL;
  364. bCanAdvance = TRUE;
  365. }
  366. else
  367. {
  368. ASSERT(BST_CHECKED == ::SendMessage(m_hwndDelegateTemplateRadio, BM_GETCHECK,0,0));
  369. bCustom = FALSE;
  370. nSelCount = 0;
  371. int nCount = m_delegationTemplatesListView.GetItemCount();
  372. for (int k=0; k<nCount; k++)
  373. {
  374. CTemplate* pTempl = (CTemplate*)m_delegationTemplatesListView.GetItemData(k);
  375. pTempl->m_bSelected = m_delegationTemplatesListView.IsItemChecked(k);
  376. if (pTempl->m_bSelected)
  377. nSelCount++;
  378. }
  379. bCanAdvance = (nSelCount > 0);
  380. }
  381. if (!bCanAdvance)
  382. goto error;
  383. // set branching info
  384. if (bCustom)
  385. {
  386. // just move to the next custom page
  387. nNextPageID = CDelegWiz_ObjectTypeSelectionPage::IDD;
  388. pWiz->m_objectTypeSelectionPage.m_nPrevPageID = IDD;
  389. pWiz->m_finishPage.m_nPrevPageID = CDelegWiz_DelegatedRightsPage::IDD;
  390. pWiz->m_finishPage.SetCustom();
  391. }
  392. else
  393. {
  394. // need to gather info for the selected templates
  395. {
  396. // scope to restore cursor
  397. CWaitCursor wait;
  398. if (!pWiz->InitPermissionHoldersFromSelectedTemplates())
  399. {
  400. // REVIEW_MARCOC: need to give a message to the user
  401. pWiz->WizMessageBox(IDS_DELEGWIZ_ERR_TEMPL_APPLY);
  402. goto error;
  403. }
  404. }
  405. // got info, can proceed
  406. nNextPageID = CDelegWiz_FinishPage::IDD;
  407. pWiz->m_finishPage.m_nPrevPageID = IDD;
  408. pWiz->m_finishPage.SetTemplate();
  409. }
  410. OnWizardNextHelper();
  411. return nNextPageID; // advance next
  412. error:
  413. // do not advance, error
  414. pWiz->SetWizardButtonsMiddle(FALSE);
  415. return -1;
  416. }
  417. void CDelegWiz_DelegationTemplateSelectionPage::SyncControlsHelper(BOOL bDelegateCustom)
  418. {
  419. CDelegWiz* pWiz = GET_OU_WIZARD();
  420. // uncheck all items in the listview if delegating custom
  421. if (bDelegateCustom)
  422. {
  423. m_delegationTemplatesListView.SetCheckAll(FALSE);
  424. pWiz->m_templateAccessPermissionsHolderManager.DeselectAll(); // in the list templates
  425. }
  426. // disable listbox if "delegate custom"
  427. m_delegationTemplatesListView.EnableWindow(!bDelegateCustom);
  428. // enable "Wizard Next"
  429. BOOL bEnableNext = bDelegateCustom ?
  430. TRUE : (m_delegationTemplatesListView.GetCheckCount() > 0);
  431. pWiz->SetWizardButtonsMiddle(bEnableNext);
  432. }
  433. ////////////////////////////////////////////////////////////////////////////
  434. // CDelegWiz_ObjectTypeSelectionPage
  435. LRESULT CDelegWiz_ObjectTypeSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  436. LPARAM lParam, BOOL& bHandled)
  437. {
  438. m_objectTypeListView.Initialize(IDC_OBJ_TYPE_LIST, m_hWnd);
  439. // set the correct value for radiobuttons text
  440. m_hwndDelegateAllRadio = GetDlgItem(IDC_DELEGATE_ALL_RADIO);
  441. ASSERT(m_hwndDelegateAllRadio != NULL);
  442. m_hwndDelegateFollowingRadio = GetDlgItem(IDC_DELEGATE_FOLLOWING_RADIO);
  443. ASSERT(m_hwndDelegateFollowingRadio != NULL);
  444. m_hwndDelegateCreateChild = GetDlgItem(IDC_DELEGATE_CREATE_CHILD);
  445. ASSERT(m_hwndDelegateCreateChild != NULL);
  446. m_hwndDelegateDeleteChild = GetDlgItem(IDC_DELEGATE_DELETE_CHILD);
  447. ASSERT(m_hwndDelegateDeleteChild != NULL);
  448. // set default setting
  449. ::SendMessage(m_hwndDelegateAllRadio, BM_SETCHECK, BST_CHECKED, 0);
  450. ::SendMessage(m_hwndDelegateCreateChild, BM_SETCHECK, BST_UNCHECKED, 0);
  451. ::SendMessage(m_hwndDelegateCreateChild, BM_SETCHECK, BST_UNCHECKED, 0);
  452. return 1;
  453. }
  454. LRESULT CDelegWiz_ObjectTypeSelectionPage::OnObjectRadioChange(WORD wNotifyCode, WORD wID,
  455. HWND hWndCtl, BOOL& bHandled)
  456. {
  457. SyncControlsHelper(IDC_DELEGATE_ALL_RADIO == wID);
  458. return 1;
  459. }
  460. LRESULT CDelegWiz_ObjectTypeSelectionPage::OnCreateDelCheckBoxChanage(WORD wNotifyCode, WORD wID,
  461. HWND hWndCtl, BOOL& bHandled)
  462. {
  463. CDelegWiz* pWiz = GET_OU_WIZARD();
  464. if( IDC_DELEGATE_CREATE_CHILD == wID )
  465. {
  466. if( ::SendMessage( hWndCtl, BM_GETCHECK,0,0 ) )
  467. pWiz->m_fCreateDelChild |= ACTRL_DS_CREATE_CHILD;
  468. else
  469. pWiz->m_fCreateDelChild &= ~ACTRL_DS_CREATE_CHILD;
  470. }
  471. if( IDC_DELEGATE_DELETE_CHILD == wID )
  472. {
  473. if( ::SendMessage( hWndCtl, BM_GETCHECK,0,0 ) )
  474. pWiz->m_fCreateDelChild |= ACTRL_DS_DELETE_CHILD;
  475. else
  476. pWiz->m_fCreateDelChild &= ~ACTRL_DS_DELETE_CHILD;
  477. }
  478. return 1;
  479. }
  480. LRESULT CDelegWiz_ObjectTypeSelectionPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  481. {
  482. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh;
  483. if (CCheckListViewHelper::CheckChanged(pNMListView))
  484. {
  485. int nSelCount = m_objectTypeListView.GetCheckCount();
  486. GET_OU_WIZARD()->SetWizardButtonsMiddle(nSelCount > 0);
  487. }
  488. return 1;
  489. }
  490. void CDelegWiz_ObjectTypeSelectionPage::SyncControlsHelper(BOOL bDelegateAll)
  491. {
  492. CDelegWiz* pWiz = GET_OU_WIZARD();
  493. if (bDelegateAll)
  494. {
  495. // uncheck all items in the listview if delegating all
  496. m_objectTypeListView.SetCheckAll(FALSE); // in the listview
  497. pWiz->DeselectSchemaClassesSelectionCustom(); // in the list of schama classes
  498. //Uncheck delete/create check boxes
  499. ::SendMessage(m_hwndDelegateCreateChild,BM_SETCHECK,0,0);
  500. ::SendMessage(m_hwndDelegateDeleteChild,BM_SETCHECK,0,0);
  501. pWiz->m_fCreateDelChild = 0;
  502. }
  503. // enable "Wizard Next" of "delegate all"
  504. pWiz->SetWizardButtonsMiddle(bDelegateAll);
  505. // disable listbox if "delegate all"
  506. m_objectTypeListView.EnableWindow(!bDelegateAll);
  507. ::EnableWindow( m_hwndDelegateCreateChild, !bDelegateAll);
  508. ::EnableWindow( m_hwndDelegateDeleteChild, !bDelegateAll);
  509. }
  510. void CDelegWiz_ObjectTypeSelectionPage::SetRadioControlText(HWND hwndCtrl, LPCWSTR lpszFmtText, LPCWSTR lpszText)
  511. {
  512. // format new text
  513. int nTextLen = lstrlen(lpszText)+1; // count NULL
  514. int nFmtTextLen = lstrlen(lpszFmtText)+1; // count NULL
  515. WCHAR* lpszNewText = (WCHAR*)alloca(sizeof(WCHAR)*(nFmtTextLen+nTextLen));
  516. wsprintf(lpszNewText, lpszFmtText, lpszText);
  517. // set back
  518. ::SendMessage(hwndCtrl, WM_SETTEXT, 0, (WPARAM)lpszNewText);
  519. }
  520. BOOL CDelegWiz_ObjectTypeSelectionPage::OnSetActive()
  521. {
  522. CDelegWiz* pWizard = GET_OU_WIZARD();
  523. BOOL bRetVal = TRUE;
  524. BOOL bDelegateAll =
  525. (BST_CHECKED == ::SendMessage(m_hwndDelegateAllRadio, BM_GETCHECK,0,0));
  526. if (pWizard->m_bFwd)
  527. {
  528. // need to fill in with data
  529. BOOL bFilter = TRUE;
  530. BOOL bHaveChildClasses = pWizard->FillCustomSchemaClassesListView(&m_objectTypeListView, bFilter) > 0;
  531. if (!bHaveChildClasses)
  532. {
  533. ::SendMessage(m_hwndDelegateAllRadio, BM_SETCHECK,BST_CHECKED,0);
  534. ::SendMessage(m_hwndDelegateFollowingRadio, BM_SETCHECK,BST_UNCHECKED,0);
  535. ::EnableWindow(m_hwndDelegateFollowingRadio, FALSE);
  536. bDelegateAll = TRUE;
  537. }
  538. SyncControlsHelper(bDelegateAll);
  539. }
  540. else
  541. {
  542. // data already in, just coming back from next page
  543. if (bDelegateAll)
  544. {
  545. pWizard->SetWizardButtonsMiddle(TRUE);
  546. }
  547. else
  548. {
  549. int nSelCount = m_objectTypeListView.GetCheckCount();
  550. pWizard->SetWizardButtonsMiddle(nSelCount > 0);
  551. }
  552. }
  553. return TRUE;
  554. }
  555. LRESULT CDelegWiz_ObjectTypeSelectionPage::OnWizardNext()
  556. {
  557. HRESULT hr = S_OK;
  558. BOOL bCanAdvance = FALSE;
  559. CDelegWiz* pWiz = GET_OU_WIZARD();
  560. pWiz->m_bAuxClass = false;
  561. // check if the delegation is on all objects
  562. if (BST_CHECKED == ::SendMessage(m_hwndDelegateAllRadio, BM_GETCHECK,0,0))
  563. {
  564. bCanAdvance = TRUE;
  565. }
  566. else
  567. {
  568. ASSERT(BST_CHECKED == ::SendMessage(m_hwndDelegateFollowingRadio, BM_GETCHECK,0,0));
  569. int nSelCount = 0;
  570. int nCount = m_objectTypeListView.GetItemCount();
  571. CSchemaClassInfo* pAuxClassInfo = NULL;
  572. for (int k=0; k<nCount; k++)
  573. {
  574. CSchemaClassInfo* pChildClassInfo = (CSchemaClassInfo*)m_objectTypeListView.GetItemData(k);
  575. pChildClassInfo->m_bSelected = m_objectTypeListView.IsItemChecked(k);
  576. if (pChildClassInfo->m_bSelected)
  577. {
  578. nSelCount++;
  579. if(pChildClassInfo->IsAux())
  580. {
  581. pWiz->m_bAuxClass = true;
  582. if(!pAuxClassInfo)
  583. pAuxClassInfo = pChildClassInfo;
  584. }
  585. }
  586. }
  587. bCanAdvance = (nSelCount > 0);
  588. if(nSelCount > 1 && pWiz->m_bAuxClass)
  589. {
  590. LPWSTR pszMessage = NULL;
  591. FormatStringID(&pszMessage, IDS_DELEGWIZ_ONE_AUX_CLASS,pAuxClassInfo->GetDisplayName());
  592. pWiz->WizMessageBox(pszMessage);
  593. LocalFree(pszMessage);
  594. bCanAdvance = FALSE;
  595. }
  596. }
  597. if (!bCanAdvance)
  598. goto error;
  599. {
  600. // scope to restore cursor
  601. CWaitCursor wait;
  602. bCanAdvance = pWiz->SetSchemaClassesSelectionCustom();
  603. }
  604. if (!bCanAdvance)
  605. goto error;
  606. // for the selected child class(es), get the access permissions
  607. // to display in the next page
  608. {
  609. // scope to restore cursor
  610. CWaitCursor wait;
  611. bCanAdvance = pWiz->GetCustomAccessPermissions();
  612. }
  613. if (!bCanAdvance)
  614. goto error;
  615. OnWizardNextHelper();
  616. return 0; // advance next
  617. error:
  618. // do not advance, error
  619. pWiz->SetWizardButtonsMiddle(FALSE);
  620. return -1;
  621. }
  622. ///////////////////////////////////////////////////////////////////////
  623. // CPrincipalListViewHelper
  624. BOOL CPrincipalListViewHelper::Initialize(UINT nID, HWND hParent)
  625. {
  626. m_hWnd = GetDlgItem(hParent, nID);
  627. if (m_hWnd == NULL)
  628. return FALSE;
  629. if (!m_imageList.Create(m_hWnd))
  630. return FALSE;
  631. SetImageList();
  632. RECT r;
  633. ::GetClientRect(m_hWnd, &r);
  634. int scroll = ::GetSystemMetrics(SM_CXVSCROLL);
  635. LV_COLUMN col;
  636. ZeroMemory(&col, sizeof(LV_COLUMN));
  637. col.mask = LVCF_WIDTH;
  638. col.cx = (r.right - r.left) - scroll;
  639. m_defaultColWidth = col.cx;
  640. return (0 == ListView_InsertColumn(m_hWnd,0,&col));
  641. }
  642. int CPrincipalListViewHelper::InsertItem(int iItem, CPrincipal* pPrincipal)
  643. {
  644. // need to get the icon index
  645. int nIconIndex = m_imageList.GetIconIndex(pPrincipal->GetClass());
  646. if (nIconIndex == -1)
  647. {
  648. nIconIndex = m_imageList.AddIcon(pPrincipal->GetClass(),
  649. pPrincipal->GetClassIcon());
  650. if (nIconIndex != -1)
  651. SetImageList();
  652. }
  653. LV_ITEM item;
  654. ZeroMemory(&item, sizeof(LV_ITEM));
  655. item.mask = LVIF_TEXT | LVIF_PARAM;
  656. item.pszText = (LPWSTR)(LPCWSTR)(pPrincipal->GetDisplayName());
  657. item.lParam = (LPARAM)pPrincipal;
  658. item.iItem = iItem;
  659. if (nIconIndex != -1)
  660. {
  661. item.iImage = nIconIndex;
  662. item.mask |= LVIF_IMAGE;
  663. }
  664. int iRes = ListView_InsertItem(m_hWnd, &item);
  665. return iRes;
  666. }
  667. BOOL CPrincipalListViewHelper::SelectItem(int iItem)
  668. {
  669. LV_ITEM item;
  670. ZeroMemory(&item, sizeof(LV_ITEM));
  671. item.mask = LVIF_STATE;
  672. item.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
  673. item.state = LVIS_FOCUSED | LVIS_SELECTED;
  674. return ListView_SetItem(m_hWnd, &item);
  675. }
  676. CPrincipal* CPrincipalListViewHelper::GetItemData(int iItem)
  677. {
  678. LV_ITEM item;
  679. ZeroMemory(&item, sizeof(LV_ITEM));
  680. item.mask = LVIF_PARAM;
  681. item.iItem = iItem;
  682. ListView_GetItem(m_hWnd, &item);
  683. return (CPrincipal*)item.lParam;
  684. }
  685. void CPrincipalListViewHelper::DeleteSelectedItems(CGrowableArr<CPrincipal>* pDeletedArr)
  686. {
  687. int nItemIndex;
  688. while ( (nItemIndex = ListView_GetNextItem(m_hWnd, -1, LVNI_SELECTED)) != -1)
  689. {
  690. CPrincipal* pPrincipal = GetItemData(nItemIndex);
  691. if (ListView_DeleteItem(m_hWnd, nItemIndex))
  692. {
  693. pDeletedArr->Add(pPrincipal);
  694. }
  695. } // if
  696. // restore selection to first item
  697. if (GetItemCount() > 0)
  698. SelectItem(0);
  699. }
  700. void CPrincipalListViewHelper::UpdateWidth(int cxNew)
  701. {
  702. int cx = GetWidth(); // get current col width from the control
  703. if (cxNew < m_defaultColWidth)
  704. cxNew = m_defaultColWidth;
  705. if (cxNew != cx)
  706. SetWidth(cx);
  707. }
  708. ////////////////////////////////////////////////////////////////////////////
  709. // CDelegWiz_PrincipalSelectionPage
  710. LRESULT CDelegWiz_PrincipalSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  711. LPARAM lParam, BOOL& bHandled)
  712. {
  713. // initialize the list of principals
  714. m_principalListView.Initialize(IDC_SELECTED_PRINCIPALS_LIST, m_hWnd);
  715. // cache handle for the remove button
  716. m_hwndRemoveButton = GetDlgItem(IDC_REMOVE_BUTTON);
  717. return 1;
  718. }
  719. LRESULT CDelegWiz_PrincipalSelectionPage::OnAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  720. {
  721. GET_OU_WIZARD()->AddPrincipals(&m_principalListView);
  722. SyncButtons();
  723. return 1;
  724. }
  725. LRESULT CDelegWiz_PrincipalSelectionPage::OnRemove(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  726. {
  727. GET_OU_WIZARD()->DeletePrincipals(&m_principalListView);
  728. SyncButtons();
  729. return 1;
  730. }
  731. LRESULT CDelegWiz_PrincipalSelectionPage::OnListViewSelChange(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  732. {
  733. SyncButtons();
  734. return 1;
  735. }
  736. BOOL CDelegWiz_PrincipalSelectionPage::OnSetActive()
  737. {
  738. CDelegWiz* pWizard = GET_OU_WIZARD();
  739. SyncButtons();
  740. return TRUE;
  741. }
  742. LRESULT CDelegWiz_PrincipalSelectionPage::OnWizardNext()
  743. {
  744. CDelegWiz* pWiz = GET_OU_WIZARD();
  745. // set branching info
  746. UINT nNextPageID = 0;
  747. if (pWiz->m_templateAccessPermissionsHolderManager.HasTemplates(pWiz->GetClass()))
  748. {
  749. nNextPageID = CDelegWiz_DelegationTemplateSelectionPage::IDD;
  750. }
  751. else
  752. {
  753. nNextPageID = CDelegWiz_ObjectTypeSelectionPage::IDD;
  754. pWiz->m_objectTypeSelectionPage.m_nPrevPageID = IDD;
  755. }
  756. OnWizardNextHelper();
  757. return nNextPageID;
  758. }
  759. void CDelegWiz_PrincipalSelectionPage::SyncButtons()
  760. {
  761. BOOL bEnable = FALSE;
  762. int nItemCount = m_principalListView.GetItemCount();
  763. if (nItemCount > 0)
  764. {
  765. bEnable = m_principalListView.GetSelCount() > 0;
  766. }
  767. ::EnableWindow(m_hwndRemoveButton, bEnable);
  768. CDelegWiz* pWiz = GET_OU_WIZARD();
  769. pWiz->SetWizardButtonsMiddle(nItemCount > 0);
  770. }
  771. ////////////////////////////////////////////////////////////////////////////
  772. // CDelegWiz_DelegatedRightsPage
  773. LRESULT CDelegWiz_DelegatedRightsPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  774. LPARAM lParam, BOOL& bHandled)
  775. {
  776. // initialize check list view
  777. m_delegatedRigthsListView.Initialize(IDC_DELEG_RIGHTS_LIST, m_hWnd);
  778. // get HWND's of controls
  779. m_hwndGeneralRigthsCheck = GetDlgItem(IDC_SHOW_GENERAL_CHECK);
  780. _ASSERTE(m_hwndGeneralRigthsCheck);
  781. m_hwndPropertyRightsCheck = GetDlgItem(IDC_SHOW_PROPERTY_CHECK);
  782. _ASSERTE(m_hwndPropertyRightsCheck);
  783. m_hwndSubobjectRightsCheck = GetDlgItem(IDC_SHOW_SUBOBJ_CHECK);
  784. _ASSERTE(m_hwndSubobjectRightsCheck);
  785. return 1;
  786. }
  787. BOOL CDelegWiz_DelegatedRightsPage::OnSetActive()
  788. {
  789. CDelegWiz* pWizard = GET_OU_WIZARD();
  790. if (pWizard->m_bFwd)
  791. {
  792. if(pWizard->m_bAuxClass)
  793. SetFilterOptions(FILTER_EXP_GEN_DISABLED|FILTER_EXP_PROP);
  794. else
  795. SetFilterOptions(FILTER_EXP_GEN);
  796. ResetCheckList(); // will set wizard button
  797. }
  798. else
  799. {
  800. //coming back from next page, just set the wizard button
  801. pWizard->SetWizardButtonsMiddle(pWizard->HasPermissionSelectedCustom());
  802. }
  803. return TRUE;
  804. }
  805. LRESULT CDelegWiz_DelegatedRightsPage::OnWizardNext()
  806. {
  807. CDelegWiz* pWiz = GET_OU_WIZARD();
  808. // must at least one check > 0
  809. if (pWiz->HasPermissionSelectedCustom())
  810. {
  811. OnWizardNextHelper();
  812. return 0;
  813. }
  814. pWiz->SetWizardButtonsMiddle(FALSE);
  815. return -1;
  816. }
  817. LRESULT CDelegWiz_DelegatedRightsPage::OnFilterChange(WORD wNotifyCode, WORD wID,
  818. HWND hWndCtl, BOOL& bHandled)
  819. {
  820. ResetCheckList();
  821. return 1;
  822. }
  823. LRESULT CDelegWiz_DelegatedRightsPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  824. {
  825. if (m_bUIUpdateInProgress)
  826. return 1;
  827. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh;
  828. if (CCheckListViewHelper::CheckChanged(pNMListView))
  829. {
  830. CRigthsListViewItem* pItem = (CRigthsListViewItem*)pNMListView->lParam; // item data
  831. CDelegWiz* pWizard = GET_OU_WIZARD();
  832. ULONG nCurrFilterOptions = GetFilterOptions();
  833. ULONG nNewFilterOptions = 0;
  834. pWizard->OnCustomAccessRightsCheckListClick(
  835. pItem, CCheckListViewHelper::IsChecked(pNMListView),
  836. &nNewFilterOptions);
  837. nNewFilterOptions |= nCurrFilterOptions;
  838. m_bUIUpdateInProgress = TRUE;
  839. // this call will cause a series of notifications:
  840. // we have to disable them to avoid reentrancy
  841. if (nNewFilterOptions == nCurrFilterOptions)
  842. {
  843. // no need to change filter selection, just update the checkboxes
  844. pWizard->UpdateAccessRightsListViewSelection(&m_delegatedRigthsListView, nNewFilterOptions);
  845. }
  846. else
  847. {
  848. // filter selection must be changed,
  849. // so we have to update the check boxes and to refill the checklist
  850. SetFilterOptions(nNewFilterOptions);
  851. ResetCheckList();
  852. }
  853. m_bUIUpdateInProgress = FALSE;
  854. BOOL bSel = pWizard->HasPermissionSelectedCustom();
  855. pWizard->SetWizardButtonsMiddle(bSel);
  856. }
  857. return 1;
  858. }
  859. void CDelegWiz_DelegatedRightsPage::ResetCheckList()
  860. {
  861. // get a new filtered list of rights in the list view
  862. CDelegWiz* pWizard = GET_OU_WIZARD();
  863. // this call will cause a series of notifications:
  864. // we have to disable them to avoid reentrancy
  865. m_bUIUpdateInProgress = TRUE;
  866. pWizard->FillCustomAccessRightsListView(&m_delegatedRigthsListView, GetFilterOptions());
  867. m_bUIUpdateInProgress = FALSE;
  868. pWizard->SetWizardButtonsMiddle(pWizard->HasPermissionSelectedCustom());
  869. }
  870. ULONG CDelegWiz_DelegatedRightsPage::GetFilterOptions()
  871. {
  872. ULONG nFilterState = 0;
  873. // read the filtering options from checkboxes
  874. if (BST_CHECKED == ::SendMessage(m_hwndGeneralRigthsCheck, BM_GETCHECK, 0, 0))
  875. nFilterState |= FILTER_EXP_GEN;
  876. if (BST_CHECKED == ::SendMessage(m_hwndPropertyRightsCheck, BM_GETCHECK, 0, 0))
  877. nFilterState |= FILTER_EXP_PROP;
  878. if (BST_CHECKED == ::SendMessage(m_hwndSubobjectRightsCheck, BM_GETCHECK, 0, 0))
  879. nFilterState |= FILTER_EXP_SUBOBJ;
  880. return nFilterState;
  881. }
  882. inline WPARAM _Checked(ULONG f) { return f ? BST_CHECKED : BST_UNCHECKED;}
  883. void CDelegWiz_DelegatedRightsPage::SetFilterOptions(ULONG nFilterOptions)
  884. {
  885. ::EnableWindow(m_hwndGeneralRigthsCheck,!(nFilterOptions & FILTER_EXP_GEN_DISABLED));
  886. ::SendMessage(m_hwndGeneralRigthsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_GEN), 0);
  887. ::SendMessage(m_hwndPropertyRightsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_PROP), 0);
  888. ::SendMessage(m_hwndSubobjectRightsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_SUBOBJ), 0);
  889. }
  890. ////////////////////////////////////////////////////////////////////////////
  891. // CDelegWiz_FinishPage
  892. LRESULT CDelegWiz_FinishPage::OnInitDialog(UINT uMsg, WPARAM wParam,
  893. LPARAM lParam, BOOL& bHandled)
  894. {
  895. SetLargeFont(m_hWnd, IDC_STATIC_COMPLETION);
  896. return 1;
  897. }
  898. LRESULT CDelegWiz_FinishPage::OnSetFocusSummaryEdit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  899. {
  900. ASSERT(hWndCtl == GetDlgItem(IDC_EDIT_SUMMARY));
  901. ::SendMessage(hWndCtl, EM_SETSEL, (WPARAM)-1, (LPARAM)0);
  902. if (m_bNeedSetFocus)
  903. {
  904. m_bNeedSetFocus = FALSE;
  905. TRACE(_T("Resetting Focus\n"));
  906. HWND hwndSheet = ::GetParent(m_hWnd);
  907. ASSERT(::IsWindow(hwndSheet));
  908. HWND hWndFinishCtrl =::GetDlgItem(hwndSheet, 0x3025);
  909. ASSERT(::IsWindow(hWndFinishCtrl));
  910. ::SetFocus(hWndFinishCtrl);
  911. }
  912. return 1;
  913. }
  914. BOOL CDelegWiz_FinishPage::OnSetActive()
  915. {
  916. CDelegWiz* pWizard = GET_OU_WIZARD();
  917. pWizard->SetWizardButtonsLast(TRUE);
  918. CWString szSummary;
  919. if (m_bCustom)
  920. pWizard->WriteSummaryInfoCustom(szSummary, g_lpszSummaryIdent, g_lpszSummaryNewLine);
  921. else
  922. pWizard->WriteSummaryInfoTemplate(szSummary, g_lpszSummaryIdent, g_lpszSummaryNewLine);
  923. HWND hWndSummary = GetDlgItem(IDC_EDIT_SUMMARY);
  924. ::SetWindowText(hWndSummary, (LPCWSTR)szSummary);
  925. m_bNeedSetFocus = TRUE;
  926. return TRUE;
  927. }
  928. BOOL CDelegWiz_FinishPage::OnWizardFinish()
  929. {
  930. CWaitCursor wait;
  931. BOOL bRes;
  932. CDelegWiz* pWizard = GET_OU_WIZARD();
  933. if (m_bCustom)
  934. bRes = GET_OU_WIZARD()->FinishCustom();
  935. else
  936. bRes = GET_OU_WIZARD()->FinishTemplate();
  937. return bRes;
  938. }
  939. ////////////////////////////////////////////////////////////////////////////
  940. // CDelegWiz
  941. const long CDelegWiz::nSchemaClassesSelAll = -2;
  942. const long CDelegWiz::nSchemaClassesSelMultiple = -1;
  943. // REVIEW_MARCOC: should probably nuke, not used
  944. BOOL Is256ColorSupported()
  945. {
  946. BOOL bRetval = FALSE;
  947. HDC hdc = GetDC(NULL);
  948. if( hdc )
  949. {
  950. if( GetDeviceCaps( hdc, BITSPIXEL ) >= 8 )
  951. {
  952. bRetval = TRUE;
  953. }
  954. ReleaseDC(NULL, hdc);
  955. }
  956. return bRetval;
  957. }
  958. CDelegWiz::CDelegWiz() :
  959. CWizardBase(IDB_DELEG_WATER, IDB_DELEG_HD, IDS_DELEGWIZ_WIZ_TITLE),
  960. m_startPage(this),
  961. m_namePage(this),
  962. m_templateSelectionPage(this),
  963. m_userOrGroupSelectionPage(this),
  964. m_objectTypeSelectionPage(this),
  965. m_delegatedRightsPage(this),
  966. m_finishPage(this),
  967. m_bAuxClass(FALSE)
  968. {
  969. m_lpszLDAPPath = NULL;
  970. m_nSchemaClassesSel = nSchemaClassesSelAll;
  971. m_fCreateDelChild = 0;
  972. // Add the property pages
  973. m_startPage.InitWiz97(TRUE);
  974. AddPage(m_startPage);
  975. m_namePage.InitWiz97(FALSE,
  976. IDS_DELEGWIZ_NAME_TITLE,
  977. IDS_DELEGWIZ_NAME_SUBTITLE);
  978. AddPage(m_namePage);
  979. m_userOrGroupSelectionPage.InitWiz97(FALSE,
  980. IDS_DELEGWIZ_PRINCIPALS_SEL_TITLE,
  981. IDS_DELEGWIZ_PRINCIPALS_SEL_SUBTITLE);
  982. AddPage(m_userOrGroupSelectionPage);
  983. // branching page
  984. m_templateSelectionPage.InitWiz97(FALSE,
  985. IDS_DELEGWIZ_TEMPLATE_SEL_TITLE,
  986. IDS_DELEGWIZ_TEMPLATE_SEL_SUBTITLE);
  987. AddPage(m_templateSelectionPage);
  988. m_objectTypeSelectionPage.InitWiz97(FALSE,
  989. IDS_DELEGWIZ_OBJ_TYPE_SEL_TITLE,
  990. IDS_DELEGWIZ_OBJ_TYPE_SEL_SUBTITLE);
  991. AddPage(m_objectTypeSelectionPage);
  992. m_delegatedRightsPage.InitWiz97(FALSE,
  993. IDS_DELEGWIZ_DELEG_RIGHTS_TITLE,
  994. IDS_DELEGWIZ_DELEG_RIGHTS_SUBTITLE);
  995. AddPage(m_delegatedRightsPage);
  996. m_finishPage.InitWiz97(TRUE);
  997. AddPage(m_finishPage);
  998. m_templateAccessPermissionsHolderManager.LoadTemplates();
  999. };
  1000. CDelegWiz::~CDelegWiz()
  1001. {
  1002. }
  1003. HRESULT CDelegWiz::AddPrincipalsFromBrowseResults(CPrincipalListViewHelper* pListViewHelper,
  1004. PDS_SELECTION_LIST pDsSelectionList)
  1005. {
  1006. TRACE(L"CDelegWiz::AddPrincipalsFromBrowseResults()\n");
  1007. HRESULT hr = S_OK;
  1008. if ( (pDsSelectionList == NULL) || (pDsSelectionList->cItems == 0))
  1009. {
  1010. TRACE(L"CDelegWiz::AddPrincipalsFromBrowseResults(), no items!!!\n");
  1011. return E_INVALIDARG;
  1012. }
  1013. int nListInsertPosition = pListViewHelper->GetItemCount();
  1014. for (int i = 0; i < pDsSelectionList->cItems; i++)
  1015. {
  1016. TRACE(L"For loop, pDsSelectionList->cItems = %d\n", pDsSelectionList->cItems);
  1017. // add to list of principals
  1018. CPrincipal* pPrincipal = new CPrincipal;
  1019. if (pPrincipal != NULL)
  1020. {
  1021. HICON hClassIcon = m_adsiObject.GetClassIcon(pDsSelectionList->aDsSelection[i].pwzClass);
  1022. HRESULT hrInit = pPrincipal->Initialize(&(pDsSelectionList->aDsSelection[i]), hClassIcon);
  1023. if (FAILED(hrInit))
  1024. {
  1025. LPCWSTR lpszName = pDsSelectionList->aDsSelection[i].pwzName;
  1026. WCHAR szFmt[256];
  1027. LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_PRINCIPAL, szFmt, 256);
  1028. int nNameLen = lstrlen(lpszName) + 1;
  1029. WCHAR* lpszMsg = (WCHAR*)alloca(sizeof(WCHAR)*(nNameLen+256));
  1030. wsprintf(lpszMsg, szFmt, lpszName);
  1031. WizReportHRESULTError(lpszMsg, hrInit);
  1032. delete pPrincipal;
  1033. continue;
  1034. }
  1035. // add to list of principals (if not already there)
  1036. if (m_principalList.AddIfNotPresent(pPrincipal))
  1037. {
  1038. // add to listbox (assume not sorted)
  1039. pListViewHelper->InsertItem(nListInsertPosition, pPrincipal);
  1040. nListInsertPosition++;
  1041. }
  1042. } // if pPrincipal not NULL
  1043. } // for
  1044. // make sure there is a selection
  1045. if ( (pListViewHelper->GetItemCount() > 0) &&
  1046. (pListViewHelper->GetSelCount() == 0) )
  1047. {
  1048. // if we have items, but none is selected, make sure we set the selection
  1049. // to the first one.
  1050. pListViewHelper->SelectItem(0);
  1051. }
  1052. // update width
  1053. //pListViewHelper->UpdateWidth(m_principalList.GetMaxListboxExtent());
  1054. return hr;
  1055. }
  1056. /*
  1057. typedef struct _DSOP_FILTER_FLAGS
  1058. {
  1059. DSOP_UPLEVEL_FILTER_FLAGS Uplevel;
  1060. ULONG flDownlevel;
  1061. } DSOP_FILTER_FLAGS;
  1062. typedef struct _DSOP_SCOPE_INIT_INFO
  1063. {
  1064. ULONG cbSize;
  1065. ULONG flType;
  1066. ULONG flScope;
  1067. DSOP_FILTER_FLAGS FilterFlags;
  1068. PCWSTR pwzDcName; // OPTIONAL
  1069. PCWSTR pwzADsPath; // OPTIONAL
  1070. HRESULT hr;
  1071. } DSOP_SCOPE_INIT_INFO, *PDSOP_SCOPE_INIT_INFO;
  1072. */
  1073. DSOP_SCOPE_INIT_INFO g_aDSOPScopes[] =
  1074. {
  1075. #if 0
  1076. {
  1077. cbSize,
  1078. flType,
  1079. flScope,
  1080. {
  1081. { flBothModes, flMixedModeOnly, flNativeModeOnly },
  1082. flDownlevel,
  1083. },
  1084. pwzDcName,
  1085. pwzADsPath,
  1086. hr // OUT
  1087. },
  1088. #endif
  1089. // The Global Catalog
  1090. {
  1091. sizeof(DSOP_SCOPE_INIT_INFO),
  1092. DSOP_SCOPE_TYPE_GLOBAL_CATALOG,
  1093. DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT|
  1094. DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS|
  1095. DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS,
  1096. {
  1097. { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS |
  1098. DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE |
  1099. DSOP_FILTER_COMPUTERS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS, 0, 0 },
  1100. 0,
  1101. },
  1102. NULL,
  1103. NULL,
  1104. S_OK
  1105. },
  1106. // The domain to which the target computer is joined.
  1107. {
  1108. sizeof(DSOP_SCOPE_INIT_INFO),
  1109. DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN,
  1110. DSOP_SCOPE_FLAG_STARTING_SCOPE |
  1111. DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT|
  1112. DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS|
  1113. DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS,
  1114. {
  1115. // joined domain is always NT5 for DS ACLs Editor
  1116. { 0,
  1117. //mixed: users, well known SIDs, local groups, builtin groups, global groups, computers
  1118. DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS | DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE | DSOP_FILTER_BUILTIN_GROUPS | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS ,
  1119. //native users, well known SIDs, local groups, builtin groups, global groups, universal groups, computers
  1120. DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS |
  1121. DSOP_FILTER_DOMAIN_LOCAL_GROUPS_SE | DSOP_FILTER_BUILTIN_GROUPS |
  1122. DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_COMPUTERS
  1123. },
  1124. 0, // zero for downlevel joined domain, should be DS-aware
  1125. },
  1126. NULL,
  1127. NULL,
  1128. S_OK
  1129. },
  1130. // The domains in the same forest (enterprise) as the domain to which
  1131. // the target machine is joined. Note these can only be DS-aware
  1132. {
  1133. sizeof(DSOP_SCOPE_INIT_INFO),
  1134. DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN,
  1135. DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT|
  1136. DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS|
  1137. DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS,
  1138. {
  1139. { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS, 0, 0},
  1140. 0,
  1141. },
  1142. NULL,
  1143. NULL,
  1144. S_OK
  1145. },
  1146. // Domains external to the enterprise but trusted directly by the
  1147. // domain to which the target machine is joined.
  1148. {
  1149. sizeof(DSOP_SCOPE_INIT_INFO),
  1150. DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN,
  1151. DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT|
  1152. DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS|
  1153. DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS,
  1154. {
  1155. { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS, 0, 0},
  1156. DSOP_DOWNLEVEL_FILTER_USERS | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS,
  1157. },
  1158. NULL,
  1159. NULL,
  1160. S_OK
  1161. },
  1162. };
  1163. HRESULT CDelegWiz::AddPrincipals(CPrincipalListViewHelper* pListViewHelper)
  1164. {
  1165. TRACE(L"CDelegWiz::AddPrincipals()\n");
  1166. // create object picker COM object
  1167. CComPtr<IDsObjectPicker> spDsObjectPicker;
  1168. HRESULT hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER,
  1169. IID_IDsObjectPicker, (void**)&spDsObjectPicker);
  1170. if (FAILED(hr))
  1171. {
  1172. TRACE(L"CoCreateInstance(CLSID_DsObjectPicker) failed, hr = 0x%x\n");
  1173. return hr;
  1174. }
  1175. // set init info
  1176. DSOP_INIT_INFO InitInfo;
  1177. ZeroMemory(&InitInfo, sizeof(InitInfo));
  1178. InitInfo.cbSize = sizeof(DSOP_INIT_INFO);
  1179. InitInfo.pwzTargetComputer = m_adsiObject.GetServerName();
  1180. InitInfo.cDsScopeInfos = sizeof(g_aDSOPScopes)/sizeof(DSOP_SCOPE_INIT_INFO);
  1181. InitInfo.aDsScopeInfos = g_aDSOPScopes;
  1182. InitInfo.flOptions = DSOP_FLAG_MULTISELECT;
  1183. InitInfo.cAttributesToFetch = 1;
  1184. LPCWSTR lpszObjectSID = L"objectSid";
  1185. InitInfo.apwzAttributeNames = const_cast<LPCTSTR *>(&lpszObjectSID);
  1186. TRACE(L"InitInfo.cbSize = %d\n", InitInfo.cbSize);
  1187. TRACE(L"InitInfo.pwzTargetComputer = %s\n", InitInfo.pwzTargetComputer);
  1188. TRACE(L"InitInfo.cDsScopeInfos = %d\n", InitInfo.cDsScopeInfos);
  1189. TRACE(L"InitInfo.aDsScopeInfos = 0x%x\n", InitInfo.aDsScopeInfos);
  1190. TRACE(L"InitInfo.flOptions = 0x%x\n", InitInfo.flOptions);
  1191. TRACE(L"InitInfo.cAttributesToFetch = %d\n", InitInfo.cAttributesToFetch);
  1192. TRACE(L"InitInfo.apwzAttributeNames[0]= %s\n", InitInfo.apwzAttributeNames[0]);
  1193. // initialize object picker
  1194. hr = spDsObjectPicker->Initialize(&InitInfo);
  1195. if (FAILED(hr))
  1196. {
  1197. TRACE(L"spDsObjectPicker->Initialize(...) failed, hr = 0x%x\n");
  1198. return hr;
  1199. }
  1200. // invoke the dialog
  1201. CComPtr<IDataObject> spdoSelections;
  1202. hr = spDsObjectPicker->InvokeDialog(m_hWnd, &spdoSelections);
  1203. if (hr == S_FALSE || !spdoSelections)
  1204. {
  1205. return S_FALSE;
  1206. }
  1207. // retrieve data from data object
  1208. FORMATETC fmte = {(CLIPFORMAT)_Module.GetCfDsopSelectionList(), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  1209. STGMEDIUM medium = {TYMED_NULL, NULL, NULL};
  1210. PDS_SELECTION_LIST pDsSelList = NULL;
  1211. hr = spdoSelections->GetData(&fmte, &medium);
  1212. if (FAILED(hr))
  1213. {
  1214. TRACE(L"spdoSelections->GetData(...) failed, hr = 0x%x\n");
  1215. return hr;
  1216. }
  1217. pDsSelList = (PDS_SELECTION_LIST)GlobalLock(medium.hGlobal);
  1218. hr = AddPrincipalsFromBrowseResults(pListViewHelper, pDsSelList);
  1219. GlobalUnlock(medium.hGlobal);
  1220. ReleaseStgMedium(&medium);
  1221. return hr;
  1222. }
  1223. BOOL CDelegWiz::DeletePrincipals(CPrincipalListViewHelper* pListViewHelper)
  1224. {
  1225. CGrowableArr<CPrincipal> deletedArr(FALSE); // do not own memory
  1226. // remove from listview
  1227. pListViewHelper->DeleteSelectedItems(&deletedArr);
  1228. // remove from list of items
  1229. int nDeletedCount = deletedArr.GetCount();
  1230. for (int k=0; k<nDeletedCount; k++)
  1231. {
  1232. m_principalList.Remove(deletedArr[k]);
  1233. }
  1234. //pListViewHelper->UpdateWidth(m_principalList.GetMaxListboxExtent());
  1235. return TRUE;
  1236. }
  1237. int CDelegWiz::FillCustomSchemaClassesListView(CCheckListViewHelper* pListViewHelper, BOOL bFilter)
  1238. {
  1239. // clear old entries
  1240. pListViewHelper->DeleteAllItems();
  1241. int nCount = m_schemaClassInfoArray.GetCount();
  1242. if (nCount == 0)
  1243. return 0; // no insertions, nothing else to do
  1244. // figure out the max len of items to get a big enough buffer
  1245. int nMaxLen = 0;
  1246. int nCurrLen = 0;
  1247. for (long index = 0; index < nCount; index++)
  1248. {
  1249. nCurrLen = lstrlen(m_schemaClassInfoArray[index]->GetDisplayName());
  1250. if (nCurrLen > nMaxLen)
  1251. nMaxLen = nCurrLen;
  1252. }
  1253. CWString szFormat;
  1254. szFormat.LoadFromResource(IDS_DELEGWIZ_CHILD_CLASS_FMT);
  1255. WCHAR* pwszNewText = (WCHAR*)alloca(sizeof(WCHAR)*(szFormat.size()+nMaxLen+1));
  1256. // add formatted entries, assume listbox not sorted
  1257. long iListBoxItem = 0;
  1258. for (index = 0; index < nCount; index++)
  1259. {
  1260. CSchemaClassInfo* pChildClassInfo = m_schemaClassInfoArray[index];
  1261. pChildClassInfo->m_bSelected = FALSE;
  1262. if (bFilter && pChildClassInfo->IsFiltered())
  1263. continue;
  1264. wsprintf(pwszNewText, (LPCWSTR)szFormat, pChildClassInfo->GetDisplayName());
  1265. pListViewHelper->InsertItem(iListBoxItem, pwszNewText, (LPARAM)pChildClassInfo, FALSE);
  1266. iListBoxItem++;
  1267. }
  1268. return iListBoxItem; // return the # of items inserted
  1269. }
  1270. BOOL CDelegWiz::SetSchemaClassesSelectionCustom()
  1271. {
  1272. int nSelCount = 0;
  1273. int nCount = m_schemaClassInfoArray.GetCount();
  1274. CComPtr<IADsClass> spSchemaObjectClass;
  1275. m_bChildClass = FALSE;
  1276. // get the selection count
  1277. int nSingleSel = -1;
  1278. for (int k=0; k < nCount; k++)
  1279. {
  1280. if (m_schemaClassInfoArray[k]->m_bSelected)
  1281. {
  1282. if( m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_NOT_CALCULATED )
  1283. {
  1284. if (m_schemaClassInfoArray[k]->GetName() != NULL)
  1285. {
  1286. int nServerNameLen = lstrlen(m_adsiObject.GetServerName());
  1287. int nClassNameLen = lstrlen(m_schemaClassInfoArray[k]->GetName());
  1288. int nFormatStringLen = lstrlen(g_wzLDAPAbstractSchemaFormat);
  1289. VARIANT var = {0};
  1290. // build the LDAP path for the schema class
  1291. WCHAR* pwszSchemaObjectPath =
  1292. (WCHAR*)alloca(sizeof(WCHAR)*(nServerNameLen+nClassNameLen+nFormatStringLen+1));
  1293. wsprintf(pwszSchemaObjectPath, g_wzLDAPAbstractSchemaFormat, m_adsiObject.GetServerName(), m_schemaClassInfoArray[k]->GetName());
  1294. // get the schema class ADSI object
  1295. HRESULT hr = ::ADsOpenObjectHelper(pwszSchemaObjectPath,
  1296. IID_IADsClass, (void**)&spSchemaObjectClass);
  1297. if (FAILED(hr))
  1298. return hr;
  1299. spSchemaObjectClass->get_Containment(&var);
  1300. if (V_VT(&var) == (VT_ARRAY | VT_VARIANT))
  1301. {
  1302. LPSAFEARRAY psa = V_ARRAY(&var);
  1303. ASSERT(psa && psa->cDims == 1);
  1304. if (psa->rgsabound[0].cElements > 0)
  1305. {
  1306. m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_EXIST;
  1307. }
  1308. else
  1309. m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_NOT_EXIST;
  1310. }
  1311. else if (V_VT(&var) == VT_BSTR) // single entry
  1312. {
  1313. m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_EXIST;
  1314. }
  1315. else
  1316. m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_NOT_EXIST;
  1317. VariantClear(&var);
  1318. }
  1319. }
  1320. if( m_schemaClassInfoArray[k]->m_dwChildClass != CHILD_CLASS_NOT_EXIST )
  1321. m_bChildClass = TRUE;
  1322. if (nSingleSel == -1)
  1323. nSingleSel = k;
  1324. nSelCount++;
  1325. }
  1326. }
  1327. if (nSelCount == 0)
  1328. {
  1329. m_nSchemaClassesSel = nSchemaClassesSelAll;
  1330. m_bChildClass = TRUE;
  1331. return TRUE; // delegate control to all types
  1332. }
  1333. // keep track if it is a single selection
  1334. if (nSelCount == 1)
  1335. {
  1336. ASSERT(nSingleSel != -1);
  1337. m_nSchemaClassesSel = nSingleSel;
  1338. return TRUE;
  1339. }
  1340. // multiple selection
  1341. m_nSchemaClassesSel = nSchemaClassesSelMultiple;
  1342. return TRUE;
  1343. }
  1344. void CDelegWiz::DeselectSchemaClassesSelectionCustom()
  1345. {
  1346. int nCount = m_schemaClassInfoArray.GetCount();
  1347. for (int k=0; k < nCount; k++)
  1348. {
  1349. m_schemaClassInfoArray[k]->m_bSelected = FALSE;
  1350. }
  1351. }
  1352. BOOL CDelegWiz::GetCustomAccessPermissions()
  1353. {
  1354. // remove all the old entries
  1355. m_permissionHolder.Clear();
  1356. // retrieve the string for the child class object type (single selection)
  1357. // for multiple selection, it will be NULL
  1358. CSchemaClassInfo* pClassInfo = NULL;
  1359. switch (m_nSchemaClassesSel)
  1360. {
  1361. case nSchemaClassesSelMultiple:
  1362. {
  1363. // for multiple selection, it will be NULL
  1364. pClassInfo = NULL;
  1365. }
  1366. break;
  1367. case nSchemaClassesSelAll:
  1368. {
  1369. // just get the class name of the object we want to delegate rights on
  1370. // need to find matching class in the schema info array
  1371. for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++)
  1372. {
  1373. if (_wcsicmp(m_schemaClassInfoArray[k]->GetName(), m_adsiObject.GetClass()) == 0)
  1374. {
  1375. pClassInfo = m_schemaClassInfoArray[k];
  1376. break;
  1377. }
  1378. } // for k
  1379. ASSERT(pClassInfo != NULL);
  1380. }
  1381. break;
  1382. default:
  1383. {
  1384. // single selection
  1385. ASSERT( (m_nSchemaClassesSel >= 0) &&
  1386. (m_nSchemaClassesSel < m_schemaClassInfoArray.GetCount()) );
  1387. pClassInfo = m_schemaClassInfoArray[m_nSchemaClassesSel];
  1388. }
  1389. } // switch
  1390. // get the permissions from the DS
  1391. LPCWSTR lpszClassName = NULL;
  1392. const GUID* pSchemaIDGUID = NULL;
  1393. if (pClassInfo != NULL)
  1394. {
  1395. lpszClassName = pClassInfo->GetName();
  1396. pSchemaIDGUID = pClassInfo->GetSchemaGUID();
  1397. }
  1398. HRESULT hr = m_permissionHolder.ReadDataFromDS(&m_adsiObject,
  1399. m_adsiObject.GetNamingContext(),
  1400. lpszClassName,
  1401. pSchemaIDGUID,
  1402. m_bChildClass,
  1403. HideListObjectAccess());
  1404. if (FAILED(hr))
  1405. {
  1406. WizReportHRESULTError(IDS_DELEGWIZ_ERR_PERMISSIONS, hr);
  1407. return FALSE;
  1408. }
  1409. return TRUE;
  1410. }
  1411. void CDelegWiz::FillCustomAccessRightsListView(CCheckListViewHelper* pListViewHelper,
  1412. ULONG nFilterState)
  1413. {
  1414. // clear check list
  1415. pListViewHelper->DeleteAllItems();
  1416. m_permissionHolder.FillAccessRightsListView(pListViewHelper, nFilterState);
  1417. }
  1418. void CDelegWiz::UpdateAccessRightsListViewSelection(
  1419. CCheckListViewHelper* pListViewHelper,
  1420. ULONG nFilterState)
  1421. {
  1422. m_permissionHolder.UpdateAccessRightsListViewSelection(
  1423. pListViewHelper, nFilterState);
  1424. }
  1425. BOOL CDelegWiz::HasPermissionSelectedCustom()
  1426. {
  1427. return m_permissionHolder.HasPermissionSelected();
  1428. }
  1429. void CDelegWiz::OnCustomAccessRightsCheckListClick(
  1430. CRigthsListViewItem* pItem,
  1431. BOOL bSelected,
  1432. ULONG* pnNewFilterState)
  1433. {
  1434. m_permissionHolder.Select(pItem, bSelected, pnNewFilterState);
  1435. }
  1436. void CDelegWiz::WriteSummaryInfoCustom(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine)
  1437. {
  1438. // write object name and principals
  1439. WriteSummaryInfoHelper(szSummary, lpszIdent, lpszNewLine);
  1440. // write the list of rights
  1441. m_permissionHolder.WriteSummary(szSummary, lpszIdent, lpszNewLine);
  1442. // write the list of child classes (if applicable)
  1443. if (m_nSchemaClassesSel != nSchemaClassesSelAll)
  1444. {
  1445. WriteSummaryTitleLine(szSummary, IDS_DELEGWIZ_FINISH_OBJECT, lpszNewLine);
  1446. for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++)
  1447. {
  1448. if (m_schemaClassInfoArray[k]->m_bSelected)
  1449. {
  1450. WriteSummaryLine(szSummary, m_schemaClassInfoArray[k]->GetDisplayName(), lpszIdent, lpszNewLine);
  1451. }
  1452. }
  1453. szSummary += lpszNewLine;
  1454. } // if
  1455. }
  1456. BOOL CDelegWiz::InitPermissionHoldersFromSelectedTemplates()
  1457. {
  1458. if (!m_templateAccessPermissionsHolderManager.InitPermissionHoldersFromSelectedTemplates(
  1459. &m_schemaClassInfoArray, &m_adsiObject))
  1460. {
  1461. // error: no valid and applicable data has been retrieved from the selected
  1462. // templates
  1463. return FALSE;
  1464. }
  1465. return TRUE;
  1466. }
  1467. void CDelegWiz::WriteSummaryInfoTemplate(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine)
  1468. {
  1469. // write object name and principals
  1470. WriteSummaryInfoHelper(szSummary,lpszIdent, lpszNewLine);
  1471. // write the list of templates
  1472. m_templateAccessPermissionsHolderManager.WriteSummary(szSummary, lpszIdent, lpszNewLine);
  1473. }
  1474. void CDelegWiz::WriteSummaryInfoHelper(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine)
  1475. {
  1476. // set the canonical name
  1477. WriteSummaryTitleLine(szSummary, IDS_DELEGWIZ_FINISH_FOLDER, lpszNewLine);
  1478. WriteSummaryLine(szSummary, GetCanonicalName(), lpszIdent, lpszNewLine);
  1479. szSummary += lpszNewLine;
  1480. // write the list of principals
  1481. m_principalList.WriteSummaryInfo(szSummary, lpszIdent, lpszNewLine);
  1482. }
  1483. /*
  1484. typedef struct _ACTRL_ACCESS_ENTRYW
  1485. {
  1486. TRUSTEE_W Trustee;
  1487. ULONG fAccessFlags;
  1488. ACCESS_RIGHTS Access;
  1489. ACCESS_RIGHTS ProvSpecificAccess;
  1490. INHERIT_FLAGS Inheritance;
  1491. LPWSTR lpInheritProperty;
  1492. } ACTRL_ACCESS_ENTRYW, *PACTRL_ACCESS_ENTRYW;
  1493. */
  1494. DWORD CDelegWiz::UpdateAccessList(CPrincipal* pPrincipal,
  1495. CSchemaClassInfo* pClassInfo,
  1496. PACL *ppAcl)
  1497. {
  1498. return m_permissionHolder.UpdateAccessList(
  1499. pPrincipal, pClassInfo,
  1500. m_adsiObject.GetServerName(),
  1501. m_adsiObject.GetPhysicalSchemaNamingContext(),
  1502. ppAcl);
  1503. }
  1504. DWORD CDelegWiz::BuildNewAccessListCustom(PACL *ppNewAcl)
  1505. {
  1506. DWORD dwErr = 0;
  1507. TRACE(L"BuildNewAccessListCustom()\n");
  1508. // loop thru all the principals and classes
  1509. CPrincipalList::iterator i;
  1510. for (i = m_principalList.begin(); i != m_principalList.end(); ++i)
  1511. {
  1512. CPrincipal* pCurrPrincipal = *i;
  1513. if (m_nSchemaClassesSel == nSchemaClassesSelAll)
  1514. {
  1515. // delegate on all objects
  1516. dwErr = UpdateAccessList(
  1517. pCurrPrincipal,
  1518. NULL, // all classes
  1519. ppNewAcl);
  1520. if (dwErr != ERROR_SUCCESS)
  1521. return dwErr;
  1522. }
  1523. else if (m_nSchemaClassesSel == nSchemaClassesSelMultiple)
  1524. {
  1525. // delegate on multiple objects
  1526. // multiple selection, loop thru each class to
  1527. // add rights for each
  1528. for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++)
  1529. {
  1530. if (m_schemaClassInfoArray[k]->m_bSelected)
  1531. {
  1532. dwErr = UpdateAccessList(
  1533. pCurrPrincipal,
  1534. m_schemaClassInfoArray[k],
  1535. ppNewAcl);
  1536. if (dwErr != ERROR_SUCCESS)
  1537. return dwErr;
  1538. if( m_fCreateDelChild != 0 )
  1539. {
  1540. dwErr = ::AddObjectRightInAcl( pCurrPrincipal->GetSid(),
  1541. m_fCreateDelChild,
  1542. m_schemaClassInfoArray[k]->GetSchemaGUID(),
  1543. NULL,
  1544. ppNewAcl);
  1545. if (dwErr != ERROR_SUCCESS)
  1546. return dwErr;
  1547. }
  1548. }
  1549. } // for k
  1550. }
  1551. else
  1552. {
  1553. // single selection on child classes
  1554. dwErr = UpdateAccessList(
  1555. pCurrPrincipal,
  1556. m_schemaClassInfoArray[m_nSchemaClassesSel],
  1557. ppNewAcl);
  1558. if (dwErr != ERROR_SUCCESS)
  1559. return dwErr;
  1560. if( m_fCreateDelChild != 0 )
  1561. {
  1562. dwErr = ::AddObjectRightInAcl( pCurrPrincipal->GetSid(),
  1563. m_fCreateDelChild,
  1564. m_schemaClassInfoArray[m_nSchemaClassesSel]->GetSchemaGUID(),
  1565. NULL,
  1566. ppNewAcl);
  1567. if (dwErr != ERROR_SUCCESS)
  1568. return dwErr;
  1569. }
  1570. }
  1571. } // for pCurrPrincipal
  1572. return dwErr;
  1573. }
  1574. DWORD CDelegWiz::BuildNewAccessListTemplate(PACL *ppNewAcl)
  1575. {
  1576. DWORD dwErr = 0;
  1577. TRACE(L"BuildNewAccessListTemplate()\n");
  1578. // loop thru all the principals and classes
  1579. CPrincipalList::iterator i;
  1580. for (i = m_principalList.begin(); i != m_principalList.end(); ++i)
  1581. {
  1582. CPrincipal* pCurrPrincipal = *i;
  1583. dwErr = m_templateAccessPermissionsHolderManager.UpdateAccessList(
  1584. pCurrPrincipal,
  1585. m_adsiObject.GetServerName(),
  1586. m_adsiObject.GetPhysicalSchemaNamingContext(),
  1587. ppNewAcl);
  1588. if (dwErr != 0)
  1589. break;
  1590. } // for pCurrPrincipal
  1591. return dwErr;
  1592. }
  1593. BOOL CDelegWiz::FinishHelper(BOOL bCustom)
  1594. {
  1595. BOOL bRetVal = FALSE;
  1596. DWORD dwErr = 0;
  1597. PACL pDacl = NULL;
  1598. PACL pOldAcl = NULL;
  1599. PSECURITY_DESCRIPTOR pSD = NULL;
  1600. LPCWSTR lpszObjectLdapPath = m_adsiObject.GetLdapPath();
  1601. // get the security info
  1602. TRACE(L"calling GetNamedSecurityInfo(%s, ...)\n", lpszObjectLdapPath);
  1603. dwErr = ::GetNamedSecurityInfo(IN const_cast<LPWSTR>(lpszObjectLdapPath),
  1604. IN SE_DS_OBJECT_ALL,
  1605. IN DACL_SECURITY_INFORMATION,
  1606. OUT NULL,
  1607. OUT NULL,
  1608. OUT &pDacl,
  1609. OUT NULL,
  1610. OUT &pSD);
  1611. TRACE(L"GetNamedSecurityInfo() returned dwErr = 0x%x\n", dwErr);
  1612. if (dwErr != ERROR_SUCCESS)
  1613. {
  1614. TRACE(L"failed on GetNamedSecurityInfo(): dwErr = 0x%x\n", dwErr);
  1615. WCHAR szMsg[512];
  1616. LoadStringHelper(IDS_DELEGWIZ_ERR_GET_SEC_INFO, szMsg, 512);
  1617. WizReportWin32Error(szMsg, dwErr);
  1618. goto exit;
  1619. }
  1620. //pOldAcl is passed to functions which free it. pDacl cannot be
  1621. //passed as pSD should be freed , not pDacl. Instead of changing code
  1622. //to pass pSD, i am changing it to make a copy of pDacl which can
  1623. //be correctly freed.
  1624. if(pDacl)
  1625. {
  1626. pOldAcl = (PACL)LocalAlloc(LPTR, pDacl->AclSize);
  1627. if(!pOldAcl)
  1628. return FALSE;
  1629. memcpy(pOldAcl, pDacl,pDacl->AclSize);
  1630. }
  1631. LocalFree(pSD);
  1632. pSD = NULL;
  1633. pDacl = NULL;
  1634. // build the new Access List
  1635. if (bCustom)
  1636. {
  1637. dwErr = BuildNewAccessListCustom(&pOldAcl); // in/out parameter
  1638. }
  1639. else
  1640. {
  1641. dwErr = BuildNewAccessListTemplate(&pOldAcl); // in/out parameter
  1642. }
  1643. if (dwErr != ERROR_SUCCESS)
  1644. {
  1645. TRACE(_T("failed on BuildNewAccessListXXX()\n"));
  1646. WCHAR szMsg[512];
  1647. LoadStringHelper(IDS_DELEGWIZ_ERR_EDIT_SEC_INFO, szMsg, 512);
  1648. WizReportWin32Error(szMsg, dwErr);
  1649. goto exit;
  1650. }
  1651. // commit changes
  1652. TRACE(L"calling SetNamedSecurityInfo(%s, ...)\n", lpszObjectLdapPath);
  1653. dwErr = ::SetNamedSecurityInfo(IN const_cast<LPWSTR>(lpszObjectLdapPath),
  1654. IN SE_DS_OBJECT_ALL,
  1655. IN DACL_SECURITY_INFORMATION,
  1656. IN NULL,
  1657. IN NULL,
  1658. IN pOldAcl,
  1659. IN NULL);
  1660. TRACE(L"SetNamedSecurityInfo() returned dwErr = 0x%x\n", dwErr);
  1661. if (dwErr != ERROR_SUCCESS)
  1662. {
  1663. TRACE(L"failed on SetNamedSecurityInfo(): dwErr = 0x%x\n", dwErr);
  1664. WCHAR szMsg[512];
  1665. if(dwErr == ERROR_ACCESS_DENIED)
  1666. LoadStringHelper(IDS_DELEGWIZ_ERR_ACCESS_DENIED, szMsg, 512);
  1667. else
  1668. LoadStringHelper(IDS_DELEGWIZ_ERR_SET_SEC_INFO, szMsg, 512);
  1669. WizReportWin32Error(szMsg, dwErr);
  1670. goto exit;
  1671. }
  1672. bRetVal = TRUE;
  1673. exit:
  1674. // cleanup memory
  1675. if (pOldAcl != NULL)
  1676. ::LocalFree(pOldAcl);
  1677. return bRetVal;
  1678. }