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.

564 lines
16 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. //
  6. // nbprop.cpp
  7. // IPX summary node property sheet and property pages
  8. //
  9. // FILE HISTORY:
  10. #include "stdafx.h"
  11. #include "rtrutil.h" // smart MPR handle pointers
  12. #include "format.h" // FormatNumber function
  13. #include "ipxstaticroute.h"
  14. #include "summary.h"
  15. #include "ipxrtdef.h"
  16. #include "filter.h"
  17. #include "ipxutil.h"
  18. extern "C"
  19. {
  20. #include "routprot.h"
  21. };
  22. // ---------------------------------------------------------------------------
  23. // IpxStaticRoutePropertySheet::IpxStaticRoutePropertySheet
  24. // Initialize the RtrPropertySheet and only Property Page.
  25. // Author: Deonb
  26. // ---------------------------------------------------------------------------
  27. IpxStaticRoutePropertySheet::IpxStaticRoutePropertySheet(ITFSNode *pNode,
  28. IComponentData *pComponentData,
  29. ITFSComponentData *pTFSCompData,
  30. LPCTSTR pszSheetName,
  31. CWnd *pParent,
  32. UINT iPage,
  33. BOOL fScopePane)
  34. : RtrPropertySheet(pNode, pComponentData, pTFSCompData,
  35. pszSheetName, pParent, iPage, fScopePane),
  36. m_pageGeneral(IDD_STATIC_ROUTE_PROPERTYPAGE)
  37. {
  38. m_spNode = pNode;
  39. }
  40. // ---------------------------------------------------------------------------
  41. // IpxStaticRoutePropertySheet::Init
  42. // Initialize the property sheets. The general action here will be
  43. // to initialize/add the various pages.
  44. // Author: Deonb
  45. // ---------------------------------------------------------------------------
  46. HRESULT IpxStaticRoutePropertySheet::Init(
  47. BaseIPXResultNodeData *pNodeData,
  48. IInterfaceInfo * spInterfaceInfo)
  49. {
  50. HRESULT hr = hrOK;
  51. BaseIPXResultNodeData * pData;
  52. m_pNodeData = pNodeData;
  53. m_spInterfaceInfo = spInterfaceInfo;
  54. pData = GET_BASEIPXRESULT_NODEDATA(m_spNode);
  55. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  56. // The pages are embedded members of the class
  57. // do not delete them.
  58. m_bAutoDeletePages = FALSE;
  59. m_pageGeneral.Init(pNodeData, this);
  60. AddPageToList((CPropertyPageBase*) &m_pageGeneral);
  61. return S_OK;
  62. }
  63. // ---------------------------------------------------------------------------
  64. // IpxStaticRoutePropertySheet::SaveSheetData
  65. // Not sure what this does - this is never called. Kenn had this so I'll just
  66. // copy this too.
  67. // Author: Deonb
  68. // ---------------------------------------------------------------------------
  69. BOOL IpxStaticRoutePropertySheet::SaveSheetData()
  70. {
  71. SPITFSNodeHandler spHandler;
  72. SPITFSNode spParent;
  73. // By this time each page should have written its information out
  74. // to the infobase
  75. // Force the node to do a resync
  76. m_spNode->GetParent(&spParent);
  77. spParent->GetHandler(&spHandler);
  78. spHandler->OnCommand(spParent, IDS_MENU_SYNC, CCT_RESULT,
  79. NULL, 0);
  80. return TRUE;
  81. }
  82. // --------------------------------------------------------------------------
  83. // IpxStaticRoutePropertySheet::CancelSheetData
  84. // -
  85. // Author: Deonb
  86. // ---------------------------------------------------------------------------
  87. void IpxStaticRoutePropertySheet::CancelSheetData()
  88. {
  89. }
  90. // ***************************************************************************
  91. // ---------------------------------------------------------------------------
  92. // IpxStaticRoutePropertyPage
  93. // ---------------------------------------------------------------------------
  94. IpxStaticRoutePropertyPage::~IpxStaticRoutePropertyPage()
  95. {
  96. }
  97. BEGIN_MESSAGE_MAP(IpxStaticRoutePropertyPage, RtrPropertyPage)
  98. //{{AFX_MSG_MAP(IpxStaticRoutePropertyPage)
  99. //}}AFX_MSG_MAP
  100. END_MESSAGE_MAP()
  101. void IpxStaticRoutePropertyPage::OnChangeButton()
  102. {
  103. SetDirty(TRUE);
  104. SetModified();
  105. }
  106. //--------------------------------------------------------------------------
  107. // IpxStaticRoutePropertyPage::Init
  108. // -
  109. // Author: Deonb
  110. //---------------------------------------------------------------------------
  111. HRESULT IpxStaticRoutePropertyPage::Init(BaseIPXResultNodeData *pNodeData,
  112. IpxStaticRoutePropertySheet * pIPXPropSheet)
  113. {
  114. ATLASSERT(pSREntry);
  115. ATLASSERT(pIPXPropSheet);
  116. m_pIPXPropSheet = pIPXPropSheet;
  117. m_SREntry.LoadFrom(pNodeData);
  118. m_InitSREntry = m_SREntry;
  119. return hrOK;
  120. }
  121. // --------------------------------------------------------------------------
  122. // IpxStaticRoutePropertyPage::OnInitDialog
  123. // -
  124. // Author: Deonb
  125. // ---------------------------------------------------------------------------
  126. BOOL IpxStaticRoutePropertyPage::OnInitDialog()
  127. {
  128. HRESULT hr = hrOK;
  129. PBYTE pData;
  130. DWORD dwIfType;
  131. UINT iButton;
  132. RtrPropertyPage::OnInitDialog();
  133. m_spinHopCount.SetRange(0, 15);
  134. m_spinHopCount.SetBuddy(GetDlgItem(IDC_SRD_EDIT_HOP_COUNT));
  135. m_spinTickCount.SetRange(0, UD_MAXVAL);
  136. m_spinTickCount.SetBuddy(GetDlgItem(IDC_SRD_EDIT_TICK_COUNT));
  137. ((CEdit *) GetDlgItem(IDC_SRD_EDIT_NETWORK_NUMBER))->LimitText(8);
  138. ((CEdit *) GetDlgItem(IDC_SRD_EDIT_NEXT_HOP))->LimitText(12);
  139. GetDlgItem(IDC_SRD_EDIT_NETWORK_NUMBER)->EnableWindow(FALSE);
  140. GetDlgItem(IDC_SRD_EDIT_NEXT_HOP)->EnableWindow(FALSE);
  141. // A route to be edited was given, so initialize the controls
  142. TCHAR szNumber[32];
  143. FormatIpxNetworkNumber(szNumber,
  144. DimensionOf(szNumber),
  145. m_SREntry.m_route.Network,
  146. sizeof(m_SREntry.m_route.Network));
  147. SetDlgItemText(IDC_SRD_EDIT_NETWORK_NUMBER, szNumber);
  148. FormatMACAddress(szNumber,
  149. DimensionOf(szNumber),
  150. m_SREntry.m_route.NextHopMacAddress,
  151. sizeof(m_SREntry.m_route.NextHopMacAddress));
  152. SetDlgItemText(IDC_SRD_EDIT_NEXT_HOP, szNumber);
  153. m_spinHopCount.SetPos(m_SREntry.m_route.HopCount);
  154. m_spinTickCount.SetPos(m_SREntry.m_route.TickCount);
  155. // Disable the network number, next hop, and interface
  156. GetDlgItem(IDC_SRD_EDIT_NETWORK_NUMBER)->EnableWindow(FALSE);
  157. GetDlgItem(IDC_SRD_EDIT_NEXT_HOP)->EnableWindow(FALSE);
  158. SetDirty(FALSE);
  159. if (!FHrSucceeded(hr))
  160. Cancel();
  161. return FHrSucceeded(hr) ? TRUE : FALSE;
  162. }
  163. // --------------------------------------------------------------------------
  164. // IpxStaticRoutePropertyPage::DoDataExchange
  165. // -
  166. // Author: Deonb
  167. // ---------------------------------------------------------------------------
  168. void IpxStaticRoutePropertyPage::DoDataExchange(CDataExchange *pDX)
  169. {
  170. RtrPropertyPage::DoDataExchange(pDX);
  171. //{{AFX_DATA_MAP(IpxStaticRoutePropertyPage)
  172. DDX_Control(pDX, IDC_SRD_SPIN_TICK_COUNT, m_spinTickCount);
  173. DDX_Control(pDX, IDC_SRD_SPIN_HOP_COUNT, m_spinHopCount);
  174. //}}AFX_DATA_MAP
  175. }
  176. // --------------------------------------------------------------------------
  177. // IpxStaticRoutePropertyPage::OnApply
  178. // -
  179. // Author: Deonb
  180. // ---------------------------------------------------------------------------
  181. BOOL IpxStaticRoutePropertyPage::OnApply()
  182. {
  183. BOOL fReturn;
  184. HRESULT hr = hrOK;
  185. if ( m_pIPXPropSheet->IsCancel() )
  186. {
  187. CancelApply();
  188. return TRUE;
  189. }
  190. CString st;
  191. GetDlgItemText(IDC_SRD_EDIT_NETWORK_NUMBER, st);
  192. ConvertNetworkNumberToBytes(st,
  193. m_SREntry.m_route.Network,
  194. sizeof(m_SREntry.m_route.Network));
  195. GetDlgItemText(IDC_SRD_EDIT_NEXT_HOP, st);
  196. ConvertMACAddressToBytes(st,
  197. m_SREntry.m_route.NextHopMacAddress,
  198. sizeof(m_SREntry.m_route.NextHopMacAddress));
  199. m_SREntry.m_route.TickCount = (USHORT) m_spinTickCount.GetPos();
  200. m_SREntry.m_route.HopCount = (USHORT) m_spinHopCount.GetPos();
  201. ModifyRouteInfo(m_pIPXPropSheet->m_spNode, &m_SREntry, &m_InitSREntry);
  202. // Update the data in the UI
  203. m_SREntry.SaveTo(m_pIPXPropSheet->m_pNodeData);
  204. m_pIPXPropSheet->m_spInterfaceInfo = m_SREntry.m_spIf;
  205. // Force a refresh
  206. m_pIPXPropSheet->m_spNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  207. fReturn = RtrPropertyPage::OnApply();
  208. return fReturn;
  209. }
  210. //--------------------------------------------------------------------------
  211. // IpxRouteHandler::ModifyRouteInfo
  212. // -
  213. // Author: KennT
  214. //--------------------------------------------------------------------------
  215. HRESULT IpxStaticRoutePropertyPage::ModifyRouteInfo(ITFSNode *pNode,
  216. SafeIPXSRListEntry *pSREntryNew,
  217. SafeIPXSRListEntry *pSREntryOld)
  218. {
  219. Assert(pSREntryNew);
  220. Assert(pSREntryOld);
  221. INT i;
  222. HRESULT hr = hrOK;
  223. InfoBlock* pBlock;
  224. SPIInfoBase spInfoBase;
  225. SPIRtrMgrInterfaceInfo spRmIf;
  226. SPITFSNode spNodeParent;
  227. IPXConnection * pIPXConn;
  228. IPX_STATIC_ROUTE_INFO *psr, *psrOld;
  229. IPX_STATIC_ROUTE_INFO IpxRow;
  230. CWaitCursor wait;
  231. pNode->GetParent(&spNodeParent);
  232. pIPXConn = GET_IPX_SR_NODEDATA(spNodeParent);
  233. Assert(pIPXConn);
  234. // Remove the old route if it is on another interface
  235. if (lstrcmpi(pSREntryOld->m_spIf->GetId(), pSREntryNew->m_spIf->GetId()) != 0)
  236. {
  237. // the outgoing interface for a route is to be changed.
  238. CORg( pSREntryOld->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  239. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  240. NULL,
  241. NULL,
  242. &spInfoBase));
  243. // Remove the old interface
  244. CORg( RemoveStaticRoute(pSREntryOld, spInfoBase) );
  245. // Update the interface information
  246. CORg( spRmIf->Save(pSREntryOld->m_spIf->GetMachineName(),
  247. pIPXConn->GetConfigHandle(),
  248. NULL,
  249. NULL,
  250. spInfoBase,
  251. 0));
  252. }
  253. spRmIf.Release();
  254. spInfoBase.Release();
  255. // Either
  256. // (a) a route is being modified (on the same interface)
  257. // (b) a route is being moved from one interface to another.
  258. // Retrieve the configuration for the interface to which the route
  259. // is now attached;
  260. CORg( pSREntryNew->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  261. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  262. NULL,
  263. NULL,
  264. &spInfoBase));
  265. // Get the IPX_STATIC_ROUTE_INFO block from the interface
  266. hr = spInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0);
  267. if (!FHrOK(hr))
  268. {
  269. //
  270. // No IPX_STATIC_ROUTE_INFO block was found; we create a new block
  271. // with the new route, and add that block to the interface-info
  272. //
  273. CORg( AddStaticRoute(pSREntryNew, spInfoBase, NULL) );
  274. }
  275. else
  276. {
  277. //
  278. // An IPX_STATIC_ROUTE_INFO block was found.
  279. //
  280. // We are modifying an existing route.
  281. // If the route's interface was not changed when it was modified,
  282. // look for the existing route in the IPX_STATIC_ROUTE_INFO, and then
  283. // update its parameters.
  284. // Otherwise, write a completely new route in the IPX_STATIC_ROUTE_INFO;
  285. //
  286. if (lstrcmpi(pSREntryOld->m_spIf->GetId(), pSREntryNew->m_spIf->GetId()) == 0)
  287. {
  288. //
  289. // The route's interface was not changed when it was modified;
  290. // We now look for it amongst the existing routes
  291. // for this interface.
  292. // The route's original parameters are in 'preOld',
  293. // so those are the parameters with which we search
  294. // for a route to modify
  295. //
  296. psr = (IPX_STATIC_ROUTE_INFO*)pBlock->pData;
  297. for (i = 0; i < (INT)pBlock->dwCount; i++, psr++)
  298. {
  299. // Compare this route to the re-configured one
  300. if (!FAreTwoRoutesEqual(&(pSREntryOld->m_route), psr))
  301. continue;
  302. // This is the route which was modified;
  303. // We can now modify the parameters for the route in-place.
  304. *psr = pSREntryNew->m_route;
  305. break;
  306. }
  307. }
  308. else
  309. {
  310. CORg( AddStaticRoute(pSREntryNew, spInfoBase, pBlock) );
  311. }
  312. }
  313. // Save the updated information
  314. CORg( spRmIf->Save(pSREntryNew->m_spIf->GetMachineName(),
  315. pIPXConn->GetConfigHandle(),
  316. NULL,
  317. NULL,
  318. spInfoBase,
  319. 0));
  320. Error:
  321. return hr;
  322. }
  323. HRESULT IpxStaticRoutePropertyPage::RemoveStaticRoute(SafeIPXSRListEntry *pSREntry, IInfoBase *pInfoBase)
  324. {
  325. HRESULT hr = hrOK;
  326. InfoBlock * pBlock;
  327. PIPX_STATIC_ROUTE_INFO pRow;
  328. INT i;
  329. // Get the IPX_STATIC_ROUTE_INFO block from the interface
  330. CORg( pInfoBase->GetBlock(IPX_STATIC_ROUTE_INFO_TYPE, &pBlock, 0) );
  331. // Look for the removed route in the IPX_STATIC_ROUTE_INFO
  332. pRow = (IPX_STATIC_ROUTE_INFO*) pBlock->pData;
  333. for (i = 0; i < (INT)pBlock->dwCount; i++, pRow++)
  334. {
  335. // Compare this route to the removed one
  336. if (FAreTwoRoutesEqual(pRow, &(pSREntry->m_route)))
  337. {
  338. // This is the removed route, so modify this block
  339. // to exclude the route:
  340. // Decrement the number of routes
  341. --pBlock->dwCount;
  342. if (pBlock->dwCount && (i < (INT)pBlock->dwCount))
  343. {
  344. // Overwrite this route with the ones which follow it
  345. ::memmove(pRow,
  346. pRow + 1,
  347. (pBlock->dwCount - i) * sizeof(*pRow));
  348. }
  349. break;
  350. }
  351. }
  352. Error:
  353. return hr;
  354. }
  355. // ***************************************************************************
  356. //--------------------------------------------------------------------------
  357. // SafeIPXSRListEntry::LoadFrom
  358. // -
  359. // Author: DeonB
  360. //--------------------------------------------------------------------------
  361. void SafeIPXSRListEntry::LoadFrom(BaseIPXResultNodeData *pNodeData)
  362. {
  363. m_spIf = pNodeData->m_spIf;
  364. ConvertNetworkNumberToBytes(pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_stData,
  365. m_route.Network,
  366. DimensionOf(m_route.Network));
  367. // This is not the correct byte order to do comparisons, but it
  368. // can be used for equality
  369. memcpy(&pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_dwData,
  370. m_route.Network,
  371. sizeof(DWORD));
  372. m_route.TickCount = (USHORT) pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_dwData;
  373. m_route.HopCount = (USHORT) pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_dwData;
  374. // Need to convert the MAC address into a byte array
  375. ConvertMACAddressToBytes(pNodeData->m_rgData[IPX_SR_SI_NEXT_HOP].m_stData,
  376. m_route.NextHopMacAddress,
  377. DimensionOf(m_route.NextHopMacAddress));
  378. }
  379. //--------------------------------------------------------------------------
  380. // SafeIPXSRListEntry::SaveTo
  381. // -
  382. // Author: DeonB
  383. //---------------------------------------------------------------------------
  384. void SafeIPXSRListEntry::SaveTo(BaseIPXResultNodeData *pNodeData)
  385. {
  386. TCHAR szNumber[32];
  387. pNodeData->m_spIf.Set(m_spIf);
  388. pNodeData->m_rgData[IPX_SR_SI_NAME].m_stData = m_spIf->GetTitle();
  389. FormatIpxNetworkNumber(szNumber,
  390. DimensionOf(szNumber),
  391. m_route.Network,
  392. DimensionOf(m_route.Network));
  393. pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_stData = szNumber;
  394. memcpy(&(pNodeData->m_rgData[IPX_SR_SI_NETWORK].m_dwData),
  395. m_route.Network,
  396. sizeof(DWORD));
  397. FormatMACAddress(szNumber,
  398. DimensionOf(szNumber),
  399. m_route.NextHopMacAddress,
  400. DimensionOf(m_route.NextHopMacAddress));
  401. pNodeData->m_rgData[IPX_SR_SI_NEXT_HOP].m_stData = szNumber;
  402. FormatNumber(m_route.TickCount,
  403. szNumber,
  404. DimensionOf(szNumber),
  405. FALSE);
  406. pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_stData = szNumber;
  407. pNodeData->m_rgData[IPX_SR_SI_TICK_COUNT].m_dwData = m_route.TickCount;
  408. FormatNumber(m_route.HopCount,
  409. szNumber,
  410. DimensionOf(szNumber),
  411. FALSE);
  412. pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_stData = szNumber;
  413. pNodeData->m_rgData[IPX_SR_SI_HOP_COUNT].m_dwData = m_route.HopCount;
  414. }
  415. ///--------------------------------------------------------------------------
  416. // AddStaticRoute
  417. // This function ASSUMES that the route is NOT in the block.
  418. // Author: KennT
  419. //---------------------------------------------------------------------------
  420. HRESULT AddStaticRoute(SafeIPXSRListEntry *pSREntryNew,
  421. IInfoBase *pInfoBase,
  422. InfoBlock *pBlock)
  423. {
  424. IPX_STATIC_ROUTE_INFO srRow;
  425. HRESULT hr = hrOK;
  426. if (pBlock == NULL)
  427. {
  428. //
  429. // No IPX_STATIC_ROUTE_INFO block was found; we create a new block
  430. // with the new route, and add that block to the interface-info
  431. //
  432. CORg( pInfoBase->AddBlock(IPX_STATIC_ROUTE_INFO_TYPE,
  433. sizeof(IPX_STATIC_ROUTE_INFO),
  434. (LPBYTE) &(pSREntryNew->m_route), 1, 0) );
  435. }
  436. else
  437. {
  438. // Either the route is completely new, or it is a route
  439. // which was moved from one interface to another.
  440. // Set a new block as the IPX_STATIC_ROUTE_INFO,
  441. // and include the re-configured route in the new block.
  442. PIPX_STATIC_ROUTE_INFO psrTable;
  443. psrTable = new IPX_STATIC_ROUTE_INFO[pBlock->dwCount + 1];
  444. Assert(psrTable);
  445. // Copy the original table of routes
  446. ::memcpy(psrTable, pBlock->pData,
  447. pBlock->dwCount * sizeof(IPX_STATIC_ROUTE_INFO));
  448. // Append the new route
  449. psrTable[pBlock->dwCount] = pSREntryNew->m_route;
  450. // Replace the old route-table with the new one
  451. CORg( pInfoBase->SetData(IPX_STATIC_ROUTE_INFO_TYPE,
  452. sizeof(IPX_STATIC_ROUTE_INFO),
  453. (LPBYTE) psrTable, pBlock->dwCount + 1, 0) );
  454. }
  455. Error:
  456. return hr;
  457. }