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.

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