//+------------------------------------------------------------------------- // // Microsoft Windows // // Copyright (C) Microsoft Corporation, 1998 - 1999 // // File: proppage.cpp // //-------------------------------------------------------------------------- #include "stdafx.h" #include "resource.h" #include "proppage.h" #include "domobj.h" #include "cdomain.h" #include "helparr.h" //////////////////////////////////////////////////////////////////////////////// // CUpnSuffixPropertyPage // hook the property sheet callback to allow // C++ object destruction // static callback override function UINT CALLBACK CUpnSuffixPropertyPage::PropSheetPageProc( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { CUpnSuffixPropertyPage* pPage = (CUpnSuffixPropertyPage*)(ppsp->lParam); ASSERT(pPage != NULL); UINT nResult = (*(pPage->m_pfnOldPropCallback))(hwnd, uMsg, ppsp); if (uMsg == PSPCB_RELEASE) { delete pPage; } return nResult; } BEGIN_MESSAGE_MAP(CUpnSuffixPropertyPage, CPropertyPage) ON_BN_CLICKED(IDC_ADD_BTN, OnAddButton) ON_BN_CLICKED(IDC_DELETE_BTN, OnDeleteButton) ON_EN_CHANGE(IDC_EDIT, OnEditChange) ON_WM_HELPINFO() END_MESSAGE_MAP() CUpnSuffixPropertyPage::CUpnSuffixPropertyPage() : CPropertyPage(IDD_UPN_SUFFIX), m_nPreviousDefaultButtonID(0) { m_pfnOldPropCallback = m_psp.pfnCallback; m_psp.pfnCallback = PropSheetPageProc; m_bDirty = FALSE; m_pIADsPartitionsCont = NULL; } CUpnSuffixPropertyPage::~CUpnSuffixPropertyPage() { if (m_pIADsPartitionsCont != NULL) { m_pIADsPartitionsCont->Release(); m_pIADsPartitionsCont = NULL; } } BOOL CUpnSuffixPropertyPage::OnInitDialog() { CPropertyPage::OnInitDialog(); VERIFY(m_listBox.SubclassDlgItem(IDC_LIST, this)); ((CEdit*)GetDlgItem(IDC_EDIT))->SetLimitText(MAX_UPN_SUFFIX_LEN); HRESULT hr = _GetPartitionsContainer(); if (SUCCEEDED(hr)) { _Read(); GetDlgItem(IDC_ADD_BTN)->EnableWindow(FALSE); } else { // failed to contact DC, disable the whole UI GetDlgItem(IDC_ADD_BTN)->EnableWindow(FALSE); GetDlgItem(IDC_DELETE_BTN)->EnableWindow(FALSE); GetDlgItem(IDC_LIST)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT)->EnableWindow(FALSE); AFX_MANAGE_STATE(AfxGetStaticModuleState()); ReportError(::GetParent(m_hWnd), IDS_CANT_GET_PARTITIONS_INFORMATION, hr); } LRESULT lDefID = ::SendMessage(GetParent()->GetSafeHwnd(), DM_GETDEFID, 0, 0); if (lDefID != 0) { m_nPreviousDefaultButtonID = LOWORD(lDefID); } _SetDirty(FALSE); return TRUE; } BOOL CUpnSuffixPropertyPage::OnApply() { if (!_IsDirty()) return TRUE; HRESULT hr = _Write(); if (SUCCEEDED(hr)) { _SetDirty(FALSE); return TRUE; } ReportError(::GetParent(m_hWnd),IDS_ERROR_WRITE_UPN_SUFFIXES, hr); return FALSE; } void CUpnSuffixPropertyPage::OnEditChange() { GetDlgItemText(IDC_EDIT, m_szEditText); m_szEditText.TrimRight(); m_szEditText.TrimLeft(); BOOL bEnable = !m_szEditText.IsEmpty(); CWnd* pWndFocus = CWnd::GetFocus(); CWnd* pAddBtnWnd = GetDlgItem(IDC_ADD_BTN); if (!bEnable && (pAddBtnWnd == pWndFocus) ) { GetDlgItem(IDC_EDIT)->SetFocus(); } GetDlgItem(IDC_ADD_BTN)->EnableWindow(bEnable); if (bEnable) { // // Set the add button as the default button // ::SendMessage(GetParent()->GetSafeHwnd(), DM_SETDEFID, (WPARAM)IDC_ADD_BTN, 0); // // Force the Add button to redraw itself // ::SendDlgItemMessage(GetSafeHwnd(), IDC_ADD_BTN, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); // // Force the previous default button to redraw itself // ::SendDlgItemMessage(GetParent()->GetSafeHwnd(), m_nPreviousDefaultButtonID, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); } else { // // Set the previous button as the default button // ::SendMessage(GetParent()->GetSafeHwnd(), DM_SETDEFID, (WPARAM)m_nPreviousDefaultButtonID, 0); // // Force the previous default button to redraw itself // ::SendDlgItemMessage(GetParent()->GetSafeHwnd(), m_nPreviousDefaultButtonID, BM_SETSTYLE, BS_DEFPUSHBUTTON, MAKELPARAM(TRUE, 0)); // // Force the Add button to redraw itself // ::SendDlgItemMessage(GetParent()->GetSafeHwnd(), IDC_ADD_BTN, BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0)); } } void CUpnSuffixPropertyPage::OnAddButton() { // cannot add duplicated items int nCount = m_listBox.GetCount(); CString szItem; for (int i=0; iEnableWindow(TRUE); } _SetDirty(TRUE); } void CUpnSuffixPropertyPage::OnDeleteButton() { int nCount = m_listBox.GetCount(); int nSel = m_listBox.GetSelection(); ASSERT(nCount > 0); ASSERT((nSel >= 0) && (nSel < nCount)); // ask the user for confirmation AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (IDNO == AfxMessageBox(IDS_WARNING_DELETE_UPN_SUFFIX, MB_YESNO|MB_ICONQUESTION)) return; // save the value and put it back in the edit control CString szText; m_listBox.GetItem(nSel, szText); GetDlgItem(IDC_EDIT)->SetWindowText(szText); // delete the item in the list VERIFY(m_listBox.DeleteItem(nSel)); m_listBox.UpdateHorizontalExtent(); // handle UI changes if (nCount == 1) { // removed the last one, lost the selection CWnd* pWndFocus = CWnd::GetFocus(); CWnd* pDelBtnWnd = GetDlgItem(IDC_DELETE_BTN); if (pDelBtnWnd == pWndFocus) { GetDlgItem(IDC_EDIT)->SetFocus(); } GetDlgItem(IDC_DELETE_BTN)->EnableWindow(FALSE); } else { // need to select again: is it the last one or not int nNewSel = (nSel == nCount-1) ? nSel-1 : nSel; VERIFY(m_listBox.SetSelection(nNewSel)); ASSERT(m_listBox.GetSelection() == nNewSel); } _SetDirty(TRUE); } BOOL CUpnSuffixPropertyPage::OnHelpInfo(HELPINFO* pHelpInfo) { DialogContextHelp((DWORD*)&g_aHelpIDs_IDD_UPN_SUFFIX, pHelpInfo); return TRUE; } ////////////////////////////////////////////////////////// // CUpnSuffixPropertyPage internal implementation methods LPWSTR g_lpszRootDSE = L"LDAP://RootDSE"; LPWSTR g_lpszConfigurationNamingContext = L"configurationNamingContext"; LPWSTR g_lpszPartitionsFormat = L"LDAP://CN=Partitions,%s"; LPWSTR g_lpszPartitionsFormatWithServer = L"LDAP://%s/CN=Partitions,%s"; LPWSTR g_lpszUpnSuffixes = L"uPNSuffixes"; HRESULT CUpnSuffixPropertyPage::_GetPartitionsContainer() { if (m_pIADsPartitionsCont != NULL) { m_pIADsPartitionsCont->Release(); m_pIADsPartitionsCont = NULL; } // get the root of the enterprise IADs* pADs; HRESULT hr = ::ADsGetObject(g_lpszRootDSE, IID_IADs, (void **)&pADs); if (!(SUCCEEDED(hr))) { return hr; } // // Get the server name so we can bind with ADS_SERVER_BIND // CString szServerName; hr = GetADSIServerName(szServerName, pADs); if (FAILED(hr)) { szServerName.Empty(); } // get the configuration naming context container VARIANT configVar; ::VariantInit(&configVar); hr = pADs->Get(g_lpszConfigurationNamingContext, &configVar); if (SUCCEEDED(hr)) { // get the partitions container DWORD dwFlags = ADS_SECURE_AUTHENTICATION; CString szPartitionsPath; if (szServerName.IsEmpty()) { szPartitionsPath.Format(g_lpszPartitionsFormat, configVar.bstrVal); } else { szPartitionsPath.Format(g_lpszPartitionsFormatWithServer, szServerName, configVar.bstrVal); dwFlags |= ADS_SERVER_BIND; } IADsContainer* pIADsContainer; hr = ::ADsOpenObject((LPWSTR)(LPCWSTR)szPartitionsPath, NULL, // username NULL, // password dwFlags, IID_IDirectoryObject, (void **)&m_pIADsPartitionsCont); if (hr == E_INVALIDARG && (dwFlags & ADS_SERVER_BIND)) { // // Trying again without the ADS_SERVER_BIND flag // dwFlags &= ~ADS_SERVER_BIND; hr = ::ADsOpenObject((LPWSTR)(LPCWSTR)szPartitionsPath, NULL, // username NULL, // password dwFlags, IID_IDirectoryObject, (void **)&m_pIADsPartitionsCont); } } ::VariantClear(&configVar); pADs->Release(); return hr; } void CUpnSuffixPropertyPage::_Read() { ASSERT(m_pIADsPartitionsCont != NULL); PADS_ATTR_INFO pAttrs = NULL; LPWSTR lpszArr[1]; DWORD cAttrs; BOOL bHaveItems = FALSE; HRESULT hr = m_pIADsPartitionsCont->GetObjectAttributes( &g_lpszUpnSuffixes, 1, &pAttrs, &cAttrs); if (SUCCEEDED(hr) && (pAttrs != NULL) && (cAttrs == 1) ) { ASSERT(pAttrs->dwADsType == ADSTYPE_CASE_IGNORE_STRING); ASSERT(cAttrs == 1); for (DWORD i=0; idwNumValues; i++) { m_listBox.AddItem(pAttrs->pADsValues[i].CaseIgnoreString); //TRACE(_T("i=%d, %s\n"), i, pAttrs->pADsValues[i].CaseIgnoreString); } bHaveItems = pAttrs->dwNumValues > 0; } if (bHaveItems) { m_listBox.UpdateHorizontalExtent(); VERIFY(m_listBox.SetSelection(0)); } GetDlgItem(IDC_DELETE_BTN)->EnableWindow(bHaveItems); if (pAttrs != NULL) { ::FreeADsMem(pAttrs); } } HRESULT CUpnSuffixPropertyPage::_Write() { ASSERT(m_pIADsPartitionsCont != NULL); DWORD cModified; CString* pStringArr = NULL; ADSVALUE* pValues = NULL; // set the update struct ADS_ATTR_INFO info; info.pszAttrName = g_lpszUpnSuffixes; info.dwADsType = ADSTYPE_CASE_IGNORE_STRING; info.dwControlCode = ADS_ATTR_CLEAR; info.pADsValues = NULL; info.dwNumValues = 0; int nCount = m_listBox.GetCount(); if (nCount > 0) { info.dwControlCode = ADS_ATTR_UPDATE; info.dwNumValues = (DWORD)nCount; pStringArr = new CString[nCount]; ADSVALUE* pValues = new ADSVALUE[nCount]; info.pADsValues = pValues; for (int i=0; iSetObjectAttributes( &info, 1, &cModified); if (pStringArr != NULL) delete[] pStringArr; if (pValues != NULL) delete[] pValues; return hr; }