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.

1357 lines
39 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Network.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CNetwork class.
  10. //
  11. // Author:
  12. // David Potter (davidp) May 6, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "CluAdmin.h"
  21. #include "ConstDef.h"
  22. #include "Network.h"
  23. #include "ClusItem.inl"
  24. #include "Cluster.h"
  25. #include "NetProp.h"
  26. #include "ExcOper.h"
  27. #include "TraceTag.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Global Variables
  35. /////////////////////////////////////////////////////////////////////////////
  36. #ifdef _DEBUG
  37. CTraceTag g_tagNetwork(_T("Document"), _T("NETWORK"), 0);
  38. CTraceTag g_tagNetNotify(_T("Notify"), _T("NET NOTIFY"), 0);
  39. CTraceTag g_tagNetRegNotify(_T("Notify"), _T("NET REG NOTIFY"), 0);
  40. #endif
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CNetwork
  43. /////////////////////////////////////////////////////////////////////////////
  44. IMPLEMENT_DYNCREATE(CNetwork, CClusterItem)
  45. /////////////////////////////////////////////////////////////////////////////
  46. // Message Maps
  47. BEGIN_MESSAGE_MAP(CNetwork, CClusterItem)
  48. //{{AFX_MSG_MAP(CNetwork)
  49. ON_UPDATE_COMMAND_UI(ID_FILE_PROPERTIES, OnUpdateProperties)
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. //++
  54. //
  55. // CNetwork::CNetwork
  56. //
  57. // Routine Description:
  58. // Default constructor.
  59. //
  60. // Arguments:
  61. // None.
  62. //
  63. // Return Value:
  64. // None.
  65. //
  66. //--
  67. /////////////////////////////////////////////////////////////////////////////
  68. CNetwork::CNetwork(void)
  69. : CClusterItem(NULL, IDS_ITEMTYPE_NETWORK)
  70. {
  71. CommonConstruct();
  72. } //*** CResoruce::CNetwork()
  73. /////////////////////////////////////////////////////////////////////////////
  74. //++
  75. //
  76. // CNetwork::CommonConstruct
  77. //
  78. // Routine Description:
  79. // Common construction.
  80. //
  81. // Arguments:
  82. // None.
  83. //
  84. // Return Value:
  85. // None.
  86. //
  87. //--
  88. /////////////////////////////////////////////////////////////////////////////
  89. void CNetwork::CommonConstruct(void)
  90. {
  91. m_idmPopupMenu = IDM_NETWORK_POPUP;
  92. m_hnetwork = NULL;
  93. m_dwCharacteristics = CLUS_CHAR_UNKNOWN;
  94. m_dwFlags = 0;
  95. m_cnr = ClusterNetworkRoleNone;
  96. m_plpciNetInterfaces = NULL;
  97. // Set the object type image.
  98. m_iimgObjectType = GetClusterAdminApp()->Iimg(IMGLI_NETWORK);
  99. // Setup the property array.
  100. {
  101. m_rgProps[epropName].Set(CLUSREG_NAME_NET_NAME, m_strName, m_strName);
  102. m_rgProps[epropRole].Set(CLUSREG_NAME_NET_ROLE, (DWORD &) m_cnr, (DWORD &) m_cnr);
  103. m_rgProps[epropAddress].Set(CLUSREG_NAME_NET_ADDRESS, m_strAddress, m_strAddress);
  104. m_rgProps[epropAddressMask].Set(CLUSREG_NAME_NET_ADDRESS_MASK, m_strAddressMask, m_strAddressMask);
  105. m_rgProps[epropDescription].Set(CLUSREG_NAME_NET_DESC, m_strDescription, m_strDescription);
  106. } // Setup the property array
  107. } //*** CNetwork::CommonConstruct()
  108. /////////////////////////////////////////////////////////////////////////////
  109. //++
  110. //
  111. // CNetwork::~CNetwork
  112. //
  113. // Routine Description:
  114. // Destructor.
  115. //
  116. // Arguments:
  117. // None.
  118. //
  119. // Return Value:
  120. // None.
  121. //
  122. //--
  123. /////////////////////////////////////////////////////////////////////////////
  124. CNetwork::~CNetwork(void)
  125. {
  126. // Cleanup this object.
  127. Cleanup();
  128. delete m_plpciNetInterfaces;
  129. // Close the network handle.
  130. if (Hnetwork() != NULL)
  131. CloseClusterNetwork(Hnetwork());
  132. } //*** CNetwork::~CNetwork
  133. /////////////////////////////////////////////////////////////////////////////
  134. //++
  135. //
  136. // CNetwork::Cleanup
  137. //
  138. // Routine Description:
  139. // Cleanup the item.
  140. //
  141. // Arguments:
  142. // None.
  143. //
  144. // Return Value:
  145. // None.
  146. //
  147. // Exceptions Thrown:
  148. // None.
  149. //
  150. //--
  151. /////////////////////////////////////////////////////////////////////////////
  152. void CNetwork::Cleanup(void)
  153. {
  154. // Delete the Network Interface list.
  155. if (m_plpciNetInterfaces != NULL)
  156. m_plpciNetInterfaces->RemoveAll();
  157. // Remove the item from the network list.
  158. {
  159. POSITION posPci;
  160. posPci = Pdoc()->LpciNetworks().Find(this);
  161. if (posPci != NULL)
  162. {
  163. Pdoc()->LpciNetworks().RemoveAt(posPci);
  164. } // if: found in the document's list
  165. } // Remove the item from the network list
  166. } //*** CNetwork::Cleanup()
  167. /////////////////////////////////////////////////////////////////////////////
  168. //++
  169. //
  170. // CNetwork::Init
  171. //
  172. // Routine Description:
  173. // Initialize the item.
  174. //
  175. // Arguments:
  176. // pdoc [IN OUT] Document to which this item belongs.
  177. // lpszName [IN] Name of the item.
  178. //
  179. // Return Value:
  180. // None.
  181. //
  182. // Exceptions Thrown:
  183. // CNTException Errors from OpenClusterNetwork or GetClusterNetworkKey.
  184. // Any exceptions thrown by new.
  185. //
  186. //--
  187. /////////////////////////////////////////////////////////////////////////////
  188. void CNetwork::Init(IN OUT CClusterDoc * pdoc, IN LPCTSTR lpszName)
  189. {
  190. DWORD dwStatus = ERROR_SUCCESS;
  191. LONG lResult;
  192. CString strName(lpszName); // Required if built non-Unicode
  193. CWaitCursor wc;
  194. ASSERT(Hnetwork() == NULL);
  195. ASSERT(Hkey() == NULL);
  196. // Call the base class method.
  197. CClusterItem::Init(pdoc, lpszName);
  198. try
  199. {
  200. // Open the network.
  201. m_hnetwork = OpenClusterNetwork(Hcluster(), strName);
  202. if (Hnetwork() == NULL)
  203. {
  204. dwStatus = GetLastError();
  205. ThrowStaticException(dwStatus, IDS_OPEN_NETWORK_ERROR, lpszName);
  206. } // if: error opening the cluster network
  207. // Get the network registry key.
  208. m_hkey = GetClusterNetworkKey(Hnetwork(), MAXIMUM_ALLOWED);
  209. // if (Hkey() == NULL)
  210. // ThrowStaticException(GetLastError(), IDS_GET_NETWORK_KEY_ERROR, lpszName);
  211. if (BDocObj())
  212. {
  213. ASSERT(Pcnk() != NULL);
  214. Trace(g_tagClusItemNotify, _T("CNetwork::Init() - Registering for network notifications (%08.8x) for '%s'"), Pcnk(), StrName());
  215. // Register for network notifications.
  216. lResult = RegisterClusterNotify(
  217. GetClusterAdminApp()->HchangeNotifyPort(),
  218. ( CLUSTER_CHANGE_NETWORK_STATE
  219. | CLUSTER_CHANGE_NETWORK_DELETED
  220. | CLUSTER_CHANGE_NETWORK_PROPERTY),
  221. Hnetwork(),
  222. (DWORD_PTR) Pcnk()
  223. );
  224. if (lResult != ERROR_SUCCESS)
  225. {
  226. dwStatus = lResult;
  227. ThrowStaticException(dwStatus, IDS_RES_NOTIF_REG_ERROR, lpszName);
  228. } // if: error registering for network notifications
  229. // Register for registry notifications.
  230. if (m_hkey != NULL)
  231. {
  232. lResult = RegisterClusterNotify(
  233. GetClusterAdminApp()->HchangeNotifyPort(),
  234. (CLUSTER_CHANGE_REGISTRY_NAME
  235. | CLUSTER_CHANGE_REGISTRY_ATTRIBUTES
  236. | CLUSTER_CHANGE_REGISTRY_VALUE
  237. | CLUSTER_CHANGE_REGISTRY_SUBTREE),
  238. Hkey(),
  239. (DWORD_PTR) Pcnk()
  240. );
  241. if (lResult != ERROR_SUCCESS)
  242. {
  243. dwStatus = lResult;
  244. ThrowStaticException(dwStatus, IDS_RES_NOTIF_REG_ERROR, lpszName);
  245. } // if: error registering for registry notifications
  246. } // if: there is a key
  247. } // if: document object
  248. // Allocate lists.
  249. m_plpciNetInterfaces = new CNetInterfaceList;
  250. if ( m_plpciNetInterfaces == NULL )
  251. {
  252. AfxThrowMemoryException();
  253. } // if: error allocating the network interface list
  254. // Read the initial state.
  255. UpdateState();
  256. } // try
  257. catch (CException *)
  258. {
  259. if (Hkey() != NULL)
  260. {
  261. ClusterRegCloseKey(Hkey());
  262. m_hkey = NULL;
  263. } // if: registry key opened
  264. if (Hnetwork() != NULL)
  265. {
  266. CloseClusterNetwork(Hnetwork());
  267. m_hnetwork = NULL;
  268. } // if: network opened
  269. m_bReadOnly = TRUE;
  270. throw;
  271. } // catch: CException
  272. } //*** CNetwork::Init()
  273. /////////////////////////////////////////////////////////////////////////////
  274. //++
  275. //
  276. // CNetwork::ReadItem
  277. //
  278. // Routine Description:
  279. // Read the item parameters from the cluster database.
  280. //
  281. // Arguments:
  282. // None.
  283. //
  284. // Return Value:
  285. // None.
  286. //
  287. // Exceptions Thrown:
  288. // CNTException Errors from CClusterItem::DwReadValue().
  289. //
  290. //--
  291. /////////////////////////////////////////////////////////////////////////////
  292. void CNetwork::ReadItem(void)
  293. {
  294. DWORD dwStatus;
  295. DWORD dwRetStatus = ERROR_SUCCESS;
  296. CString strOldName;
  297. CWaitCursor wc;
  298. ASSERT_VALID(this);
  299. if (Hnetwork() != NULL)
  300. {
  301. m_rgProps[epropDescription].m_value.pstr = &m_strDescription;
  302. m_rgProps[epropRole].m_value.pdw = (DWORD *) &m_cnr;
  303. // Save the name so we can detect changes.
  304. strOldName = StrName();
  305. // Call the base class method.
  306. CClusterItem::ReadItem();
  307. // Read and parse the common properties.
  308. {
  309. CClusPropList cpl;
  310. dwStatus = cpl.ScGetNetworkProperties(
  311. Hnetwork(),
  312. CLUSCTL_NETWORK_GET_COMMON_PROPERTIES
  313. );
  314. if (dwStatus == ERROR_SUCCESS)
  315. dwStatus = DwParseProperties(cpl);
  316. if (dwStatus != ERROR_SUCCESS)
  317. dwRetStatus = dwStatus;
  318. } // Read and parse the common properties
  319. // Read and parse the read-only common properties.
  320. if (dwRetStatus == ERROR_SUCCESS)
  321. {
  322. CClusPropList cpl;
  323. dwStatus = cpl.ScGetNetworkProperties(
  324. Hnetwork(),
  325. CLUSCTL_NETWORK_GET_RO_COMMON_PROPERTIES
  326. );
  327. if (dwStatus == ERROR_SUCCESS)
  328. dwStatus = DwParseProperties(cpl);
  329. if (dwStatus != ERROR_SUCCESS)
  330. dwRetStatus = dwStatus;
  331. } // if: no error yet
  332. // Read the characteristics.
  333. if (dwRetStatus == ERROR_SUCCESS)
  334. {
  335. DWORD cbReturned;
  336. dwStatus = ClusterNetworkControl(
  337. Hnetwork(),
  338. NULL,
  339. CLUSCTL_NETWORK_GET_CHARACTERISTICS,
  340. NULL,
  341. NULL,
  342. &m_dwCharacteristics,
  343. sizeof(m_dwCharacteristics),
  344. &cbReturned
  345. );
  346. if (dwStatus != ERROR_SUCCESS)
  347. dwRetStatus = dwStatus;
  348. else
  349. {
  350. ASSERT(cbReturned == sizeof(m_dwCharacteristics));
  351. } // else: data retrieved successfully
  352. } // if: no error yet
  353. // Read the flags.
  354. if (dwRetStatus == ERROR_SUCCESS)
  355. {
  356. DWORD cbReturned;
  357. dwStatus = ClusterNetworkControl(
  358. Hnetwork(),
  359. NULL,
  360. CLUSCTL_NETWORK_GET_FLAGS,
  361. NULL,
  362. NULL,
  363. &m_dwFlags,
  364. sizeof(m_dwFlags),
  365. &cbReturned
  366. );
  367. if (dwStatus != ERROR_SUCCESS)
  368. dwRetStatus = dwStatus;
  369. else
  370. {
  371. ASSERT(cbReturned == sizeof(m_dwFlags));
  372. } // else: data retrieved successfully
  373. } // if: no error yet
  374. // Construct the list of extensions.
  375. ReadExtensions();
  376. // If the name changed, update all the network interfaces.
  377. if ( (m_plpciNetInterfaces != NULL) && (StrName() != strOldName) )
  378. {
  379. POSITION posPciNetIFaces;
  380. CNetInterface * pciNetIFace;
  381. posPciNetIFaces = m_plpciNetInterfaces->GetHeadPosition();
  382. while ( posPciNetIFaces != NULL )
  383. {
  384. pciNetIFace = reinterpret_cast< CNetInterface * >( m_plpciNetInterfaces->GetNext(posPciNetIFaces) );
  385. ASSERT_VALID(pciNetIFace);
  386. ASSERT_KINDOF(CNetInterface, pciNetIFace);
  387. pciNetIFace->ReadItem();
  388. } // while: more items in the list
  389. } // if: list exists and name changed
  390. } // if: network is available
  391. // Read the initial state.
  392. UpdateState();
  393. // If any errors occurred, throw an exception.
  394. if (dwRetStatus != ERROR_SUCCESS)
  395. {
  396. m_bReadOnly = TRUE;
  397. // if (dwRetStatus != ERROR_FILE_NOT_FOUND)
  398. ThrowStaticException(dwRetStatus, IDS_READ_NETWORK_PROPS_ERROR, StrName());
  399. } // if: error reading properties
  400. MarkAsChanged(FALSE);
  401. } //*** CNetwork::ReadItem()
  402. /////////////////////////////////////////////////////////////////////////////
  403. //++
  404. //
  405. // CNetwork::ReadExtensions
  406. //
  407. // Routine Description:
  408. // Read extension lists.
  409. //
  410. // Arguments:
  411. // None.
  412. //
  413. // Return Value:
  414. // None.
  415. //
  416. // Exceptions Thrown:
  417. // None.
  418. //
  419. //--
  420. /////////////////////////////////////////////////////////////////////////////
  421. void CNetwork::ReadExtensions(void)
  422. {
  423. } //*** CNetwork::ReadExtensions()
  424. /////////////////////////////////////////////////////////////////////////////
  425. //++
  426. //
  427. // CNetwork::PlstrExtension
  428. //
  429. // Routine Description:
  430. // Return the list of admin extensions.
  431. //
  432. // Arguments:
  433. // None.
  434. //
  435. // Return Value:
  436. // plstr List of extensions.
  437. // NULL No extension associated with this object.
  438. //
  439. // Exceptions Thrown:
  440. // None.
  441. //
  442. //--
  443. /////////////////////////////////////////////////////////////////////////////
  444. const CStringList * CNetwork::PlstrExtensions(void) const
  445. {
  446. return &Pdoc()->PciCluster()->LstrNetworkExtensions();
  447. } //*** CNetwork::PlstrExtensions()
  448. /////////////////////////////////////////////////////////////////////////////
  449. //++
  450. //
  451. // CNetwork::CollectInterfaces
  452. //
  453. // Routine Description:
  454. // Construct a list of interfaces connected to this network.
  455. //
  456. // Arguments:
  457. // plpci [IN OUT] List to fill.
  458. //
  459. // Return Value:
  460. // None.
  461. //
  462. // Exceptions Thrown:
  463. // CNTException Errors from ClusterNetworkOpenEnum() or
  464. // ClusterNetworkEnum().
  465. // Any exceptions thrown by new or CList::AddTail().
  466. //
  467. //--
  468. /////////////////////////////////////////////////////////////////////////////
  469. void CNetwork::CollectInterfaces(IN OUT CNetInterfaceList * plpci) const
  470. {
  471. DWORD dwStatus;
  472. HNETWORKENUM hnetenum;
  473. int ienum;
  474. LPWSTR pwszName = NULL;
  475. DWORD cchName;
  476. DWORD cchmacName;
  477. DWORD dwRetType;
  478. CNetInterface * pciNetIFace;
  479. CWaitCursor wc;
  480. ASSERT_VALID(Pdoc());
  481. ASSERT(Hnetwork() != NULL);
  482. if (plpci == NULL)
  483. plpci = m_plpciNetInterfaces;
  484. ASSERT(plpci != NULL);
  485. // Remove the previous contents of the list.
  486. plpci->RemoveAll();
  487. if (Hnetwork() != NULL)
  488. {
  489. // Open the enumeration.
  490. hnetenum = ClusterNetworkOpenEnum(Hnetwork(), CLUSTER_NETWORK_ENUM_NETINTERFACES);
  491. if (hnetenum == NULL)
  492. ThrowStaticException(GetLastError(), IDS_ENUM_NETWORK_INTERFACES_ERROR, StrName());
  493. try
  494. {
  495. // Allocate a name buffer.
  496. cchmacName = 128;
  497. pwszName = new WCHAR[cchmacName];
  498. if ( pwszName == NULL )
  499. {
  500. AfxThrowMemoryException();
  501. } // if: error allocating name buffer
  502. // Loop through the enumeration and add each interface to the list.
  503. for (ienum = 0 ; ; ienum++)
  504. {
  505. // Get the next item in the enumeration.
  506. cchName = cchmacName;
  507. dwStatus = ClusterNetworkEnum(hnetenum, ienum, &dwRetType, pwszName, &cchName);
  508. if (dwStatus == ERROR_MORE_DATA)
  509. {
  510. delete [] pwszName;
  511. cchmacName = ++cchName;
  512. pwszName = new WCHAR[cchmacName];
  513. if ( pwszName == NULL )
  514. {
  515. AfxThrowMemoryException();
  516. } // if: error allocating name buffer
  517. dwStatus = ClusterNetworkEnum(hnetenum, ienum, &dwRetType, pwszName, &cchName);
  518. } // if: name buffer was too small
  519. if (dwStatus == ERROR_NO_MORE_ITEMS)
  520. break;
  521. else if (dwStatus != ERROR_SUCCESS)
  522. ThrowStaticException(dwStatus, IDS_ENUM_NETWORK_INTERFACES_ERROR, StrName());
  523. ASSERT(dwRetType == CLUSTER_NETWORK_ENUM_NETINTERFACES);
  524. // Find the item in the list of networks on the document.
  525. pciNetIFace = Pdoc()->LpciNetInterfaces().PciNetInterfaceFromName(pwszName);
  526. ASSERT_VALID(pciNetIFace);
  527. // Add the interface to the list.
  528. if (pciNetIFace != NULL)
  529. {
  530. plpci->AddTail(pciNetIFace);
  531. } // if: found node in list
  532. } // for: each network interface connected to this network
  533. delete [] pwszName;
  534. ClusterNetworkCloseEnum(hnetenum);
  535. } // try
  536. catch (CException *)
  537. {
  538. delete [] pwszName;
  539. ClusterNetworkCloseEnum(hnetenum);
  540. throw;
  541. } // catch: any exception
  542. } // if: network is available
  543. } //*** CNetwork::CollecPossibleOwners()
  544. /////////////////////////////////////////////////////////////////////////////
  545. //++
  546. //
  547. // CNetwork::AddNetInterface
  548. //
  549. // Routine Description:
  550. // Add a network interface to the list of interaces connected to this
  551. // network.
  552. //
  553. // Arguments:
  554. // pciNetIFace [IN OUT] New network interface.
  555. //
  556. // Return Value:
  557. // None.
  558. //
  559. //--
  560. /////////////////////////////////////////////////////////////////////////////
  561. void CNetwork::AddNetInterface(IN OUT CNetInterface * pciNetIFace)
  562. {
  563. POSITION posPci;
  564. ASSERT_VALID(pciNetIFace);
  565. Trace(g_tagNetwork, _T("(%s) (%s (%x)) - Adding network interface '%s'"), Pdoc()->StrNode(), StrName(), this, pciNetIFace->StrName());
  566. // Make sure the network interface is not already in the list.
  567. VERIFY((posPci = LpciNetInterfaces().Find(pciNetIFace)) == NULL);
  568. if (posPci == NULL)
  569. {
  570. POSITION posPtiNetwork;
  571. CTreeItem * ptiNetwork;
  572. // Loop through each tree item to update the Network list.
  573. posPtiNetwork = LptiBackPointers().GetHeadPosition();
  574. while (posPtiNetwork != NULL)
  575. {
  576. ptiNetwork = LptiBackPointers().GetNext(posPtiNetwork);
  577. ASSERT_VALID(ptiNetwork);
  578. // Add the new network interface.
  579. VERIFY(ptiNetwork->PliAddChild(pciNetIFace) != NULL);
  580. } // while: more tree items for this network
  581. m_plpciNetInterfaces->AddTail(pciNetIFace);
  582. } // if: network interface not in the list yet
  583. } //*** CNetwork::AddNetInterface()
  584. /////////////////////////////////////////////////////////////////////////////
  585. //++
  586. //
  587. // CNetwork::RemoveNetInterface
  588. //
  589. // Routine Description:
  590. // Remove a network interface from the list of interfaces connected to
  591. // this network
  592. //
  593. // Arguments:
  594. // pciNetIFace [IN OUT] Network interface that is no longer
  595. // connected to this network.
  596. //
  597. // Return Value:
  598. // None.
  599. //
  600. //--
  601. /////////////////////////////////////////////////////////////////////////////
  602. void CNetwork::RemoveNetInterface(IN OUT CNetInterface * pciNetIFace)
  603. {
  604. POSITION posPci;
  605. ASSERT_VALID(pciNetIFace);
  606. Trace(g_tagNetwork, _T("(%s) (%s (%x)) - Removing network interface '%s'"), Pdoc()->StrNode(), StrName(), this, pciNetIFace->StrName());
  607. // Make sure the network interface is in the list.
  608. VERIFY((posPci = LpciNetInterfaces().Find(pciNetIFace)) != NULL);
  609. if (posPci != NULL)
  610. {
  611. POSITION posPtiNetwork;
  612. CTreeItem * ptiNetwork;
  613. // Loop through each tree item to update the Network list.
  614. posPtiNetwork = LptiBackPointers().GetHeadPosition();
  615. while (posPtiNetwork != NULL)
  616. {
  617. ptiNetwork = LptiBackPointers().GetNext(posPtiNetwork);
  618. ASSERT_VALID(ptiNetwork);
  619. // Remove the network interface.
  620. ptiNetwork->RemoveChild(pciNetIFace);
  621. } // while: more tree items for this network
  622. m_plpciNetInterfaces->RemoveAt(posPci);
  623. } // if: network interface in the list
  624. } //*** CNetwork::RemoveNetInterface()
  625. /////////////////////////////////////////////////////////////////////////////
  626. //++
  627. //
  628. // CNetwork::SetName
  629. //
  630. // Routine Description:
  631. // Set the name of this network.
  632. //
  633. // Arguments:
  634. // pszName [IN] New name of the network.
  635. //
  636. // Return Value:
  637. // None.
  638. //
  639. // Exceptions Thrown:
  640. // Any exceptions thrown by Rename().
  641. //--
  642. /////////////////////////////////////////////////////////////////////////////
  643. void CNetwork::SetName(IN LPCTSTR pszName)
  644. {
  645. Rename(pszName);
  646. } //*** CNetwork::SetName()
  647. /////////////////////////////////////////////////////////////////////////////
  648. //++
  649. //
  650. // CNetwork::SetCommonProperties
  651. //
  652. // Routine Description:
  653. // Set the common properties for this network in the cluster database.
  654. //
  655. // Arguments:
  656. // rstrDesc [IN] Description string.
  657. // cnr [IN] Network role.
  658. // bValidateOnly [IN] Only validate the data.
  659. //
  660. // Return Value:
  661. // None.
  662. //
  663. // Exceptions Thrown:
  664. // Any exceptions thrown by CClusterItem::SetCommonProperties().
  665. //
  666. //--
  667. /////////////////////////////////////////////////////////////////////////////
  668. void CNetwork::SetCommonProperties(
  669. IN const CString & rstrDesc,
  670. IN CLUSTER_NETWORK_ROLE cnr,
  671. IN BOOL bValidateOnly
  672. )
  673. {
  674. CNTException nte(ERROR_SUCCESS, 0, NULL, NULL, FALSE /*bAutoDelete*/);
  675. m_rgProps[epropDescription].m_value.pstr = (CString *) &rstrDesc;
  676. m_rgProps[epropRole].m_value.pdw = (DWORD *) &cnr;
  677. try
  678. {
  679. CClusterItem::SetCommonProperties(bValidateOnly);
  680. } // try
  681. catch (CNTException * pnte)
  682. {
  683. nte.SetOperation(
  684. pnte->Sc(),
  685. pnte->IdsOperation(),
  686. pnte->PszOperArg1(),
  687. pnte->PszOperArg2()
  688. );
  689. } // catch: CNTException
  690. m_rgProps[epropDescription].m_value.pstr = &m_strDescription;
  691. m_rgProps[epropRole].m_value.pdw = (DWORD *) &m_cnr;
  692. if (nte.Sc() != ERROR_SUCCESS)
  693. ThrowStaticException(
  694. nte.Sc(),
  695. nte.IdsOperation(),
  696. nte.PszOperArg1(),
  697. nte.PszOperArg2()
  698. );
  699. } //*** CNetwork::SetCommonProperties()
  700. /////////////////////////////////////////////////////////////////////////////
  701. //++
  702. //
  703. // CNetwork::DwSetCommonProperties
  704. //
  705. // Routine Description:
  706. // Set the common properties for this network in the cluster database.
  707. //
  708. // Arguments:
  709. // rcpl [IN] Property list to set.
  710. // bValidateOnly [IN] Only validate the data.
  711. //
  712. // Return Value:
  713. // Any status returned by ClusterNetworkControl().
  714. //
  715. //--
  716. /////////////////////////////////////////////////////////////////////////////
  717. DWORD CNetwork::DwSetCommonProperties(
  718. IN const CClusPropList & rcpl,
  719. IN BOOL bValidateOnly
  720. )
  721. {
  722. DWORD dwStatus;
  723. CWaitCursor wc;
  724. ASSERT(Hnetwork());
  725. if ((rcpl.PbPropList() != NULL) && (rcpl.CbPropList() > 0))
  726. {
  727. DWORD cbProps;
  728. DWORD dwControl;
  729. if (bValidateOnly)
  730. dwControl = CLUSCTL_NETWORK_VALIDATE_COMMON_PROPERTIES;
  731. else
  732. dwControl = CLUSCTL_NETWORK_SET_COMMON_PROPERTIES;
  733. // Set common properties.
  734. dwStatus = ClusterNetworkControl(
  735. Hnetwork(),
  736. NULL, // hNode
  737. dwControl,
  738. rcpl.PbPropList(),
  739. rcpl.CbPropList(),
  740. NULL, // lpOutBuffer
  741. 0, // nOutBufferSize
  742. &cbProps
  743. );
  744. } // if: there is data to set
  745. else
  746. dwStatus = ERROR_SUCCESS;
  747. return dwStatus;
  748. } //*** CNetwork::DwSetCommonProperties()
  749. /////////////////////////////////////////////////////////////////////////////
  750. //++
  751. //
  752. // CNetwork::UpdateState
  753. //
  754. // Routine Description:
  755. // Update the current state of the item.
  756. //
  757. // Arguments:
  758. // None.
  759. //
  760. // Return Value:
  761. // None.
  762. //
  763. //--
  764. /////////////////////////////////////////////////////////////////////////////
  765. void CNetwork::UpdateState(void)
  766. {
  767. CClusterAdminApp * papp = GetClusterAdminApp();
  768. Trace(g_tagNetwork, _T("(%s) (%s (%x)) - Updating state"), Pdoc()->StrNode(), StrName(), this);
  769. // Get the current state of the network.
  770. if (Hnetwork() == NULL)
  771. m_cns = ClusterNetworkStateUnknown;
  772. else
  773. {
  774. CWaitCursor wc;
  775. m_cns = GetClusterNetworkState(Hnetwork());
  776. } // else: network is available
  777. // Save the current state image index.
  778. switch (Cns())
  779. {
  780. case ClusterNetworkStateUnknown:
  781. case ClusterNetworkUnavailable:
  782. m_iimgState = papp->Iimg(IMGLI_NETWORK_UNKNOWN);
  783. break;
  784. case ClusterNetworkUp:
  785. m_iimgState = papp->Iimg(IMGLI_NETWORK);
  786. break;
  787. case ClusterNetworkPartitioned:
  788. m_iimgState = papp->Iimg(IMGLI_NETWORK_PARTITIONED);
  789. break;
  790. case ClusterNetworkDown:
  791. m_iimgState = papp->Iimg(IMGLI_NETWORK_DOWN);
  792. break;
  793. default:
  794. Trace(g_tagNetwork, _T("(%s) (%s (%x)) - UpdateState: Unknown state '%d' for network '%s'"), Pdoc()->StrNode(), StrName(), this, Cns(), StrName());
  795. m_iimgState = (UINT) -1;
  796. break;
  797. } // switch: Crs()
  798. // Call the base class method.
  799. CClusterItem::UpdateState();
  800. } //*** CNetwork::UpdateState()
  801. /////////////////////////////////////////////////////////////////////////////
  802. //++
  803. //
  804. // CNetwork::BGetColumnData
  805. //
  806. // Routine Description:
  807. // Returns a string with the column data.
  808. //
  809. // Arguments:
  810. // colid [IN] Column ID.
  811. // rstrText [OUT] String in which to return the text for the column.
  812. //
  813. // Return Value:
  814. // TRUE Column data returned.
  815. // FALSE Column ID not recognized.
  816. //
  817. //--
  818. /////////////////////////////////////////////////////////////////////////////
  819. BOOL CNetwork::BGetColumnData(IN COLID colid, OUT CString & rstrText)
  820. {
  821. BOOL bSuccess;
  822. switch (colid)
  823. {
  824. case IDS_COLTEXT_STATE:
  825. GetStateName(rstrText);
  826. bSuccess = TRUE;
  827. break;
  828. case IDS_COLTEXT_ROLE:
  829. GetRoleName(rstrText);
  830. bSuccess = TRUE;
  831. break;
  832. case IDS_COLTEXT_ADDRESS:
  833. rstrText = m_strAddress;
  834. bSuccess = TRUE;
  835. break;
  836. case IDS_COLTEXT_MASK:
  837. rstrText = m_strAddressMask;
  838. bSuccess = TRUE;
  839. break;
  840. default:
  841. bSuccess = CClusterItem::BGetColumnData(colid, rstrText);
  842. break;
  843. } // switch: colid
  844. return bSuccess;
  845. } //*** CNetwork::BGetColumnData()
  846. /////////////////////////////////////////////////////////////////////////////
  847. //++
  848. //
  849. // CNetwork::GetTreeName
  850. //
  851. // Routine Description:
  852. // Returns a string to be used in a tree control.
  853. //
  854. // Arguments:
  855. // rstrName [OUT] String in which to return the name.
  856. //
  857. // Return Value:
  858. // None.
  859. //
  860. //--
  861. /////////////////////////////////////////////////////////////////////////////
  862. #ifdef _DISPLAY_STATE_TEXT_IN_TREE
  863. void CNetwork::GetTreeName(OUT CString & rstrName) const
  864. {
  865. CString strState;
  866. GetStateName(strState);
  867. rstrName.Format(_T("%s (%s)"), StrName(), strState);
  868. } //*** CNetwork::GetTreeName()
  869. #endif
  870. /////////////////////////////////////////////////////////////////////////////
  871. //++
  872. //
  873. // CNetwork::GetStateName
  874. //
  875. // Routine Description:
  876. // Returns a string with the name of the current state.
  877. //
  878. // Arguments:
  879. // rstrState [OUT] String in which to return the name of the current state.
  880. //
  881. // Return Value:
  882. // None.
  883. //
  884. //--
  885. /////////////////////////////////////////////////////////////////////////////
  886. void CNetwork::GetStateName(OUT CString & rstrState) const
  887. {
  888. switch (Cns())
  889. {
  890. case ClusterNetworkStateUnknown:
  891. rstrState.LoadString(IDS_UNKNOWN);
  892. break;
  893. case ClusterNetworkUp:
  894. rstrState.LoadString(IDS_UP);
  895. break;
  896. case ClusterNetworkPartitioned:
  897. rstrState.LoadString(IDS_PARTITIONED);
  898. break;
  899. case ClusterNetworkDown:
  900. rstrState.LoadString(IDS_DOWN);
  901. break;
  902. case ClusterNetworkUnavailable:
  903. rstrState.LoadString(IDS_UNAVAILABLE);
  904. break;
  905. default:
  906. rstrState.Empty();
  907. break;
  908. } // switch: Crs()
  909. } //*** CNetwork::GetStateName()
  910. /////////////////////////////////////////////////////////////////////////////
  911. //++
  912. //
  913. // CNetwork::GetRoleName
  914. //
  915. // Routine Description:
  916. // Returns a string with the name of the current network role.
  917. //
  918. // Arguments:
  919. // rstrRole [OUT] String in which to return the name of the current role.
  920. //
  921. // Return Value:
  922. // None.
  923. //
  924. //--
  925. /////////////////////////////////////////////////////////////////////////////
  926. void CNetwork::GetRoleName(OUT CString & rstrRole) const
  927. {
  928. switch (Cnr())
  929. {
  930. case ClusterNetworkRoleInternalAndClient:
  931. rstrRole.LoadString(IDS_CLIENT_AND_CLUSTER);
  932. break;
  933. case ClusterNetworkRoleClientAccess:
  934. rstrRole.LoadString(IDS_CLIENT_ONLY);
  935. break;
  936. case ClusterNetworkRoleInternalUse:
  937. rstrRole.LoadString(IDS_CLUSTER_ONLY);
  938. break;
  939. case ClusterNetworkRoleNone:
  940. rstrRole.LoadString(IDS_DONT_USE);
  941. break;
  942. default:
  943. rstrRole.Empty();
  944. break;
  945. } // switch: Cnr()
  946. } //*** CNetwork::GetRoleName()
  947. /////////////////////////////////////////////////////////////////////////////
  948. //++
  949. //
  950. // CNetwork::BCanBeEdited
  951. //
  952. // Routine Description:
  953. // Determines if the network can be renamed.
  954. //
  955. // Arguments:
  956. // None.
  957. //
  958. // Return Value:
  959. // TRUE Network can be renamed.
  960. // FALSE Network cannot be renamed.
  961. //
  962. //--
  963. /////////////////////////////////////////////////////////////////////////////
  964. BOOL CNetwork::BCanBeEdited(void) const
  965. {
  966. BOOL bCanBeEdited;
  967. if ( (Cns() == ClusterNetworkStateUnknown)
  968. || BReadOnly())
  969. bCanBeEdited = FALSE;
  970. else
  971. bCanBeEdited = TRUE;
  972. return bCanBeEdited;
  973. } //*** CNetwork::BCanBeEdited()
  974. /////////////////////////////////////////////////////////////////////////////
  975. //++
  976. //
  977. // CNetwork::Rename
  978. //
  979. // Routine Description:
  980. // Rename the network.
  981. //
  982. // Arguments:
  983. // pszName [IN] New name to give to the network.
  984. //
  985. // Return Value:
  986. // None.
  987. //
  988. // Exceptions Thrown:
  989. // CNTException Errors returned from SetClusterNetwName().
  990. // Any exceptions thrown by SetClusterNetworkName().
  991. //
  992. //--
  993. /////////////////////////////////////////////////////////////////////////////
  994. void CNetwork::Rename(IN LPCTSTR pszName)
  995. {
  996. DWORD dwStatus;
  997. CWaitCursor wc;
  998. ASSERT(Hnetwork() != NULL);
  999. if (StrName() != pszName)
  1000. {
  1001. // Validate the name.
  1002. if (!NcIsValidConnectionName(pszName))
  1003. {
  1004. ThrowStaticException((IDS) IDS_INVALID_NETWORK_CONNECTION_NAME);
  1005. } // if: error validating the name
  1006. dwStatus = SetClusterNetworkName(Hnetwork(), pszName);
  1007. if (dwStatus != ERROR_SUCCESS)
  1008. ThrowStaticException(dwStatus, IDS_RENAME_NETWORK_ERROR, StrName(), pszName);
  1009. } // if: the name changed
  1010. } //*** CNetwork::Rename()
  1011. /////////////////////////////////////////////////////////////////////////////
  1012. //++
  1013. //
  1014. // CNetwork::OnBeginLabelEdit
  1015. //
  1016. // Routine Description:
  1017. // Prepare an edit control in a view for editing the cluster name.
  1018. //
  1019. // Arguments:
  1020. // pedit [IN OUT] Edit control to prepare.
  1021. //
  1022. // Return Value:
  1023. // None.
  1024. //
  1025. //--
  1026. /////////////////////////////////////////////////////////////////////////////
  1027. void CNetwork::OnBeginLabelEdit(IN OUT CEdit * pedit)
  1028. {
  1029. ASSERT_VALID(pedit);
  1030. pedit->SetLimitText(NETCON_MAX_NAME_LEN);
  1031. } //*** CNetwork::OnBeginLabelEdit()
  1032. /////////////////////////////////////////////////////////////////////////////
  1033. //++
  1034. //
  1035. // CNetwork::OnUpdateProperties
  1036. //
  1037. // Routine Description:
  1038. // Determines whether menu items corresponding to ID_FILE_PROPERTIES
  1039. // should be enabled or not.
  1040. //
  1041. // Arguments:
  1042. // pCmdUI [IN OUT] Command routing object.
  1043. //
  1044. // Return Value:
  1045. // None.
  1046. //
  1047. //--
  1048. /////////////////////////////////////////////////////////////////////////////
  1049. void CNetwork::OnUpdateProperties(CCmdUI * pCmdUI)
  1050. {
  1051. pCmdUI->Enable(TRUE);
  1052. } //*** CNetwork::OnUpdateProperties()
  1053. /////////////////////////////////////////////////////////////////////////////
  1054. //++
  1055. //
  1056. // CNetwork::BDisplayProperties
  1057. //
  1058. // Routine Description:
  1059. // Display properties for the object.
  1060. //
  1061. // Arguments:
  1062. // bReadOnly [IN] Don't allow edits to the object properties.
  1063. //
  1064. // Return Value:
  1065. // TRUE OK pressed.
  1066. // FALSE OK not pressed.
  1067. //
  1068. //--
  1069. /////////////////////////////////////////////////////////////////////////////
  1070. BOOL CNetwork::BDisplayProperties(IN BOOL bReadOnly)
  1071. {
  1072. BOOL bChanged = FALSE;
  1073. CNetworkPropSheet sht(AfxGetMainWnd());
  1074. // Do this in case this object is deleted while we are operating on it.
  1075. AddRef();
  1076. // If the object has changed, read it.
  1077. if (BChanged())
  1078. ReadItem();
  1079. // Display the property sheet.
  1080. try
  1081. {
  1082. sht.SetReadOnly(bReadOnly);
  1083. if (sht.BInit(this, IimgObjectType()))
  1084. bChanged = ((sht.DoModal() == IDOK) && !bReadOnly);
  1085. } // try
  1086. catch (CException * pe)
  1087. {
  1088. pe->Delete();
  1089. } // catch: CException
  1090. Release();
  1091. return bChanged;
  1092. } //*** CNetwork::BDisplayProperties()
  1093. /////////////////////////////////////////////////////////////////////////////
  1094. //++
  1095. //
  1096. // CNetwork::OnClusterNotify
  1097. //
  1098. // Routine Description:
  1099. // Handler for the WM_CAM_CLUSTER_NOTIFY message.
  1100. // Processes cluster notifications for this object.
  1101. //
  1102. // Arguments:
  1103. // pnotify [IN OUT] Object describing the notification.
  1104. //
  1105. // Return Value:
  1106. // Value returned from the application method.
  1107. //
  1108. //--
  1109. /////////////////////////////////////////////////////////////////////////////
  1110. LRESULT CNetwork::OnClusterNotify(IN OUT CClusterNotify * pnotify)
  1111. {
  1112. ASSERT(pnotify != NULL);
  1113. ASSERT_VALID(this);
  1114. try
  1115. {
  1116. switch (pnotify->m_dwFilterType)
  1117. {
  1118. case CLUSTER_CHANGE_NETWORK_STATE:
  1119. Trace(g_tagNetNotify, _T("(%s) - Network '%s' (%x) state changed (%s)"), Pdoc()->StrNode(), StrName(), this, pnotify->m_strName);
  1120. UpdateState();
  1121. break;
  1122. case CLUSTER_CHANGE_NETWORK_DELETED:
  1123. Trace(g_tagNetNotify, _T("(%s) - Network '%s' (%x) deleted (%s)"), Pdoc()->StrNode(), StrName(), this, pnotify->m_strName);
  1124. if (Pdoc()->BClusterAvailable())
  1125. Delete();
  1126. break;
  1127. case CLUSTER_CHANGE_NETWORK_PROPERTY:
  1128. Trace(g_tagNetNotify, _T("(%s) - Network '%s' (%x) properties changed (%s)"), Pdoc()->StrNode(), StrName(), this, pnotify->m_strName);
  1129. if (Pdoc()->BClusterAvailable())
  1130. ReadItem();
  1131. break;
  1132. case CLUSTER_CHANGE_REGISTRY_NAME:
  1133. Trace(g_tagNetRegNotify, _T("(%s) - Registry namespace '%s' changed (%s %s (%x))"), Pdoc()->StrNode(), pnotify->m_strName, StrType(), StrName(), this);
  1134. MarkAsChanged();
  1135. break;
  1136. case CLUSTER_CHANGE_REGISTRY_ATTRIBUTES:
  1137. Trace(g_tagNetRegNotify, _T("(%s) - Registry attributes for '%s' changed (%s %s (%x))"), Pdoc()->StrNode(), pnotify->m_strName, StrType(), StrName(), this);
  1138. MarkAsChanged();
  1139. break;
  1140. case CLUSTER_CHANGE_REGISTRY_VALUE:
  1141. Trace(g_tagNetRegNotify, _T("(%s) - Registry value '%s' changed (%s %s (%x))"), Pdoc()->StrNode(), pnotify->m_strName, StrType(), StrName(), this);
  1142. MarkAsChanged();
  1143. break;
  1144. default:
  1145. Trace(g_tagNetNotify, _T("(%s) - Unknown network notification (%x) for '%s' (%x) (%s)"), Pdoc()->StrNode(), pnotify->m_dwFilterType, StrName(), this, pnotify->m_strName);
  1146. } // switch: dwFilterType
  1147. } // try
  1148. catch (CException * pe)
  1149. {
  1150. // Don't display anything on notification errors.
  1151. // If it's really a problem, the user will see it when
  1152. // refreshing the view.
  1153. //pe->ReportError();
  1154. pe->Delete();
  1155. } // catch: CException
  1156. delete pnotify;
  1157. return 0;
  1158. } //*** CNetwork::OnClusterNotify()
  1159. //*************************************************************************//
  1160. /////////////////////////////////////////////////////////////////////////////
  1161. // Global Functions
  1162. /////////////////////////////////////////////////////////////////////////////
  1163. /////////////////////////////////////////////////////////////////////////////
  1164. //++
  1165. //
  1166. // DeleteAllItemData
  1167. //
  1168. // Routine Description:
  1169. // Deletes all item data in a CList.
  1170. //
  1171. // Arguments:
  1172. // rlp [IN OUT] List whose data is to be deleted.
  1173. //
  1174. // Return Value:
  1175. // None.
  1176. //
  1177. //--
  1178. /////////////////////////////////////////////////////////////////////////////
  1179. #ifdef NEVER
  1180. void DeleteAllItemData(IN OUT CNetworkList & rlp)
  1181. {
  1182. POSITION pos;
  1183. CNetwork * pci;
  1184. // Delete all the items in the Contained list.
  1185. pos = rlp.GetHeadPosition();
  1186. while (pos != NULL)
  1187. {
  1188. pci = rlp.GetNext(pos);
  1189. ASSERT_VALID(pci);
  1190. // Trace(g_tagClusItemDelete, _T("DeleteAllItemData(rlp) - Deleting network cluster item '%s' (%x)"), pci->StrName(), pci);
  1191. pci->Delete();
  1192. } // while: more items in the list
  1193. } //*** DeleteAllItemData()
  1194. #endif