/*++ Module Name: JPProp.cpp Abstract: This module contains the implementation for CReplicaSetPropPage This is used to implement the property page for Junction Point(aka Replica Set) --*/ #include "stdafx.h" #include "resource.h" #include "utils.h" #include "JpProp.h" #include "dfshelp.h" CReplicaSetPropPage::CReplicaSetPropPage() : m_lReferralTime(300), m_lNotifyHandle(0), m_lNotifyParam(0), m_bDfsRoot(FALSE), m_bHideTimeout(FALSE), CQWizardPageImpl(false) { } CReplicaSetPropPage::~CReplicaSetPropPage() { if (m_lNotifyHandle) MMCFreeNotifyHandle(m_lNotifyHandle); } extern WNDPROC g_fnOldEditCtrlProc; LRESULT CReplicaSetPropPage::OnInitDialog( IN UINT i_uMsg, IN WPARAM i_wParam, LPARAM i_lParam, IN OUT BOOL& io_bHandled ) { ::SendMessage(GetDlgItem(IDC_REFFERAL_TIME), EM_LIMITTEXT, 10, 0); ::SendMessage(GetDlgItem(IDC_REPLICA_SET_COMMENT), EM_LIMITTEXT, MAXCOMMENTSZ, 0); TCHAR szTime[16]; _stprintf(szTime, _T("%u"), m_lReferralTime); SetDlgItemText(IDC_REFFERAL_TIME, szTime); g_fnOldEditCtrlProc = reinterpret_cast( ::SetWindowLongPtr( GetDlgItem(IDC_REFFERAL_TIME), GWLP_WNDPROC, reinterpret_cast(NoPasteEditCtrlProc))); SetDlgItemText(IDC_REPLICA_SET_NAME, m_bstrJPEntryPath); SetDlgItemText(IDC_REPLICA_SET_COMMENT, m_bstrJPComment); if (m_bHideTimeout) { MyShowWindow(GetDlgItem(IDC_REFFERAL_TIME_LABEL), FALSE); MyShowWindow(GetDlgItem(IDC_REFFERAL_TIME), FALSE); } return TRUE; // To let the dialg set the control } /*++ This function is called when a user clicks the ? in the top right of a property sheet and then clciks a control, or when they hit F1 in a control. --*/ LRESULT CReplicaSetPropPage::OnCtxHelp( IN UINT i_uMsg, IN WPARAM i_wParam, IN LPARAM i_lParam, IN OUT BOOL& io_bHandled ) { LPHELPINFO lphi = (LPHELPINFO) i_lParam; if (!lphi || lphi->iContextType != HELPINFO_WINDOW || lphi->iCtrlId < 0) return FALSE; ::WinHelp((HWND)(lphi->hItemHandle), DFS_CTX_HELP_FILE, HELP_WM_HELP, (DWORD_PTR)(PVOID)g_aHelpIDs_IDD_JP_PROP); return TRUE; } /*++ This function handles "What's This" help when a user right clicks the control --*/ LRESULT CReplicaSetPropPage::OnCtxMenuHelp( IN UINT i_uMsg, IN WPARAM i_wParam, IN LPARAM i_lParam, IN OUT BOOL& io_bHandled ) { ::WinHelp((HWND)i_wParam, DFS_CTX_HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR)(PVOID)g_aHelpIDs_IDD_JP_PROP); return TRUE; } void CReplicaSetPropPage::_ReSet() { if ((IDfsRoot *)m_piDfsRoot) m_piDfsRoot.Release(); if ((IDfsJunctionPoint *)m_piDfsJPObject) m_piDfsJPObject.Release(); m_bstrJPEntryPath.Empty(); m_bstrJPComment.Empty(); m_lReferralTime = 0; m_bDfsRoot = FALSE; m_bHideTimeout = FALSE; } HRESULT CReplicaSetPropPage::Initialize( IN IDfsRoot* i_piDfsRoot, IN IDfsJunctionPoint* i_piDfsJPObject ) { if (i_piDfsRoot && i_piDfsJPObject || !i_piDfsRoot && !i_piDfsJPObject) return E_INVALIDARG; _ReSet(); HRESULT hr = S_OK; do { if (i_piDfsRoot) { m_piDfsRoot = i_piDfsRoot; m_bDfsRoot = TRUE; hr = m_piDfsRoot->get_RootEntryPath(&m_bstrJPEntryPath); BREAK_IF_FAILED(hr); hr = m_piDfsRoot->get_Comment(&m_bstrJPComment); BREAK_IF_FAILED(hr); hr = m_piDfsRoot->get_Timeout(&m_lReferralTime); if (HRESULT_FROM_WIN32(RPC_X_BAD_STUB_DATA) == hr) { // NT4 doesn't support Timeout, NetDfsGetInfo with level 4 will return 1783 when managing a NT4 root hr = S_OK; m_bHideTimeout = TRUE; m_lReferralTime = 0; } BREAK_IF_FAILED(hr); } if (i_piDfsJPObject) { m_piDfsJPObject = i_piDfsJPObject; m_bDfsRoot = FALSE; hr = m_piDfsJPObject->get_EntryPath(&m_bstrJPEntryPath); BREAK_IF_FAILED(hr); hr = m_piDfsJPObject->get_Comment(&m_bstrJPComment); BREAK_IF_FAILED(hr); hr = m_piDfsJPObject->get_Timeout(&m_lReferralTime); if (HRESULT_FROM_WIN32(RPC_X_BAD_STUB_DATA) == hr) { // NT4 doesn't support Timeout, NetDfsGetInfo with level 4 will return 1783 when managing a NT4 root hr = S_OK; m_bHideTimeout = TRUE; m_lReferralTime = 0; } BREAK_IF_FAILED(hr); } } while (0); if (FAILED(hr)) _ReSet(); return hr; } HRESULT CReplicaSetPropPage::_Save( IN BSTR i_bstrJPComment, IN long i_lTimeout) { if (m_bDfsRoot) { RETURN_INVALIDARG_IF_NULL((IDfsRoot *)m_piDfsRoot); } else { RETURN_INVALIDARG_IF_NULL((IDfsJunctionPoint *)m_piDfsJPObject); } HRESULT hr = S_OK; if (FALSE == PROPSTRNOCHNG((BSTR)m_bstrJPComment, i_bstrJPComment)) { if (m_bDfsRoot) hr = m_piDfsRoot->put_Comment(i_bstrJPComment); else hr = m_piDfsJPObject->put_Comment(i_bstrJPComment); if (SUCCEEDED(hr)) m_bstrJPComment = i_bstrJPComment; } if (SUCCEEDED(hr) && m_lReferralTime != i_lTimeout) { if (m_bDfsRoot) hr = m_piDfsRoot->put_Timeout(i_lTimeout); else hr = m_piDfsJPObject->put_Timeout(i_lTimeout); if (SUCCEEDED(hr)) m_lReferralTime = i_lTimeout; } return hr; } LRESULT CReplicaSetPropPage::OnApply() /*++ Routine Description: Called on when OK or Apply are pressed by the user. We get the information from the dialog box and notify the snapin MMCPropertyChangeNotify is used to pass on this information to the snapin. */ { CWaitCursor wait; HRESULT hr = S_OK; DWORD dwTextLength = 0; int idControl = 0; int idString = 0; BOOL bValidInput = FALSE; ULONG ulTimeout = 0; CComBSTR bstrJPComment; do { idControl = IDC_REFFERAL_TIME; CComBSTR bstrTime; hr = GetInputText(GetDlgItem(IDC_REFFERAL_TIME), &bstrTime, &dwTextLength); BREAK_IF_FAILED(hr); if (0 == dwTextLength || !ValidateTimeout(bstrTime, &ulTimeout)) { idString = IDS_MSG_TIMEOUT_INVALIDRANGE; break; } idControl = IDC_REPLICA_SET_COMMENT; hr = GetInputText(GetDlgItem(IDC_REPLICA_SET_COMMENT), &bstrJPComment, &dwTextLength); BREAK_IF_FAILED(hr); if (0 == dwTextLength) bstrJPComment = _T(""); bValidInput = TRUE; } while (0); if (FAILED(hr)) { SetActivePropertyPage(GetParent(), m_hWnd); DisplayMessageBoxForHR(hr); ::SetFocus(GetDlgItem(idControl)); return FALSE; } else if (bValidInput) { hr = _Save(bstrJPComment, ulTimeout); if (FAILED(hr)) { SetActivePropertyPage(GetParent(), m_hWnd); DisplayMessageBoxForHR(hr); return FALSE; } ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0); if (m_lNotifyHandle && m_lNotifyParam) MMCPropertyChangeNotify(m_lNotifyHandle, m_lNotifyParam); return TRUE; } else { SetActivePropertyPage(GetParent(), m_hWnd); if (idString) DisplayMessageBoxWithOK(idString); ::SetFocus(GetDlgItem(idControl)); return FALSE; } } LRESULT CReplicaSetPropPage::OnComment( IN WORD i_wNotifyCode, IN WORD i_wID, IN HWND i_hWndCtl, IN OUT BOOL& io_bHandled ) { if (EN_CHANGE == i_wNotifyCode) ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); return TRUE; } LRESULT CReplicaSetPropPage::OnReferralTime( IN WORD i_wNotifyCode, IN WORD i_wID, IN HWND i_hWndCtl, IN OUT BOOL& io_bHandled ) /*++ Routine Description: Called on an event on the Referral edit box Arguments: i_wNotifyCode - What type of event is this */ { if (EN_CHANGE == i_wNotifyCode) ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0); return TRUE; } LRESULT CReplicaSetPropPage::OnParentClosing( IN UINT i_uMsg, IN WPARAM i_wParam, LPARAM i_lParam, IN OUT BOOL& io_bHandled ) /*++ Routine Description: Used by the node to tell the propery page to close. Arguments: Not used. --*/ { ::SendMessage(GetParent(), PSM_PRESSBUTTON, PSBTN_CANCEL, 0); return TRUE; } HRESULT CReplicaSetPropPage::SetNotifyData( IN LONG_PTR i_lNotifyHandle, IN LPARAM i_lParam ) /*++ Routine Description: Set the value of notify handle to be used to notify changes and the lparam to be used for notifications. Arguments: i_lNotifyHandle - The notify handle. i_lParam - The lparam to be used with notifications --*/ { m_lNotifyHandle = i_lNotifyHandle; m_lNotifyParam = i_lParam; return S_OK; }