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.

1819 lines
49 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. summary.cpp
  7. IPX Static NetBIOS Name implementation.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "util.h"
  12. #include "snview.h"
  13. #include "reg.h"
  14. #include "ipxadmin.h"
  15. #include "rtrutil.h" // smart MPR handle pointers
  16. #include "ipxstrm.h" // IPXAdminConfigStream
  17. #include "strmap.h" // XXXtoCString functions
  18. #include "service.h" // TFS service APIs
  19. #include "format.h" // FormatNumber function
  20. #include "coldlg.h" // columndlg
  21. #include "ipxutil.h"
  22. #include "column.h" // ComponentConfigStream
  23. #include "rtrui.h"
  24. #include "routprot.h" // IP_LOCAL
  25. #include "rtrres.h"
  26. #include "dumbprop.h"
  27. HRESULT SetNameData(BaseIPXResultNodeData *pData,
  28. IpxSNListEntry *pName);
  29. HRESULT AddStaticNetBIOSName(IpxSNListEntry *pSNEntry,
  30. IInfoBase *InfoBase,
  31. InfoBlock *pBlock);
  32. BOOL FAreTwoNamesEqual(IPX_STATIC_NETBIOS_NAME_INFO *pName1,
  33. IPX_STATIC_NETBIOS_NAME_INFO *pName2);
  34. /*---------------------------------------------------------------------------
  35. Keep this in sync with the column ids in snview.h
  36. ---------------------------------------------------------------------------*/
  37. extern const ContainerColumnInfo s_rgSNViewColumnInfo[];
  38. const ContainerColumnInfo s_rgSNViewColumnInfo[] =
  39. {
  40. { IDS_IPX_SN_COL_NAME, CON_SORT_BY_STRING, TRUE, COL_STRING },
  41. { IDS_IPX_SN_COL_NETBIOS_NAME, CON_SORT_BY_STRING, TRUE, COL_NETBIOS_NAME },
  42. { IDS_IPX_SN_COL_NETBIOS_TYPE, CON_SORT_BY_STRING, TRUE, COL_STRING },
  43. };
  44. /*---------------------------------------------------------------------------
  45. IpxSNHandler implementation
  46. ---------------------------------------------------------------------------*/
  47. DEBUG_DECLARE_INSTANCE_COUNTER(IpxSNHandler)
  48. IpxSNHandler::IpxSNHandler(ITFSComponentData *pCompData)
  49. : BaseContainerHandler(pCompData, COLUMNS_STATICNETBIOSNAMES,
  50. s_rgSNViewColumnInfo),
  51. m_ulConnId(0),
  52. m_ulRefreshConnId(0)
  53. {
  54. // Setup the verb states
  55. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  56. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  57. DEBUG_INCREMENT_INSTANCE_COUNTER(IpxSNHandler)
  58. }
  59. IpxSNHandler::~IpxSNHandler()
  60. {
  61. DEBUG_DECREMENT_INSTANCE_COUNTER(IpxSNHandler)
  62. }
  63. STDMETHODIMP IpxSNHandler::QueryInterface(REFIID riid, LPVOID *ppv)
  64. {
  65. // Is the pointer bad?
  66. if (ppv == NULL)
  67. return E_INVALIDARG;
  68. // Place NULL in *ppv in case of failure
  69. *ppv = NULL;
  70. // This is the non-delegating IUnknown implementation
  71. if (riid == IID_IUnknown)
  72. *ppv = (LPVOID) this;
  73. else if (riid == IID_IRtrAdviseSink)
  74. *ppv = &m_IRtrAdviseSink;
  75. else
  76. return BaseContainerHandler::QueryInterface(riid, ppv);
  77. // If we're going to return an interface, AddRef it first
  78. if (*ppv)
  79. {
  80. ((LPUNKNOWN) *ppv)->AddRef();
  81. return hrOK;
  82. }
  83. else
  84. return E_NOINTERFACE;
  85. }
  86. /*!--------------------------------------------------------------------------
  87. IpxSNHandler::DestroyHandler
  88. Implementation of ITFSNodeHandler::DestroyHandler
  89. Author: KennT
  90. ---------------------------------------------------------------------------*/
  91. STDMETHODIMP IpxSNHandler::DestroyHandler(ITFSNode *pNode)
  92. {
  93. IPXConnection * pIPXConn;
  94. pIPXConn = GET_IPX_SN_NODEDATA(pNode);
  95. pIPXConn->Release();
  96. if (m_ulRefreshConnId)
  97. {
  98. SPIRouterRefresh spRefresh;
  99. if (m_spRouterInfo)
  100. m_spRouterInfo->GetRefreshObject(&spRefresh);
  101. if (spRefresh)
  102. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  103. }
  104. m_ulRefreshConnId = 0;
  105. if (m_ulConnId)
  106. m_spRtrMgrInfo->RtrUnadvise(m_ulConnId);
  107. m_ulConnId = 0;
  108. m_spRtrMgrInfo.Release();
  109. m_spRouterInfo.Release();
  110. return hrOK;
  111. }
  112. /*!--------------------------------------------------------------------------
  113. IpxSNHandler::HasPropertyPages
  114. Implementation of ITFSNodeHandler::HasPropertyPages
  115. NOTE: the root node handler has to over-ride this function to
  116. handle the snapin manager property page (wizard) case!!!
  117. Author: KennT
  118. ---------------------------------------------------------------------------*/
  119. STDMETHODIMP
  120. IpxSNHandler::HasPropertyPages
  121. (
  122. ITFSNode * pNode,
  123. LPDATAOBJECT pDataObject,
  124. DATA_OBJECT_TYPES type,
  125. DWORD dwType
  126. )
  127. {
  128. return hrFalse;
  129. }
  130. /*---------------------------------------------------------------------------
  131. Menu data structure for our menus
  132. ---------------------------------------------------------------------------*/
  133. static const SRouterNodeMenu s_rgIfNodeMenu[] =
  134. {
  135. { IDS_MENU_IPX_SN_NEW_NETBIOSNAME, 0,
  136. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  137. };
  138. /*!--------------------------------------------------------------------------
  139. IpxSNHandler::OnAddMenuItems
  140. Implementation of ITFSNodeHandler::OnAddMenuItems
  141. Author: KennT
  142. ---------------------------------------------------------------------------*/
  143. STDMETHODIMP IpxSNHandler::OnAddMenuItems(
  144. ITFSNode *pNode,
  145. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  146. LPDATAOBJECT lpDataObject,
  147. DATA_OBJECT_TYPES type,
  148. DWORD dwType,
  149. long *pInsertionAllowed)
  150. {
  151. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  152. HRESULT hr = S_OK;
  153. IpxSNHandler::SMenuData menuData;
  154. COM_PROTECT_TRY
  155. {
  156. menuData.m_spNode.Set(pNode);
  157. hr = AddArrayOfMenuItems(pNode, s_rgIfNodeMenu,
  158. DimensionOf(s_rgIfNodeMenu),
  159. pContextMenuCallback,
  160. *pInsertionAllowed,
  161. reinterpret_cast<INT_PTR>(&menuData));
  162. }
  163. COM_PROTECT_CATCH;
  164. return hr;
  165. }
  166. HRESULT IpxSNHandler::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  167. {
  168. HRESULT hr = hrOK;
  169. SPITFSNode spNode, spParent;
  170. SPITFSResultHandler spParentRH;
  171. m_spNodeMgr->FindNode(cookie, &spNode);
  172. // forward this command to the parent to handle
  173. CORg (spNode->GetParent(&spParent));
  174. CORg (spParent->GetResultHandler(&spParentRH));
  175. CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
  176. Error:
  177. return hrOK;
  178. }
  179. /*!--------------------------------------------------------------------------
  180. IpxSNHandler::OnCommand
  181. Implementation of ITFSNodeHandler::OnCommand
  182. Author: KennT
  183. ---------------------------------------------------------------------------*/
  184. STDMETHODIMP IpxSNHandler::OnCommand(ITFSNode *pNode, long nCommandId,
  185. DATA_OBJECT_TYPES type,
  186. LPDATAOBJECT pDataObject,
  187. DWORD dwType)
  188. {
  189. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  190. HRESULT hr = S_OK;
  191. COM_PROTECT_TRY
  192. {
  193. switch (nCommandId)
  194. {
  195. case IDS_MENU_IPX_SN_NEW_NETBIOSNAME:
  196. hr = OnNewName(pNode);
  197. if (!FHrSucceeded(hr))
  198. DisplayErrorMessage(NULL, hr);
  199. break;
  200. case IDS_MENU_SYNC:
  201. SynchronizeNodeData(pNode);
  202. break;
  203. }
  204. }
  205. COM_PROTECT_CATCH;
  206. return hr;
  207. }
  208. /*!--------------------------------------------------------------------------
  209. IpxSNHandler::GenerateListOfNames
  210. -
  211. Author: KennT
  212. ---------------------------------------------------------------------------*/
  213. HRESULT IpxSNHandler::GenerateListOfNames(ITFSNode *pNode, IpxSNList *pSNList)
  214. {
  215. Assert(pSNList);
  216. HRESULT hr = hrOK;
  217. SPIEnumInterfaceInfo spEnumIf;
  218. SPIInterfaceInfo spIf;
  219. SPIRtrMgrInterfaceInfo spRmIf;
  220. SPIInfoBase spInfoBase;
  221. PIPX_STATIC_NETBIOS_NAME_INFO pName;
  222. InfoBlock * pBlock;
  223. int i;
  224. IpxSNListEntry * pSNEntry;
  225. COM_PROTECT_TRY
  226. {
  227. // Ok go through and find all of the static Names
  228. CORg( m_spRouterInfo->EnumInterface(&spEnumIf) );
  229. for (; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  230. {
  231. // Get the next interface
  232. spRmIf.Release();
  233. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
  234. continue;
  235. // Load IP information for this interface
  236. spInfoBase.Release();
  237. if (spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) != hrOK)
  238. continue;
  239. // Retrieve the data for the IPX_STATIC_NETBIOS_NAME_INFO block
  240. if (spInfoBase->GetBlock(IPX_STATIC_NETBIOS_NAME_INFO_TYPE, &pBlock, 0) != hrOK)
  241. continue;
  242. pName = (PIPX_STATIC_NETBIOS_NAME_INFO) pBlock->pData;
  243. // Update our list of Names with the Names read from this
  244. // interface
  245. for (i=0; i<(int) pBlock->dwCount; i++, pName++)
  246. {
  247. pSNEntry = new IpxSNListEntry;
  248. pSNEntry->m_spIf.Set(spIf);
  249. pSNEntry->m_name = *pName;
  250. pSNList->AddTail(pSNEntry);
  251. }
  252. }
  253. }
  254. COM_PROTECT_CATCH;
  255. if (!FHrSucceeded(hr))
  256. {
  257. // Should make sure that we get the SRList cleaned up
  258. while (!pSNList->IsEmpty())
  259. delete pSNList->RemoveHead();
  260. }
  261. Error:
  262. return hr;
  263. }
  264. /*!--------------------------------------------------------------------------
  265. IpxSNHandler::OnExpand
  266. -
  267. Author: KennT
  268. ---------------------------------------------------------------------------*/
  269. HRESULT IpxSNHandler::OnExpand(ITFSNode *pNode,LPDATAOBJECT pDataObject,
  270. DWORD dwType,
  271. LPARAM arg,
  272. LPARAM lParam)
  273. {
  274. HRESULT hr = hrOK;
  275. IpxSNList SRList;
  276. IpxSNListEntry * pSNEntry;
  277. if (m_bExpanded)
  278. return hrOK;
  279. COM_PROTECT_TRY
  280. {
  281. // Ok go through and find all of the static Names
  282. CORg( GenerateListOfNames(pNode, &SRList) );
  283. // Now iterate through the list of static Names adding them
  284. // all in. Ideally we could merge this into the Refresh code,
  285. // but the refresh code can't assume a blank slate.
  286. while (!SRList.IsEmpty())
  287. {
  288. pSNEntry = SRList.RemoveHead();
  289. AddStaticNetBIOSNameNode(pNode, pSNEntry);
  290. delete pSNEntry;
  291. }
  292. COM_PROTECT_ERROR_LABEL;
  293. }
  294. COM_PROTECT_CATCH;
  295. // Should make sure that we get the SRList cleaned up
  296. while (!SRList.IsEmpty())
  297. delete SRList.RemoveHead();
  298. m_bExpanded = TRUE;
  299. return hr;
  300. }
  301. /*!--------------------------------------------------------------------------
  302. IpxSNHandler::GetString
  303. Implementation of ITFSNodeHandler::GetString
  304. We don't need to do anything, since our root node is an extension
  305. only and thus can't do anything to the node text.
  306. Author: KennT
  307. ---------------------------------------------------------------------------*/
  308. STDMETHODIMP_(LPCTSTR) IpxSNHandler::GetString(ITFSNode *pNode, int nCol)
  309. {
  310. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  311. HRESULT hr = hrOK;
  312. COM_PROTECT_TRY
  313. {
  314. if (m_stTitle.IsEmpty())
  315. m_stTitle.LoadString(IDS_IPX_SN_TITLE);
  316. }
  317. COM_PROTECT_CATCH;
  318. return m_stTitle;
  319. }
  320. /*!--------------------------------------------------------------------------
  321. IpxSNHandler::OnCreateDataObject
  322. -
  323. Author: KennT
  324. ---------------------------------------------------------------------------*/
  325. STDMETHODIMP IpxSNHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  326. {
  327. HRESULT hr = hrOK;
  328. COM_PROTECT_TRY
  329. {
  330. Assert(m_spRtrMgrInfo);
  331. CORg( CreateDataObjectFromRtrMgrInfo(m_spRtrMgrInfo,
  332. type, cookie, m_spTFSCompData,
  333. ppDataObject) );
  334. COM_PROTECT_ERROR_LABEL;
  335. }
  336. COM_PROTECT_CATCH;
  337. return hr;
  338. }
  339. /*!--------------------------------------------------------------------------
  340. IpxSNHandler::Init
  341. -
  342. Author: KennT
  343. ---------------------------------------------------------------------------*/
  344. HRESULT IpxSNHandler::Init(IRtrMgrInfo *pRmInfo, IPXAdminConfigStream *pConfigStream)
  345. {
  346. m_spRtrMgrInfo.Set(pRmInfo);
  347. if (pRmInfo)
  348. pRmInfo->GetParentRouterInfo(&m_spRouterInfo);
  349. m_pConfigStream = pConfigStream;
  350. // Also need to register for change notifications
  351. Assert(m_ulConnId == 0);
  352. m_spRtrMgrInfo->RtrAdvise(&m_IRtrAdviseSink, &m_ulConnId, 0);
  353. return hrOK;
  354. }
  355. /*!--------------------------------------------------------------------------
  356. IpxSNHandler::ConstructNode
  357. Initializes the root node (sets it up).
  358. Author: KennT
  359. ---------------------------------------------------------------------------*/
  360. HRESULT IpxSNHandler::ConstructNode(ITFSNode *pNode, LPCTSTR pszName,
  361. IPXConnection *pIPXConn)
  362. {
  363. Assert(pIPXConn);
  364. HRESULT hr = hrOK;
  365. if (pNode == NULL)
  366. return hrOK;
  367. COM_PROTECT_TRY
  368. {
  369. // Need to initialize the data for the root node
  370. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  371. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  372. pNode->SetData(TFS_DATA_SCOPEID, 0);
  373. // This is a leaf node in the scope pane
  374. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  375. m_cookie = reinterpret_cast<DWORD_PTR>(pNode);
  376. pNode->SetData(TFS_DATA_COOKIE, m_cookie);
  377. pNode->SetNodeType(&GUID_IPXStaticNetBIOSNamesNodeType);
  378. // Setup the node data
  379. pIPXConn->AddRef();
  380. SET_IPX_SN_NODEDATA(pNode, pIPXConn);
  381. }
  382. COM_PROTECT_CATCH;
  383. if (!FHrSucceeded(hr))
  384. {
  385. SET_IPX_SN_NODEDATA(pNode, NULL);
  386. }
  387. return hr;
  388. }
  389. /*!--------------------------------------------------------------------------
  390. IpxSNHandler::AddStaticNetBIOSNameNode
  391. -
  392. Author: KennT
  393. ---------------------------------------------------------------------------*/
  394. HRESULT IpxSNHandler::AddStaticNetBIOSNameNode(ITFSNode *pParent, IpxSNListEntry *pName)
  395. {
  396. IpxStaticNetBIOSNameHandler * pHandler;
  397. SPITFSResultHandler spHandler;
  398. SPITFSNode spNode;
  399. HRESULT hr = hrOK;
  400. BaseIPXResultNodeData * pData;
  401. IPXConnection * pIPXConn;
  402. // Create the handler for this node
  403. pHandler = new IpxStaticNetBIOSNameHandler(m_spTFSCompData);
  404. spHandler = pHandler;
  405. CORg( pHandler->Init(pName->m_spIf, pParent) );
  406. pIPXConn = GET_IPX_SN_NODEDATA(pParent);
  407. // Create a result item node (or a leaf node)
  408. CORg( CreateLeafTFSNode(&spNode,
  409. NULL,
  410. static_cast<ITFSNodeHandler *>(pHandler),
  411. static_cast<ITFSResultHandler *>(pHandler),
  412. m_spNodeMgr) );
  413. CORg( pHandler->ConstructNode(spNode, pName->m_spIf, pIPXConn) );
  414. pData = GET_BASEIPXRESULT_NODEDATA(spNode);
  415. Assert(pData);
  416. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  417. // Set the data for this node
  418. SetNameData(pData, pName);
  419. // Make the node immediately visible
  420. CORg( spNode->SetVisibilityState(TFS_VIS_SHOW) );
  421. CORg( pParent->AddChild(spNode) );
  422. Error:
  423. return hr;
  424. }
  425. /*!--------------------------------------------------------------------------
  426. IpxSNHandler::SynchronizeNodeData
  427. -
  428. Author: KennT
  429. ---------------------------------------------------------------------------*/
  430. HRESULT IpxSNHandler::SynchronizeNodeData(ITFSNode *pNode)
  431. {
  432. HRESULT hr = hrOK;
  433. BaseIPXResultNodeData * pNodeData;
  434. SPITFSNodeEnum spNodeEnum;
  435. SPITFSNode spChildNode;
  436. BOOL fFound;
  437. IpxSNList SRList;
  438. IpxSNList newSRList;
  439. IpxSNListEntry * pSNEntry;
  440. COM_PROTECT_TRY
  441. {
  442. // Mark all of the nodes
  443. CORg( pNode->GetEnum(&spNodeEnum) );
  444. MarkAllNodes(pNode, spNodeEnum);
  445. // Go out and grab the data, merge the new data in with the old data
  446. // This is the data-gathering code and this is what should go
  447. // on the background thread for the refresh code.
  448. CORg( GenerateListOfNames(pNode, &SRList) );
  449. while (!SRList.IsEmpty())
  450. {
  451. pSNEntry = SRList.RemoveHead();
  452. // Look for this entry in our current list of nodes
  453. spNodeEnum->Reset();
  454. spChildNode.Release();
  455. fFound = FALSE;
  456. for (;spNodeEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  457. {
  458. TCHAR szNumber[32];
  459. char szNbName[16];
  460. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  461. Assert(pNodeData);
  462. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  463. ConvertToNetBIOSName(szNbName,
  464. pNodeData->m_rgData[IPX_SN_SI_NETBIOS_NAME].m_stData,
  465. (USHORT) pNodeData->m_rgData[IPX_SN_SI_NETBIOS_TYPE].m_dwData);
  466. if (memcmp(szNbName,
  467. pSNEntry->m_name.Name,
  468. sizeof(pSNEntry->m_name.Name)) == 0)
  469. {
  470. // Ok, this name already exists, update the metric
  471. // and mark it
  472. Assert(pNodeData->m_dwMark == FALSE);
  473. pNodeData->m_dwMark = TRUE;
  474. fFound = TRUE;
  475. // Force MMC to redraw the node
  476. spChildNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  477. break;
  478. }
  479. }
  480. if (fFound)
  481. delete pSNEntry;
  482. else
  483. newSRList.AddTail(pSNEntry);
  484. }
  485. // Now remove all nodes that were not marked
  486. RemoveAllUnmarkedNodes(pNode, spNodeEnum);
  487. // Now iterate through the list of static Names adding them
  488. // all in. Ideally we could merge this into the Refresh code,
  489. // but the refresh code can't assume a blank slate.
  490. POSITION pos;
  491. while (!newSRList.IsEmpty())
  492. {
  493. pSNEntry = newSRList.RemoveHead();
  494. AddStaticNetBIOSNameNode(pNode, pSNEntry);
  495. delete pSNEntry;
  496. }
  497. COM_PROTECT_ERROR_LABEL;
  498. }
  499. COM_PROTECT_CATCH;
  500. while (!SRList.IsEmpty())
  501. delete SRList.RemoveHead();
  502. while (!newSRList.IsEmpty())
  503. delete newSRList.RemoveHead();
  504. return hr;
  505. }
  506. /*!--------------------------------------------------------------------------
  507. IpxSNHandler::MarkAllNodes
  508. -
  509. Author: KennT
  510. ---------------------------------------------------------------------------*/
  511. HRESULT IpxSNHandler::MarkAllNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  512. {
  513. SPITFSNode spChildNode;
  514. BaseIPXResultNodeData * pNodeData;
  515. pEnum->Reset();
  516. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  517. {
  518. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  519. Assert(pNodeData);
  520. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  521. pNodeData->m_dwMark = FALSE;
  522. }
  523. return hrOK;
  524. }
  525. /*!--------------------------------------------------------------------------
  526. IpxSNHandler::RemoveAllUnmarkedNodes
  527. -
  528. Author: KennT
  529. ---------------------------------------------------------------------------*/
  530. HRESULT IpxSNHandler::RemoveAllUnmarkedNodes(ITFSNode *pNode, ITFSNodeEnum *pEnum)
  531. {
  532. HRESULT hr = hrOK;
  533. SPITFSNode spChildNode;
  534. BaseIPXResultNodeData * pNodeData;
  535. pEnum->Reset();
  536. for ( ;pEnum->Next(1, &spChildNode, NULL) == hrOK; spChildNode.Release())
  537. {
  538. pNodeData = GET_BASEIPXRESULT_NODEDATA(spChildNode);
  539. Assert(pNodeData);
  540. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  541. if (pNodeData->m_dwMark == FALSE)
  542. {
  543. pNode->RemoveChild(spChildNode);
  544. spChildNode->Destroy();
  545. }
  546. }
  547. return hr;
  548. }
  549. /*---------------------------------------------------------------------------
  550. This is the set of menus that will appear when a right-click is
  551. done on the blank area of the result pane.
  552. ---------------------------------------------------------------------------*/
  553. static const SRouterNodeMenu s_rgIfResultNodeMenu[] =
  554. {
  555. { IDS_MENU_IPX_SN_NEW_NETBIOSNAME, 0,
  556. CCM_INSERTIONPOINTID_PRIMARY_TOP },
  557. };
  558. /*!--------------------------------------------------------------------------
  559. IpxSNHandler::AddMenuItems
  560. Implementation of ITFSResultHandler::AddMenuItems
  561. Use this to add commands to the context menu of the blank areas
  562. of the result pane.
  563. Author: KennT
  564. ---------------------------------------------------------------------------*/
  565. STDMETHODIMP IpxSNHandler::AddMenuItems(ITFSComponent *pComponent,
  566. MMC_COOKIE cookie,
  567. LPDATAOBJECT pDataObject,
  568. LPCONTEXTMENUCALLBACK pCallback,
  569. long *pInsertionAllowed)
  570. {
  571. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  572. HRESULT hr = hrOK;
  573. SPITFSNode spNode;
  574. IpxSNHandler::SMenuData menuData;
  575. COM_PROTECT_TRY
  576. {
  577. m_spNodeMgr->FindNode(cookie, &spNode);
  578. menuData.m_spNode.Set(spNode);
  579. hr = AddArrayOfMenuItems(spNode,
  580. s_rgIfResultNodeMenu,
  581. DimensionOf(s_rgIfResultNodeMenu),
  582. pCallback,
  583. *pInsertionAllowed,
  584. reinterpret_cast<INT_PTR>(&menuData));
  585. }
  586. COM_PROTECT_CATCH;
  587. return hr;
  588. }
  589. /*!--------------------------------------------------------------------------
  590. IpxSNHandler::Command
  591. -
  592. Author: KennT
  593. ---------------------------------------------------------------------------*/
  594. STDMETHODIMP IpxSNHandler::Command(ITFSComponent *pComponent,
  595. MMC_COOKIE cookie,
  596. int nCommandID,
  597. LPDATAOBJECT pDataObject)
  598. {
  599. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  600. SPITFSNode spNode;
  601. HRESULT hr = hrOK;
  602. switch (nCommandID)
  603. {
  604. case IDS_MENU_IPX_SN_NEW_NETBIOSNAME:
  605. {
  606. m_spNodeMgr->FindNode(cookie, &spNode);
  607. hr = OnNewName(spNode);
  608. if (!FHrSucceeded(hr))
  609. DisplayErrorMessage(NULL, hr);
  610. }
  611. break;
  612. }
  613. return hr;
  614. }
  615. /*!--------------------------------------------------------------------------
  616. IpxSNHandler::CompareItems
  617. -
  618. Author: KennT
  619. ---------------------------------------------------------------------------*/
  620. STDMETHODIMP_(int) IpxSNHandler::CompareItems(
  621. ITFSComponent * pComponent,
  622. MMC_COOKIE cookieA,
  623. MMC_COOKIE cookieB,
  624. int nCol)
  625. {
  626. // Get the strings from the nodes and use that as a basis for
  627. // comparison.
  628. SPITFSNode spNode;
  629. SPITFSResultHandler spResult;
  630. m_spNodeMgr->FindNode(cookieA, &spNode);
  631. spNode->GetResultHandler(&spResult);
  632. return spResult->CompareItems(pComponent, cookieA, cookieB, nCol);
  633. }
  634. /*!--------------------------------------------------------------------------
  635. IpxSNHandler::OnNewName
  636. -
  637. Author: KennT
  638. ---------------------------------------------------------------------------*/
  639. HRESULT IpxSNHandler::OnNewName(ITFSNode *pNode)
  640. {
  641. HRESULT hr = hrOK;
  642. IpxSNListEntry SNEntry;
  643. CStaticNetBIOSNameDlg srdlg(&SNEntry, 0, m_spRouterInfo);
  644. SPIInfoBase spInfoBase;
  645. SPIRtrMgrInterfaceInfo spRmIf;
  646. IPXConnection * pIPXConn;
  647. InfoBlock * pBlock;
  648. pIPXConn = GET_IPX_SN_NODEDATA(pNode);
  649. Assert(pIPXConn);
  650. ::ZeroMemory(&(SNEntry.m_name), sizeof(SNEntry.m_name));
  651. if (srdlg.DoModal() == IDOK)
  652. {
  653. CORg( SNEntry.m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  654. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  655. NULL,
  656. NULL,
  657. &spInfoBase));
  658. // Ok, go ahead and add the name
  659. // Get the IPX_STATIC_NETBIOS_NAME_INFO block from the interface
  660. spInfoBase->GetBlock(IPX_STATIC_NETBIOS_NAME_INFO_TYPE, &pBlock, 0);
  661. CORg( AddStaticNetBIOSName(&SNEntry, spInfoBase, pBlock) );
  662. // Update the interface information
  663. CORg( spRmIf->Save(SNEntry.m_spIf->GetMachineName(),
  664. pIPXConn->GetConfigHandle(),
  665. NULL,
  666. NULL,
  667. spInfoBase,
  668. 0));
  669. // Refresh the node
  670. SynchronizeNodeData(pNode);
  671. }
  672. Error:
  673. return hr;
  674. }
  675. ImplementEmbeddedUnknown(IpxSNHandler, IRtrAdviseSink)
  676. STDMETHODIMP IpxSNHandler::EIRtrAdviseSink::OnChange(LONG_PTR ulConn,
  677. DWORD dwChangeType, DWORD dwObjectType, LPARAM lUserParam, LPARAM lParam)
  678. {
  679. InitPThis(IpxSNHandler, IRtrAdviseSink);
  680. HRESULT hr = hrOK;
  681. COM_PROTECT_TRY
  682. {
  683. if (dwChangeType == ROUTER_REFRESH)
  684. {
  685. SPITFSNode spNode;
  686. Assert(ulConn == pThis->m_ulRefreshConnId);
  687. pThis->m_spNodeMgr->FindNode(pThis->m_cookie, &spNode);
  688. pThis->SynchronizeNodeData(spNode);
  689. }
  690. }
  691. COM_PROTECT_CATCH;
  692. return hr;
  693. }
  694. /*!--------------------------------------------------------------------------
  695. IpxSNHandler::OnResultShow
  696. -
  697. Author: KennT
  698. ---------------------------------------------------------------------------*/
  699. HRESULT IpxSNHandler::OnResultShow(ITFSComponent *pTFSComponent, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  700. {
  701. BOOL bSelect = (BOOL) arg;
  702. HRESULT hr = hrOK;
  703. SPIRouterRefresh spRefresh;
  704. SPITFSNode spNode;
  705. BaseContainerHandler::OnResultShow(pTFSComponent, cookie, arg, lParam);
  706. if (bSelect)
  707. {
  708. // Call synchronize on this node
  709. m_spNodeMgr->FindNode(cookie, &spNode);
  710. if (spNode)
  711. SynchronizeNodeData(spNode);
  712. }
  713. // Un/Register for refresh advises
  714. if (m_spRouterInfo)
  715. m_spRouterInfo->GetRefreshObject(&spRefresh);
  716. if (spRefresh)
  717. {
  718. if (bSelect)
  719. {
  720. if (m_ulRefreshConnId == 0)
  721. spRefresh->AdviseRefresh(&m_IRtrAdviseSink, &m_ulRefreshConnId, 0);
  722. }
  723. else
  724. {
  725. if (m_ulRefreshConnId)
  726. spRefresh->UnadviseRefresh(m_ulRefreshConnId);
  727. m_ulRefreshConnId = 0;
  728. }
  729. }
  730. return hr;
  731. }
  732. /*---------------------------------------------------------------------------
  733. Class: IpxStaticNetBIOSNameHandler
  734. ---------------------------------------------------------------------------*/
  735. IpxStaticNetBIOSNameHandler::IpxStaticNetBIOSNameHandler(ITFSComponentData *pCompData)
  736. : BaseIPXResultHandler(pCompData, COLUMNS_STATICNETBIOSNAMES),
  737. m_ulConnId(0)
  738. {
  739. m_rgButtonState[MMC_VERB_PROPERTIES_INDEX] = ENABLED;
  740. m_bState[MMC_VERB_PROPERTIES_INDEX] = TRUE;
  741. m_rgButtonState[MMC_VERB_DELETE_INDEX] = ENABLED;
  742. m_bState[MMC_VERB_DELETE_INDEX] = TRUE;
  743. m_rgButtonState[MMC_VERB_REFRESH_INDEX] = ENABLED;
  744. m_bState[MMC_VERB_REFRESH_INDEX] = TRUE;
  745. m_verbDefault = MMC_VERB_PROPERTIES;
  746. }
  747. /*!--------------------------------------------------------------------------
  748. IpxStaticNetBIOSNameHandler::ConstructNode
  749. Initializes the Domain node (sets it up).
  750. Author: KennT
  751. ---------------------------------------------------------------------------*/
  752. HRESULT IpxStaticNetBIOSNameHandler::ConstructNode(ITFSNode *pNode, IInterfaceInfo *pIfInfo, IPXConnection *pIPXConn)
  753. {
  754. HRESULT hr = hrOK;
  755. int i;
  756. if (pNode == NULL)
  757. return hrOK;
  758. COM_PROTECT_TRY
  759. {
  760. // Need to initialize the data for the Domain node
  761. pNode->SetData(TFS_DATA_SCOPEID, 0);
  762. // We don't want icons for these nodes.
  763. pNode->SetData(TFS_DATA_IMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  764. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, IMAGE_IDX_IPX_NODE_GENERAL);
  765. pNode->SetData(TFS_DATA_COOKIE, reinterpret_cast<DWORD_PTR>(pNode));
  766. //$ Review: kennt, what are the different type of interfaces
  767. // do we distinguish based on the same list as above? (i.e. the
  768. // one for image indexes).
  769. pNode->SetNodeType(&GUID_IPXStaticNetBIOSNamesResultNodeType);
  770. BaseIPXResultNodeData::Init(pNode, pIfInfo, pIPXConn);
  771. }
  772. COM_PROTECT_CATCH
  773. return hr;
  774. }
  775. /*!--------------------------------------------------------------------------
  776. IpxStaticNetBIOSNameHandler::OnCreateDataObject
  777. -
  778. Author: KennT
  779. ---------------------------------------------------------------------------*/
  780. STDMETHODIMP IpxStaticNetBIOSNameHandler::OnCreateDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  781. {
  782. HRESULT hr = hrOK;
  783. COM_PROTECT_TRY
  784. {
  785. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  786. type, cookie, m_spTFSCompData,
  787. ppDataObject) );
  788. COM_PROTECT_ERROR_LABEL;
  789. }
  790. COM_PROTECT_CATCH;
  791. return hr;
  792. }
  793. /*!--------------------------------------------------------------------------
  794. IpxStaticNetBIOSNameHandler::OnCreateDataObject
  795. Implementation of ITFSResultHandler::OnCreateDataObject
  796. Author: KennT
  797. ---------------------------------------------------------------------------*/
  798. STDMETHODIMP IpxStaticNetBIOSNameHandler::OnCreateDataObject(ITFSComponent *pComp, MMC_COOKIE cookie, DATA_OBJECT_TYPES type, IDataObject **ppDataObject)
  799. {
  800. HRESULT hr = hrOK;
  801. COM_PROTECT_TRY
  802. {
  803. CORg( CreateDataObjectFromInterfaceInfo(m_spInterfaceInfo,
  804. type, cookie, m_spTFSCompData,
  805. ppDataObject) );
  806. COM_PROTECT_ERROR_LABEL;
  807. }
  808. COM_PROTECT_CATCH;
  809. return hr;
  810. }
  811. /*!--------------------------------------------------------------------------
  812. IpxStaticNetBIOSNameHandler::Init
  813. -
  814. Author: KennT
  815. ---------------------------------------------------------------------------*/
  816. HRESULT IpxStaticNetBIOSNameHandler::Init(IInterfaceInfo *pIfInfo, ITFSNode *pParent)
  817. {
  818. Assert(pIfInfo);
  819. m_spInterfaceInfo.Set(pIfInfo);
  820. pIfInfo->GetParentRouterInfo(&m_spRouterInfo);
  821. BaseIPXResultHandler::Init(pIfInfo, pParent);
  822. return hrOK;
  823. }
  824. /*!--------------------------------------------------------------------------
  825. IpxStaticNetBIOSNameHandler::DestroyResultHandler
  826. -
  827. Author: KennT
  828. ---------------------------------------------------------------------------*/
  829. STDMETHODIMP IpxStaticNetBIOSNameHandler::DestroyResultHandler(MMC_COOKIE cookie)
  830. {
  831. m_spInterfaceInfo.Release();
  832. BaseIPXResultHandler::DestroyResultHandler(cookie);
  833. return hrOK;
  834. }
  835. /*---------------------------------------------------------------------------
  836. This is the list of commands that will show up for the result pane
  837. nodes.
  838. ---------------------------------------------------------------------------*/
  839. struct SIPInterfaceNodeMenu
  840. {
  841. ULONG m_sidMenu; // string/command id for this menu item
  842. ULONG (IpxStaticNetBIOSNameHandler:: *m_pfnGetMenuFlags)(IpxStaticNetBIOSNameHandler::SMenuData *);
  843. ULONG m_ulPosition;
  844. };
  845. /*!--------------------------------------------------------------------------
  846. IpxStaticNetBIOSNameHandler::AddMenuItems
  847. Implementation of ITFSResultHandler::AddMenuItems
  848. Author: KennT
  849. ---------------------------------------------------------------------------*/
  850. STDMETHODIMP IpxStaticNetBIOSNameHandler::AddMenuItems(
  851. ITFSComponent *pComponent,
  852. MMC_COOKIE cookie,
  853. LPDATAOBJECT lpDataObject,
  854. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  855. long *pInsertionAllowed)
  856. {
  857. return hrOK;
  858. }
  859. /*!--------------------------------------------------------------------------
  860. IpxStaticNetBIOSNameHandler::Command
  861. -
  862. Author: KennT
  863. ---------------------------------------------------------------------------*/
  864. STDMETHODIMP IpxStaticNetBIOSNameHandler::Command(ITFSComponent *pComponent,
  865. MMC_COOKIE cookie,
  866. int nCommandID,
  867. LPDATAOBJECT pDataObject)
  868. {
  869. return hrOK;
  870. }
  871. /*!--------------------------------------------------------------------------
  872. IpxStaticNetBIOSNameHandler::HasPropertyPages
  873. -
  874. Author: KennT
  875. ---------------------------------------------------------------------------*/
  876. STDMETHODIMP IpxStaticNetBIOSNameHandler::HasPropertyPages
  877. (
  878. ITFSNode * pNode,
  879. LPDATAOBJECT pDataObject,
  880. DATA_OBJECT_TYPES type,
  881. DWORD dwType
  882. )
  883. {
  884. return S_OK;
  885. /* AFX_MANAGE_STATE(AfxGetStaticModuleState());
  886. // Need to fill in a IpxSNListEntry
  887. IpxSNListEntry SNEntry;
  888. IpxSNListEntry SNEntryOld;
  889. SPIRouterInfo spRouterInfo;
  890. HRESULT hr = hrOK;
  891. CORg( m_spInterfaceInfo->GetParentRouterInfo(&spRouterInfo) );
  892. BaseIPXResultNodeData * pNodeData;
  893. pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
  894. Assert(pNodeData);
  895. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  896. // Fill in our SNEntry
  897. SNEntry.LoadFrom(pNodeData);
  898. SNEntryOld.LoadFrom(pNodeData);
  899. {
  900. CStaticNetBIOSNameDlg srdlg(&SNEntry, SR_DLG_MODIFY, spRouterInfo);
  901. if (srdlg.DoModal() == IDOK)
  902. {
  903. // Updates the name info for this name
  904. ModifyNameInfo(pNode, &SNEntry, &SNEntryOld);
  905. // Update the data in the UI
  906. SetNameData(pNodeData, &SNEntry);
  907. m_spInterfaceInfo.Set(SNEntry.m_spIf);
  908. // Force a refresh
  909. pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  910. }
  911. }
  912. Error:
  913. return hrOK;*/
  914. }
  915. STDMETHODIMP IpxStaticNetBIOSNameHandler::HasPropertyPages(ITFSComponent *pComponent,
  916. MMC_COOKIE cookie,
  917. LPDATAOBJECT pDataObject)
  918. {
  919. SPITFSNode spNode;
  920. m_spNodeMgr->FindNode(cookie, &spNode);
  921. return HasPropertyPages(spNode, pDataObject, CCT_RESULT, 0);
  922. }
  923. /*!--------------------------------------------------------------------------
  924. IpxStaticNetBIOSNameHandler::CreatePropertyPages
  925. Implementation of ResultHandler::CreatePropertyPages
  926. Author: KennT
  927. ---------------------------------------------------------------------------*/
  928. STDMETHODIMP IpxStaticNetBIOSNameHandler::CreatePropertyPages
  929. (
  930. ITFSComponent * pComponent,
  931. MMC_COOKIE cookie,
  932. LPPROPERTYSHEETCALLBACK lpProvider,
  933. LPDATAOBJECT pDataObject,
  934. LONG_PTR handle
  935. )
  936. {
  937. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  938. HRESULT hr = hrOK;
  939. SPITFSNode spNode;
  940. Assert( m_spNodeMgr );
  941. CORg( m_spNodeMgr->FindNode(cookie, &spNode) );
  942. // Call the ITFSNodeHandler::CreatePropertyPages
  943. hr = CreatePropertyPages(spNode, lpProvider, pDataObject, handle, 0);
  944. Error:
  945. return hr;
  946. }
  947. /*!--------------------------------------------------------------------------
  948. IpxStaticNetBIOSNameHandler::CreatePropertyPages
  949. Implementation of NodeHandler::CreatePropertyPages
  950. Author: Deonb
  951. ---------------------------------------------------------------------------*/
  952. STDMETHODIMP IpxStaticNetBIOSNameHandler::CreatePropertyPages
  953. (
  954. ITFSNode * pNode,
  955. LPPROPERTYSHEETCALLBACK lpProvider,
  956. LPDATAOBJECT pDataObject,
  957. LONG_PTR handle,
  958. DWORD dwType
  959. )
  960. {
  961. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  962. HRESULT hr = hrOK;
  963. IpxStaticNBNamePropertySheet *pProperties = NULL;
  964. SPIComponentData spComponentData;
  965. CString stTitle;
  966. CComPtr<IInterfaceInfo> spInterfaceInfo;
  967. BaseIPXResultNodeData * pNodeData;
  968. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  969. if (m_spInterfaceInfo)
  970. stTitle.Format(IDS_IPXSUMMARY_IF_PAGE_TITLE,
  971. m_spInterfaceInfo->GetTitle());
  972. else
  973. stTitle.LoadString(IDS_IPXSUMMARY_CLIENT_IF_PAGE_TITLE);
  974. pProperties = new IpxStaticNBNamePropertySheet(pNode, spComponentData,
  975. m_spTFSCompData, stTitle);
  976. pNodeData = GET_BASEIPXRESULT_NODEDATA(pNode);
  977. Assert(pNodeData);
  978. ASSERT_BASEIPXRESULT_NODEDATA(pNodeData);
  979. CORg( m_spNodeMgr->GetComponentData(&spComponentData) );
  980. spInterfaceInfo = m_spInterfaceInfo;
  981. CORg( pProperties->Init(pNodeData, spInterfaceInfo) );
  982. if (lpProvider)
  983. hr = pProperties->CreateModelessSheet(lpProvider, handle);
  984. else
  985. hr = pProperties->DoModelessSheet();
  986. Error:
  987. return hr;
  988. }
  989. /*!--------------------------------------------------------------------------
  990. IpxStaticNetBIOSNameHandler::OnResultDelete
  991. -
  992. Author: KennT
  993. ---------------------------------------------------------------------------*/
  994. HRESULT IpxStaticNetBIOSNameHandler::OnResultDelete(ITFSComponent *pComponent,
  995. LPDATAOBJECT pDataObject,
  996. MMC_COOKIE cookie,
  997. LPARAM arg,
  998. LPARAM param)
  999. {
  1000. SPITFSNode spNode;
  1001. m_spNodeMgr->FindNode(cookie, &spNode);
  1002. return OnRemoveStaticNetBIOSName(spNode);
  1003. }
  1004. /*!--------------------------------------------------------------------------
  1005. IpxStaticNetBIOSNameHandler::OnRemoveStaticNetBIOSName
  1006. -
  1007. Author: KennT
  1008. ---------------------------------------------------------------------------*/
  1009. HRESULT IpxStaticNetBIOSNameHandler::OnRemoveStaticNetBIOSName(ITFSNode *pNode)
  1010. {
  1011. HRESULT hr = hrOK;
  1012. SPIInfoBase spInfoBase;
  1013. SPIRtrMgrInterfaceInfo spRmIf;
  1014. IPXConnection *pIPXConn;
  1015. SPITFSNode spNodeParent;
  1016. BaseIPXResultNodeData * pData;
  1017. IpxSNListEntry SNEntry;
  1018. CWaitCursor wait;
  1019. pNode->GetParent(&spNodeParent);
  1020. pIPXConn = GET_IPX_SN_NODEDATA(spNodeParent);
  1021. Assert(pIPXConn);
  1022. pData = GET_BASEIPXRESULT_NODEDATA(pNode);
  1023. Assert(pData);
  1024. ASSERT_BASEIPXRESULT_NODEDATA(pData);
  1025. //
  1026. // Load the old interface's information
  1027. //
  1028. Assert(lstrcmpi(m_spInterfaceInfo->GetId(), pData->m_spIf->GetId()) == 0);
  1029. CORg( m_spInterfaceInfo->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1030. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1031. NULL,
  1032. NULL,
  1033. &spInfoBase));
  1034. SNEntry.LoadFrom(pData);
  1035. CORg( RemoveStaticNetBIOSName(&SNEntry, spInfoBase) );
  1036. // Update the interface information
  1037. CORg( spRmIf->Save(m_spInterfaceInfo->GetMachineName(),
  1038. pIPXConn->GetConfigHandle(),
  1039. NULL,
  1040. NULL,
  1041. spInfoBase,
  1042. 0));
  1043. // Refresh the node
  1044. ParentRefresh(pNode);
  1045. Error:
  1046. return hr;
  1047. }
  1048. /*!--------------------------------------------------------------------------
  1049. IpxStaticNetBIOSNameHandler::RemoveStaticNetBIOSName
  1050. -
  1051. Author: KennT
  1052. ---------------------------------------------------------------------------*/
  1053. HRESULT IpxStaticNetBIOSNameHandler::RemoveStaticNetBIOSName(IpxSNListEntry *pSNEntry,
  1054. IInfoBase *pInfoBase)
  1055. {
  1056. HRESULT hr = hrOK;
  1057. InfoBlock * pBlock;
  1058. PIPX_STATIC_NETBIOS_NAME_INFO pRow;
  1059. INT i;
  1060. // Get the IPX_STATIC_NETBIOS_NAME_INFO block from the interface
  1061. CORg( pInfoBase->GetBlock(IPX_STATIC_NETBIOS_NAME_INFO_TYPE, &pBlock, 0) );
  1062. // Look for the removed name in the IPX_STATIC_NETBIOS_NAME_INFO
  1063. pRow = (IPX_STATIC_NETBIOS_NAME_INFO*) pBlock->pData;
  1064. for (i = 0; i < (INT)pBlock->dwCount; i++, pRow++)
  1065. {
  1066. // Compare this name to the removed one
  1067. if (FAreTwoNamesEqual(pRow, &(pSNEntry->m_name)))
  1068. {
  1069. // This is the removed name, so modify this block
  1070. // to exclude the name:
  1071. // Decrement the number of Names
  1072. --pBlock->dwCount;
  1073. if (pBlock->dwCount && (i < (INT)pBlock->dwCount))
  1074. {
  1075. // Overwrite this name with the ones which follow it
  1076. ::memmove(pRow,
  1077. pRow + 1,
  1078. (pBlock->dwCount - i) * sizeof(*pRow));
  1079. }
  1080. break;
  1081. }
  1082. }
  1083. Error:
  1084. return hr;
  1085. }
  1086. /*!--------------------------------------------------------------------------
  1087. IpxStaticNetBIOSNameHandler::ModifyNameInfo
  1088. -
  1089. Author: KennT
  1090. ---------------------------------------------------------------------------*/
  1091. HRESULT IpxStaticNetBIOSNameHandler::ModifyNameInfo(ITFSNode *pNode,
  1092. IpxSNListEntry *pSNEntryNew,
  1093. IpxSNListEntry *pSNEntryOld)
  1094. {
  1095. Assert(pSNEntryNew);
  1096. Assert(pSNEntryOld);
  1097. INT i;
  1098. HRESULT hr = hrOK;
  1099. InfoBlock* pBlock;
  1100. SPIInfoBase spInfoBase;
  1101. SPIRtrMgrInterfaceInfo spRmIf;
  1102. SPITFSNode spNodeParent;
  1103. IPXConnection * pIPXConn;
  1104. IPX_STATIC_NETBIOS_NAME_INFO *psr, *psrOld;
  1105. IPX_STATIC_NETBIOS_NAME_INFO IpxRow;
  1106. CWaitCursor wait;
  1107. pNode->GetParent(&spNodeParent);
  1108. pIPXConn = GET_IPX_SN_NODEDATA(spNodeParent);
  1109. Assert(pIPXConn);
  1110. // Remove the old name if it is on another interface
  1111. if (lstrcmpi(pSNEntryOld->m_spIf->GetId(), pSNEntryNew->m_spIf->GetId()) != 0)
  1112. {
  1113. // the outgoing interface for a name is to be changed.
  1114. CORg( pSNEntryOld->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1115. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1116. NULL,
  1117. NULL,
  1118. &spInfoBase));
  1119. // Remove the old interface
  1120. CORg( RemoveStaticNetBIOSName(pSNEntryOld, spInfoBase) );
  1121. // Update the interface information
  1122. CORg( spRmIf->Save(pSNEntryOld->m_spIf->GetMachineName(),
  1123. pIPXConn->GetConfigHandle(),
  1124. NULL,
  1125. NULL,
  1126. spInfoBase,
  1127. 0));
  1128. }
  1129. spRmIf.Release();
  1130. spInfoBase.Release();
  1131. // Either
  1132. // (a) a name is being modified (on the same interface)
  1133. // (b) a name is being moved from one interface to another.
  1134. // Retrieve the configuration for the interface to which the name
  1135. // is now attached;
  1136. CORg( pSNEntryNew->m_spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) );
  1137. CORg( spRmIf->GetInfoBase(pIPXConn->GetConfigHandle(),
  1138. NULL,
  1139. NULL,
  1140. &spInfoBase));
  1141. // Get the IPX_STATIC_NETBIOS_NAME_INFO block from the interface
  1142. hr = spInfoBase->GetBlock(IPX_STATIC_NETBIOS_NAME_INFO_TYPE, &pBlock, 0);
  1143. if (!FHrOK(hr))
  1144. {
  1145. //
  1146. // No IPX_STATIC_NETBIOS_NAME_INFO block was found; we create a new block
  1147. // with the new name, and add that block to the interface-info
  1148. //
  1149. CORg( AddStaticNetBIOSName(pSNEntryNew, spInfoBase, NULL) );
  1150. }
  1151. else
  1152. {
  1153. //
  1154. // An IPX_STATIC_NETBIOS_NAME_INFO block was found.
  1155. //
  1156. // We are modifying an existing name.
  1157. // If the name's interface was not changed when it was modified,
  1158. // look for the existing name in the IPX_STATIC_NETBIOS_NAME_INFO, and then
  1159. // update its parameters.
  1160. // Otherwise, write a completely new name in the IPX_STATIC_NETBIOS_NAME_INFO;
  1161. //
  1162. if (lstrcmpi(pSNEntryOld->m_spIf->GetId(), pSNEntryNew->m_spIf->GetId()) == 0)
  1163. {
  1164. //
  1165. // The name's interface was not changed when it was modified;
  1166. // We now look for it amongst the existing Names
  1167. // for this interface.
  1168. // The name's original parameters are in 'preOld',
  1169. // so those are the parameters with which we search
  1170. // for a name to modify
  1171. //
  1172. psr = (IPX_STATIC_NETBIOS_NAME_INFO*)pBlock->pData;
  1173. for (i = 0; i < (INT)pBlock->dwCount; i++, psr++)
  1174. {
  1175. // Compare this name to the re-configured one
  1176. if (!FAreTwoNamesEqual(&(pSNEntryOld->m_name), psr))
  1177. continue;
  1178. // This is the name which was modified;
  1179. // We can now modify the parameters for the name in-place.
  1180. *psr = pSNEntryNew->m_name;
  1181. break;
  1182. }
  1183. }
  1184. else
  1185. {
  1186. CORg( AddStaticNetBIOSName(pSNEntryNew, spInfoBase, pBlock) );
  1187. }
  1188. // Save the updated information
  1189. CORg( spRmIf->Save(pSNEntryNew->m_spIf->GetMachineName(),
  1190. pIPXConn->GetConfigHandle(),
  1191. NULL,
  1192. NULL,
  1193. spInfoBase,
  1194. 0));
  1195. }
  1196. Error:
  1197. return hr;
  1198. }
  1199. /*!--------------------------------------------------------------------------
  1200. IpxStaticNetBIOSNameHandler::ParentRefresh
  1201. -
  1202. Author: KennT
  1203. ---------------------------------------------------------------------------*/
  1204. HRESULT IpxStaticNetBIOSNameHandler::ParentRefresh(ITFSNode *pNode)
  1205. {
  1206. return ForwardCommandToParent(pNode, IDS_MENU_SYNC,
  1207. CCT_RESULT, NULL, 0);
  1208. }
  1209. //----------------------------------------------------------------------------
  1210. // Class: CStaticNetBIOSNameDlg
  1211. //
  1212. //----------------------------------------------------------------------------
  1213. //----------------------------------------------------------------------------
  1214. // Function: CStaticNetBIOSNameDlg::CStaticNetBIOSNameDlg
  1215. //
  1216. // Constructor: initialize the base-class and the dialog's data.
  1217. //----------------------------------------------------------------------------
  1218. CStaticNetBIOSNameDlg::CStaticNetBIOSNameDlg(IpxSNListEntry * pSNEntry,
  1219. DWORD dwFlags,
  1220. IRouterInfo *pRouter,
  1221. CWnd *pParent)
  1222. : CBaseDialog(IDD_STATIC_NETBIOS_NAME, pParent),
  1223. m_pSNEntry(pSNEntry),
  1224. m_dwFlags(dwFlags)
  1225. {
  1226. //{{AFX_DATA_INIT(CStaticNetBIOSNameDlg)
  1227. //}}AFX_DATA_INIT
  1228. m_spRouterInfo.Set(pRouter);
  1229. // SetHelpMap(m_dwHelpMap);
  1230. }
  1231. //----------------------------------------------------------------------------
  1232. // Function: CStaticNetBIOSNameDlg::DoDataExchange
  1233. //----------------------------------------------------------------------------
  1234. VOID
  1235. CStaticNetBIOSNameDlg::DoDataExchange(
  1236. CDataExchange* pDX
  1237. ) {
  1238. CBaseDialog::DoDataExchange(pDX);
  1239. //{{AFX_DATA_MAP(CStaticNetBIOSNameDlg)
  1240. DDX_Control(pDX, IDC_SND_COMBO_INTERFACE, m_cbInterfaces);
  1241. //}}AFX_DATA_MAP
  1242. }
  1243. BEGIN_MESSAGE_MAP(CStaticNetBIOSNameDlg, CBaseDialog)
  1244. //{{AFX_MSG_MAP(CStaticNetBIOSNameDlg)
  1245. //}}AFX_MSG_MAP
  1246. END_MESSAGE_MAP()
  1247. DWORD CStaticNetBIOSNameDlg::m_dwHelpMap[] =
  1248. {
  1249. // IDC_SRD_DESTINATION, HIDC_SRD_DESTINATION,
  1250. // IDC_SRD_NETMASK, HIDC_SRD_NETMASK,
  1251. // IDC_SRD_GATEWAY, HIDC_SRD_GATEWAY,
  1252. // IDC_SRD_METRIC, HIDC_SRD_METRIC,
  1253. // IDC_SRD_SPINMETRIC, HIDC_SRD_SPINMETRIC,
  1254. // IDC_SRD_INTERFACES, HIDC_SRD_INTERFACES,
  1255. 0,0
  1256. };
  1257. //----------------------------------------------------------------------------
  1258. // Function: CStaticNetBIOSNameDlg::OnInitDialog
  1259. //
  1260. // Handles the 'WM_INITDIALOG' message for the dialog.
  1261. //----------------------------------------------------------------------------
  1262. BOOL
  1263. CStaticNetBIOSNameDlg::OnInitDialog(
  1264. )
  1265. {
  1266. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1267. SPIEnumInterfaceInfo spEnumIf;
  1268. SPIInterfaceInfo spIf;
  1269. SPIRtrMgrInterfaceInfo spRmIf;
  1270. TCHAR szName[32];
  1271. TCHAR szType[32];
  1272. CString st;
  1273. USHORT uType;
  1274. CBaseDialog::OnInitDialog();
  1275. // initialize the controls
  1276. ((CEdit *) GetDlgItem(IDC_SND_EDIT_NAME))->LimitText(15);
  1277. ((CEdit *) GetDlgItem(IDC_SND_EDIT_TYPE))->LimitText(2);
  1278. // Get a list of the interfaces enabled for IPX routing.
  1279. m_spRouterInfo->EnumInterface(&spEnumIf);
  1280. for( ; spEnumIf->Next(1, &spIf, NULL) == hrOK; spIf.Release())
  1281. {
  1282. spRmIf.Release();
  1283. if (spIf->FindRtrMgrInterface(PID_IPX, &spRmIf) != hrOK)
  1284. continue;
  1285. // Add the interface to the combobox
  1286. INT i = m_cbInterfaces.AddString(spIf->GetTitle());
  1287. m_cbInterfaces.SetItemData(i, (DWORD_PTR)m_ifidList.AddTail(spIf->GetId()));
  1288. }
  1289. if (!m_cbInterfaces.GetCount())
  1290. {
  1291. AfxMessageBox(IDS_ERR_NO_IPX_INTERFACES);
  1292. EndDialog(IDCANCEL);
  1293. return FALSE;
  1294. }
  1295. m_cbInterfaces.SetCurSel(0);
  1296. //
  1297. // If we were given a name to modify, set the dialog up
  1298. // with the parameters in the name
  1299. //
  1300. if ((m_dwFlags & SR_DLG_MODIFY) == 0)
  1301. {
  1302. // No name was given, so leave the controls blank
  1303. }
  1304. else
  1305. {
  1306. FormatNetBIOSName(szName, &uType, (LPCSTR) m_pSNEntry->m_name.Name);
  1307. st = szName;
  1308. st.TrimRight();
  1309. st.TrimLeft();
  1310. SetDlgItemText(IDC_SND_EDIT_NAME, st);
  1311. m_cbInterfaces.SelectString(-1, m_pSNEntry->m_spIf->GetTitle());
  1312. wsprintf(szType, _T("%.2x"), uType);
  1313. SetDlgItemText(IDC_SND_EDIT_TYPE, szType);
  1314. // Disable the network number, next hop, and interface
  1315. GetDlgItem(IDC_SND_COMBO_INTERFACE)->EnableWindow(FALSE);
  1316. }
  1317. return TRUE;
  1318. }
  1319. //----------------------------------------------------------------------------
  1320. // Function: CStaticNetBIOSNameDlg::OnOK
  1321. //
  1322. // Handles 'BN_CLICKED' notification from the 'OK' button.
  1323. //----------------------------------------------------------------------------
  1324. VOID
  1325. CStaticNetBIOSNameDlg::OnOK(
  1326. ) {
  1327. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1328. CString st;
  1329. SPIInterfaceInfo spIf;
  1330. CString stIf;
  1331. POSITION pos;
  1332. USHORT uType;
  1333. do
  1334. {
  1335. // Get the name's outgoing interface
  1336. INT item = m_cbInterfaces.GetCurSel();
  1337. if (item == CB_ERR)
  1338. break;
  1339. pos = (POSITION)m_cbInterfaces.GetItemData(item);
  1340. stIf = (LPCTSTR)m_ifidList.GetAt(pos);
  1341. m_spRouterInfo->FindInterface(stIf, &spIf);
  1342. m_pSNEntry->m_spIf.Set(spIf);
  1343. // Get the rest of the data
  1344. GetDlgItemText(IDC_SND_EDIT_TYPE, st);
  1345. uType = (USHORT) _tcstoul(st, NULL, 16);
  1346. GetDlgItemText(IDC_SND_EDIT_NAME, st);
  1347. st.TrimLeft();
  1348. st.TrimRight();
  1349. if (st.IsEmpty())
  1350. {
  1351. GetDlgItem(IDC_SND_EDIT_NAME)->SetFocus();
  1352. AfxMessageBox(IDS_ERR_INVALID_NETBIOS_NAME);
  1353. break;
  1354. }
  1355. ConvertToNetBIOSName((LPSTR) m_pSNEntry->m_name.Name, st, uType);
  1356. CBaseDialog::OnOK();
  1357. } while(FALSE);
  1358. }
  1359. /*!--------------------------------------------------------------------------
  1360. IpxSNListEntry::LoadFrom
  1361. -
  1362. Author: KennT
  1363. ---------------------------------------------------------------------------*/
  1364. void IpxSNListEntry::LoadFrom(BaseIPXResultNodeData *pNodeData)
  1365. {
  1366. m_spIf.Set(pNodeData->m_spIf);
  1367. ConvertToNetBIOSName((LPSTR) m_name.Name,
  1368. pNodeData->m_rgData[IPX_SN_SI_NETBIOS_NAME].m_stData,
  1369. (USHORT) pNodeData->m_rgData[IPX_SN_SI_NETBIOS_TYPE].m_dwData);
  1370. }
  1371. /*!--------------------------------------------------------------------------
  1372. IpxSNListEntry::SaveTo
  1373. -
  1374. Author: KennT
  1375. ---------------------------------------------------------------------------*/
  1376. void IpxSNListEntry::SaveTo(BaseIPXResultNodeData *pNodeData)
  1377. {
  1378. TCHAR szName[32];
  1379. TCHAR szType[32];
  1380. CString st;
  1381. USHORT uType;
  1382. FormatNetBIOSName(szName, &uType,
  1383. (LPCSTR) m_name.Name);
  1384. st = szName;
  1385. st.TrimLeft();
  1386. st.TrimRight();
  1387. pNodeData->m_spIf.Set(m_spIf);
  1388. pNodeData->m_rgData[IPX_SN_SI_NAME].m_stData = m_spIf->GetTitle();
  1389. pNodeData->m_rgData[IPX_SN_SI_NETBIOS_NAME].m_stData = st;
  1390. wsprintf(szType, _T("%.2x"), uType);
  1391. pNodeData->m_rgData[IPX_SN_SI_NETBIOS_TYPE].m_stData = szType;
  1392. pNodeData->m_rgData[IPX_SN_SI_NETBIOS_TYPE].m_dwData = uType;
  1393. }
  1394. /*!--------------------------------------------------------------------------
  1395. SetNameData
  1396. -
  1397. Author: KennT
  1398. ---------------------------------------------------------------------------*/
  1399. HRESULT SetNameData(BaseIPXResultNodeData *pData,
  1400. IpxSNListEntry *pName)
  1401. {
  1402. pName->SaveTo(pData);
  1403. return hrOK;
  1404. }
  1405. /*!--------------------------------------------------------------------------
  1406. AddStaticNetBIOSName
  1407. This function ASSUMES that the name is NOT in the block.
  1408. Author: KennT
  1409. ---------------------------------------------------------------------------*/
  1410. HRESULT AddStaticNetBIOSName(IpxSNListEntry *pSNEntryNew,
  1411. IInfoBase *pInfoBase,
  1412. InfoBlock *pBlock)
  1413. {
  1414. IPX_STATIC_NETBIOS_NAME_INFO srRow;
  1415. HRESULT hr = hrOK;
  1416. if (pBlock == NULL)
  1417. {
  1418. //
  1419. // No IPX_STATIC_NETBIOS_NAME_INFO block was found; we create a new block
  1420. // with the new name, and add that block to the interface-info
  1421. //
  1422. CORg( pInfoBase->AddBlock(IPX_STATIC_NETBIOS_NAME_INFO_TYPE,
  1423. sizeof(IPX_STATIC_NETBIOS_NAME_INFO),
  1424. (LPBYTE) &(pSNEntryNew->m_name), 1, 0) );
  1425. }
  1426. else
  1427. {
  1428. // Either the name is completely new, or it is a name
  1429. // which was moved from one interface to another.
  1430. // Set a new block as the IPX_STATIC_NETBIOS_NAME_INFO,
  1431. // and include the re-configured name in the new block.
  1432. PIPX_STATIC_NETBIOS_NAME_INFO psrTable;
  1433. psrTable = new IPX_STATIC_NETBIOS_NAME_INFO[pBlock->dwCount + 1];
  1434. Assert(psrTable);
  1435. // Copy the original table of Names
  1436. ::memcpy(psrTable, pBlock->pData,
  1437. pBlock->dwCount * sizeof(IPX_STATIC_NETBIOS_NAME_INFO));
  1438. // Append the new name
  1439. psrTable[pBlock->dwCount] = pSNEntryNew->m_name;
  1440. // Replace the old name-table with the new one
  1441. CORg( pInfoBase->SetData(IPX_STATIC_NETBIOS_NAME_INFO_TYPE,
  1442. sizeof(IPX_STATIC_NETBIOS_NAME_INFO),
  1443. (LPBYTE) psrTable, pBlock->dwCount + 1, 0) );
  1444. }
  1445. Error:
  1446. return hr;
  1447. }
  1448. BOOL FAreTwoNamesEqual(IPX_STATIC_NETBIOS_NAME_INFO *pName1,
  1449. IPX_STATIC_NETBIOS_NAME_INFO *pName2)
  1450. {
  1451. return (memcmp(pName1->Name, pName2->Name, sizeof(pName1->Name)) == 0);
  1452. }