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.

575 lines
16 KiB

  1. /*++
  2. Copyright(c) 1998,99 Microsoft Corporation
  3. Module Name:
  4. wlbs.cpp
  5. Abstract:
  6. Windows Load Balancing Service (WLBS)
  7. Notifier object - main module implementing object
  8. Author:
  9. kyrilf
  10. --*/
  11. #include "pch.h"
  12. #pragma hdrstop
  13. #include "netcon.h"
  14. #include "ncatlui.h"
  15. #include "ndispnp.h"
  16. #include "ncsetup.h"
  17. #include "wlbs.h"
  18. #include "help.h"
  19. #include "tracelog.h"
  20. #include "wlbs.tmh" // for event tracing
  21. // ----------------------------------------------------------------------
  22. //
  23. // Function: CWLBS::CWLBS
  24. //
  25. // Purpose: constructor for class CWLBS
  26. //
  27. // Arguments: None
  28. //
  29. // Returns: None
  30. //
  31. // Notes:
  32. //
  33. // ----------------------------------------------------------------------
  34. CWLBS::CWLBS(VOID) {
  35. m_pClusterDlg = NULL;
  36. m_pHostDlg = NULL;
  37. m_pPortsDlg = NULL;
  38. ZeroMemory(&m_AdapterGuid, sizeof(m_AdapterGuid));
  39. ZeroMemory(&m_OriginalConfig, sizeof(m_OriginalConfig));
  40. ZeroMemory(&m_AdapterConfig, sizeof(m_AdapterConfig));
  41. //
  42. // Register tracing
  43. //
  44. WPP_INIT_TRACING(L"Microsoft\\NLB");
  45. }
  46. // ----------------------------------------------------------------------
  47. //
  48. // Function: CWLBS::~CWLBS
  49. //
  50. // Purpose: destructor for class CWLBS
  51. //
  52. // Arguments: None
  53. //
  54. // Returns: None
  55. //
  56. // Notes:
  57. //
  58. // ----------------------------------------------------------------------
  59. CWLBS::~CWLBS(VOID) {
  60. if (m_pClusterDlg != NULL) delete m_pClusterDlg;
  61. if (m_pHostDlg != NULL) delete m_pHostDlg;
  62. if (m_pPortsDlg != NULL) delete m_pPortsDlg;
  63. //
  64. // DeRegister tracing
  65. //
  66. WPP_CLEANUP();;
  67. }
  68. // =================================================================
  69. // INetCfgNotify
  70. //
  71. // The following functions provide the INetCfgNotify interface
  72. // =================================================================
  73. // ----------------------------------------------------------------------
  74. //
  75. // Function: CWLBS::Initialize
  76. //
  77. // Purpose: Initialize the notify object
  78. //
  79. // Arguments:
  80. // pnccItem [in] pointer to INetCfgComponent object
  81. // pnc [in] pointer to INetCfg object
  82. // fInstalling [in] TRUE if we are being installed
  83. //
  84. // Returns:
  85. //
  86. // Notes:
  87. //
  88. // ----------------------------------------------------------------------
  89. STDMETHODIMP CWLBS::Initialize(INetCfgComponent* pnccItem, INetCfg* pINetCfg, BOOL fInstalling) {
  90. TRACE_VERB("<->%!FUNC!");
  91. return m_WlbsConfig.Initialize(pINetCfg, fInstalling);
  92. }
  93. // ----------------------------------------------------------------------
  94. //
  95. // Function: CWLBS::ReadAnswerFile
  96. //
  97. // Purpose: Read settings from answerfile and configure WLBS
  98. //
  99. // Arguments:
  100. // pszAnswerFile [in] name of AnswerFile
  101. // pszAnswerSection [in] name of parameters section
  102. //
  103. // Returns:
  104. //
  105. // Notes: Dont do anything irreversible (like modifying registry) yet
  106. // since the config. actually complete only when Apply is called!
  107. //
  108. // ----------------------------------------------------------------------
  109. STDMETHODIMP CWLBS::ReadAnswerFile(PCWSTR pszAnswerFile, PCWSTR pszAnswerSection) {
  110. TRACE_VERB("<->%!FUNC!");
  111. return m_WlbsConfig.ReadAnswerFile(pszAnswerFile, pszAnswerSection);
  112. }
  113. // ----------------------------------------------------------------------
  114. //
  115. // Function: CWLBS::Install
  116. //
  117. // Purpose: Do operations necessary for install.
  118. //
  119. // Arguments:
  120. // dwSetupFlags [in] Setup flags
  121. //
  122. // Returns: S_OK on success, otherwise an error code
  123. //
  124. // Notes: Dont do anything irreversible (like modifying registry) yet
  125. // since the config. actually complete only when Apply is called!
  126. //
  127. // ----------------------------------------------------------------------
  128. STDMETHODIMP CWLBS::Install(DWORD dw) {
  129. TRACE_VERB("<->%!FUNC!");
  130. return m_WlbsConfig.Install(dw);
  131. }
  132. // ----------------------------------------------------------------------
  133. //
  134. // Function: CWLBS::Upgrade
  135. //
  136. // Purpose: Do operations necessary for upgrade.
  137. //
  138. // Arguments:
  139. // dwSetupFlags [in] Setup flags
  140. //
  141. // Returns: S_OK on success, otherwise an error code
  142. //
  143. // ----------------------------------------------------------------------
  144. STDMETHODIMP CWLBS::Upgrade(DWORD dw1, DWORD dw2) {
  145. TRACE_VERB("<->%!FUNC!");
  146. return m_WlbsConfig.Upgrade(dw1, dw2);
  147. }
  148. // ----------------------------------------------------------------------
  149. //
  150. // Function: CWLBS::Removing
  151. //
  152. // Purpose: Do necessary cleanup when being removed
  153. //
  154. // Arguments: None
  155. //
  156. // Returns: S_OK on success, otherwise an error code
  157. //
  158. // Notes: Dont do anything irreversible (like modifying registry) yet
  159. // since the removal is actually complete only when Apply is called!
  160. //
  161. // ----------------------------------------------------------------------
  162. STDMETHODIMP CWLBS::Removing(VOID) {
  163. TRACE_VERB("<->%!FUNC!");
  164. return m_WlbsConfig.Removing();
  165. }
  166. // ----------------------------------------------------------------------
  167. //
  168. // Function: CWLBS::Validate
  169. //
  170. // Purpose: Do necessary parameter validation
  171. //
  172. // Arguments: None
  173. //
  174. // Returns: S_OK on success, otherwise an error code
  175. //
  176. // Notes:
  177. //
  178. // ----------------------------------------------------------------------
  179. STDMETHODIMP CWLBS::Validate() {
  180. TRACE_VERB("<->%!FUNC!");
  181. return S_OK;
  182. }
  183. // ----------------------------------------------------------------------
  184. //
  185. // Function: CWLBS::Cancel
  186. //
  187. // Purpose: Cancel any changes made to internal data
  188. //
  189. // Arguments: None
  190. //
  191. // Returns: S_OK on success, otherwise an error code
  192. //
  193. // Notes:
  194. //
  195. // ----------------------------------------------------------------------
  196. STDMETHODIMP CWLBS::CancelChanges(VOID) {
  197. TRACE_VERB("<->%!FUNC!");
  198. return S_OK;
  199. }
  200. // ----------------------------------------------------------------------
  201. //
  202. // Function: CWLBS::ApplyRegistryChanges
  203. //
  204. // Purpose: Apply changes.
  205. //
  206. // Arguments: None
  207. //
  208. // Returns: S_OK on success, otherwise an error code
  209. //
  210. // Notes: We can make changes to registry etc. here.
  211. //
  212. // ----------------------------------------------------------------------
  213. STDMETHODIMP CWLBS::ApplyRegistryChanges(VOID) {
  214. TRACE_VERB("<->%!FUNC!");
  215. return m_WlbsConfig.ApplyRegistryChanges();
  216. }
  217. // ----------------------------------------------------------------------
  218. //
  219. // Function: CWLBS::ApplyPnpChanges
  220. //
  221. // Purpose: Apply changes.
  222. //
  223. // Arguments: None
  224. //
  225. // Returns: S_OK on success, otherwise an error code
  226. //
  227. // Notes: Propagate changes to the driver.
  228. //
  229. // ----------------------------------------------------------------------
  230. STDMETHODIMP CWLBS::ApplyPnpChanges(INetCfgPnpReconfigCallback* pICallback) {
  231. TRACE_VERB("<->%!FUNC!");
  232. return m_WlbsConfig.ApplyPnpChanges();
  233. }
  234. // =================================================================
  235. // INetCfgBindNotify
  236. // =================================================================
  237. // ----------------------------------------------------------------------
  238. //
  239. // Function: CWLBS::QueryBindingPath
  240. //
  241. // Purpose: Allow or veto a binding path involving us
  242. //
  243. // Arguments:
  244. // dwChangeFlag [in] type of binding change
  245. // pncbi [in] pointer to INetCfgBindingPath object
  246. //
  247. // Returns: S_OK on success, otherwise an error code
  248. //
  249. // Notes:
  250. //
  251. // ----------------------------------------------------------------------
  252. STDMETHODIMP CWLBS::QueryBindingPath(DWORD dwChangeFlag, INetCfgBindingPath* pncbp) {
  253. TRACE_VERB("->%!FUNC!");
  254. INetCfgComponent* pAdapter = NULL;
  255. HRESULT hr = HrGetLastComponentAndInterface (pncbp, &pAdapter, NULL);
  256. if (SUCCEEDED(hr) && pAdapter) {
  257. TRACE_INFO("%!FUNC! get last component succeeded");
  258. hr = m_WlbsConfig.QueryBindingPath(dwChangeFlag, pAdapter);
  259. pAdapter->Release();
  260. if (FAILED(hr))
  261. {
  262. TRACE_CRIT("%!FUNC! failed to query binding path with %d", hr);
  263. }
  264. else
  265. {
  266. TRACE_INFO("%!FUNC! query binding path succeeded");
  267. }
  268. }
  269. else {
  270. TRACE_CRIT("%!FUNC! failed on get last component with %d", hr);
  271. }
  272. TRACE_VERB("<-%!FUNC!");
  273. return hr;
  274. }
  275. // ----------------------------------------------------------------------
  276. //
  277. // Function: CWLBS::NotifyBindingPath
  278. //
  279. // Purpose: System tells us by calling this function which
  280. // binding path involving us has just been formed.
  281. //
  282. // Arguments:
  283. // dwChangeFlag [in] type of binding change
  284. // pncbp [in] pointer to INetCfgBindingPath object
  285. //
  286. // Returns: S_OK on success, otherwise an error code
  287. //
  288. // Notes:
  289. //
  290. // ----------------------------------------------------------------------
  291. STDMETHODIMP CWLBS::NotifyBindingPath(DWORD dwChangeFlag, INetCfgBindingPath* pncbp) {
  292. TRACE_VERB("<->%!FUNC!");
  293. return m_WlbsConfig.NotifyBindingPath(dwChangeFlag, pncbp);
  294. }
  295. // =================================================================
  296. // INetCfgProperties
  297. // =================================================================
  298. // ----------------------------------------------------------------------
  299. //
  300. // Function: CWLBS::SetContext
  301. //
  302. // Purpose:
  303. //
  304. // Arguments:
  305. //
  306. // Returns:
  307. //
  308. // Notes:
  309. //
  310. // ----------------------------------------------------------------------
  311. STDMETHODIMP CWLBS::SetContext(IUnknown * pUnk) {
  312. TRACE_VERB("->%!FUNC!");
  313. HRESULT hr = S_OK;
  314. if (pUnk) {
  315. INetLanConnectionUiInfo * pLanConnUiInfo;
  316. /* Set the new context. Here we assume that we are going to be called only for
  317. a LAN connection since the sample IM works only with LAN devices. */
  318. hr = pUnk->QueryInterface(IID_INetLanConnectionUiInfo, reinterpret_cast<PVOID *>(&pLanConnUiInfo));
  319. if (SUCCEEDED(hr)) {
  320. hr = pLanConnUiInfo->GetDeviceGuid(&m_AdapterGuid);
  321. ReleaseObj(pLanConnUiInfo);
  322. TRACE_INFO("%!FUNC! query interface succeeded");
  323. } else {
  324. TraceError("CWLBS::SetContext called for non-lan connection", hr);
  325. TRACE_INFO("%!FUNC! query interface failed with %d", hr);
  326. return hr;
  327. }
  328. } else {
  329. /* Clear context. */
  330. ZeroMemory(&m_AdapterGuid, sizeof(m_AdapterGuid));
  331. TRACE_INFO("%!FUNC! clearing context");
  332. }
  333. /* If S_OK is not returned, the property page will not be displayed. */
  334. TRACE_VERB("<-%!FUNC!");
  335. return S_OK;
  336. }
  337. // ----------------------------------------------------------------------
  338. //
  339. // Function: CWLBS::MergePropPages
  340. //
  341. // Purpose: Supply our property page to system
  342. //
  343. // Arguments:
  344. // pdwDefPages [out] pointer to num default pages
  345. // pahpspPrivate [out] pointer to array of pages
  346. // pcPages [out] pointer to num pages
  347. // hwndParent [in] handle of parent window
  348. // szStartPage [in] pointer to
  349. //
  350. // Returns: S_OK on success, otherwise an error code
  351. //
  352. // Notes:
  353. //
  354. // ----------------------------------------------------------------------
  355. STDMETHODIMP CWLBS::MergePropPages(DWORD* pdwDefPages, LPBYTE* pahpspPrivate, UINT* pcPages, HWND hwndParent, PCWSTR* pszStartPage) {
  356. TRACE_VERB("->%!FUNC!");
  357. HPROPSHEETPAGE * ahpsp = NULL;
  358. HRESULT hr = S_OK;;
  359. /* We don't want any default pages to be shown. */
  360. *pdwDefPages = 0;
  361. *pcPages = 0;
  362. *pahpspPrivate = NULL;
  363. ahpsp = (HPROPSHEETPAGE*)CoTaskMemAlloc(3 * sizeof(HPROPSHEETPAGE));
  364. if (m_pClusterDlg != NULL) {
  365. delete m_pClusterDlg;
  366. m_pClusterDlg = NULL;
  367. }
  368. if (m_pHostDlg != NULL) {
  369. delete m_pHostDlg;
  370. m_pHostDlg = NULL;
  371. }
  372. if (m_pPortsDlg != NULL) {
  373. delete m_pPortsDlg;
  374. m_pPortsDlg = NULL;
  375. }
  376. if (ahpsp) {
  377. /* Get the cached configuration. */
  378. if (FAILED (hr = m_WlbsConfig.GetAdapterConfig(m_AdapterGuid, &m_OriginalConfig))) {
  379. TraceError("CWLBS::MergePropPages failed to query cluster config", hr);
  380. m_WlbsConfig.SetDefaults(&m_OriginalConfig);
  381. TRACE_CRIT("%!FUNC! failed in query to cluster configuration with %d", hr);
  382. }
  383. else
  384. {
  385. TRACE_INFO("%!FUNC! successfully retrieved the cached configuration");
  386. }
  387. /* Copy the configuration into the "current" config. */
  388. CopyMemory(&m_AdapterConfig, &m_OriginalConfig, sizeof(m_OriginalConfig));
  389. m_pClusterDlg = new CDialogCluster(&m_AdapterConfig, g_aHelpIDs_IDD_DIALOG_CLUSTER);
  390. if (NULL == m_pClusterDlg)
  391. {
  392. TRACE_CRIT("%!FUNC! memory allocation failure for cluster page dialog");
  393. }
  394. ahpsp[0] = m_pClusterDlg->CreatePage(IDD_DIALOG_CLUSTER, 0);
  395. m_pHostDlg = new CDialogHost(&m_AdapterConfig, g_aHelpIDs_IDD_DIALOG_HOST);
  396. if (NULL == m_pHostDlg)
  397. {
  398. TRACE_CRIT("%!FUNC! memory allocation failure for host page dialog");
  399. }
  400. ahpsp[1] = m_pHostDlg->CreatePage(IDD_DIALOG_HOST, 0);
  401. m_pPortsDlg = new CDialogPorts(&m_AdapterConfig, g_aHelpIDs_IDD_DIALOG_PORTS);
  402. if (NULL == m_pPortsDlg)
  403. {
  404. TRACE_CRIT("%!FUNC! memory allocation failure for ports page dialog");
  405. }
  406. ahpsp[2] = m_pPortsDlg->CreatePage(IDD_DIALOG_PORTS, 0);
  407. *pcPages = 3;
  408. *pahpspPrivate = (LPBYTE)ahpsp;
  409. }
  410. else
  411. {
  412. TRACE_CRIT("%!FUNC! CoTaskMemAlloc failed");
  413. }
  414. TRACE_VERB("<-%!FUNC!");
  415. return S_OK;
  416. }
  417. // ----------------------------------------------------------------------
  418. //
  419. // Function: CWLBS::ValidateProperties
  420. //
  421. // Purpose: Validate changes to property page
  422. //
  423. // Arguments:
  424. // hwndSheet [in] window handle of property sheet
  425. //
  426. // Returns: S_OK on success, otherwise an error code
  427. //
  428. // Notes:
  429. //
  430. // ----------------------------------------------------------------------
  431. STDMETHODIMP CWLBS::ValidateProperties(HWND hwndSheet) {
  432. TRACE_VERB("->%!FUNC!");
  433. NETCFG_WLBS_CONFIG adapterConfig;
  434. /* Make a copy of our config. It is voodoo to pass a pointer to
  435. a private date member, so we make a copy instead. */
  436. CopyMemory(&adapterConfig, &m_AdapterConfig, sizeof(m_AdapterConfig));
  437. TRACE_VERB("<-%!FUNC!");
  438. return m_WlbsConfig.ValidateProperties(hwndSheet, m_AdapterGuid, &adapterConfig);
  439. }
  440. // ----------------------------------------------------------------------
  441. //
  442. // Function: CWLBS::CancelProperties
  443. //
  444. // Purpose: Cancel changes to property page
  445. //
  446. // Arguments: None
  447. //
  448. // Returns: S_OK on success, otherwise an error code
  449. //
  450. // Notes:
  451. //
  452. // ----------------------------------------------------------------------
  453. STDMETHODIMP CWLBS::CancelProperties(VOID) {
  454. TRACE_VERB("->%!FUNC!");
  455. delete m_pClusterDlg;
  456. delete m_pHostDlg;
  457. delete m_pPortsDlg;
  458. m_pClusterDlg = NULL;
  459. m_pHostDlg = NULL;
  460. m_pPortsDlg = NULL;
  461. TRACE_VERB("<-%!FUNC!");
  462. return S_OK;
  463. }
  464. // ----------------------------------------------------------------------
  465. //
  466. // Function: CWLBS::ApplyProperties
  467. //
  468. // Purpose: Apply value of controls on property page
  469. // to internal memory structure
  470. //
  471. // Arguments: None
  472. //
  473. // Returns: S_OK on success, otherwise an error code
  474. //
  475. // Notes: We do this work in OnOk so no need to do it here again.
  476. //
  477. // ----------------------------------------------------------------------
  478. STDMETHODIMP CWLBS::ApplyProperties(VOID) {
  479. TRACE_VERB("->%!FUNC!");
  480. /* If the cluster IP address / subnet mask or the dedicated IP address / subnet mask has changed in this
  481. configuration session, remind the user that they have to enter this address in TCP/IP properties as well. */
  482. if (wcscmp(m_OriginalConfig.cl_ip_addr, m_AdapterConfig.cl_ip_addr) ||
  483. wcscmp(m_OriginalConfig.cl_net_mask, m_AdapterConfig.cl_net_mask) ||
  484. wcscmp(m_OriginalConfig.ded_ip_addr, m_AdapterConfig.ded_ip_addr) ||
  485. wcscmp(m_OriginalConfig.ded_net_mask, m_AdapterConfig.ded_net_mask)) {
  486. /* Alert the user. */
  487. NcMsgBox(::GetActiveWindow(), IDS_PARM_INFORMATION, IDS_PARM_TCPIP, MB_APPLMODAL | MB_ICONINFORMATION | MB_OK);
  488. TRACE_INFO("%!FUNC! vip and/or dip ip settings were modified");
  489. }
  490. /* Commit the configuration. */
  491. DWORD dwStatus = m_WlbsConfig.SetAdapterConfig(m_AdapterGuid, &m_AdapterConfig);
  492. if (S_OK != dwStatus)
  493. {
  494. TRACE_CRIT("%!FUNC! call to set the adapter configuration failed with %d", dwStatus);
  495. }
  496. else
  497. {
  498. TRACE_INFO("%!FUNC! call to set the adapter configuration succeeded");
  499. }
  500. delete m_pClusterDlg;
  501. delete m_pHostDlg;
  502. delete m_pPortsDlg;
  503. m_pClusterDlg = NULL;
  504. m_pHostDlg = NULL;
  505. m_pPortsDlg = NULL;
  506. TRACE_VERB("<-%!FUNC!");
  507. return S_OK;
  508. }