Leaked source code of windows server 2003
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.

1288 lines
29 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // IPAddressPage.cpp
  7. //
  8. // Maintained By:
  9. // David Potter (DavidP) 31-JAN-2001
  10. // Geoffrey Pease (GPease) 12-MAY-2000
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. #include "Pch.h"
  14. #include "IPAddressPage.h"
  15. DEFINE_THISCLASS("CIPAddressPage");
  16. #define CONVERT_ADDRESS( _addrOut, _addrIn ) \
  17. _addrOut = ( FIRST_IPADDRESS( _addrIn ) ) | ( SECOND_IPADDRESS( _addrIn ) << 8 ) | ( THIRD_IPADDRESS( _addrIn ) << 16 ) | ( FOURTH_IPADDRESS( _addrIn ) << 24 )
  18. //////////////////////////////////////////////////////////////////////////////
  19. //++
  20. //
  21. // FIsValidIPAddress
  22. //
  23. // Description:
  24. // Determine whether an IP address is compatible with a given adapter's
  25. // address and subnet
  26. //
  27. // Arguments:
  28. // ulAddressToTest
  29. // ulAdapterAddress
  30. // ulAdapterSubnet
  31. //
  32. // Return Values:
  33. //
  34. // TRUE - The address is compatible.
  35. // FALSE - The address is not compatible.
  36. //
  37. // Remarks:
  38. //
  39. //--
  40. //////////////////////////////////////////////////////////////////////////////
  41. static
  42. BOOL
  43. FIsValidIPAddress(
  44. ULONG ulAddressToTest
  45. , ULONG ulAdapterAddress
  46. , ULONG ulAdapterSubnet
  47. )
  48. {
  49. TraceFunc( "" );
  50. BOOL fAddressIsValid = FALSE;
  51. if ( !ClRtlIsValidTcpipAddress( ulAddressToTest ) )
  52. {
  53. TraceFlow4(
  54. "Invalid IP address: %d.%d.%d.%d"
  55. , FIRST_IPADDRESS( ulAddressToTest )
  56. , SECOND_IPADDRESS( ulAddressToTest )
  57. , THIRD_IPADDRESS( ulAddressToTest )
  58. , FOURTH_IPADDRESS( ulAddressToTest )
  59. );
  60. goto Exit;
  61. }
  62. if ( !ClRtlIsValidTcpipSubnetMask( ulAdapterSubnet ) )
  63. {
  64. TraceFlow4(
  65. "Invalid subnet mask: %d.%d.%d.%d"
  66. , FIRST_IPADDRESS( ulAdapterSubnet )
  67. , SECOND_IPADDRESS( ulAdapterSubnet )
  68. , THIRD_IPADDRESS( ulAdapterSubnet )
  69. , FOURTH_IPADDRESS( ulAdapterSubnet )
  70. );
  71. goto Exit;
  72. }
  73. if ( !ClRtlIsValidTcpipAddressAndSubnetMask( ulAddressToTest, ulAdapterSubnet ) )
  74. {
  75. TraceFlow( "Mismatched IP address and subnet mask..." );
  76. TraceFlow4(
  77. "IP address: %d.%d.%d.%d"
  78. , FIRST_IPADDRESS( ulAddressToTest )
  79. , SECOND_IPADDRESS( ulAddressToTest )
  80. , THIRD_IPADDRESS( ulAddressToTest )
  81. , FOURTH_IPADDRESS( ulAddressToTest )
  82. );
  83. TraceFlow4(
  84. "Subnet mask: %d.%d.%d.%d"
  85. , FIRST_IPADDRESS( ulAdapterSubnet )
  86. , SECOND_IPADDRESS( ulAdapterSubnet )
  87. , THIRD_IPADDRESS( ulAdapterSubnet )
  88. , FOURTH_IPADDRESS( ulAdapterSubnet )
  89. );
  90. goto Exit;
  91. }
  92. if ( !ClRtlAreTcpipAddressesOnSameSubnet( ulAddressToTest, ulAdapterAddress, ulAdapterSubnet ) )
  93. {
  94. TraceFlow( "IP address on different subnet mask than adapter..." );
  95. TraceFlow4(
  96. "IP address: %d.%d.%d.%d"
  97. , FIRST_IPADDRESS( ulAddressToTest )
  98. , SECOND_IPADDRESS( ulAddressToTest )
  99. , THIRD_IPADDRESS( ulAddressToTest )
  100. , FOURTH_IPADDRESS( ulAddressToTest )
  101. );
  102. TraceFlow4(
  103. "Adapter address: %d.%d.%d.%d"
  104. , FIRST_IPADDRESS( ulAdapterAddress )
  105. , SECOND_IPADDRESS( ulAdapterAddress )
  106. , THIRD_IPADDRESS( ulAdapterAddress )
  107. , FOURTH_IPADDRESS( ulAdapterAddress )
  108. );
  109. TraceFlow4(
  110. "Subnet mask: %d.%d.%d.%d"
  111. , FIRST_IPADDRESS( ulAdapterSubnet )
  112. , SECOND_IPADDRESS( ulAdapterSubnet )
  113. , THIRD_IPADDRESS( ulAdapterSubnet )
  114. , FOURTH_IPADDRESS( ulAdapterSubnet )
  115. );
  116. goto Exit;
  117. }
  118. fAddressIsValid = TRUE;
  119. Exit:
  120. RETURN( fAddressIsValid );
  121. } //*** FIsValidIPAddress
  122. //////////////////////////////////////////////////////////////////////////////
  123. //++
  124. //
  125. // CIPAddressPage::CIPAddressPage
  126. //
  127. // Descriptor:
  128. // Constructor.
  129. //
  130. // Arguments:
  131. // pccwIn -- CClusCfgWizard
  132. // ecamCreateAddModeIn -- Creating cluster or adding nodes to cluster.
  133. // pulIPAddressInout -- Pointer to IP address fill in.
  134. // pulIPSubnetInout -- Pointer to subnet mask to fill in.
  135. // pbstrNetworkNameInout -- Pointer to network name string to fill in.
  136. //
  137. // Return Values:
  138. // None.
  139. //
  140. // Remarks:
  141. //
  142. //--
  143. //////////////////////////////////////////////////////////////////////////////
  144. CIPAddressPage::CIPAddressPage(
  145. CClusCfgWizard * pccwIn,
  146. ECreateAddMode ecamCreateAddModeIn,
  147. ULONG * pulIPAddressInout,
  148. ULONG * pulIPSubnetInout,
  149. BSTR * pbstrNetworkNameInout
  150. )
  151. : m_pccw( pccwIn )
  152. {
  153. TraceFunc( "" );
  154. Assert( pulIPAddressInout != NULL );
  155. Assert( pulIPSubnetInout != NULL );
  156. Assert( pbstrNetworkNameInout != NULL );
  157. // m_hwnd
  158. Assert( pccwIn != NULL );
  159. m_pccw->AddRef();
  160. m_pulIPAddress = pulIPAddressInout;
  161. m_pulIPSubnet = pulIPSubnetInout;
  162. m_pbstrNetworkName = pbstrNetworkNameInout;
  163. m_cookieCompletion = NULL;
  164. m_event = NULL;
  165. m_cRef = 0;
  166. TraceFuncExit();
  167. } //*** CIPAddressPage::CIPAddressPage
  168. //////////////////////////////////////////////////////////////////////////////
  169. //++
  170. //
  171. // CIPAddressPage::~CIPAddressPage
  172. //
  173. // Description:
  174. // Destructor.
  175. //
  176. // Arguments:
  177. // None.
  178. //
  179. // Return Values:
  180. // None.
  181. //
  182. // Remarks:
  183. //
  184. //--
  185. //////////////////////////////////////////////////////////////////////////////
  186. CIPAddressPage::~CIPAddressPage( void )
  187. {
  188. TraceFunc( "" );
  189. if ( m_pccw != NULL )
  190. {
  191. m_pccw->Release();
  192. }
  193. if ( m_event != NULL )
  194. {
  195. CloseHandle( m_event );
  196. }
  197. Assert( m_cRef == 0 );
  198. TraceFuncExit();
  199. } //*** CIPAddressPage::~CIPAddressPage
  200. //////////////////////////////////////////////////////////////////////////////
  201. //++
  202. //
  203. // CIPAddressPage::OnInitDialog
  204. //
  205. // Description:
  206. //
  207. // Arguments:
  208. // None.
  209. //
  210. // Return Values:
  211. // FALSE
  212. //
  213. // Remarks:
  214. //
  215. //--
  216. //////////////////////////////////////////////////////////////////////////////
  217. LRESULT
  218. CIPAddressPage::OnInitDialog( void )
  219. {
  220. TraceFunc( "" );
  221. LRESULT lr = FALSE;
  222. if ( *m_pulIPAddress != 0 )
  223. {
  224. ULONG ulIPAddress;
  225. CONVERT_ADDRESS( ulIPAddress, *m_pulIPAddress );
  226. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, IPM_SETADDRESS, 0, ulIPAddress );
  227. }
  228. m_event = CreateEvent( NULL, TRUE, FALSE, NULL );
  229. Assert( m_event != NULL );
  230. RETURN( lr );
  231. } //*** CIPAddressPage::OnInitDialog
  232. //////////////////////////////////////////////////////////////////////////////
  233. //++
  234. //
  235. // CIPAddressPage::OnCommand
  236. //
  237. // Description:
  238. //
  239. // Arguments:
  240. // idNotificationIn
  241. // idControlIn
  242. // hwndSenderIn
  243. //
  244. // Return Values:
  245. // TRUE
  246. // FALSE
  247. //
  248. // Remarks:
  249. //
  250. //--
  251. //////////////////////////////////////////////////////////////////////////////
  252. LRESULT
  253. CIPAddressPage::OnCommand(
  254. UINT idNotificationIn,
  255. UINT idControlIn,
  256. HWND hwndSenderIn
  257. )
  258. {
  259. TraceFunc( "" );
  260. LRESULT lr = FALSE;
  261. switch ( idControlIn )
  262. {
  263. case IDC_IPADDRESS_IP_ADDRESS:
  264. if ( idNotificationIn == IPN_FIELDCHANGED
  265. || idNotificationIn == EN_CHANGE
  266. )
  267. {
  268. THR( HrUpdateWizardButtons() );
  269. lr = TRUE;
  270. }
  271. break;
  272. } // switch: idControlIn
  273. RETURN( lr );
  274. } //*** CIPAddressPage::OnCommand
  275. //////////////////////////////////////////////////////////////////////////////
  276. //++
  277. //
  278. // CIPAddressPage::HrUpdateWizardButtons
  279. //
  280. // Description:
  281. //
  282. // Arguments:
  283. // None.
  284. //
  285. // Return Values:
  286. // S_OK
  287. // Other HRESULT values.
  288. //
  289. // Remarks:
  290. //
  291. //--
  292. //////////////////////////////////////////////////////////////////////////////
  293. HRESULT
  294. CIPAddressPage::HrUpdateWizardButtons( void )
  295. {
  296. TraceFunc( "" );
  297. HRESULT hr = S_OK;
  298. DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  299. LRESULT lr;
  300. ULONG ulIPAddress;
  301. lr = SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, IPM_ISBLANK, 0, 0 );
  302. if ( lr != 0 )
  303. {
  304. dwFlags &= ~PSWIZB_NEXT;
  305. }
  306. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, IPM_GETADDRESS, 0, (LPARAM) &ulIPAddress );
  307. if ( ( ulIPAddress == 0) // Bad IP
  308. || ( ulIPAddress == MAKEIPADDRESS( 255, 255, 255, 255 ) ) // Bad IP
  309. )
  310. {
  311. dwFlags &= ~PSWIZB_NEXT;
  312. }
  313. PropSheet_SetWizButtons( GetParent( m_hwnd ), dwFlags );
  314. HRETURN( hr );
  315. } //*** CIPAddressPage::HrUpdateWizardButtons
  316. //////////////////////////////////////////////////////////////////////////////
  317. //++
  318. //
  319. // CIPAddressPage::OnNotifyQueryCancel
  320. //
  321. // Description:
  322. //
  323. // Arguments:
  324. // None.
  325. //
  326. // Return Values:
  327. // TRUE
  328. //
  329. // Remarks:
  330. //
  331. //--
  332. //////////////////////////////////////////////////////////////////////////////
  333. LRESULT
  334. CIPAddressPage::OnNotifyQueryCancel( void )
  335. {
  336. TraceFunc( "" );
  337. LRESULT lr = TRUE;
  338. int iRet;
  339. iRet = MessageBoxFromStrings( m_hwnd,
  340. IDS_QUERY_CANCEL_TITLE,
  341. IDS_QUERY_CANCEL_TEXT,
  342. MB_YESNO
  343. );
  344. if ( iRet == IDNO )
  345. {
  346. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  347. } // if:
  348. else
  349. {
  350. THR( m_pccw->HrLaunchCleanupTask() );
  351. } // else:
  352. RETURN( lr );
  353. } //*** CIPAddressPage::OnNotifyQueryCancel
  354. //////////////////////////////////////////////////////////////////////////////
  355. //++
  356. //
  357. // CIPAddressPage::OnNotifySetActive
  358. //
  359. // Description:
  360. //
  361. // Arguments:
  362. // None.
  363. //
  364. // Return Values:
  365. // TRUE
  366. //
  367. // Remarks:
  368. //
  369. //--
  370. //////////////////////////////////////////////////////////////////////////////
  371. LRESULT
  372. CIPAddressPage::OnNotifySetActive( void )
  373. {
  374. TraceFunc( "" );
  375. LRESULT lr = TRUE;
  376. // Enable controls on the page.
  377. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, WM_ENABLE, TRUE, 0 );
  378. THR( HrUpdateWizardButtons() );
  379. RETURN( lr );
  380. } //*** CIPAddressPage::OnNotifySetActive
  381. //////////////////////////////////////////////////////////////////////////////
  382. //++
  383. //
  384. // CIPAddressPage::OnNotifyWizNext
  385. //
  386. // Description:
  387. //
  388. // Arguments:
  389. // None.
  390. //
  391. // Return Values:
  392. // TRUE
  393. //
  394. // Remarks:
  395. //
  396. //--
  397. //////////////////////////////////////////////////////////////////////////////
  398. LRESULT
  399. CIPAddressPage::OnNotifyWizNext( void )
  400. {
  401. TraceFunc( "" );
  402. HRESULT hr;
  403. HRESULT hrStatus;
  404. BOOL fRet;
  405. DWORD ulAddress;
  406. LRESULT lr = TRUE;
  407. DWORD dwCookieNotify = 0;
  408. IUnknown * punkTask = NULL;
  409. IClusCfgClusterInfo * pccci = NULL;
  410. IClusCfgNetworkInfo * pccni = NULL;
  411. ITaskVerifyIPAddress * ptvipa = NULL;
  412. CWaitCursor WaitCursor;
  413. // Disable controls on the page.
  414. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, WM_ENABLE, FALSE, 0 );
  415. //
  416. // Get the IP address from the UI.
  417. //
  418. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, IPM_GETADDRESS, 0, (LPARAM) &ulAddress );
  419. CONVERT_ADDRESS( *m_pulIPAddress, ulAddress );
  420. //
  421. // See if this IP address can be matched to a network.
  422. hr = THR( HrFindNetworkForIPAddress( &pccni ) );
  423. if ( FAILED( hr ) )
  424. {
  425. goto Error;
  426. }
  427. if ( hr == S_FALSE )
  428. {
  429. MessageBoxFromStrings(
  430. m_hwnd
  431. , IDS_CANNOT_FIND_MATCHING_NETWORK_TITLE
  432. , IDS_CANNOT_FIND_MATCHING_NETWORK_TEXT
  433. , MB_OK
  434. );
  435. goto Error;
  436. }
  437. //
  438. // Get the cluster configuration info.
  439. //
  440. hr = THR( m_pccw->HrGetClusterObject( &pccci ) );
  441. if ( FAILED( hr ) )
  442. {
  443. goto Error;
  444. }
  445. //
  446. // Set the IP adddress.
  447. //
  448. hr = THR( pccci->SetIPAddress( *m_pulIPAddress ) );
  449. if ( FAILED( hr ) )
  450. {
  451. goto Error;
  452. }
  453. //
  454. // Set the IP subnet mask.
  455. //
  456. hr = THR( pccci->SetSubnetMask( *m_pulIPSubnet ) );
  457. if ( FAILED( hr ) )
  458. {
  459. goto Error;
  460. }
  461. //
  462. // Set the network.
  463. //
  464. hr = THR( pccci->SetNetworkInfo( pccni ) );
  465. if ( FAILED( hr ) )
  466. {
  467. goto Error;
  468. }
  469. //
  470. // Register to get UI notification (if needed)
  471. //
  472. hr = THR( m_pccw->HrAdvise( IID_INotifyUI, this, &dwCookieNotify ) );
  473. if ( FAILED( hr ) )
  474. {
  475. goto Error;
  476. }
  477. //
  478. // See the IP address is already present on the network.
  479. //
  480. hr = THR( m_pccw->HrCreateTask( TASK_VerifyIPAddress, &punkTask ) );
  481. if ( FAILED( hr ) )
  482. {
  483. goto Error;
  484. }
  485. hr = THR( punkTask->TypeSafeQI( ITaskVerifyIPAddress, &ptvipa ) );
  486. if ( FAILED( hr ) )
  487. {
  488. goto Error;
  489. }
  490. hr = THR( ptvipa->SetIPAddress( *m_pulIPAddress ) );
  491. if ( FAILED( hr ) )
  492. {
  493. goto Error;
  494. }
  495. // Don't wrap - this can fail with E_PENDING
  496. hr = m_pccw->HrGetCompletionCookie( CLSID_TaskVerifyIPAddressCompletionCookieType, &m_cookieCompletion );
  497. if ( hr == E_PENDING )
  498. {
  499. // no-op.
  500. }
  501. else if ( FAILED( hr ) )
  502. {
  503. THR( hr );
  504. goto Error;
  505. }
  506. hr = THR( ptvipa->SetCookie( m_cookieCompletion ) );
  507. if ( FAILED( hr ) )
  508. {
  509. goto Error;
  510. }
  511. // reset the event before submitting.
  512. if ( m_event != NULL )
  513. {
  514. fRet = ResetEvent( m_event );
  515. Assert( fRet );
  516. }
  517. hr = THR( m_pccw->HrSubmitTask( ptvipa ) );
  518. if ( FAILED( hr ) )
  519. {
  520. goto Error;
  521. }
  522. //
  523. // Now wait for the work to be done.
  524. //
  525. if ( m_event != NULL )
  526. {
  527. MSG msg;
  528. DWORD dwErr;
  529. for ( dwErr = (DWORD) -1; dwErr != WAIT_OBJECT_0; )
  530. {
  531. while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  532. {
  533. TranslateMessage( &msg );
  534. DispatchMessage( &msg );
  535. } // while: PeekMessage
  536. CWaitCursor Wait2;
  537. dwErr = MsgWaitForMultipleObjects( 1,
  538. &m_event,
  539. FALSE,
  540. 10000, // wait at most 10 seconds
  541. QS_ALLEVENTS | QS_ALLINPUT | QS_ALLPOSTMESSAGE
  542. );
  543. AssertMsg( dwErr != WAIT_TIMEOUT, "Need to bump up the timeout period." );
  544. if ( dwErr == WAIT_TIMEOUT )
  545. {
  546. break; // give up and continue
  547. }
  548. } // for: dwErr
  549. }
  550. hr = THR( m_pccw->HrGetCompletionStatus( m_cookieCompletion, &hrStatus ) );
  551. if ( FAILED( hr ) )
  552. {
  553. goto Error;
  554. }
  555. if ( hrStatus == S_FALSE )
  556. {
  557. int iAnswer;
  558. //
  559. // We detected a duplicate IP address on the network. Ask the user if
  560. // they want to go back and change the IP or continue on.
  561. //
  562. iAnswer = MessageBoxFromStrings( m_hwnd,
  563. IDS_ERR_IPADDRESS_ALREADY_PRESENT_TITLE,
  564. IDS_ERR_IPADDRESS_ALREADY_PRESENT_TEXT,
  565. MB_YESNO
  566. );
  567. if ( iAnswer == IDYES )
  568. {
  569. goto Error;
  570. }
  571. }
  572. goto Cleanup;
  573. Error:
  574. // Enable controls on the page again.
  575. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, WM_ENABLE, TRUE, 0 );
  576. SendDlgItemMessage( m_hwnd, IDC_IPADDRESS_IP_ADDRESS, WM_SETFOCUS, 0, 0 );
  577. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  578. goto Cleanup;
  579. Cleanup:
  580. if ( punkTask != NULL )
  581. {
  582. punkTask->Release();
  583. }
  584. if ( ptvipa != NULL )
  585. {
  586. ptvipa->Release();
  587. }
  588. if ( pccci != NULL )
  589. {
  590. pccci->Release();
  591. }
  592. if ( pccni != NULL )
  593. {
  594. pccni->Release();
  595. }
  596. if ( dwCookieNotify != 0 )
  597. {
  598. THR( m_pccw->HrUnadvise( IID_INotifyUI, dwCookieNotify ) );
  599. }
  600. Assert( m_cRef == 0 );
  601. RETURN( lr );
  602. } //*** CIPAddressPage::OnNotifyWizNext
  603. //////////////////////////////////////////////////////////////////////////////
  604. //++
  605. //
  606. // CIPAddressPage::OnNotify
  607. //
  608. // Description:
  609. // Handle the WM_NOTIFY windows message.
  610. //
  611. // Arguments:
  612. // idCtrlIn
  613. // pnmhdrIn
  614. //
  615. // Return Values:
  616. // TRUE
  617. // Other LRESULT values.
  618. //
  619. // Remarks:
  620. //
  621. //--
  622. //////////////////////////////////////////////////////////////////////////////
  623. LRESULT
  624. CIPAddressPage::OnNotify(
  625. WPARAM idCtrlIn,
  626. LPNMHDR pnmhdrIn
  627. )
  628. {
  629. TraceFunc( "" );
  630. LRESULT lr = TRUE;
  631. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
  632. switch( pnmhdrIn->code )
  633. {
  634. case PSN_SETACTIVE:
  635. lr = OnNotifySetActive();
  636. break;
  637. case PSN_WIZNEXT:
  638. lr = OnNotifyWizNext();
  639. break;
  640. case PSN_QUERYCANCEL:
  641. lr = OnNotifyQueryCancel();
  642. break;
  643. }
  644. RETURN( lr );
  645. } //*** CIPAddressPage::OnNotify
  646. //////////////////////////////////////////////////////////////////////////////
  647. //++
  648. //
  649. // static
  650. // CALLBACK
  651. // CIPAddressPage::S_DlgProc
  652. //
  653. // Description:
  654. // Dialog proc for this page.
  655. //
  656. // Arguments:
  657. // hDlgIn
  658. // MsgIn
  659. // wParam
  660. // lParam
  661. //
  662. // Return Values:
  663. // FALSE
  664. // Other LRESULT values.
  665. //
  666. // Remarks:
  667. //
  668. //--
  669. //////////////////////////////////////////////////////////////////////////////
  670. INT_PTR
  671. CALLBACK
  672. CIPAddressPage::S_DlgProc(
  673. HWND hDlgIn,
  674. UINT MsgIn,
  675. WPARAM wParam,
  676. LPARAM lParam
  677. )
  678. {
  679. // Don't do TraceFunc because every mouse movement
  680. // will cause this function to be called.
  681. WndMsg( hDlgIn, MsgIn, wParam, lParam );
  682. LRESULT lr = FALSE;
  683. CIPAddressPage * pPage = reinterpret_cast< CIPAddressPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
  684. if ( MsgIn == WM_INITDIALOG )
  685. {
  686. PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
  687. SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
  688. pPage = reinterpret_cast< CIPAddressPage * >( ppage->lParam );
  689. pPage->m_hwnd = hDlgIn;
  690. }
  691. if ( pPage != NULL )
  692. {
  693. Assert( hDlgIn == pPage->m_hwnd );
  694. switch( MsgIn )
  695. {
  696. case WM_INITDIALOG:
  697. lr = pPage->OnInitDialog();
  698. break;
  699. case WM_NOTIFY:
  700. lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
  701. break;
  702. case WM_COMMAND:
  703. lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
  704. break;
  705. // no default clause needed
  706. } // switch: message
  707. } // if: there is a page associated with the window
  708. return lr;
  709. } //*** CIPAddressPage::S_DlgProc
  710. // ************************************************************************
  711. //
  712. // IUnknown
  713. //
  714. // ************************************************************************
  715. //////////////////////////////////////////////////////////////////////////////
  716. //++
  717. //
  718. // CIPAddressPage::QueryInterface
  719. //
  720. // Description:
  721. // Query this object for the passed in interface.
  722. //
  723. // Arguments:
  724. // riidIn
  725. // Id of interface requested.
  726. //
  727. // ppvOut
  728. // Pointer to the requested interface.
  729. //
  730. // Return Value:
  731. // S_OK
  732. // If the interface is available on this object.
  733. //
  734. // E_NOINTERFACE
  735. // If the interface is not available.
  736. //
  737. // E_POINTER
  738. // ppvOut was NULL.
  739. //
  740. // Remarks:
  741. // This QI implementation does not use the interface tracing macros due
  742. // to problems with CITracker's marshalling support.
  743. //
  744. //--
  745. //////////////////////////////////////////////////////////////////////////////
  746. STDMETHODIMP
  747. CIPAddressPage::QueryInterface(
  748. REFIID riidIn
  749. , LPVOID * ppvOut
  750. )
  751. {
  752. TraceFunc( "" );
  753. HRESULT hr = S_OK;
  754. //
  755. // Validate arguments.
  756. //
  757. Assert( ppvOut != NULL );
  758. if ( ppvOut == NULL )
  759. {
  760. hr = THR( E_POINTER );
  761. goto Cleanup;
  762. }
  763. //
  764. // Handle known interfaces.
  765. //
  766. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  767. {
  768. *ppvOut = static_cast< IUnknown * >( this );
  769. } // if: IUnknown
  770. else if ( IsEqualIID( riidIn, IID_INotifyUI ) )
  771. {
  772. *ppvOut = static_cast< INotifyUI * >( this );
  773. } // else if: INotifyUI
  774. else
  775. {
  776. *ppvOut = NULL;
  777. hr = E_NOINTERFACE;
  778. } // else
  779. //
  780. // Add a reference to the interface if successful.
  781. //
  782. if ( SUCCEEDED( hr ) )
  783. {
  784. ((IUnknown *) *ppvOut)->AddRef();
  785. } // if: success
  786. Cleanup:
  787. HRETURN( hr );
  788. } //*** CIPAddressPage::QueryInterface
  789. //////////////////////////////////////////////////////////////////////////////
  790. //++
  791. //
  792. // CIPAddressPage::AddRef
  793. //
  794. // Description:
  795. //
  796. // Arguments:
  797. // None.
  798. //
  799. // Return Values:
  800. // New reference count.
  801. //
  802. // Remarks:
  803. //
  804. //--
  805. //////////////////////////////////////////////////////////////////////////////
  806. STDMETHODIMP_( ULONG )
  807. CIPAddressPage::AddRef( void )
  808. {
  809. TraceFunc( "[IUnknown]" );
  810. InterlockedIncrement( &m_cRef );
  811. CRETURN( m_cRef );
  812. } //*** CIPAddressPage::AddRef
  813. //////////////////////////////////////////////////////////////////////////////
  814. //++
  815. //
  816. // CIPAddressPage::Release
  817. //
  818. // Description:
  819. //
  820. // Arguments:
  821. // None.
  822. //
  823. // Return Values:
  824. // New reference count.
  825. //
  826. // Remarks:
  827. //
  828. //--
  829. //////////////////////////////////////////////////////////////////////////////
  830. STDMETHODIMP_( ULONG )
  831. CIPAddressPage::Release( void )
  832. {
  833. TraceFunc( "[IUnknown]" );
  834. LONG cRef;
  835. cRef = InterlockedDecrement( &m_cRef );
  836. if ( cRef == 0 )
  837. {
  838. // do nothing -- COM interface does not control object lifetime
  839. }
  840. CRETURN( cRef );
  841. } //*** CIPAddressPage::Release
  842. //****************************************************************************
  843. //
  844. // INotifyUI
  845. //
  846. //****************************************************************************
  847. //////////////////////////////////////////////////////////////////////////////
  848. //++
  849. //
  850. // [INotifyUI]
  851. // CIPAddressPage::ObjectChanged
  852. //
  853. // Description:
  854. //
  855. // Arguments:
  856. // cookieIn
  857. //
  858. // Return Values:
  859. // S_OK
  860. //
  861. // Remarks:
  862. //
  863. //--
  864. //////////////////////////////////////////////////////////////////////////////
  865. STDMETHODIMP
  866. CIPAddressPage::ObjectChanged(
  867. OBJECTCOOKIE cookieIn
  868. )
  869. {
  870. TraceFunc( "[INotifyUI]" );
  871. BOOL fRet;
  872. HRESULT hr = S_OK;
  873. if ( cookieIn == m_cookieCompletion
  874. && m_event != NULL
  875. )
  876. {
  877. fRet = SetEvent( m_event );
  878. Assert( fRet );
  879. }
  880. HRETURN( hr );
  881. } //*** CIPAddressPage::ObjectChanged
  882. //****************************************************************************
  883. //
  884. // Private Functions
  885. //
  886. //****************************************************************************
  887. //////////////////////////////////////////////////////////////////////////////
  888. //++
  889. //
  890. // CIPAddressPage::HrFindNetworkForIPAddress
  891. //
  892. // Description:
  893. // Find the network for the saved IP address.
  894. //
  895. // Arguments:
  896. // ppccniOut -- Network info to return.
  897. //
  898. // Return Values:
  899. // S_OK
  900. // S_FALSE
  901. //
  902. // Remarks:
  903. //
  904. //--
  905. //////////////////////////////////////////////////////////////////////////////
  906. HRESULT
  907. CIPAddressPage::HrFindNetworkForIPAddress(
  908. IClusCfgNetworkInfo ** ppccniOut
  909. )
  910. {
  911. TraceFunc( "" );
  912. HRESULT hr = S_OK;
  913. IUnknown * punk = NULL;
  914. IEnumClusCfgNetworks * peccn = NULL;
  915. IClusCfgNetworkInfo * pccni = NULL;
  916. BSTR bstrNetName = NULL;
  917. ULONG celtDummy;
  918. bool fFoundNetwork = false;
  919. Assert( ppccniOut != NULL );
  920. //
  921. // Get the network enumerator for the first node in the cluster.
  922. //
  923. hr = THR( m_pccw->HrGetNodeChild( 0, CLSID_NetworkType, DFGUID_EnumManageableNetworks, &punk ) );
  924. if ( FAILED( hr ) )
  925. {
  926. goto Cleanup;
  927. }
  928. hr = THR( punk->TypeSafeQI( IEnumClusCfgNetworks, &peccn ) );
  929. if ( FAILED( hr ) )
  930. {
  931. goto Cleanup;
  932. }
  933. //
  934. // Add each network to the combobox.
  935. //
  936. for ( ;; )
  937. {
  938. // Get the next network.
  939. hr = STHR( peccn->Next( 1, &pccni, &celtDummy ) );
  940. if ( hr == S_FALSE )
  941. {
  942. break;
  943. }
  944. if ( FAILED( hr ) )
  945. {
  946. goto Cleanup;
  947. }
  948. // Skip this network if it isn't public.
  949. hr = STHR( pccni->IsPublic() );
  950. if ( hr == S_OK )
  951. {
  952. // Get the name of the network.
  953. hr = THR( pccni->GetName( &bstrNetName ) );
  954. if ( SUCCEEDED( hr ) )
  955. {
  956. TraceMemoryAddBSTR( bstrNetName );
  957. // Determine if this network matches the user's IP address.
  958. // If it is, select it in the combobox.
  959. if ( ! fFoundNetwork )
  960. {
  961. hr = STHR( HrMatchNetwork( pccni, bstrNetName ) );
  962. if ( hr == S_OK )
  963. {
  964. fFoundNetwork = true;
  965. *ppccniOut = pccni;
  966. (*ppccniOut)->AddRef();
  967. break;
  968. }
  969. }
  970. // Cleanup.
  971. TraceSysFreeString( bstrNetName );
  972. bstrNetName = NULL;
  973. } // if: name retrieved successfully
  974. } // if: network is public
  975. pccni->Release();
  976. pccni = NULL;
  977. } // forever
  978. if ( fFoundNetwork )
  979. {
  980. hr = S_OK;
  981. }
  982. else
  983. {
  984. hr = S_FALSE;
  985. }
  986. Cleanup:
  987. if ( punk != NULL )
  988. {
  989. punk->Release();
  990. }
  991. TraceSysFreeString( bstrNetName );
  992. if ( pccni != NULL )
  993. {
  994. pccni->Release();
  995. }
  996. if ( peccn != NULL )
  997. {
  998. peccn->Release();
  999. }
  1000. HRETURN( hr );
  1001. } //*** CIPAddressPage::HrFindNetworkForIPAddress
  1002. //////////////////////////////////////////////////////////////////////////////
  1003. //++
  1004. //
  1005. // CIPAddressPage::HrMatchNetwork
  1006. //
  1007. // Description:
  1008. // Match a network to the saved IP address.
  1009. //
  1010. // Arguments:
  1011. // pccniIn
  1012. // bstrNetworkNameIn
  1013. //
  1014. // Return Values:
  1015. // S_OK
  1016. // S_FALSE
  1017. //
  1018. // Remarks:
  1019. //
  1020. //--
  1021. //////////////////////////////////////////////////////////////////////////////
  1022. HRESULT
  1023. CIPAddressPage::HrMatchNetwork(
  1024. IClusCfgNetworkInfo * pccniIn,
  1025. BSTR bstrNetworkNameIn
  1026. )
  1027. {
  1028. TraceFunc( "" );
  1029. HRESULT hr = S_OK;
  1030. IClusCfgIPAddressInfo * pccipai = NULL;
  1031. ULONG ulIPAddress;
  1032. ULONG ulIPSubnet;
  1033. Assert( pccniIn != NULL );
  1034. Assert( bstrNetworkNameIn != NULL );
  1035. //
  1036. // Get the IP Address Info for the network.
  1037. //
  1038. hr = THR( pccniIn->GetPrimaryNetworkAddress( &pccipai ) );
  1039. if ( FAILED( hr ) )
  1040. {
  1041. goto Cleanup;
  1042. }
  1043. //
  1044. // Get the address and subnet of the network.
  1045. //
  1046. hr = THR( pccipai->GetIPAddress( &ulIPAddress ) );
  1047. if ( FAILED( hr ) )
  1048. {
  1049. goto Cleanup;
  1050. }
  1051. hr = THR( pccipai->GetSubnetMask( &ulIPSubnet ) );
  1052. if ( FAILED( hr ) )
  1053. {
  1054. goto Cleanup;
  1055. }
  1056. //
  1057. // Determine if these match.
  1058. //
  1059. if ( FIsValidIPAddress( *m_pulIPAddress, ulIPAddress, ulIPSubnet) )
  1060. {
  1061. // Save the subnet mask.
  1062. *m_pulIPSubnet = ulIPSubnet;
  1063. // Save the name of the network.
  1064. if ( *m_pbstrNetworkName == NULL )
  1065. {
  1066. *m_pbstrNetworkName = TraceSysAllocString( bstrNetworkNameIn );
  1067. if ( *m_pbstrNetworkName == NULL )
  1068. {
  1069. hr = THR( E_OUTOFMEMORY );
  1070. goto Cleanup;
  1071. }
  1072. }
  1073. else
  1074. {
  1075. INT iRet = TraceSysReAllocString( m_pbstrNetworkName, bstrNetworkNameIn );
  1076. if ( ! iRet )
  1077. {
  1078. hr = THR( E_OUTOFMEMORY );
  1079. goto Cleanup;
  1080. }
  1081. }
  1082. } // if: match found
  1083. else
  1084. {
  1085. hr = S_FALSE;
  1086. }
  1087. goto Cleanup;
  1088. Cleanup:
  1089. if ( pccipai != NULL )
  1090. {
  1091. pccipai->Release();
  1092. }
  1093. HRETURN( hr );
  1094. } //*** CIPAddressPage::HrMatchNetwork