|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: R P C D L G . C P P
//
// Contents: Dialog box handling for RPC configuration.
//
// Notes:
//
// Author: danielwe 3 Mar 1997
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "mscliobj.h"
#include "msclidlg.h"
#include "ncatlui.h"
#include "ncerror.h"
#include "ncreg.h"
#include "ncui.h"
#include "msclihlp.h"
//
// Name service provider struct. Just holds some data used by the dialog.
//
struct NSP { PCWSTR pszProtocol; PCWSTR pszEndPoint; WCHAR szNetAddr[c_cchMaxNetAddr]; BOOL fUsesNetAddr; };
static const WCHAR c_szRegKeyNameSvc[] = L"Software\\Microsoft\\Rpc\\NameService"; static const WCHAR c_szNetAddress[] = L"NetworkAddress"; static const WCHAR c_szSrvNetAddress[] = L"ServerNetworkAddress"; static const WCHAR c_szProtocol[] = L"Protocol"; static const WCHAR c_szValueEndPoint[] = L"Endpoint"; static const WCHAR c_szProtDCE[] = L"ncacn_ip_tcp"; static const WCHAR c_szEndPoint[] = L"\\pipe\\locator";
// Used externally
extern const WCHAR c_szDefNetAddr[] = L"\\\\."; extern const WCHAR c_szProtWinNT[] = L"ncacn_np";
// Helpfile
extern const WCHAR c_szNetCfgHelpFile[];
//+---------------------------------------------------------------------------
//
// Member: CMSClient::HrGetRPCRegistryInfo
//
// Purpose: Reads the current state of the RPC configuration from the
// registry into an in-memory struct. All changes occur to the
// struct until Apply() is called at which time all changes are
// written from the struct to the registry. Any values that
// cannot be obtained are given reasonable defaults.
//
// Arguments:
// (none)
//
// Returns: HRESULT, Error code.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
HRESULT CMSClient::HrGetRPCRegistryInfo() { HRESULT hr = S_OK;
// This key *will* be there because it's in the system hive.
hr = HrRegOpenKeyBestAccess(HKEY_LOCAL_MACHINE, c_szRegKeyNameSvc, &m_hkeyRPCName); if (FAILED(hr)) { goto err; }
// Find out what protocol the current name service provider is using.
// This will allow us to set the default selection for the combo box.
hr = HrRegQueryString(m_hkeyRPCName, c_szProtocol, &m_rpcData.strProt); if (FAILED(hr)) { goto err; }
// Get the current value of the end point
hr = HrRegQueryString(m_hkeyRPCName, c_szValueEndPoint, &m_rpcData.strEndPoint); if (FAILED(hr)) { if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { // Use default value
m_rpcData.strEndPoint = c_szEndPoint; hr = S_OK; } else { goto err; } }
// If the name service provider uses a network address, we need to get it
// too so we can fill in that nice little edit box with it.
hr = HrRegQueryString(m_hkeyRPCName, c_szNetAddress, &m_rpcData.strNetAddr); if (FAILED(hr)) { goto err; }
err: TraceError("CMSClient::HrGetRPCRegistryInfo", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Member: CMSClient::HrSetRPCRegistryInfo
//
// Purpose: Write out changes to the data structure (if there were any) to
// the registry.
//
// Arguments:
// (none)
//
// Returns: HRESULT, Error code.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
HRESULT CMSClient::HrSetRPCRegistryInfo() { HRESULT hr = S_OK;
struct REG_SET { PCWSTR pszValue; const tstring * pstrData; };
const REG_SET aregs[] = { {c_szNetAddress, &m_rpcData.strNetAddr}, {c_szSrvNetAddress, &m_rpcData.strNetAddr}, {c_szValueEndPoint, &m_rpcData.strEndPoint}, {c_szProtocol, &m_rpcData.strProt}, }; static const INT cregs = celems(aregs);
if (m_fRPCChanges) { INT iregs;
for (iregs = 0; iregs < cregs; iregs++) { Assert(aregs[iregs].pstrData); hr = HrRegSetString(m_hkeyRPCName, aregs[iregs].pszValue, *aregs[iregs].pstrData); if (FAILED(hr)) { goto err; } } } err: TraceError("CMSClient::HrSetRPCRegistryInfo", hr); return hr; }
//
// Dialog handlers
//
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::OnInitDialog
//
// Purpose: Called when this dialog is first brought up.
//
// Arguments:
// uMsg [in]
// wParam [in] See the ATL documentation for params.
// lParam [in]
// bHandled [in]
//
// Returns: See the ATL documentation for return results.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
LRESULT CRPCConfigDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { HRESULT hr = S_OK; PCWSTR pszCBItem; NSP * pnspNT = NULL; NSP * pnspDCE = NULL; INT iItem; INT cItems;
const RPC_CONFIG_DATA * prpcData;
// Make sure selection is always undetermined when the dialog is invoked.
m_isel = -1;
prpcData = m_pmsc->RPCData(); Assert(prpcData);
// Allocate some structs to associate with item data.
pnspNT = new NSP; pnspDCE = new NSP;
if ((pnspNT == NULL) || (pnspDCE == NULL)) { return(E_OUTOFMEMORY); }
pnspNT->pszProtocol = c_szProtWinNT; pnspNT->pszEndPoint = c_szEndPoint;
// This field is unused by NT name service. Just zero it out. When it
// comes time to save the network address, we'll see that fUsesNetAddr is
// FALSE and the szNetAddr string is empty and just save a hardcoded
// net address.
*pnspNT->szNetAddr = 0; pnspNT->fUsesNetAddr = FALSE;
pnspDCE->pszProtocol = c_szProtDCE; pnspDCE->pszEndPoint = L""; *pnspDCE->szNetAddr = 0; pnspDCE->fUsesNetAddr = TRUE;
//
// Setup Name Service combo box
//
pszCBItem = SzLoadIds(STR_NTLocator); iItem = SendDlgItemMessage(CMB_NameService, CB_ADDSTRING, 0, (LPARAM)pszCBItem); SendDlgItemMessage(CMB_NameService, CB_SETITEMDATA, iItem, (LPARAM)pnspNT);
pszCBItem = SzLoadIds(STR_DCELocator); iItem = SendDlgItemMessage(CMB_NameService, CB_ADDSTRING, 0, (LPARAM)pszCBItem); SendDlgItemMessage(CMB_NameService, CB_SETITEMDATA, iItem, (LPARAM)pnspDCE);
cItems = SendDlgItemMessage(CMB_NameService, CB_GETCOUNT);
// Find the item in the list that has the same protocol as the one from
// the registry and make it the current selection.
for (iItem = 0; iItem < cItems; iItem++) { NSP *pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, iItem, 0); Assert(pnsp); if (!lstrcmpiW (pnsp->pszProtocol, prpcData->strProt.c_str())) { lstrcpyW (pnsp->szNetAddr, prpcData->strNetAddr.c_str()); SendDlgItemMessage (CMB_NameService, CB_SETCURSEL, iItem, 0); break; } }
AssertSz(iItem != cItems, "Protocol not found!");
// Limit the edit box to the maximum length of a network address.
SendDlgItemMessage(EDT_NetAddress, EM_LIMITTEXT, c_cchMaxNetAddr, 0);
SetState();
TraceError("CRPCConfigDlg::OnInitDialog", hr); return LresFromHr(hr); }
//+---------------------------------------------------------------------------
//
// Method: CRPCConfigDlg::OnContextMenu
//
// Desc: Bring up context-sensitive help
//
// Args: Standard command parameters
//
// Return: LRESULT
//
LRESULT CRPCConfigDlg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { if (g_aHelpIDs_DLG_RPCConfig != NULL) { ::WinHelp(m_hWnd, c_szNetCfgHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)g_aHelpIDs_DLG_RPCConfig); } return 0; }
//+---------------------------------------------------------------------------
//
// Method: CRPCConfigDlg::OnHelp
//
// Desc: Bring up context-sensitive help when dragging ? icon over a control
//
// Args: Standard command parameters
//
// Return: LRESULT
//
//
LRESULT CRPCConfigDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled) { LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam); Assert(lphi);
if ((g_aHelpIDs_DLG_RPCConfig != NULL) && (HELPINFO_WINDOW == lphi->iContextType)) { ::WinHelp(static_cast<HWND>(lphi->hItemHandle), c_szNetCfgHelpFile, HELP_WM_HELP, (ULONG_PTR)g_aHelpIDs_DLG_RPCConfig); } return 0; }
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::SetState
//
// Purpose: Set the state of the edit control when selection changes.
//
// Arguments:
// (none)
//
// Returns: Nothing.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
VOID CRPCConfigDlg::SetState() { INT iItem; NSP * pnsp; NSP * pnspOld = NULL; HWND hwndEdit = GetDlgItem(EDT_NetAddress);
iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0); Assert(iItem != CB_ERR);
// If the selection hasn't changed, just return
if (iItem == m_isel) return;
if (m_isel != -1) { // Get the item data of the previous selection
pnspOld = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, m_isel, 0); }
m_isel = iItem;
// Get the item data of the new selection
pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, iItem, 0); Assert(pnsp);
if (pnsp->fUsesNetAddr) { // This provider uses the NetAddress field. Set the edit control with
// its text.
::SetWindowText(hwndEdit, pnsp->szNetAddr); } else { // Doesn't use NetAddress. Blank it out and save the old one.
if (pnspOld) { ::GetWindowText(hwndEdit, pnspOld->szNetAddr, c_cchMaxNetAddr); } ::SetWindowText(hwndEdit, L""); }
// Disable the edit box for name service providers that don't use the
// network address field.
::EnableWindow(hwndEdit, pnsp->fUsesNetAddr); ::EnableWindow(GetDlgItem(IDC_TXT_NetAddress), pnsp->fUsesNetAddr); }
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::HrValidateRpcData
//
// Purpose: Ensures that the RPC data entered in the dialog is valid.
//
// Arguments:
// (none)
//
// Returns: S_OK, if no errors, or NETCFG_E_PSNRET_INVALID_NCPAGE if there
// were errors.
//
// Author: danielwe 21 Apr 1997
//
// Notes:
//
HRESULT CRPCConfigDlg::HrValidateRpcData() { HRESULT hr = S_OK; INT iItem; NSP * pnsp; HWND hwndEdit = GetDlgItem(EDT_NetAddress);
iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0); if (iItem != CB_ERR) { // Get current name service info.
pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, iItem, 0); Assert(pnsp);
if (pnsp->fUsesNetAddr) { INT cch;
// This name service uses the network address field. Make sure it
// is not empty
cch = ::GetWindowTextLength(hwndEdit); if (!cch) { // DCE doesn't allow empty network addresses
NcMsgBox(m_hWnd, STR_ErrorCaption, STR_InvalidNetAddress, MB_OK | MB_ICONEXCLAMATION); ::SetFocus(hwndEdit); hr = NETCFG_E_PSNRET_INVALID_NCPAGE; } } }
TraceError("CRPCConfigDlg::HrValidateRpcData", hr); return hr; }
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::OnKillActive
//
// Purpose: Called when the current page is switched away from or the
// property sheet is closed.
//
// Arguments:
// idCtrl []
// pnmh [] See the ATL documentation for return results.
// bHandled []
//
// Returns: S_OK, if no errors, or NETCFG_E_PSNRET_INVALID_NCPAGE if there
// were errors.
//
// Author: danielwe 21 Apr 1997
//
// Notes:
//
LRESULT CRPCConfigDlg::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { HRESULT hr = S_OK;
hr = HrValidateRpcData();
TraceError("CRPCConfigDlg::OnKillActive", hr); return LresFromHr(hr); }
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::OnOk
//
// Purpose: Called when the OK button is pressed.
//
// Arguments:
// idCtrl [in]
// pnmh [in] See the ATL documentation for params.
// bHandled [in]
//
// Returns: See the ATL documentation for return results.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
LRESULT CRPCConfigDlg::OnOk(int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { HRESULT hr = S_OK; INT iItem; NSP * pnsp; HWND hwndEdit = GetDlgItem(EDT_NetAddress); RPC_CONFIG_DATA * prpcData;
// Get a read-write version of the in-memory RPC data
prpcData = m_pmsc->RPCDataRW(); Assert(prpcData);
iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0); Assert(iItem != CB_ERR);
pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, iItem, 0); Assert(pnsp);
if (pnsp->fUsesNetAddr) { #ifdef DBG
INT cch;
cch = ::GetWindowTextLength(hwndEdit); AssertSz(cch, "I though we validated this was not empty!"); #endif
// obtain network address from edit control
::GetWindowText(hwndEdit, pnsp->szNetAddr, c_cchMaxNetAddr); } else { // copy in a default network address
lstrcpyW (pnsp->szNetAddr, c_szDefNetAddr); }
// Set the in-memory RPC data
prpcData->strNetAddr = pnsp->szNetAddr; prpcData->strEndPoint = pnsp->pszEndPoint; prpcData->strProt = pnsp->pszProtocol; m_pmsc->SetRPCDirty();
TraceError("CRPCConfigDlg::OnOk", hr); return LresFromHr(hr); }
//+---------------------------------------------------------------------------
//
// Member: CRPCConfigDlg::OnDestroy
//
// Purpose: Called when the dialog is destroyed.
//
// Arguments:
// uMsg [in]
// wParam [in] See the ATL documentation for params.
// lParam [in]
// bHandled [in]
//
// Returns: See the ATL documentation for return results.
//
// Author: danielwe 3 Mar 1997
//
// Notes:
//
LRESULT CRPCConfigDlg::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { INT iItem; INT cItems; NSP * pnsp;
// Walk the list of name service providers and free the NSP structs we
// allocated before.
cItems = SendDlgItemMessage(CMB_NameService, CB_GETCOUNT, 0, 0); for (iItem = 0; iItem < cItems; iItem++) { pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA, iItem, 0); AssertSz(pnsp, "This should not be NULL!"); delete pnsp; }
return 0; }
|