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.

1343 lines
29 KiB

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