Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

588 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: R P C D L G . C P P
  7. //
  8. // Contents: Dialog box handling for RPC configuration.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 3 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "mscliobj.h"
  18. #include "msclidlg.h"
  19. #include "ncatlui.h"
  20. #include "ncerror.h"
  21. #include "ncreg.h"
  22. #include "ncui.h"
  23. #include "msclihlp.h"
  24. //
  25. // Name service provider struct. Just holds some data used by the dialog.
  26. //
  27. struct NSP
  28. {
  29. PCWSTR pszProtocol;
  30. PCWSTR pszEndPoint;
  31. WCHAR szNetAddr[c_cchMaxNetAddr];
  32. BOOL fUsesNetAddr;
  33. };
  34. static const WCHAR c_szRegKeyNameSvc[] = L"Software\\Microsoft\\Rpc\\NameService";
  35. static const WCHAR c_szNetAddress[] = L"NetworkAddress";
  36. static const WCHAR c_szSrvNetAddress[] = L"ServerNetworkAddress";
  37. static const WCHAR c_szProtocol[] = L"Protocol";
  38. static const WCHAR c_szValueEndPoint[] = L"Endpoint";
  39. static const WCHAR c_szProtDCE[] = L"ncacn_ip_tcp";
  40. static const WCHAR c_szEndPoint[] = L"\\pipe\\locator";
  41. // Used externally
  42. extern const WCHAR c_szDefNetAddr[] = L"\\\\.";
  43. extern const WCHAR c_szProtWinNT[] = L"ncacn_np";
  44. // Helpfile
  45. extern const WCHAR c_szNetCfgHelpFile[];
  46. //+---------------------------------------------------------------------------
  47. //
  48. // Member: CMSClient::HrGetRPCRegistryInfo
  49. //
  50. // Purpose: Reads the current state of the RPC configuration from the
  51. // registry into an in-memory struct. All changes occur to the
  52. // struct until Apply() is called at which time all changes are
  53. // written from the struct to the registry. Any values that
  54. // cannot be obtained are given reasonable defaults.
  55. //
  56. // Arguments:
  57. // (none)
  58. //
  59. // Returns: HRESULT, Error code.
  60. //
  61. // Author: danielwe 3 Mar 1997
  62. //
  63. // Notes:
  64. //
  65. HRESULT CMSClient::HrGetRPCRegistryInfo()
  66. {
  67. HRESULT hr = S_OK;
  68. // This key *will* be there because it's in the system hive.
  69. hr = HrRegOpenKeyBestAccess(HKEY_LOCAL_MACHINE, c_szRegKeyNameSvc,
  70. &m_hkeyRPCName);
  71. if (FAILED(hr))
  72. {
  73. goto err;
  74. }
  75. // Find out what protocol the current name service provider is using.
  76. // This will allow us to set the default selection for the combo box.
  77. hr = HrRegQueryString(m_hkeyRPCName, c_szProtocol,
  78. &m_rpcData.strProt);
  79. if (FAILED(hr))
  80. {
  81. goto err;
  82. }
  83. // Get the current value of the end point
  84. hr = HrRegQueryString(m_hkeyRPCName, c_szValueEndPoint,
  85. &m_rpcData.strEndPoint);
  86. if (FAILED(hr))
  87. {
  88. if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  89. {
  90. // Use default value
  91. m_rpcData.strEndPoint = c_szEndPoint;
  92. hr = S_OK;
  93. }
  94. else
  95. {
  96. goto err;
  97. }
  98. }
  99. // If the name service provider uses a network address, we need to get it
  100. // too so we can fill in that nice little edit box with it.
  101. hr = HrRegQueryString(m_hkeyRPCName, c_szNetAddress,
  102. &m_rpcData.strNetAddr);
  103. if (FAILED(hr))
  104. {
  105. goto err;
  106. }
  107. err:
  108. TraceError("CMSClient::HrGetRPCRegistryInfo", hr);
  109. return hr;
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CMSClient::HrSetRPCRegistryInfo
  114. //
  115. // Purpose: Write out changes to the data structure (if there were any) to
  116. // the registry.
  117. //
  118. // Arguments:
  119. // (none)
  120. //
  121. // Returns: HRESULT, Error code.
  122. //
  123. // Author: danielwe 3 Mar 1997
  124. //
  125. // Notes:
  126. //
  127. HRESULT CMSClient::HrSetRPCRegistryInfo()
  128. {
  129. HRESULT hr = S_OK;
  130. struct REG_SET
  131. {
  132. PCWSTR pszValue;
  133. const tstring * pstrData;
  134. };
  135. const REG_SET aregs[] =
  136. {
  137. {c_szNetAddress, &m_rpcData.strNetAddr},
  138. {c_szSrvNetAddress, &m_rpcData.strNetAddr},
  139. {c_szValueEndPoint, &m_rpcData.strEndPoint},
  140. {c_szProtocol, &m_rpcData.strProt},
  141. };
  142. static const INT cregs = celems(aregs);
  143. if (m_fRPCChanges)
  144. {
  145. INT iregs;
  146. for (iregs = 0; iregs < cregs; iregs++)
  147. {
  148. Assert(aregs[iregs].pstrData);
  149. hr = HrRegSetString(m_hkeyRPCName, aregs[iregs].pszValue,
  150. *aregs[iregs].pstrData);
  151. if (FAILED(hr))
  152. {
  153. goto err;
  154. }
  155. }
  156. }
  157. err:
  158. TraceError("CMSClient::HrSetRPCRegistryInfo", hr);
  159. return hr;
  160. }
  161. //
  162. // Dialog handlers
  163. //
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Member: CRPCConfigDlg::OnInitDialog
  167. //
  168. // Purpose: Called when this dialog is first brought up.
  169. //
  170. // Arguments:
  171. // uMsg [in]
  172. // wParam [in] See the ATL documentation for params.
  173. // lParam [in]
  174. // bHandled [in]
  175. //
  176. // Returns: See the ATL documentation for return results.
  177. //
  178. // Author: danielwe 3 Mar 1997
  179. //
  180. // Notes:
  181. //
  182. LRESULT CRPCConfigDlg::OnInitDialog(UINT uMsg, WPARAM wParam,
  183. LPARAM lParam, BOOL& bHandled)
  184. {
  185. HRESULT hr = S_OK;
  186. PCWSTR pszCBItem;
  187. NSP * pnspNT = NULL;
  188. NSP * pnspDCE = NULL;
  189. INT iItem;
  190. INT cItems;
  191. const RPC_CONFIG_DATA * prpcData;
  192. // Make sure selection is always undetermined when the dialog is invoked.
  193. m_isel = -1;
  194. prpcData = m_pmsc->RPCData();
  195. Assert(prpcData);
  196. // Allocate some structs to associate with item data.
  197. pnspNT = new NSP;
  198. pnspDCE = new NSP;
  199. if ((pnspNT == NULL) ||
  200. (pnspDCE == NULL))
  201. {
  202. return(E_OUTOFMEMORY);
  203. }
  204. pnspNT->pszProtocol = c_szProtWinNT;
  205. pnspNT->pszEndPoint = c_szEndPoint;
  206. // This field is unused by NT name service. Just zero it out. When it
  207. // comes time to save the network address, we'll see that fUsesNetAddr is
  208. // FALSE and the szNetAddr string is empty and just save a hardcoded
  209. // net address.
  210. *pnspNT->szNetAddr = 0;
  211. pnspNT->fUsesNetAddr = FALSE;
  212. pnspDCE->pszProtocol = c_szProtDCE;
  213. pnspDCE->pszEndPoint = L"";
  214. *pnspDCE->szNetAddr = 0;
  215. pnspDCE->fUsesNetAddr = TRUE;
  216. //
  217. // Setup Name Service combo box
  218. //
  219. pszCBItem = SzLoadIds(STR_NTLocator);
  220. iItem = SendDlgItemMessage(CMB_NameService, CB_ADDSTRING, 0,
  221. (LPARAM)pszCBItem);
  222. SendDlgItemMessage(CMB_NameService, CB_SETITEMDATA, iItem,
  223. (LPARAM)pnspNT);
  224. pszCBItem = SzLoadIds(STR_DCELocator);
  225. iItem = SendDlgItemMessage(CMB_NameService, CB_ADDSTRING, 0,
  226. (LPARAM)pszCBItem);
  227. SendDlgItemMessage(CMB_NameService, CB_SETITEMDATA, iItem,
  228. (LPARAM)pnspDCE);
  229. cItems = SendDlgItemMessage(CMB_NameService, CB_GETCOUNT);
  230. // Find the item in the list that has the same protocol as the one from
  231. // the registry and make it the current selection.
  232. for (iItem = 0; iItem < cItems; iItem++)
  233. {
  234. NSP *pnsp = (NSP *)SendDlgItemMessage(CMB_NameService,
  235. CB_GETITEMDATA, iItem, 0);
  236. Assert(pnsp);
  237. if (!lstrcmpiW (pnsp->pszProtocol, prpcData->strProt.c_str()))
  238. {
  239. lstrcpyW (pnsp->szNetAddr, prpcData->strNetAddr.c_str());
  240. SendDlgItemMessage (CMB_NameService, CB_SETCURSEL, iItem, 0);
  241. break;
  242. }
  243. }
  244. AssertSz(iItem != cItems, "Protocol not found!");
  245. // Limit the edit box to the maximum length of a network address.
  246. SendDlgItemMessage(EDT_NetAddress, EM_LIMITTEXT, c_cchMaxNetAddr, 0);
  247. SetState();
  248. TraceError("CRPCConfigDlg::OnInitDialog", hr);
  249. return LresFromHr(hr);
  250. }
  251. //+---------------------------------------------------------------------------
  252. //
  253. // Method: CRPCConfigDlg::OnContextMenu
  254. //
  255. // Desc: Bring up context-sensitive help
  256. //
  257. // Args: Standard command parameters
  258. //
  259. // Return: LRESULT
  260. //
  261. LRESULT
  262. CRPCConfigDlg::OnContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  263. {
  264. if (g_aHelpIDs_DLG_RPCConfig != NULL)
  265. {
  266. ::WinHelp(m_hWnd,
  267. c_szNetCfgHelpFile,
  268. HELP_CONTEXTMENU,
  269. (ULONG_PTR)g_aHelpIDs_DLG_RPCConfig);
  270. }
  271. return 0;
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // Method: CRPCConfigDlg::OnHelp
  276. //
  277. // Desc: Bring up context-sensitive help when dragging ? icon over a control
  278. //
  279. // Args: Standard command parameters
  280. //
  281. // Return: LRESULT
  282. //
  283. //
  284. LRESULT
  285. CRPCConfigDlg::OnHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& fHandled)
  286. {
  287. LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
  288. Assert(lphi);
  289. if ((g_aHelpIDs_DLG_RPCConfig != NULL) && (HELPINFO_WINDOW == lphi->iContextType))
  290. {
  291. ::WinHelp(static_cast<HWND>(lphi->hItemHandle),
  292. c_szNetCfgHelpFile,
  293. HELP_WM_HELP,
  294. (ULONG_PTR)g_aHelpIDs_DLG_RPCConfig);
  295. }
  296. return 0;
  297. }
  298. //+---------------------------------------------------------------------------
  299. //
  300. // Member: CRPCConfigDlg::SetState
  301. //
  302. // Purpose: Set the state of the edit control when selection changes.
  303. //
  304. // Arguments:
  305. // (none)
  306. //
  307. // Returns: Nothing.
  308. //
  309. // Author: danielwe 3 Mar 1997
  310. //
  311. // Notes:
  312. //
  313. VOID CRPCConfigDlg::SetState()
  314. {
  315. INT iItem;
  316. NSP * pnsp;
  317. NSP * pnspOld = NULL;
  318. HWND hwndEdit = GetDlgItem(EDT_NetAddress);
  319. iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0);
  320. Assert(iItem != CB_ERR);
  321. // If the selection hasn't changed, just return
  322. if (iItem == m_isel)
  323. return;
  324. if (m_isel != -1)
  325. {
  326. // Get the item data of the previous selection
  327. pnspOld = (NSP *)SendDlgItemMessage(CMB_NameService,
  328. CB_GETITEMDATA, m_isel, 0);
  329. }
  330. m_isel = iItem;
  331. // Get the item data of the new selection
  332. pnsp = (NSP *)SendDlgItemMessage(CMB_NameService,
  333. CB_GETITEMDATA, iItem, 0);
  334. Assert(pnsp);
  335. if (pnsp->fUsesNetAddr)
  336. {
  337. // This provider uses the NetAddress field. Set the edit control with
  338. // its text.
  339. ::SetWindowText(hwndEdit, pnsp->szNetAddr);
  340. }
  341. else
  342. {
  343. // Doesn't use NetAddress. Blank it out and save the old one.
  344. if (pnspOld)
  345. {
  346. ::GetWindowText(hwndEdit, pnspOld->szNetAddr, c_cchMaxNetAddr);
  347. }
  348. ::SetWindowText(hwndEdit, L"");
  349. }
  350. // Disable the edit box for name service providers that don't use the
  351. // network address field.
  352. ::EnableWindow(hwndEdit, pnsp->fUsesNetAddr);
  353. ::EnableWindow(GetDlgItem(IDC_TXT_NetAddress), pnsp->fUsesNetAddr);
  354. }
  355. //+---------------------------------------------------------------------------
  356. //
  357. // Member: CRPCConfigDlg::HrValidateRpcData
  358. //
  359. // Purpose: Ensures that the RPC data entered in the dialog is valid.
  360. //
  361. // Arguments:
  362. // (none)
  363. //
  364. // Returns: S_OK, if no errors, or NETCFG_E_PSNRET_INVALID_NCPAGE if there
  365. // were errors.
  366. //
  367. // Author: danielwe 21 Apr 1997
  368. //
  369. // Notes:
  370. //
  371. HRESULT CRPCConfigDlg::HrValidateRpcData()
  372. {
  373. HRESULT hr = S_OK;
  374. INT iItem;
  375. NSP * pnsp;
  376. HWND hwndEdit = GetDlgItem(EDT_NetAddress);
  377. iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0);
  378. if (iItem != CB_ERR)
  379. {
  380. // Get current name service info.
  381. pnsp = (NSP *)SendDlgItemMessage(CMB_NameService, CB_GETITEMDATA,
  382. iItem, 0);
  383. Assert(pnsp);
  384. if (pnsp->fUsesNetAddr)
  385. {
  386. INT cch;
  387. // This name service uses the network address field. Make sure it
  388. // is not empty
  389. cch = ::GetWindowTextLength(hwndEdit);
  390. if (!cch)
  391. {
  392. // DCE doesn't allow empty network addresses
  393. NcMsgBox(m_hWnd, STR_ErrorCaption, STR_InvalidNetAddress,
  394. MB_OK | MB_ICONEXCLAMATION);
  395. ::SetFocus(hwndEdit);
  396. hr = NETCFG_E_PSNRET_INVALID_NCPAGE;
  397. }
  398. }
  399. }
  400. TraceError("CRPCConfigDlg::HrValidateRpcData", hr);
  401. return hr;
  402. }
  403. //+---------------------------------------------------------------------------
  404. //
  405. // Member: CRPCConfigDlg::OnKillActive
  406. //
  407. // Purpose: Called when the current page is switched away from or the
  408. // property sheet is closed.
  409. //
  410. // Arguments:
  411. // idCtrl []
  412. // pnmh [] See the ATL documentation for return results.
  413. // bHandled []
  414. //
  415. // Returns: S_OK, if no errors, or NETCFG_E_PSNRET_INVALID_NCPAGE if there
  416. // were errors.
  417. //
  418. // Author: danielwe 21 Apr 1997
  419. //
  420. // Notes:
  421. //
  422. LRESULT CRPCConfigDlg::OnKillActive(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  423. {
  424. HRESULT hr = S_OK;
  425. hr = HrValidateRpcData();
  426. TraceError("CRPCConfigDlg::OnKillActive", hr);
  427. return LresFromHr(hr);
  428. }
  429. //+---------------------------------------------------------------------------
  430. //
  431. // Member: CRPCConfigDlg::OnOk
  432. //
  433. // Purpose: Called when the OK button is pressed.
  434. //
  435. // Arguments:
  436. // idCtrl [in]
  437. // pnmh [in] See the ATL documentation for params.
  438. // bHandled [in]
  439. //
  440. // Returns: See the ATL documentation for return results.
  441. //
  442. // Author: danielwe 3 Mar 1997
  443. //
  444. // Notes:
  445. //
  446. LRESULT CRPCConfigDlg::OnOk(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  447. {
  448. HRESULT hr = S_OK;
  449. INT iItem;
  450. NSP * pnsp;
  451. HWND hwndEdit = GetDlgItem(EDT_NetAddress);
  452. RPC_CONFIG_DATA * prpcData;
  453. // Get a read-write version of the in-memory RPC data
  454. prpcData = m_pmsc->RPCDataRW();
  455. Assert(prpcData);
  456. iItem = SendDlgItemMessage(CMB_NameService, CB_GETCURSEL, 0, 0);
  457. Assert(iItem != CB_ERR);
  458. pnsp = (NSP *)SendDlgItemMessage(CMB_NameService,
  459. CB_GETITEMDATA, iItem, 0);
  460. Assert(pnsp);
  461. if (pnsp->fUsesNetAddr)
  462. {
  463. #ifdef DBG
  464. INT cch;
  465. cch = ::GetWindowTextLength(hwndEdit);
  466. AssertSz(cch, "I though we validated this was not empty!");
  467. #endif
  468. // obtain network address from edit control
  469. ::GetWindowText(hwndEdit, pnsp->szNetAddr, c_cchMaxNetAddr);
  470. }
  471. else
  472. {
  473. // copy in a default network address
  474. lstrcpyW (pnsp->szNetAddr, c_szDefNetAddr);
  475. }
  476. // Set the in-memory RPC data
  477. prpcData->strNetAddr = pnsp->szNetAddr;
  478. prpcData->strEndPoint = pnsp->pszEndPoint;
  479. prpcData->strProt = pnsp->pszProtocol;
  480. m_pmsc->SetRPCDirty();
  481. TraceError("CRPCConfigDlg::OnOk", hr);
  482. return LresFromHr(hr);
  483. }
  484. //+---------------------------------------------------------------------------
  485. //
  486. // Member: CRPCConfigDlg::OnDestroy
  487. //
  488. // Purpose: Called when the dialog is destroyed.
  489. //
  490. // Arguments:
  491. // uMsg [in]
  492. // wParam [in] See the ATL documentation for params.
  493. // lParam [in]
  494. // bHandled [in]
  495. //
  496. // Returns: See the ATL documentation for return results.
  497. //
  498. // Author: danielwe 3 Mar 1997
  499. //
  500. // Notes:
  501. //
  502. LRESULT CRPCConfigDlg::OnDestroy(UINT uMsg, WPARAM wParam,
  503. LPARAM lParam, BOOL& bHandled)
  504. {
  505. INT iItem;
  506. INT cItems;
  507. NSP * pnsp;
  508. // Walk the list of name service providers and free the NSP structs we
  509. // allocated before.
  510. cItems = SendDlgItemMessage(CMB_NameService, CB_GETCOUNT, 0, 0);
  511. for (iItem = 0; iItem < cItems; iItem++)
  512. {
  513. pnsp = (NSP *)SendDlgItemMessage(CMB_NameService,
  514. CB_GETITEMDATA, iItem, 0);
  515. AssertSz(pnsp, "This should not be NULL!");
  516. delete pnsp;
  517. }
  518. return 0;
  519. }