|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: delegwiz.cpp
//
//--------------------------------------------------------------------------
#include "pch.h"
#include "wizbase.h"
#include "util.h"
#include <initguid.h>
#include <cmnquery.h> // ICommonQuery
#include <dsquery.h>
#include <dsclient.h>
#include "resource.h"
#include "dsuiwiz.h"
#include "delegWiz.h"
#define GET_OU_WIZARD() ((CDelegWiz*)GetWizard())
/////////////////////////////////////////////////////////////////////////////
void InitBigBoldFont(HWND hWnd, HFONT& hFont) { ASSERT(::IsWindow(hWnd));
NONCLIENTMETRICS ncm; memset(&ncm, 0, sizeof(ncm)); ncm.cbSize = sizeof(ncm); ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
LOGFONT boldLogFont = ncm.lfMessageFont; boldLogFont.lfWeight = FW_BOLD;
// load big font definition from resources
WCHAR szFontName[LF_FACESIZE]; if (0 == ::LoadString(_Module.GetResourceInstance(), IDS_BIG_BOLD_FONT_NAME, boldLogFont.lfFaceName, LF_FACESIZE)) { // set to default of failed to load
wcscpy(boldLogFont.lfFaceName, L"Verdana Bold"); // LF_FACESIZE == 32
} WCHAR szFontSize[128]; int nFontSize = 0; if (0 != ::LoadString(_Module.GetResourceInstance(), IDS_BIG_BOLD_FONT_SIZE, szFontSize, sizeof(szFontSize)/sizeof(WCHAR))) { nFontSize = _wtoi(szFontSize); } if (nFontSize == 0) nFontSize = 12; // default
HDC hdc = ::GetDC(hWnd); //Bug fix 447884
if( hdc ) {
boldLogFont.lfHeight = 0 - (::GetDeviceCaps(hdc, LOGPIXELSY) * nFontSize / 72);
hFont = ::CreateFontIndirect((const LOGFONT*)(&boldLogFont));
::ReleaseDC(hWnd, hdc); } }
void SetLargeFont(HWND hWndDialog, int nControlID) { ASSERT(::IsWindow(hWndDialog)); ASSERT(nControlID);
static HFONT boldLogFont = 0; if (boldLogFont == 0) { InitBigBoldFont(hWndDialog, boldLogFont); }
HWND hWndControl = ::GetDlgItem(hWndDialog, nControlID);
if (hWndControl) { ::SendMessage(hWndControl, WM_SETFONT, (WPARAM)boldLogFont, MAKELPARAM(TRUE, 0)); } }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_StartPage
BOOL CDelegWiz_StartPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD(); pWizard->SetWizardButtonsFirst(TRUE); return TRUE; }
BOOL CALLBACK CDelegWiz_StartPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SetLargeFont(m_hWnd, IDC_STATIC_WELCOME);
return TRUE; }
#ifdef _SKIP_NAME_PAGE
LRESULT CDelegWiz_StartPage::OnWizardNext() { BOOL bSuccess = TRUE; HRESULT hr = S_OK; CDelegWiz* pWiz = GET_OU_WIZARD();
// if we do not have an object, we will browse from the next page
if (!pWiz->CanChangeName() && !m_bBindOK) { // make sure it exists and it is of the right type
{ // scope to restore cursor
CWaitCursor wait; hr = pWiz->GetObjectInfo(); }
if (FAILED(hr)) { WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256); WCHAR szMsg[512]; if(SUCCEEDED(StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(WCHAR),szFmt, pWiz->GetCanonicalName()))) { pWiz->WizReportHRESULTError(szMsg, hr); } goto error; }
{ // scope to restore cursor
CWaitCursor wait; hr = pWiz->GetClassInfoFromSchema(); }
if (FAILED(hr)) { WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_INFO, szFmt, 256); WCHAR szMsg[512]; if(SUCCEEDED(StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(WCHAR),szFmt, pWiz->GetCanonicalName()))) { pWiz->WizReportHRESULTError(szMsg, hr); } goto error; }
// all fine, we do not need to do it anymore
m_bBindOK = TRUE; }
OnWizardNextHelper(); return 0; // all fine, go to next page
error: pWiz->SetWizardButtonsFirst(FALSE); return -1; // do not advance
}
#endif
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_NamePage
BOOL CALLBACK CDelegWiz_NamePage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { BOOL bRes = TRUE;
CDelegWiz* pWiz = GET_OU_WIZARD(); m_hwndNameEdit = GetDlgItem(IDC_OBJ_NAME_EDIT);
if (!pWiz->CanChangeName()) // called on a given object
{ // hide static text that gives instructions
HWND hwndNameStatic = GetDlgItem(IDC_OBJ_NAME_STATIC); ::ShowWindow(hwndNameStatic, FALSE);
// change text to the editbox
HWND hwndNameEditStatic = GetDlgItem(IDC_OBJ_NAME_EDIT_STATIC); CWString szLabel; szLabel.LoadFromResource(IDS_OBJ_NAME_EDIT_STATIC); ::SendMessage(hwndNameEditStatic, WM_SETTEXT,0 , (LPARAM)(LPCWSTR)szLabel);
// remove the tabstop flag from the Edit Box
LONG style = ::GetWindowLong(m_hwndNameEdit, GWL_STYLE); style &= ~WS_TABSTOP; ::SetWindowLong(m_hwndNameEdit, GWL_STYLE, style); // make the Edit Box Read Only
::SendMessage(m_hwndNameEdit, EM_SETREADONLY, TRUE, 0L);
// disable and hide the Browse Button
HWND hWndBrowseButton = GetDlgItem(IDC_BROWSE_BUTTON); ::EnableWindow(hWndBrowseButton, FALSE); ::ShowWindow(hWndBrowseButton, FALSE);
bRes = FALSE; } return bRes; }
LRESULT CDelegWiz_NamePage::OnBrowse(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { // load resources to customize dialog
TCHAR szCaption[256]; LoadStringHelper(IDS_DELEGWIZ_BROWSE_CONTAINER_CAPTION, szCaption, ARRAYSIZE(szCaption)); TCHAR szTitle[256]; LoadStringHelper(IDS_DELEGWIZ_BROWSE_CONTAINER_TITLE, szTitle, ARRAYSIZE(szTitle));
// set dialog struct
TCHAR szPath[MAX_PATH+1]; szPath[0] = NULL; DSBROWSEINFO dsbi; ::ZeroMemory( &dsbi, sizeof(dsbi) );
dsbi.cbStruct = sizeof(DSBROWSEINFO); dsbi.hwndOwner = m_hWnd; dsbi.pszCaption = szCaption; dsbi.pszTitle = szTitle; dsbi.pszRoot = NULL; // ADS path to root (NULL == root of DS namespace)
dsbi.pszPath = szPath; dsbi.cchPath = (sizeof(szPath) / sizeof(TCHAR)); dsbi.dwFlags = DSBI_ENTIREDIRECTORY;
// REVIEW_MARCOC: need to determine how to show/hide hidden folders
dsbi.dwFlags |= DSBI_INCLUDEHIDDEN; //m_fBrowseHiddenFolders ? DSBI_INCLUDEHIDDEN : 0;
dsbi.pfnCallback = NULL; dsbi.lParam = 0;
// make the call to the dialog
int iRet = ::DsBrowseForContainer( &dsbi );
if ( IDOK == iRet ) { // returns -1, 0, IDOK or IDCANCEL
// get path from BROWSEINFO struct, put in text edit field
//TRACE(_T("returned from DS Browse successfully with:\n %s\n"),
// dsbi.pszPath);
::SetWindowText(m_hwndNameEdit, szPath); }
return 1; }
BOOL CDelegWiz_NamePage::OnSetActive() { CDelegWiz* pWiz = GET_OU_WIZARD();
#ifdef _SKIP_NAME_PAGE
if (!pWiz->CanChangeName()) { // just cause the page to fail, so that we skip it
return FALSE; } #endif
HRESULT hr = S_OK; if (pWiz->m_bFwd && !pWiz->CanChangeName()) // called on a given object
{ // need to bind now to get the needed data
hr = pWiz->GetObjectInfo(); if (SUCCEEDED(hr)) { // set the name of the object in the Edit Box
::SendMessage(m_hwndNameEdit, WM_SETTEXT, 0, (LPARAM)pWiz->GetCanonicalName()); } else { WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256); WCHAR szMsg[512]; if(SUCCEEDED(StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(WCHAR),szFmt, pWiz->GetCanonicalName()))) { pWiz->WizReportHRESULTError(szMsg, hr); } } }
pWiz->SetWizardButtonsMiddle(SUCCEEDED(hr)); return TRUE; }
LRESULT CDelegWiz_NamePage::OnWizardNext() { BOOL bSuccess = TRUE; HRESULT hr = S_OK; CDelegWiz* pWiz = GET_OU_WIZARD(); if (pWiz->CanChangeName()) { // retrieve name from the edit control
int nEditTextLen = ::SendMessage(m_hwndNameEdit, WM_GETTEXTLENGTH,0,0) + 1;// count NULL
TCHAR* lpszName = (TCHAR*)alloca(sizeof(TCHAR)*(nEditTextLen)); ::SendMessage(m_hwndNameEdit, WM_GETTEXT, (WPARAM)nEditTextLen, (LPARAM)lpszName);
// this will get the equivalent LDAP path
pWiz->SetName(lpszName); // make sure it exists and it is of the right type
{ // scope to restore cursor
CWaitCursor wait; hr = pWiz->GetObjectInfo(); } if (FAILED(hr)) { WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_NAME, szFmt, 256); WCHAR szMsg[512]; if(SUCCEEDED(StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(WCHAR),szFmt, pWiz->GetCanonicalName()))) { pWiz->WizReportHRESULTError(szMsg, hr); } goto error; } } // if can change name
{ // scope to restore cursor
CWaitCursor wait; hr = pWiz->GetClassInfoFromSchema(); }
if (FAILED(hr)) { WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_OBJ_INFO, szFmt, 256); WCHAR szMsg[512]; if(SUCCEEDED(StringCchPrintf(szMsg, sizeof(szMsg)/sizeof(WCHAR),szFmt, pWiz->GetCanonicalName()))) { pWiz->WizReportHRESULTError(szMsg, hr); } goto error; }
OnWizardNextHelper(); return 0; // all fine, go to next page
error: pWiz->SetWizardButtonsMiddle(FALSE); return -1; // do not advance
}
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_DelegationTemplateSelectionPage
BOOL CALLBACK CDelegWiz_DelegationTemplateSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { m_delegationTemplatesListView.Initialize(IDC_DELEGATE_TEMPLATE_LIST, m_hWnd); // set the correct value for radiobuttons text
m_hwndDelegateTemplateRadio = GetDlgItem(IDC_DELEGATE_TEMPLATE_RADIO); _ASSERTE(m_hwndDelegateTemplateRadio != NULL); m_hwndDelegateCustomRadio = GetDlgItem(IDC_DELEGATE_CUSTOM_RADIO); _ASSERTE(m_hwndDelegateCustomRadio != NULL); // set default setting
::SendMessage(m_hwndDelegateTemplateRadio, BM_SETCHECK, BST_CHECKED, 0);
return TRUE; }
LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnDelegateTypeRadioChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SyncControlsHelper(IDC_DELEGATE_CUSTOM_RADIO == wID); return 1; }
LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh; if (CCheckListViewHelper::CheckChanged(pNMListView)) { int nSelCount = m_delegationTemplatesListView.GetCheckCount(); GET_OU_WIZARD()->SetWizardButtonsMiddle(nSelCount > 0); } return 1; }
BOOL CDelegWiz_DelegationTemplateSelectionPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD(); BOOL bRetVal = TRUE; BOOL bDelegateCustom = (BST_CHECKED == ::SendMessage(m_hwndDelegateCustomRadio, BM_GETCHECK,0,0));
if (pWizard->m_bFwd) { // need to fill in with data
BOOL bHaveTemplates = pWizard->m_templateAccessPermissionsHolderManager.FillTemplatesListView( &m_delegationTemplatesListView, pWizard->GetClass())> 0; if (!bDelegateCustom && !bHaveTemplates) { ::SendMessage(m_hwndDelegateCustomRadio, BM_SETCHECK,BST_CHECKED,0); ::SendMessage(m_hwndDelegateTemplateRadio, BM_SETCHECK,BST_UNCHECKED,0); bDelegateCustom = TRUE; } SyncControlsHelper(bDelegateCustom); } else { // data already in, just coming back from next page
if (bDelegateCustom) { pWizard->SetWizardButtonsMiddle(TRUE); } else { int nSelCount = m_delegationTemplatesListView.GetCheckCount(); pWizard->SetWizardButtonsMiddle(nSelCount > 0); } } return TRUE; }
LRESULT CDelegWiz_DelegationTemplateSelectionPage::OnWizardNext() { HRESULT hr = S_OK; int nSelCount = -1; int* nSelArray = NULL; BOOL bCanAdvance = FALSE;
CDelegWiz* pWiz = GET_OU_WIZARD();
// check if the delegation is on all objects
BOOL bCustom = TRUE; UINT nNextPageID = 0; if (BST_CHECKED == ::SendMessage(m_hwndDelegateCustomRadio, BM_GETCHECK,0,0)) { nSelCount = 0; nSelArray = NULL; bCanAdvance = TRUE; } else { ASSERT(BST_CHECKED == ::SendMessage(m_hwndDelegateTemplateRadio, BM_GETCHECK,0,0)); bCustom = FALSE;
nSelCount = 0; int nCount = m_delegationTemplatesListView.GetItemCount(); for (int k=0; k<nCount; k++) { CTemplate* pTempl = (CTemplate*)m_delegationTemplatesListView.GetItemData(k); pTempl->m_bSelected = m_delegationTemplatesListView.IsItemChecked(k); if (pTempl->m_bSelected) nSelCount++; }
bCanAdvance = (nSelCount > 0); }
if (!bCanAdvance) goto error;
// set branching info
if (bCustom) { // just move to the next custom page
nNextPageID = CDelegWiz_ObjectTypeSelectionPage::IDD; pWiz->m_objectTypeSelectionPage.m_nPrevPageID = IDD; pWiz->m_finishPage.m_nPrevPageID = CDelegWiz_DelegatedRightsPage::IDD; pWiz->m_finishPage.SetCustom(); } else { // need to gather info for the selected templates
{ // scope to restore cursor
CWaitCursor wait;
if (!pWiz->InitPermissionHoldersFromSelectedTemplates()) { // REVIEW_MARCOC: need to give a message to the user
pWiz->WizMessageBox(IDS_DELEGWIZ_ERR_TEMPL_APPLY); goto error; } }
// got info, can proceed
nNextPageID = CDelegWiz_FinishPage::IDD; pWiz->m_finishPage.m_nPrevPageID = IDD; pWiz->m_finishPage.SetTemplate(); } OnWizardNextHelper();
return nNextPageID; // advance next
error: // do not advance, error
pWiz->SetWizardButtonsMiddle(FALSE); return -1; }
void CDelegWiz_DelegationTemplateSelectionPage::SyncControlsHelper(BOOL bDelegateCustom) { CDelegWiz* pWiz = GET_OU_WIZARD(); // uncheck all items in the listview if delegating custom
if (bDelegateCustom) { m_delegationTemplatesListView.SetCheckAll(FALSE); pWiz->m_templateAccessPermissionsHolderManager.DeselectAll(); // in the list templates
}
// disable listbox if "delegate custom"
m_delegationTemplatesListView.EnableWindow(!bDelegateCustom);
// enable "Wizard Next"
BOOL bEnableNext = bDelegateCustom ? TRUE : (m_delegationTemplatesListView.GetCheckCount() > 0);
pWiz->SetWizardButtonsMiddle(bEnableNext); }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_ObjectTypeSelectionPage
BOOL CALLBACK CDelegWiz_ObjectTypeSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { m_objectTypeListView.Initialize(IDC_OBJ_TYPE_LIST, m_hWnd); // set the correct value for radiobuttons text
m_hwndDelegateAllRadio = GetDlgItem(IDC_DELEGATE_ALL_RADIO); ASSERT(m_hwndDelegateAllRadio != NULL); m_hwndDelegateFollowingRadio = GetDlgItem(IDC_DELEGATE_FOLLOWING_RADIO); ASSERT(m_hwndDelegateFollowingRadio != NULL); m_hwndDelegateCreateChild = GetDlgItem(IDC_DELEGATE_CREATE_CHILD); ASSERT(m_hwndDelegateCreateChild != NULL); m_hwndDelegateDeleteChild = GetDlgItem(IDC_DELEGATE_DELETE_CHILD); ASSERT(m_hwndDelegateDeleteChild != NULL);
// set default setting
::SendMessage(m_hwndDelegateAllRadio, BM_SETCHECK, BST_CHECKED, 0); ::SendMessage(m_hwndDelegateCreateChild, BM_SETCHECK, BST_UNCHECKED, 0); ::SendMessage(m_hwndDelegateCreateChild, BM_SETCHECK, BST_UNCHECKED, 0);
return TRUE; }
LRESULT CDelegWiz_ObjectTypeSelectionPage::OnObjectRadioChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { SyncControlsHelper(IDC_DELEGATE_ALL_RADIO == wID); return 1; }
LRESULT CDelegWiz_ObjectTypeSelectionPage::OnCreateDelCheckBoxChanage(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { CDelegWiz* pWiz = GET_OU_WIZARD(); if( IDC_DELEGATE_CREATE_CHILD == wID ) { if( ::SendMessage( hWndCtl, BM_GETCHECK,0,0 ) ) pWiz->m_fCreateDelChild |= ACTRL_DS_CREATE_CHILD; else pWiz->m_fCreateDelChild &= ~ACTRL_DS_CREATE_CHILD; }
if( IDC_DELEGATE_DELETE_CHILD == wID ) { if( ::SendMessage( hWndCtl, BM_GETCHECK,0,0 ) ) pWiz->m_fCreateDelChild |= ACTRL_DS_DELETE_CHILD; else pWiz->m_fCreateDelChild &= ~ACTRL_DS_DELETE_CHILD; } return 1; }
LRESULT CDelegWiz_ObjectTypeSelectionPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh; if (CCheckListViewHelper::CheckChanged(pNMListView)) { int nSelCount = m_objectTypeListView.GetCheckCount(); GET_OU_WIZARD()->SetWizardButtonsMiddle(nSelCount > 0); } return 1; }
void CDelegWiz_ObjectTypeSelectionPage::SyncControlsHelper(BOOL bDelegateAll) { CDelegWiz* pWiz = GET_OU_WIZARD(); if (bDelegateAll) { // uncheck all items in the listview if delegating all
m_objectTypeListView.SetCheckAll(FALSE); // in the listview
pWiz->DeselectSchemaClassesSelectionCustom(); // in the list of schama classes
//Uncheck delete/create check boxes
::SendMessage(m_hwndDelegateCreateChild,BM_SETCHECK,0,0); ::SendMessage(m_hwndDelegateDeleteChild,BM_SETCHECK,0,0); pWiz->m_fCreateDelChild = 0;
}
// enable "Wizard Next" of "delegate all"
pWiz->SetWizardButtonsMiddle(bDelegateAll); // disable listbox if "delegate all"
m_objectTypeListView.EnableWindow(!bDelegateAll); ::EnableWindow( m_hwndDelegateCreateChild, !bDelegateAll); ::EnableWindow( m_hwndDelegateDeleteChild, !bDelegateAll); }
void CDelegWiz_ObjectTypeSelectionPage::SetRadioControlText(HWND hwndCtrl, LPCWSTR lpszFmtText, LPCWSTR lpszText) { // format new text
int nTextLen = lstrlen(lpszText)+1; // count NULL
int nFmtTextLen = lstrlen(lpszFmtText)+1; // count NULL
WCHAR* lpszNewText = (WCHAR*)alloca(sizeof(WCHAR)*(nFmtTextLen+nTextLen)); wsprintf(lpszNewText, lpszFmtText, lpszText);
// set back
::SendMessage(hwndCtrl, WM_SETTEXT, 0, (WPARAM)lpszNewText); }
BOOL CDelegWiz_ObjectTypeSelectionPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD(); BOOL bRetVal = TRUE; BOOL bDelegateAll = (BST_CHECKED == ::SendMessage(m_hwndDelegateAllRadio, BM_GETCHECK,0,0));
if (pWizard->m_bFwd) { // need to fill in with data
BOOL bFilter = TRUE; BOOL bHaveChildClasses = pWizard->FillCustomSchemaClassesListView(&m_objectTypeListView, bFilter) > 0; if (!bHaveChildClasses) { ::SendMessage(m_hwndDelegateAllRadio, BM_SETCHECK,BST_CHECKED,0); ::SendMessage(m_hwndDelegateFollowingRadio, BM_SETCHECK,BST_UNCHECKED,0); ::EnableWindow(m_hwndDelegateFollowingRadio, FALSE); bDelegateAll = TRUE; } SyncControlsHelper(bDelegateAll); } else { // data already in, just coming back from next page
if (bDelegateAll) { pWizard->SetWizardButtonsMiddle(TRUE); } else { int nSelCount = m_objectTypeListView.GetCheckCount(); pWizard->SetWizardButtonsMiddle(nSelCount > 0); } } return TRUE; }
LRESULT CDelegWiz_ObjectTypeSelectionPage::OnWizardNext() { HRESULT hr = S_OK; BOOL bCanAdvance = FALSE; CDelegWiz* pWiz = GET_OU_WIZARD(); pWiz->m_bAuxClass = false; // check if the delegation is on all objects
if (BST_CHECKED == ::SendMessage(m_hwndDelegateAllRadio, BM_GETCHECK,0,0)) { bCanAdvance = TRUE; } else { ASSERT(BST_CHECKED == ::SendMessage(m_hwndDelegateFollowingRadio, BM_GETCHECK,0,0)); int nSelCount = 0; int nCount = m_objectTypeListView.GetItemCount(); CSchemaClassInfo* pAuxClassInfo = NULL; for (int k=0; k<nCount; k++) { CSchemaClassInfo* pChildClassInfo = (CSchemaClassInfo*)m_objectTypeListView.GetItemData(k); pChildClassInfo->m_bSelected = m_objectTypeListView.IsItemChecked(k); if (pChildClassInfo->m_bSelected) { nSelCount++; if(pChildClassInfo->IsAux()) { pWiz->m_bAuxClass = true; if(!pAuxClassInfo) pAuxClassInfo = pChildClassInfo; } } } bCanAdvance = (nSelCount > 0); if(nSelCount > 1 && pWiz->m_bAuxClass) { LPWSTR pszMessage = NULL; FormatStringID(&pszMessage, IDS_DELEGWIZ_ONE_AUX_CLASS,pAuxClassInfo->GetDisplayName()); pWiz->WizMessageBox(pszMessage); LocalFree(pszMessage);
bCanAdvance = FALSE; } }
if (!bCanAdvance) goto error;
{ // scope to restore cursor
CWaitCursor wait; bCanAdvance = pWiz->SetSchemaClassesSelectionCustom(); } if (!bCanAdvance) goto error; // for the selected child class(es), get the access permissions
// to display in the next page
{ // scope to restore cursor
CWaitCursor wait; bCanAdvance = pWiz->GetCustomAccessPermissions(); } if (!bCanAdvance) goto error;
OnWizardNextHelper(); return 0; // advance next
error: // do not advance, error
pWiz->SetWizardButtonsMiddle(FALSE); return -1; }
///////////////////////////////////////////////////////////////////////
// CPrincipalListViewHelper
BOOL CPrincipalListViewHelper::Initialize(UINT nID, HWND hParent) { m_hWnd = GetDlgItem(hParent, nID); if (m_hWnd == NULL) return FALSE;
if (!m_imageList.Create(m_hWnd)) return FALSE;
SetImageList();
RECT r; ::GetClientRect(m_hWnd, &r); int scroll = ::GetSystemMetrics(SM_CXVSCROLL); LV_COLUMN col; ZeroMemory(&col, sizeof(LV_COLUMN)); col.mask = LVCF_WIDTH; col.cx = (r.right - r.left) - scroll; m_defaultColWidth = col.cx; return (0 == ListView_InsertColumn(m_hWnd,0,&col)); }
int CPrincipalListViewHelper::InsertItem(int iItem, CPrincipal* pPrincipal) { // need to get the icon index
int nIconIndex = m_imageList.GetIconIndex(pPrincipal->GetClass()); if (nIconIndex == -1) { nIconIndex = m_imageList.AddIcon(pPrincipal->GetClass(), pPrincipal->GetClassIcon()); if (nIconIndex != -1) SetImageList(); }
LV_ITEM item; ZeroMemory(&item, sizeof(LV_ITEM)); item.mask = LVIF_TEXT | LVIF_PARAM; item.pszText = (LPWSTR)(LPCWSTR)(pPrincipal->GetDisplayName()); item.lParam = (LPARAM)pPrincipal; item.iItem = iItem; if (nIconIndex != -1) { item.iImage = nIconIndex; item.mask |= LVIF_IMAGE; } int iRes = ListView_InsertItem(m_hWnd, &item); return iRes; }
BOOL CPrincipalListViewHelper::SelectItem(int iItem) { LV_ITEM item; ZeroMemory(&item, sizeof(LV_ITEM)); item.mask = LVIF_STATE; item.stateMask = LVIS_FOCUSED | LVIS_SELECTED; item.state = LVIS_FOCUSED | LVIS_SELECTED; return ListView_SetItem(m_hWnd, &item); }
CPrincipal* CPrincipalListViewHelper::GetItemData(int iItem) { LV_ITEM item; ZeroMemory(&item, sizeof(LV_ITEM)); item.mask = LVIF_PARAM; item.iItem = iItem; ListView_GetItem(m_hWnd, &item); return (CPrincipal*)item.lParam; }
void CPrincipalListViewHelper::DeleteSelectedItems(CGrowableArr<CPrincipal>* pDeletedArr) { int nItemIndex; while ( (nItemIndex = ListView_GetNextItem(m_hWnd, -1, LVNI_SELECTED)) != -1) { CPrincipal* pPrincipal = GetItemData(nItemIndex); if (ListView_DeleteItem(m_hWnd, nItemIndex)) { pDeletedArr->Add(pPrincipal); } } // if
// restore selection to first item
if (GetItemCount() > 0) SelectItem(0); }
void CPrincipalListViewHelper::UpdateWidth(int cxNew) { int cx = GetWidth(); // get current col width from the control
if (cxNew < m_defaultColWidth) cxNew = m_defaultColWidth; if (cxNew != cx) SetWidth(cx); }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_PrincipalSelectionPage
BOOL CALLBACK CDelegWiz_PrincipalSelectionPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // initialize the list of principals
m_principalListView.Initialize(IDC_SELECTED_PRINCIPALS_LIST, m_hWnd);
// cache handle for the remove button
m_hwndRemoveButton = GetDlgItem(IDC_REMOVE_BUTTON); return TRUE; }
LRESULT CDelegWiz_PrincipalSelectionPage::OnAdd(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { GET_OU_WIZARD()->AddPrincipals(&m_principalListView); SyncButtons(); return 1; }
LRESULT CDelegWiz_PrincipalSelectionPage::OnRemove(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { GET_OU_WIZARD()->DeletePrincipals(&m_principalListView); SyncButtons(); return 1; }
LRESULT CDelegWiz_PrincipalSelectionPage::OnListViewSelChange(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { SyncButtons(); return 1; }
BOOL CDelegWiz_PrincipalSelectionPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD(); SyncButtons(); return TRUE; }
LRESULT CDelegWiz_PrincipalSelectionPage::OnWizardNext() { CDelegWiz* pWiz = GET_OU_WIZARD();
// set branching info
UINT nNextPageID = 0; if (pWiz->m_templateAccessPermissionsHolderManager.HasTemplates(pWiz->GetClass())) { nNextPageID = CDelegWiz_DelegationTemplateSelectionPage::IDD; } else { nNextPageID = CDelegWiz_ObjectTypeSelectionPage::IDD; pWiz->m_objectTypeSelectionPage.m_nPrevPageID = IDD; }
OnWizardNextHelper(); return nNextPageID; }
void CDelegWiz_PrincipalSelectionPage::SyncButtons() { BOOL bEnable = FALSE; int nItemCount = m_principalListView.GetItemCount(); if (nItemCount > 0) { bEnable = m_principalListView.GetSelCount() > 0; } ::EnableWindow(m_hwndRemoveButton, bEnable);
CDelegWiz* pWiz = GET_OU_WIZARD(); pWiz->SetWizardButtonsMiddle(nItemCount > 0); }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_DelegatedRightsPage
BOOL CALLBACK CDelegWiz_DelegatedRightsPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { // initialize check list view
m_delegatedRigthsListView.Initialize(IDC_DELEG_RIGHTS_LIST, m_hWnd);
// get HWND's of controls
m_hwndGeneralRigthsCheck = GetDlgItem(IDC_SHOW_GENERAL_CHECK); _ASSERTE(m_hwndGeneralRigthsCheck); m_hwndPropertyRightsCheck = GetDlgItem(IDC_SHOW_PROPERTY_CHECK); _ASSERTE(m_hwndPropertyRightsCheck); m_hwndSubobjectRightsCheck = GetDlgItem(IDC_SHOW_SUBOBJ_CHECK); _ASSERTE(m_hwndSubobjectRightsCheck);
return TRUE; }
BOOL CDelegWiz_DelegatedRightsPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD();
if (pWizard->m_bFwd) { if(pWizard->m_bAuxClass) SetFilterOptions(FILTER_EXP_GEN_DISABLED|FILTER_EXP_PROP); else SetFilterOptions(FILTER_EXP_GEN);
ResetCheckList(); // will set wizard button
} else { //coming back from next page, just set the wizard button
pWizard->SetWizardButtonsMiddle(pWizard->HasPermissionSelectedCustom()); } return TRUE; }
LRESULT CDelegWiz_DelegatedRightsPage::OnWizardNext() { CDelegWiz* pWiz = GET_OU_WIZARD(); // must at least one check > 0
if (pWiz->HasPermissionSelectedCustom()) { OnWizardNextHelper(); return 0; }
pWiz->SetWizardButtonsMiddle(FALSE); return -1; }
LRESULT CDelegWiz_DelegatedRightsPage::OnFilterChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ResetCheckList(); return 1; }
LRESULT CDelegWiz_DelegatedRightsPage::OnListViewItemChanged(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { if (m_bUIUpdateInProgress) return 1;
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pnmh; if (CCheckListViewHelper::CheckChanged(pNMListView)) { CRigthsListViewItem* pItem = (CRigthsListViewItem*)pNMListView->lParam; // item data
CDelegWiz* pWizard = GET_OU_WIZARD();
ULONG nCurrFilterOptions = GetFilterOptions();
ULONG nNewFilterOptions = 0; pWizard->OnCustomAccessRightsCheckListClick( pItem, CCheckListViewHelper::IsChecked(pNMListView), &nNewFilterOptions);
nNewFilterOptions |= nCurrFilterOptions;
m_bUIUpdateInProgress = TRUE; // this call will cause a series of notifications:
// we have to disable them to avoid reentrancy
if (nNewFilterOptions == nCurrFilterOptions) { // no need to change filter selection, just update the checkboxes
pWizard->UpdateAccessRightsListViewSelection(&m_delegatedRigthsListView, nNewFilterOptions); } else { // filter selection must be changed,
// so we have to update the check boxes and to refill the checklist
SetFilterOptions(nNewFilterOptions); ResetCheckList(); } m_bUIUpdateInProgress = FALSE;
BOOL bSel = pWizard->HasPermissionSelectedCustom(); pWizard->SetWizardButtonsMiddle(bSel); }
return 1; }
void CDelegWiz_DelegatedRightsPage::ResetCheckList() { // get a new filtered list of rights in the list view
CDelegWiz* pWizard = GET_OU_WIZARD();
// this call will cause a series of notifications:
// we have to disable them to avoid reentrancy
m_bUIUpdateInProgress = TRUE; pWizard->FillCustomAccessRightsListView(&m_delegatedRigthsListView, GetFilterOptions()); m_bUIUpdateInProgress = FALSE; pWizard->SetWizardButtonsMiddle(pWizard->HasPermissionSelectedCustom()); }
ULONG CDelegWiz_DelegatedRightsPage::GetFilterOptions() { ULONG nFilterState = 0; // read the filtering options from checkboxes
if (BST_CHECKED == ::SendMessage(m_hwndGeneralRigthsCheck, BM_GETCHECK, 0, 0)) nFilterState |= FILTER_EXP_GEN;
if (BST_CHECKED == ::SendMessage(m_hwndPropertyRightsCheck, BM_GETCHECK, 0, 0)) nFilterState |= FILTER_EXP_PROP;
if (BST_CHECKED == ::SendMessage(m_hwndSubobjectRightsCheck, BM_GETCHECK, 0, 0)) nFilterState |= FILTER_EXP_SUBOBJ;
return nFilterState; }
inline WPARAM _Checked(ULONG f) { return f ? BST_CHECKED : BST_UNCHECKED;}
void CDelegWiz_DelegatedRightsPage::SetFilterOptions(ULONG nFilterOptions) { ::EnableWindow(m_hwndGeneralRigthsCheck,!(nFilterOptions & FILTER_EXP_GEN_DISABLED)); ::SendMessage(m_hwndGeneralRigthsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_GEN), 0); ::SendMessage(m_hwndPropertyRightsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_PROP), 0); ::SendMessage(m_hwndSubobjectRightsCheck, BM_SETCHECK, _Checked(nFilterOptions & FILTER_EXP_SUBOBJ), 0); }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz_FinishPage
BOOL CALLBACK CDelegWiz_FinishPage::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { SetLargeFont(m_hWnd, IDC_STATIC_COMPLETION); return TRUE; }
LRESULT CDelegWiz_FinishPage::OnSetFocusSummaryEdit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { ASSERT(hWndCtl == GetDlgItem(IDC_EDIT_SUMMARY)); ::SendMessage(hWndCtl, EM_SETSEL, (WPARAM)-1, (LPARAM)0);
if (m_bNeedSetFocus) { m_bNeedSetFocus = FALSE; TRACE(_T("Resetting Focus\n"));
HWND hwndSheet = ::GetParent(m_hWnd); ASSERT(::IsWindow(hwndSheet)); HWND hWndFinishCtrl =::GetDlgItem(hwndSheet, 0x3025); ASSERT(::IsWindow(hWndFinishCtrl)); ::SetFocus(hWndFinishCtrl); } return 1; }
BOOL CDelegWiz_FinishPage::OnSetActive() { CDelegWiz* pWizard = GET_OU_WIZARD(); pWizard->SetWizardButtonsLast(TRUE);
CWString szSummary; if (m_bCustom) pWizard->WriteSummaryInfoCustom(szSummary, g_lpszSummaryIdent, g_lpszSummaryNewLine); else pWizard->WriteSummaryInfoTemplate(szSummary, g_lpszSummaryIdent, g_lpszSummaryNewLine);
HWND hWndSummary = GetDlgItem(IDC_EDIT_SUMMARY); ::SetWindowText(hWndSummary, (LPCWSTR)szSummary);
m_bNeedSetFocus = TRUE;
return TRUE; }
BOOL CDelegWiz_FinishPage::OnWizardFinish() { CWaitCursor wait; BOOL bRes; CDelegWiz* pWizard = GET_OU_WIZARD();
if (m_bCustom) bRes = GET_OU_WIZARD()->FinishCustom(); else bRes = GET_OU_WIZARD()->FinishTemplate(); return bRes; }
////////////////////////////////////////////////////////////////////////////
// CDelegWiz
const long CDelegWiz::nSchemaClassesSelAll = -2; const long CDelegWiz::nSchemaClassesSelMultiple = -1;
// REVIEW_MARCOC: should probably nuke, not used
BOOL Is256ColorSupported() { BOOL bRetval = FALSE; HDC hdc = GetDC(NULL); if( hdc ) { if( GetDeviceCaps( hdc, BITSPIXEL ) >= 8 ) { bRetval = TRUE; } ReleaseDC(NULL, hdc); } return bRetval; }
CDelegWiz::CDelegWiz() : CWizardBase(IDB_DELEG_WATER, IDB_DELEG_HD, IDS_DELEGWIZ_WIZ_TITLE), m_startPage(this), m_namePage(this), m_templateSelectionPage(this), m_userOrGroupSelectionPage(this), m_objectTypeSelectionPage(this), m_delegatedRightsPage(this), m_finishPage(this), m_bAuxClass(FALSE) { m_lpszLDAPPath = NULL;
m_nSchemaClassesSel = nSchemaClassesSelAll; m_fCreateDelChild = 0;
// Add the property pages
m_startPage.InitWiz97(TRUE); AddPage(m_startPage);
m_namePage.InitWiz97(FALSE, IDS_DELEGWIZ_NAME_TITLE, IDS_DELEGWIZ_NAME_SUBTITLE); AddPage(m_namePage);
m_userOrGroupSelectionPage.InitWiz97(FALSE, IDS_DELEGWIZ_PRINCIPALS_SEL_TITLE, IDS_DELEGWIZ_PRINCIPALS_SEL_SUBTITLE); AddPage(m_userOrGroupSelectionPage); // branching page
m_templateSelectionPage.InitWiz97(FALSE, IDS_DELEGWIZ_TEMPLATE_SEL_TITLE, IDS_DELEGWIZ_TEMPLATE_SEL_SUBTITLE); AddPage(m_templateSelectionPage);
m_objectTypeSelectionPage.InitWiz97(FALSE, IDS_DELEGWIZ_OBJ_TYPE_SEL_TITLE, IDS_DELEGWIZ_OBJ_TYPE_SEL_SUBTITLE); AddPage(m_objectTypeSelectionPage); m_delegatedRightsPage.InitWiz97(FALSE, IDS_DELEGWIZ_DELEG_RIGHTS_TITLE, IDS_DELEGWIZ_DELEG_RIGHTS_SUBTITLE); AddPage(m_delegatedRightsPage); m_finishPage.InitWiz97(TRUE); AddPage(m_finishPage);
m_templateAccessPermissionsHolderManager.LoadTemplates(); };
CDelegWiz::~CDelegWiz() { }
HRESULT CDelegWiz::AddPrincipalsFromBrowseResults(CPrincipalListViewHelper* pListViewHelper, PDS_SELECTION_LIST pDsSelectionList) { TRACE(L"CDelegWiz::AddPrincipalsFromBrowseResults()\n");
HRESULT hr = S_OK; if ( (pDsSelectionList == NULL) || (pDsSelectionList->cItems == 0)) { TRACE(L"CDelegWiz::AddPrincipalsFromBrowseResults(), no items!!!\n"); return E_INVALIDARG; }
int nListInsertPosition = pListViewHelper->GetItemCount(); for (int i = 0; i < pDsSelectionList->cItems; i++) { TRACE(L"For loop, pDsSelectionList->cItems = %d\n", pDsSelectionList->cItems);
// add to list of principals
CPrincipal* pPrincipal = new CPrincipal; if (pPrincipal != NULL) { HICON hClassIcon = m_adsiObject.GetClassIcon(pDsSelectionList->aDsSelection[i].pwzClass); HRESULT hrInit = pPrincipal->Initialize(&(pDsSelectionList->aDsSelection[i]), hClassIcon); if (FAILED(hrInit)) { LPCWSTR lpszName = pDsSelectionList->aDsSelection[i].pwzName; WCHAR szFmt[256]; LoadStringHelper(IDS_DELEGWIZ_ERR_INVALID_PRINCIPAL, szFmt, 256); int nNameLen = lstrlen(lpszName) + 1;
WCHAR* lpszMsg = (WCHAR*)alloca(sizeof(WCHAR)*(nNameLen+256)); wsprintf(lpszMsg, szFmt, lpszName); WizReportHRESULTError(lpszMsg, hrInit); delete pPrincipal; continue; }
// add to list of principals (if not already there)
if (m_principalList.AddIfNotPresent(pPrincipal)) { // add to listbox (assume not sorted)
pListViewHelper->InsertItem(nListInsertPosition, pPrincipal); nListInsertPosition++; }
} // if pPrincipal not NULL
} // for
// make sure there is a selection
if ( (pListViewHelper->GetItemCount() > 0) && (pListViewHelper->GetSelCount() == 0) ) { // if we have items, but none is selected, make sure we set the selection
// to the first one.
pListViewHelper->SelectItem(0); }
// update width
//pListViewHelper->UpdateWidth(m_principalList.GetMaxListboxExtent());
return hr; }
/*
typedef struct _DSOP_FILTER_FLAGS { DSOP_UPLEVEL_FILTER_FLAGS Uplevel; ULONG flDownlevel; } DSOP_FILTER_FLAGS;
typedef struct _DSOP_SCOPE_INIT_INFO { ULONG cbSize; ULONG flType; ULONG flScope; DSOP_FILTER_FLAGS FilterFlags; PCWSTR pwzDcName; // OPTIONAL
PCWSTR pwzADsPath; // OPTIONAL
HRESULT hr; } DSOP_SCOPE_INIT_INFO, *PDSOP_SCOPE_INIT_INFO;
*/
DSOP_SCOPE_INIT_INFO g_aDSOPScopes[] = { #if 0
{ cbSize, flType, flScope, { { flBothModes, flMixedModeOnly, flNativeModeOnly }, flDownlevel, }, pwzDcName, pwzADsPath, hr // OUT
}, #endif
// The Global Catalog
{ sizeof(DSOP_SCOPE_INIT_INFO), DSOP_SCOPE_TYPE_GLOBAL_CATALOG, DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT| DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS| DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS, { { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS | DSOP_FILTER_WELL_KNOWN_PRINCIPALS, 0, 0 }, 0, }, NULL, NULL, S_OK },
// The domain to which the target computer is joined.
{ sizeof(DSOP_SCOPE_INIT_INFO), DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN, DSOP_SCOPE_FLAG_STARTING_SCOPE | DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT| DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS| DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS, { // joined domain is always NT5 for DS ACLs Editor
{ 0, //mixed: users, well known SIDs, local groups, builtin groups, global groups, computers
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 ,
//native users, well known SIDs, local groups, builtin groups, global groups, universal groups, computers
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_UNIVERSAL_GROUPS_SE | DSOP_FILTER_COMPUTERS }, 0, // zero for downlevel joined domain, should be DS-aware
}, NULL, NULL, S_OK },
// The domains in the same forest (enterprise) as the domain to which
// the target machine is joined. Note these can only be DS-aware
{ sizeof(DSOP_SCOPE_INIT_INFO), DSOP_SCOPE_TYPE_ENTERPRISE_DOMAIN, DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT| DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS| DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS,
{ { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS, 0, 0}, 0, }, NULL, NULL, S_OK },
// Domains external to the enterprise but trusted directly by the
// domain to which the target machine is joined.
{ sizeof(DSOP_SCOPE_INIT_INFO), DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN, DSOP_SCOPE_FLAG_WANT_PROVIDER_WINNT| DSOP_SCOPE_FLAG_DEFAULT_FILTER_GROUPS| DSOP_SCOPE_FLAG_DEFAULT_FILTER_USERS, { { DSOP_FILTER_INCLUDE_ADVANCED_VIEW | DSOP_FILTER_USERS | DSOP_FILTER_UNIVERSAL_GROUPS_SE | DSOP_FILTER_GLOBAL_GROUPS_SE | DSOP_FILTER_COMPUTERS, 0, 0}, DSOP_DOWNLEVEL_FILTER_USERS | DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS, }, NULL, NULL, S_OK }, };
//
// Attributes that we want the Object Picker to retrieve
//
static const LPCTSTR g_aszOPAttributes[] = { TEXT("ObjectSid"), TEXT("userAccountControl"), };
HRESULT CDelegWiz::AddPrincipals(CPrincipalListViewHelper* pListViewHelper) { TRACE(L"CDelegWiz::AddPrincipals()\n");
// create object picker COM object
CComPtr<IDsObjectPicker> spDsObjectPicker; HRESULT hr = CoCreateInstance(CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void**)&spDsObjectPicker); if (FAILED(hr)) { TRACE(L"CoCreateInstance(CLSID_DsObjectPicker) failed, hr = 0x%x\n"); return hr; }
// set init info
DSOP_INIT_INFO InitInfo; ZeroMemory(&InitInfo, sizeof(InitInfo));
InitInfo.cbSize = sizeof(DSOP_INIT_INFO); InitInfo.pwzTargetComputer = m_adsiObject.GetServerName(); InitInfo.cDsScopeInfos = sizeof(g_aDSOPScopes)/sizeof(DSOP_SCOPE_INIT_INFO); InitInfo.aDsScopeInfos = g_aDSOPScopes; InitInfo.flOptions = DSOP_FLAG_MULTISELECT; InitInfo.cAttributesToFetch = 2; InitInfo.apwzAttributeNames = (LPCTSTR*)g_aszOPAttributes;;
TRACE(L"InitInfo.cbSize = %d\n", InitInfo.cbSize); TRACE(L"InitInfo.pwzTargetComputer = %s\n", InitInfo.pwzTargetComputer); TRACE(L"InitInfo.cDsScopeInfos = %d\n", InitInfo.cDsScopeInfos); TRACE(L"InitInfo.aDsScopeInfos = 0x%x\n", InitInfo.aDsScopeInfos); TRACE(L"InitInfo.flOptions = 0x%x\n", InitInfo.flOptions); TRACE(L"InitInfo.cAttributesToFetch = %d\n", InitInfo.cAttributesToFetch); TRACE(L"InitInfo.apwzAttributeNames[0]= %s\n", InitInfo.apwzAttributeNames[0]);
// initialize object picker
hr = spDsObjectPicker->Initialize(&InitInfo); if (FAILED(hr)) { TRACE(L"spDsObjectPicker->Initialize(...) failed, hr = 0x%x\n"); return hr; }
// invoke the dialog
CComPtr<IDataObject> spdoSelections;
hr = spDsObjectPicker->InvokeDialog(m_hWnd, &spdoSelections); if (hr == S_FALSE || !spdoSelections) { return S_FALSE; }
// retrieve data from data object
FORMATETC fmte = {(CLIPFORMAT)_Module.GetCfDsopSelectionList(), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM medium = {TYMED_NULL, NULL, NULL}; PDS_SELECTION_LIST pDsSelList = NULL;
hr = spdoSelections->GetData(&fmte, &medium); if (FAILED(hr)) { TRACE(L"spdoSelections->GetData(...) failed, hr = 0x%x\n"); return hr; }
pDsSelList = (PDS_SELECTION_LIST)GlobalLock(medium.hGlobal);
if(!DoDisabledCheck(*this,pDsSelList)) { return S_FALSE; }
hr = AddPrincipalsFromBrowseResults(pListViewHelper, pDsSelList);
GlobalUnlock(medium.hGlobal); ReleaseStgMedium(&medium);
return hr; }
BOOL CDelegWiz::DeletePrincipals(CPrincipalListViewHelper* pListViewHelper) { CGrowableArr<CPrincipal> deletedArr(FALSE); // do not own memory
// remove from listview
pListViewHelper->DeleteSelectedItems(&deletedArr); // remove from list of items
int nDeletedCount = deletedArr.GetCount(); for (int k=0; k<nDeletedCount; k++) { m_principalList.Remove(deletedArr[k]); } //pListViewHelper->UpdateWidth(m_principalList.GetMaxListboxExtent());
return TRUE; }
int CDelegWiz::FillCustomSchemaClassesListView(CCheckListViewHelper* pListViewHelper, BOOL bFilter) { // clear old entries
pListViewHelper->DeleteAllItems();
int nCount = m_schemaClassInfoArray.GetCount(); if (nCount == 0) return 0; // no insertions, nothing else to do
// figure out the max len of items to get a big enough buffer
int nMaxLen = 0; int nCurrLen = 0; for (long index = 0; index < nCount; index++) { nCurrLen = lstrlen(m_schemaClassInfoArray[index]->GetDisplayName()); if (nCurrLen > nMaxLen) nMaxLen = nCurrLen; }
CWString szFormat; szFormat.LoadFromResource(IDS_DELEGWIZ_CHILD_CLASS_FMT);
WCHAR* pwszNewText = (WCHAR*)alloca(sizeof(WCHAR)*(szFormat.size()+nMaxLen+1));
// add formatted entries, assume listbox not sorted
long iListBoxItem = 0; for (index = 0; index < nCount; index++) { CSchemaClassInfo* pChildClassInfo = m_schemaClassInfoArray[index]; pChildClassInfo->m_bSelected = FALSE; if (bFilter && pChildClassInfo->IsFiltered()) continue;
wsprintf(pwszNewText, (LPCWSTR)szFormat, pChildClassInfo->GetDisplayName()); pListViewHelper->InsertItem(iListBoxItem, pwszNewText, (LPARAM)pChildClassInfo, FALSE); iListBoxItem++; }
return iListBoxItem; // return the # of items inserted
}
BOOL CDelegWiz::SetSchemaClassesSelectionCustom() { int nSelCount = 0; int nCount = m_schemaClassInfoArray.GetCount(); CComPtr<IADsClass> spSchemaObjectClass; m_bChildClass = FALSE;
// get the selection count
int nSingleSel = -1; for (int k=0; k < nCount; k++) { if (m_schemaClassInfoArray[k]->m_bSelected) { if( m_schemaClassInfoArray[k]->m_dwChildClass == CHILD_CLASS_NOT_CALCULATED ) { if (m_schemaClassInfoArray[k]->GetName() != NULL) { int nServerNameLen = lstrlen(m_adsiObject.GetServerName()); int nClassNameLen = lstrlen(m_schemaClassInfoArray[k]->GetName()); int nFormatStringLen = lstrlen(g_wzLDAPAbstractSchemaFormat); VARIANT var = {0};
// build the LDAP path for the schema class
WCHAR* pwszSchemaObjectPath = (WCHAR*)alloca(sizeof(WCHAR)*(nServerNameLen+nClassNameLen+nFormatStringLen+1)); wsprintf(pwszSchemaObjectPath, g_wzLDAPAbstractSchemaFormat, m_adsiObject.GetServerName(), m_schemaClassInfoArray[k]->GetName());
// get the schema class ADSI object
HRESULT hr = ::ADsOpenObjectHelper(pwszSchemaObjectPath, IID_IADsClass, 0, (void**)&spSchemaObjectClass); if (FAILED(hr)) //NTRAID#NTBUG9-530206-2002/06/18-ronmart-PREFAST: Casting HRESULT to BOOL
//return hr;
return FALSE;
spSchemaObjectClass->get_Containment(&var);
if (V_VT(&var) == (VT_ARRAY | VT_VARIANT)) { LPSAFEARRAY psa = V_ARRAY(&var);
ASSERT(psa && psa->cDims == 1);
if (psa->rgsabound[0].cElements > 0) { m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_EXIST; } else m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_NOT_EXIST; } else if (V_VT(&var) == VT_BSTR) // single entry
{ m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_EXIST; } else m_schemaClassInfoArray[k]->m_dwChildClass = CHILD_CLASS_NOT_EXIST;
VariantClear(&var);
} }
if( m_schemaClassInfoArray[k]->m_dwChildClass != CHILD_CLASS_NOT_EXIST ) m_bChildClass = TRUE;
if (nSingleSel == -1) nSingleSel = k; nSelCount++; } }
if (nSelCount == 0) { m_nSchemaClassesSel = nSchemaClassesSelAll; m_bChildClass = TRUE; return TRUE; // delegate control to all types
}
// keep track if it is a single selection
if (nSelCount == 1) { ASSERT(nSingleSel != -1); m_nSchemaClassesSel = nSingleSel; return TRUE; } // multiple selection
m_nSchemaClassesSel = nSchemaClassesSelMultiple;
return TRUE; }
void CDelegWiz::DeselectSchemaClassesSelectionCustom() { int nCount = m_schemaClassInfoArray.GetCount(); for (int k=0; k < nCount; k++) { m_schemaClassInfoArray[k]->m_bSelected = FALSE; } }
BOOL CDelegWiz::GetCustomAccessPermissions() { // remove all the old entries
m_permissionHolder.Clear();
// retrieve the string for the child class object type (single selection)
// for multiple selection, it will be NULL
CSchemaClassInfo* pClassInfo = NULL;
switch (m_nSchemaClassesSel) { case nSchemaClassesSelMultiple: { // for multiple selection, it will be NULL
pClassInfo = NULL; } break; case nSchemaClassesSelAll: { // just get the class name of the object we want to delegate rights on
// need to find matching class in the schema info array
for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++) { if (_wcsicmp(m_schemaClassInfoArray[k]->GetName(), m_adsiObject.GetClass()) == 0) { pClassInfo = m_schemaClassInfoArray[k]; break; } } // for k
ASSERT(pClassInfo != NULL); } break; default: { // single selection
ASSERT( (m_nSchemaClassesSel >= 0) && (m_nSchemaClassesSel < m_schemaClassInfoArray.GetCount()) ); pClassInfo = m_schemaClassInfoArray[m_nSchemaClassesSel]; } } // switch
// get the permissions from the DS
LPCWSTR lpszClassName = NULL; const GUID* pSchemaIDGUID = NULL; if (pClassInfo != NULL) { lpszClassName = pClassInfo->GetName(); pSchemaIDGUID = pClassInfo->GetSchemaGUID(); }
HRESULT hr = m_permissionHolder.ReadDataFromDS(&m_adsiObject, m_adsiObject.GetNamingContext(), lpszClassName, pSchemaIDGUID, m_bChildClass, HideListObjectAccess()); if (FAILED(hr)) { WizReportHRESULTError(IDS_DELEGWIZ_ERR_PERMISSIONS, hr); return FALSE; } return TRUE; }
void CDelegWiz::FillCustomAccessRightsListView(CCheckListViewHelper* pListViewHelper, ULONG nFilterState) { // clear check list
pListViewHelper->DeleteAllItems(); m_permissionHolder.FillAccessRightsListView(pListViewHelper, nFilterState); }
void CDelegWiz::UpdateAccessRightsListViewSelection( CCheckListViewHelper* pListViewHelper, ULONG nFilterState) { m_permissionHolder.UpdateAccessRightsListViewSelection( pListViewHelper, nFilterState); }
BOOL CDelegWiz::HasPermissionSelectedCustom() { return m_permissionHolder.HasPermissionSelected(); }
void CDelegWiz::OnCustomAccessRightsCheckListClick( CRigthsListViewItem* pItem, BOOL bSelected, ULONG* pnNewFilterState) {
m_permissionHolder.Select(pItem, bSelected, pnNewFilterState); }
void CDelegWiz::WriteSummaryInfoCustom(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine) { // write object name and principals
WriteSummaryInfoHelper(szSummary, lpszIdent, lpszNewLine);
// write the list of rights
m_permissionHolder.WriteSummary(szSummary, lpszIdent, lpszNewLine);
// write the list of child classes (if applicable)
if (m_nSchemaClassesSel != nSchemaClassesSelAll) { WriteSummaryTitleLine(szSummary, IDS_DELEGWIZ_FINISH_OBJECT, lpszNewLine);
for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++) { if (m_schemaClassInfoArray[k]->m_bSelected) { WriteSummaryLine(szSummary, m_schemaClassInfoArray[k]->GetDisplayName(), lpszIdent, lpszNewLine); } } szSummary += lpszNewLine;
} // if
}
BOOL CDelegWiz::InitPermissionHoldersFromSelectedTemplates() { if (!m_templateAccessPermissionsHolderManager.InitPermissionHoldersFromSelectedTemplates( &m_schemaClassInfoArray, &m_adsiObject)) { // error: no valid and applicable data has been retrieved from the selected
// templates
return FALSE; } return TRUE; }
void CDelegWiz::WriteSummaryInfoTemplate(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine) { // write object name and principals
WriteSummaryInfoHelper(szSummary,lpszIdent, lpszNewLine);
// write the list of templates
m_templateAccessPermissionsHolderManager.WriteSummary(szSummary, lpszIdent, lpszNewLine); }
void CDelegWiz::WriteSummaryInfoHelper(CWString& szSummary, LPCWSTR lpszIdent, LPCWSTR lpszNewLine) { // set the canonical name
WriteSummaryTitleLine(szSummary, IDS_DELEGWIZ_FINISH_FOLDER, lpszNewLine);
WriteSummaryLine(szSummary, GetCanonicalName(), lpszIdent, lpszNewLine); szSummary += lpszNewLine;
// write the list of principals
m_principalList.WriteSummaryInfo(szSummary, lpszIdent, lpszNewLine); }
/*
typedef struct _ACTRL_ACCESS_ENTRYW { TRUSTEE_W Trustee; ULONG fAccessFlags; ACCESS_RIGHTS Access; ACCESS_RIGHTS ProvSpecificAccess; INHERIT_FLAGS Inheritance; LPWSTR lpInheritProperty; } ACTRL_ACCESS_ENTRYW, *PACTRL_ACCESS_ENTRYW; */
DWORD CDelegWiz::UpdateAccessList(CPrincipal* pPrincipal, CSchemaClassInfo* pClassInfo, PACL *ppAcl) {
return m_permissionHolder.UpdateAccessList( pPrincipal, pClassInfo, m_adsiObject.GetServerName(), m_adsiObject.GetPhysicalSchemaNamingContext(), ppAcl); }
DWORD CDelegWiz::BuildNewAccessListCustom(PACL *ppNewAcl) { DWORD dwErr = 0;
TRACE(L"BuildNewAccessListCustom()\n");
// loop thru all the principals and classes
CPrincipalList::iterator i; for (i = m_principalList.begin(); i != m_principalList.end(); ++i) { CPrincipal* pCurrPrincipal = *i; if (m_nSchemaClassesSel == nSchemaClassesSelAll) { // delegate on all objects
dwErr = UpdateAccessList( pCurrPrincipal, NULL, // all classes
ppNewAcl); if (dwErr != ERROR_SUCCESS) return dwErr; } else if (m_nSchemaClassesSel == nSchemaClassesSelMultiple) { // delegate on multiple objects
// multiple selection, loop thru each class to
// add rights for each
for (int k=0; k < m_schemaClassInfoArray.GetCount(); k++) { if (m_schemaClassInfoArray[k]->m_bSelected) { dwErr = UpdateAccessList( pCurrPrincipal, m_schemaClassInfoArray[k], ppNewAcl); if (dwErr != ERROR_SUCCESS) return dwErr; if( m_fCreateDelChild != 0 ) { dwErr = ::AddObjectRightInAcl( pCurrPrincipal->GetSid(), m_fCreateDelChild, m_schemaClassInfoArray[k]->GetSchemaGUID(), NULL, ppNewAcl);
if (dwErr != ERROR_SUCCESS) return dwErr; } } } // for k
} else { // single selection on child classes
dwErr = UpdateAccessList( pCurrPrincipal, m_schemaClassInfoArray[m_nSchemaClassesSel], ppNewAcl); if (dwErr != ERROR_SUCCESS) return dwErr;
if( m_fCreateDelChild != 0 ) { dwErr = ::AddObjectRightInAcl( pCurrPrincipal->GetSid(), m_fCreateDelChild, m_schemaClassInfoArray[m_nSchemaClassesSel]->GetSchemaGUID(), NULL, ppNewAcl);
if (dwErr != ERROR_SUCCESS) return dwErr; } } } // for pCurrPrincipal
return dwErr; }
DWORD CDelegWiz::BuildNewAccessListTemplate(PACL *ppNewAcl) { DWORD dwErr = 0; TRACE(L"BuildNewAccessListTemplate()\n");
// loop thru all the principals and classes
CPrincipalList::iterator i; for (i = m_principalList.begin(); i != m_principalList.end(); ++i) { CPrincipal* pCurrPrincipal = *i; dwErr = m_templateAccessPermissionsHolderManager.UpdateAccessList( pCurrPrincipal, m_adsiObject.GetServerName(), m_adsiObject.GetPhysicalSchemaNamingContext(), ppNewAcl);
if (dwErr != 0) break; } // for pCurrPrincipal
return dwErr; }
BOOL CDelegWiz::FinishHelper(BOOL bCustom) { BOOL bRetVal = FALSE; DWORD dwErr = 0;
PACL pDacl = NULL; PACL pOldAcl = NULL; PSECURITY_DESCRIPTOR pSD = NULL;
LPCWSTR lpszObjectLdapPath = m_adsiObject.GetLdapPath();
// get the security info
TRACE(L"calling GetSDForDsObjectPath(%s, ...)\n", lpszObjectLdapPath);
HRESULT hr = ::GetSDForDsObjectPath(IN const_cast<LPWSTR>(lpszObjectLdapPath), &pDacl, &pSD);
if (FAILED(hr)) { TRACE(L"failed on GetSDForDsObjectPath(): hr = 0x%x\n", hr); WCHAR szMsg[512]; LoadStringHelper(IDS_DELEGWIZ_ERR_GET_SEC_INFO, szMsg, 512); WizReportHRESULTError(szMsg, hr); goto exit; }
//pOldAcl is passed to functions which free it. pDacl cannot be
//passed as pSD should be freed , not pDacl. Instead of changing code
//to pass pSD, i am changing it to make a copy of pDacl which can
//be correctly freed.
if(pDacl) { pOldAcl = (PACL)LocalAlloc(LPTR, pDacl->AclSize); if(!pOldAcl) return FALSE; memcpy(pOldAcl, pDacl,pDacl->AclSize); } LocalFree(pSD); pSD = NULL; pDacl = NULL;
// build the new Access List
if (bCustom) { dwErr = BuildNewAccessListCustom(&pOldAcl); // in/out parameter
} else { dwErr = BuildNewAccessListTemplate(&pOldAcl); // in/out parameter
}
if (dwErr != ERROR_SUCCESS) { TRACE(_T("failed on BuildNewAccessListXXX()\n")); WCHAR szMsg[512]; LoadStringHelper(IDS_DELEGWIZ_ERR_EDIT_SEC_INFO, szMsg, 512); WizReportWin32Error(szMsg, dwErr); goto exit; }
// commit changes
TRACE(L"calling SetDaclForDsObjectPath(%s, ...)\n", lpszObjectLdapPath);
hr = ::SetDaclForDsObjectPath(IN const_cast<LPWSTR>(lpszObjectLdapPath),pOldAcl);
if(FAILED(hr)) { TRACE(L"failed on SetDaclForDsObjectPath(): hr = 0x%x\n", hr); WCHAR szMsg[512]; if(dwErr == ERROR_ACCESS_DENIED) LoadStringHelper(IDS_DELEGWIZ_ERR_ACCESS_DENIED, szMsg, 512); else LoadStringHelper(IDS_DELEGWIZ_ERR_SET_SEC_INFO, szMsg, 512); WizReportHRESULTError(szMsg, hr); goto exit; } bRetVal = TRUE;
exit: // cleanup memory
if (pOldAcl != NULL) ::LocalFree(pOldAcl);
return bRetVal; }
//+----------------------------------------------------------------------------
// Function:DoDisabledCheck
// Synopsis:Check if any of the object in pDsSelList is disabled. if yes,
// function displays a dialog box to user.
// Returns: TRUE if to add objects in list to acl else no.
//-----------------------------------------------------------------------------
BOOL DoDisabledCheck(IN CDelegWiz& refWiz, IN PDS_SELECTION_LIST pDsSelList) { if(!pDsSelList) { return FALSE; }
HRESULT hr = S_OK; int cNames = pDsSelList->cItems; BOOL bDisabled = FALSE;
//
//Check if account of any of the object in the list is disbled
//
for (int i = 0; i < cNames; i++) { //Second element in the array is pointer to UserAccountControl
LPVARIANT pvarUAC = pDsSelList->aDsSelection[i].pvarFetchedAttributes + 1;
if (NULL == pvarUAC || (VT_I4 != V_VT(pvarUAC))) { continue; } if(bDisabled = V_I4(pvarUAC) & UF_ACCOUNTDISABLE) break; }
BOOL bReturn = TRUE; if(bDisabled) { if(IDCANCEL == refWiz.WizMessageBox(IDS_DISABLED_USER, MB_OKCANCEL | MB_ICONWARNING | MB_APPLMODAL )) { bReturn = FALSE; } }
return bReturn; }
|