2111 lines
57 KiB
C++
2111 lines
57 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|
|
|
|
LRESULT CDelegWiz_StartPage::OnInitDialog(UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
LRESULT lRes = 1;
|
|
|
|
SetLargeFont(m_hWnd, IDC_STATIC_WELCOME);
|
|
|
|
return lRes;
|
|
}
|
|
|
|
|
|
#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];
|
|
wsprintf(szMsg, 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];
|
|
wsprintf(szMsg, 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
|
|
|
|
|
|
|
|
|
|
LRESULT CDelegWiz_NamePage::OnInitDialog(UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
LRESULT lRes = 1;
|
|
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);
|
|
|
|
lRes = 0;
|
|
}
|
|
return lRes;
|
|
}
|
|
|
|
|
|
|
|
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];
|
|
wsprintf(szMsg, 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];
|
|
wsprintf(szMsg, 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];
|
|
wsprintf(szMsg, 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
|
|
|
|
LRESULT 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 1;
|
|
}
|
|
|
|
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
|
|
|
|
|
|
LRESULT 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 1;
|
|
}
|
|
|
|
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
|
|
|
|
LRESULT 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 1;
|
|
}
|
|
|
|
|
|
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
|
|
|
|
|
|
LRESULT 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 1;
|
|
}
|
|
|
|
|
|
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
|
|
|
|
LRESULT CDelegWiz_FinishPage::OnInitDialog(UINT uMsg, WPARAM wParam,
|
|
LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
SetLargeFont(m_hWnd, IDC_STATIC_COMPLETION);
|
|
return 1;
|
|
}
|
|
|
|
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
|
|
},
|
|
};
|
|
|
|
|
|
|
|
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 = 1;
|
|
LPCWSTR lpszObjectSID = L"objectSid";
|
|
InitInfo.apwzAttributeNames = const_cast<LPCTSTR *>(&lpszObjectSID);
|
|
|
|
|
|
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);
|
|
|
|
|
|
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, (void**)&spSchemaObjectClass);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
|
|
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 GetNamedSecurityInfo(%s, ...)\n", lpszObjectLdapPath);
|
|
|
|
dwErr = ::GetNamedSecurityInfo(IN const_cast<LPWSTR>(lpszObjectLdapPath),
|
|
IN SE_DS_OBJECT_ALL,
|
|
IN DACL_SECURITY_INFORMATION,
|
|
OUT NULL,
|
|
OUT NULL,
|
|
OUT &pDacl,
|
|
OUT NULL,
|
|
OUT &pSD);
|
|
|
|
TRACE(L"GetNamedSecurityInfo() returned dwErr = 0x%x\n", dwErr);
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
TRACE(L"failed on GetNamedSecurityInfo(): dwErr = 0x%x\n", dwErr);
|
|
WCHAR szMsg[512];
|
|
LoadStringHelper(IDS_DELEGWIZ_ERR_GET_SEC_INFO, szMsg, 512);
|
|
WizReportWin32Error(szMsg, dwErr);
|
|
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 SetNamedSecurityInfo(%s, ...)\n", lpszObjectLdapPath);
|
|
|
|
dwErr = ::SetNamedSecurityInfo(IN const_cast<LPWSTR>(lpszObjectLdapPath),
|
|
IN SE_DS_OBJECT_ALL,
|
|
IN DACL_SECURITY_INFORMATION,
|
|
IN NULL,
|
|
IN NULL,
|
|
IN pOldAcl,
|
|
IN NULL);
|
|
|
|
TRACE(L"SetNamedSecurityInfo() returned dwErr = 0x%x\n", dwErr);
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
TRACE(L"failed on SetNamedSecurityInfo(): dwErr = 0x%x\n", dwErr);
|
|
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);
|
|
|
|
WizReportWin32Error(szMsg, dwErr);
|
|
goto exit;
|
|
}
|
|
bRetVal = TRUE;
|
|
|
|
|
|
exit:
|
|
// cleanup memory
|
|
if (pOldAcl != NULL)
|
|
::LocalFree(pOldAcl);
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
|
|
|
|
|