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.

3138 lines
80 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. mscope.cpp
  7. This file contains the implementation for the multicast scope node.
  8. FILE HISTORY:
  9. 9/25/97 EricDav Created
  10. */
  11. #include "stdafx.h"
  12. #include "server.h" // Server definition
  13. #include "nodes.h" // Result pane node definitions
  14. #include "mscope.h" // mscope definition
  15. #include "addexcl.h"
  16. #include "mscopepp.h" // properties of the mScope
  17. #include "dlgrecon.h" // reconcile dialog
  18. /*---------------------------------------------------------------------------
  19. GetLangTag
  20. Sets the language tag based on the name
  21. Author: EricDav
  22. ---------------------------------------------------------------------------*/
  23. void
  24. GetLangTag
  25. (
  26. CString & strLangTag
  27. )
  28. {
  29. char b1[32], b2[32];
  30. static char buff[80];
  31. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, b1, sizeof(b1));
  32. GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, b2, sizeof(b2));
  33. ZeroMemory(buff, sizeof(buff));
  34. if (_stricmp(b1, b2))
  35. sprintf(buff, "%s-%s", b1, b2);
  36. else
  37. strcpy(buff, b1);
  38. strLangTag = buff;
  39. }
  40. /*---------------------------------------------------------------------------
  41. Class CDhcpMScope implementation
  42. ---------------------------------------------------------------------------*/
  43. /*---------------------------------------------------------------------------
  44. Function Name Here
  45. Description
  46. Author: EricDav
  47. ---------------------------------------------------------------------------*/
  48. CDhcpMScope::CDhcpMScope
  49. (
  50. ITFSComponentData* pTFSComponentData
  51. ) : CMTDhcpHandler(pTFSComponentData)
  52. {
  53. }
  54. CDhcpMScope::~CDhcpMScope()
  55. {
  56. }
  57. /*!--------------------------------------------------------------------------
  58. CDhcpMScope::InitializeNode
  59. Initializes node specific data
  60. Author: EricDav
  61. ---------------------------------------------------------------------------*/
  62. HRESULT
  63. CDhcpMScope::InitializeNode
  64. (
  65. ITFSNode * pNode
  66. )
  67. {
  68. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  69. CString strDisplayName;
  70. BuildDisplayName(&strDisplayName, m_SubnetInfo.SubnetName);
  71. SetDisplayName(strDisplayName);
  72. if (m_SubnetInfo.SubnetState == DhcpSubnetDisabled)
  73. {
  74. m_strState.LoadString(IDS_SCOPE_INACTIVE);
  75. }
  76. else
  77. {
  78. m_strState.LoadString(IDS_SCOPE_ACTIVE);
  79. }
  80. // Make the node immediately visible
  81. pNode->SetVisibilityState(TFS_VIS_SHOW);
  82. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  83. pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
  84. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
  85. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  86. pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_MSCOPE);
  87. SetColumnStringIDs(&aColumns[DHCPSNAP_MSCOPE][0]);
  88. SetColumnWidths(&aColumnWidths[DHCPSNAP_MSCOPE][0]);
  89. return hrOK;
  90. }
  91. /*---------------------------------------------------------------------------
  92. CDhcpMScope::OnCreateNodeId2
  93. Returns a unique string for this node
  94. Author: EricDav
  95. ---------------------------------------------------------------------------*/
  96. HRESULT CDhcpMScope::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  97. {
  98. const GUID * pGuid = pNode->GetNodeType();
  99. CString strNode, strGuid;
  100. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  101. strGuid.ReleaseBuffer();
  102. // id string is server name, scope name and guid.
  103. strNode = GetServerObject()->GetName();
  104. strNode += GetName() + strGuid;
  105. strId = strNode;
  106. return hrOK;
  107. }
  108. /*---------------------------------------------------------------------------
  109. CDhcpMScope::GetImageIndex
  110. Description
  111. Author: EricDav
  112. ---------------------------------------------------------------------------*/
  113. int
  114. CDhcpMScope::GetImageIndex(BOOL bOpenImage)
  115. {
  116. int nIndex = -1;
  117. switch (m_nState)
  118. {
  119. // TODO: these need to be updated with new busy state icons
  120. case loading:
  121. if (bOpenImage)
  122. nIndex = (IsEnabled()) ? ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_BUSY : ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_BUSY;
  123. else
  124. nIndex = (IsEnabled()) ? ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_BUSY : ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_BUSY;
  125. return nIndex;
  126. case notLoaded:
  127. case loaded:
  128. if (bOpenImage)
  129. nIndex = (IsEnabled()) ? ICON_IDX_SCOPE_FOLDER_OPEN : ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN;
  130. else
  131. nIndex = (IsEnabled()) ? ICON_IDX_SCOPE_FOLDER_CLOSED : ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED;
  132. break;
  133. case unableToLoad:
  134. if (bOpenImage)
  135. nIndex = (IsEnabled()) ? ICON_IDX_SCOPE_FOLDER_OPEN_LOST_CONNECTION : ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN_LOST_CONNECTION;
  136. else
  137. nIndex = (IsEnabled()) ? ICON_IDX_SCOPE_FOLDER_CLOSED_LOST_CONNECTION : ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED_LOST_CONNECTION;
  138. return nIndex;
  139. default:
  140. ASSERT(FALSE);
  141. }
  142. if (m_spServerNode && IsEnabled())
  143. {
  144. CDhcpServer * pServer = GetServerObject();
  145. LPDHCP_MCAST_MIB_INFO pMibInfo = pServer->DuplicateMCastMibInfo();
  146. if (!pMibInfo)
  147. return nIndex;
  148. LPMSCOPE_MIB_INFO pScopeMibInfo = pMibInfo->ScopeInfo;
  149. // walk the list of scopes and find our info
  150. for (UINT i = 0; i < pMibInfo->Scopes; i++)
  151. {
  152. // Find our scope stats
  153. if ( (m_SubnetInfo.SubnetName.CompareNoCase(pScopeMibInfo[i].MScopeName) == 0) &&
  154. (m_SubnetInfo.SubnetAddress == pScopeMibInfo[i].MScopeId) )
  155. {
  156. int nPercentInUse;
  157. if ((pScopeMibInfo[i].NumAddressesInuse + pScopeMibInfo[i].NumAddressesFree) == 0)
  158. nPercentInUse = 0;
  159. else
  160. nPercentInUse = (pScopeMibInfo[i].NumAddressesInuse * 100) / (pScopeMibInfo[i].NumAddressesInuse + pScopeMibInfo[i].NumAddressesFree);
  161. // look to see if this scope meets the warning or red flag case
  162. if (pScopeMibInfo[i].NumAddressesFree == 0)
  163. {
  164. // red flag case, no addresses free, this is the highest
  165. // level of warning, so break out of the loop if we set this.
  166. if (bOpenImage)
  167. nIndex = ICON_IDX_SCOPE_FOLDER_OPEN_ALERT;
  168. else
  169. nIndex = ICON_IDX_SCOPE_FOLDER_CLOSED_ALERT;
  170. break;
  171. }
  172. else
  173. if (nPercentInUse >= SCOPE_WARNING_LEVEL)
  174. {
  175. // warning condition if Num Addresses in use is greater than
  176. // some pre-defined threshold.
  177. if (bOpenImage)
  178. nIndex = ICON_IDX_SCOPE_FOLDER_OPEN_WARNING;
  179. else
  180. nIndex = ICON_IDX_SCOPE_FOLDER_CLOSED_WARNING;
  181. }
  182. break;
  183. }
  184. }
  185. pServer->FreeDupMCastMibInfo(pMibInfo);
  186. }
  187. return nIndex;
  188. }
  189. /*---------------------------------------------------------------------------
  190. Overridden base handler functions
  191. ---------------------------------------------------------------------------*/
  192. /*---------------------------------------------------------------------------
  193. CDhcpMScope::OnAddMenuItems
  194. Description
  195. Author: EricDav
  196. ---------------------------------------------------------------------------*/
  197. STDMETHODIMP
  198. CDhcpMScope::OnAddMenuItems
  199. (
  200. ITFSNode * pNode,
  201. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  202. LPDATAOBJECT lpDataObject,
  203. DATA_OBJECT_TYPES type,
  204. DWORD dwType,
  205. long * pInsertionAllowed
  206. )
  207. {
  208. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  209. LONG fFlags = 0, fLoadingFlags = 0;
  210. HRESULT hr = S_OK;
  211. CString strMenuText;
  212. if ( m_nState != loaded )
  213. {
  214. fFlags |= MF_GRAYED;
  215. }
  216. if ( m_nState == loading)
  217. {
  218. fLoadingFlags = MF_GRAYED;
  219. }
  220. if (type == CCT_SCOPE)
  221. {
  222. //
  223. // these menu items go in the new menu,
  224. // only visible from scope pane
  225. //
  226. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  227. {
  228. strMenuText.LoadString(IDS_SCOPE_SHOW_STATISTICS);
  229. hr = LoadAndAddMenuItem( pContextMenuCallback,
  230. strMenuText,
  231. IDS_SCOPE_SHOW_STATISTICS,
  232. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  233. fFlags );
  234. ASSERT( SUCCEEDED(hr) );
  235. // separator
  236. hr = LoadAndAddMenuItem( pContextMenuCallback,
  237. strMenuText,
  238. 0,
  239. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  240. MF_SEPARATOR);
  241. ASSERT( SUCCEEDED(hr) );
  242. // reconcile
  243. strMenuText.LoadString(IDS_SCOPE_RECONCILE);
  244. hr = LoadAndAddMenuItem( pContextMenuCallback,
  245. strMenuText,
  246. IDS_SCOPE_RECONCILE,
  247. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  248. fFlags );
  249. ASSERT( SUCCEEDED(hr) );
  250. // separator
  251. hr = LoadAndAddMenuItem( pContextMenuCallback,
  252. strMenuText,
  253. 0,
  254. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  255. MF_SEPARATOR);
  256. ASSERT( SUCCEEDED(hr) );
  257. // activate/deactivate
  258. if (m_SubnetInfo.SubnetState == DhcpSubnetDisabled)
  259. {
  260. strMenuText.LoadString(IDS_SCOPE_ACTIVATE);
  261. hr = LoadAndAddMenuItem( pContextMenuCallback,
  262. strMenuText,
  263. IDS_SCOPE_ACTIVATE,
  264. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  265. fFlags );
  266. ASSERT( SUCCEEDED(hr) );
  267. }
  268. else
  269. {
  270. strMenuText.LoadString(IDS_SCOPE_DEACTIVATE);
  271. hr = LoadAndAddMenuItem( pContextMenuCallback,
  272. strMenuText,
  273. IDS_SCOPE_DEACTIVATE,
  274. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  275. fFlags );
  276. ASSERT( SUCCEEDED(hr) );
  277. }
  278. }
  279. }
  280. return hr;
  281. }
  282. /*---------------------------------------------------------------------------
  283. CDhcpMScope::OnCommand
  284. Description
  285. Author: EricDav
  286. ---------------------------------------------------------------------------*/
  287. STDMETHODIMP
  288. CDhcpMScope::OnCommand
  289. (
  290. ITFSNode * pNode,
  291. long nCommandId,
  292. DATA_OBJECT_TYPES type,
  293. LPDATAOBJECT pDataObject,
  294. DWORD dwType
  295. )
  296. {
  297. HRESULT hr = S_OK;
  298. switch (nCommandId)
  299. {
  300. case IDS_ACTIVATE:
  301. case IDS_DEACTIVATE:
  302. case IDS_SCOPE_ACTIVATE:
  303. case IDS_SCOPE_DEACTIVATE:
  304. OnActivateScope(pNode);
  305. break;
  306. case IDS_REFRESH:
  307. OnRefresh(pNode, pDataObject, dwType, 0, 0);
  308. break;
  309. case IDS_SCOPE_SHOW_STATISTICS:
  310. OnShowScopeStats(pNode);
  311. break;
  312. case IDS_SCOPE_RECONCILE:
  313. OnReconcileScope(pNode);
  314. break;
  315. case IDS_DELETE:
  316. OnDelete(pNode);
  317. break;
  318. default:
  319. break;
  320. }
  321. return hr;
  322. }
  323. /*---------------------------------------------------------------------------
  324. CDhcpMScope::CreatePropertyPages
  325. Description
  326. Author: EricDav
  327. ---------------------------------------------------------------------------*/
  328. STDMETHODIMP
  329. CDhcpMScope::CreatePropertyPages
  330. (
  331. ITFSNode * pNode,
  332. LPPROPERTYSHEETCALLBACK lpProvider,
  333. LPDATAOBJECT pDataObject,
  334. LONG_PTR handle,
  335. DWORD dwType
  336. )
  337. {
  338. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  339. HRESULT hr = hrOK;
  340. DWORD dwError;
  341. DWORD dwDynDnsFlags;
  342. SPIComponentData spComponentData;
  343. LARGE_INTEGER liVersion;
  344. CDhcpServer * pServer;
  345. DHCP_IP_RANGE dhcpIpRange;
  346. //
  347. // Create the property page
  348. //
  349. m_spNodeMgr->GetComponentData(&spComponentData);
  350. CMScopeProperties * pScopeProp =
  351. new CMScopeProperties(pNode, spComponentData, m_spTFSCompData, NULL);
  352. // Get the Server version and set it in the property sheet
  353. pServer = GetServerObject();
  354. pServer->GetVersion(liVersion);
  355. pScopeProp->SetVersion(liVersion);
  356. // Set scope specific data in the prop sheet
  357. pScopeProp->m_pageGeneral.m_SubnetInfo = m_SubnetInfo;
  358. BEGIN_WAIT_CURSOR;
  359. ZeroMemory(&dhcpIpRange, sizeof(dhcpIpRange));
  360. dwError = GetIpRange(&dhcpIpRange);
  361. if (dwError != ERROR_SUCCESS)
  362. {
  363. ::DhcpMessageBox(dwError);
  364. goto Cleanup;
  365. }
  366. pScopeProp->m_pageGeneral.m_ScopeCfg.m_dwStartAddress = dhcpIpRange.StartAddress;
  367. pScopeProp->m_pageGeneral.m_ScopeCfg.m_dwEndAddress = dhcpIpRange.EndAddress;
  368. pScopeProp->m_pageGeneral.m_uImage = GetImageIndex(FALSE);
  369. dwError = GetLeaseTime(&pScopeProp->m_pageGeneral.m_ScopeCfg.m_dwLeaseTime);
  370. END_WAIT_CURSOR;
  371. GetLifetime(&pScopeProp->m_pageLifetime.m_Expiry);
  372. //
  373. // Object gets deleted when the page is destroyed
  374. //
  375. Assert(lpProvider != NULL);
  376. return pScopeProp->CreateModelessSheet(lpProvider, handle);
  377. Cleanup:
  378. delete pScopeProp;
  379. return hrFalse;
  380. }
  381. /*---------------------------------------------------------------------------
  382. CDhcpMScope::OnPropertyChange
  383. Description
  384. Author: EricDav
  385. ---------------------------------------------------------------------------*/
  386. HRESULT
  387. CDhcpMScope::OnPropertyChange
  388. (
  389. ITFSNode * pNode,
  390. LPDATAOBJECT pDataobject,
  391. DWORD dwType,
  392. LPARAM arg,
  393. LPARAM lParam
  394. )
  395. {
  396. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  397. CMScopeProperties * pScopeProp = reinterpret_cast<CMScopeProperties *>(lParam);
  398. LONG_PTR changeMask = 0;
  399. // tell the property page to do whatever now that we are back on the
  400. // main thread
  401. pScopeProp->OnPropertyChange(TRUE, &changeMask);
  402. pScopeProp->AcknowledgeNotify();
  403. if (changeMask)
  404. pNode->ChangeNode(changeMask);
  405. return hrOK;
  406. }
  407. /*!--------------------------------------------------------------------------
  408. CDhcpMScope::GetString
  409. Returns string information for display in the result pane columns
  410. Author: EricDav
  411. ---------------------------------------------------------------------------*/
  412. STDMETHODIMP_(LPCTSTR)
  413. CDhcpMScope::GetString
  414. (
  415. ITFSNode * pNode,
  416. int nCol
  417. )
  418. {
  419. switch (nCol)
  420. {
  421. case 0:
  422. return GetDisplayName();
  423. case 1:
  424. return m_strState;
  425. case 2:
  426. return m_SubnetInfo.SubnetComment;
  427. }
  428. return NULL;
  429. }
  430. /*---------------------------------------------------------------------------
  431. CDhcpMScope::CompareItems
  432. Description
  433. Author: EricDav
  434. ---------------------------------------------------------------------------*/
  435. STDMETHODIMP_(int)
  436. CDhcpMScope::CompareItems
  437. (
  438. ITFSComponent * pComponent,
  439. MMC_COOKIE cookieA,
  440. MMC_COOKIE cookieB,
  441. int nCol
  442. )
  443. {
  444. SPITFSNode spNode1, spNode2;
  445. m_spNodeMgr->FindNode(cookieA, &spNode1);
  446. m_spNodeMgr->FindNode(cookieB, &spNode2);
  447. int nCompare = 0;
  448. return nCompare;
  449. }
  450. /*!--------------------------------------------------------------------------
  451. CDhcpServer::OnDelete
  452. The base handler calls this when MMC sends a MMCN_DELETE for a
  453. scope pane item. We just call our delete command handler.
  454. Author: EricDav
  455. ---------------------------------------------------------------------------*/
  456. HRESULT
  457. CDhcpMScope::OnDelete
  458. (
  459. ITFSNode * pNode,
  460. LPARAM arg,
  461. LPARAM lParam
  462. )
  463. {
  464. return OnDelete(pNode);
  465. }
  466. /*---------------------------------------------------------------------------
  467. CDhcpMScope::OnResultDelete
  468. This function is called when we are supposed to delete result
  469. pane items. We build a list of selected items and then delete them.
  470. Author: EricDav
  471. ---------------------------------------------------------------------------*/
  472. HRESULT
  473. CDhcpMScope::OnResultDelete
  474. (
  475. ITFSComponent * pComponent,
  476. LPDATAOBJECT pDataObject,
  477. MMC_COOKIE cookie,
  478. LPARAM arg,
  479. LPARAM param
  480. )
  481. {
  482. HRESULT hr = hrOK;
  483. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  484. return hr;
  485. }
  486. /*!--------------------------------------------------------------------------
  487. CDhcpMScope::OnGetResultViewType
  488. MMC calls this to get the result view information
  489. Author: EricDav
  490. ---------------------------------------------------------------------------*/
  491. HRESULT
  492. CDhcpMScope::OnGetResultViewType
  493. (
  494. ITFSComponent * pComponent,
  495. MMC_COOKIE cookie,
  496. LPOLESTR * ppViewType,
  497. long * pViewOptions
  498. )
  499. {
  500. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  501. // we still want the default MMC result pane view, we just want
  502. // multiselect, so return S_FALSE
  503. return S_FALSE;
  504. }
  505. /*!--------------------------------------------------------------------------
  506. CDhcpMScope::OnUpdateToolbarButtons
  507. We override this function to show/hide the correct
  508. activate/deactivate buttons
  509. Author: EricDav
  510. ---------------------------------------------------------------------------*/
  511. HRESULT
  512. CDhcpMScope::OnUpdateToolbarButtons
  513. (
  514. ITFSNode * pNode,
  515. LPDHCPTOOLBARNOTIFY pToolbarNotify
  516. )
  517. {
  518. HRESULT hr = hrOK;
  519. if (pToolbarNotify->bSelect)
  520. {
  521. UpdateToolbarStates();
  522. }
  523. CMTDhcpHandler::OnUpdateToolbarButtons(pNode, pToolbarNotify);
  524. return hr;
  525. }
  526. /*!--------------------------------------------------------------------------
  527. CDhcpMScope::UpdateToolbarStates
  528. Description
  529. Author: EricDav
  530. ---------------------------------------------------------------------------*/
  531. void
  532. CDhcpMScope::UpdateToolbarStates()
  533. {
  534. if (m_SubnetInfo.SubnetState == DhcpSubnetDisabled)
  535. {
  536. g_SnapinButtonStates[DHCPSNAP_MSCOPE][TOOLBAR_IDX_ACTIVATE] = ENABLED;
  537. g_SnapinButtonStates[DHCPSNAP_MSCOPE][TOOLBAR_IDX_DEACTIVATE] = HIDDEN;
  538. }
  539. else
  540. {
  541. g_SnapinButtonStates[DHCPSNAP_MSCOPE][TOOLBAR_IDX_ACTIVATE] = HIDDEN;
  542. g_SnapinButtonStates[DHCPSNAP_MSCOPE][TOOLBAR_IDX_DEACTIVATE] = ENABLED;
  543. }
  544. }
  545. /*---------------------------------------------------------------------------
  546. Command Handlers
  547. ---------------------------------------------------------------------------*/
  548. /*---------------------------------------------------------------------------
  549. CDhcpmScope::OnActivateScope
  550. Message handler for the scope activate/deactivate menu
  551. Author: EricDav
  552. ---------------------------------------------------------------------------*/
  553. DWORD
  554. CDhcpMScope::OnActivateScope
  555. (
  556. ITFSNode * pNode
  557. )
  558. {
  559. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  560. DWORD err = 0;
  561. int nOpenImage, nClosedImage;
  562. DHCP_SUBNET_STATE dhcpOldState = m_SubnetInfo.SubnetState;
  563. if (m_SubnetInfo.SubnetState == DhcpSubnetEnabled)
  564. {
  565. // if they want to disable the scope, confirm
  566. if (AfxMessageBox(IDS_SCOPE_DISABLE_CONFIRM, MB_YESNO) != IDYES)
  567. {
  568. return err;
  569. }
  570. }
  571. m_SubnetInfo.SubnetState = (m_SubnetInfo.SubnetState == DhcpSubnetDisabled) ?
  572. DhcpSubnetEnabled : DhcpSubnetDisabled;
  573. // Tell the scope to update it's state
  574. err = SetInfo();
  575. if (err != 0)
  576. {
  577. ::DhcpMessageBox(err);
  578. m_SubnetInfo.SubnetState = dhcpOldState;
  579. }
  580. else
  581. {
  582. // update the icon and the status text
  583. if (m_SubnetInfo.SubnetState == DhcpSubnetDisabled)
  584. {
  585. nOpenImage = ICON_IDX_SCOPE_INACTIVE_FOLDER_OPEN;
  586. nClosedImage = ICON_IDX_SCOPE_INACTIVE_FOLDER_CLOSED;
  587. m_strState.LoadString(IDS_SCOPE_INACTIVE);
  588. }
  589. else
  590. {
  591. nOpenImage = GetImageIndex(TRUE);
  592. nClosedImage = GetImageIndex(FALSE);
  593. m_strState.LoadString(IDS_SCOPE_ACTIVE);
  594. }
  595. pNode->SetData(TFS_DATA_IMAGEINDEX, nClosedImage);
  596. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, nOpenImage);
  597. VERIFY(SUCCEEDED(pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM)));
  598. // Update the toolbar button
  599. UpdateToolbarStates();
  600. SendUpdateToolbar(pNode, TRUE);
  601. }
  602. return err;
  603. }
  604. /*---------------------------------------------------------------------------
  605. CDhcpMScope::OnReconcileScope
  606. Reconciles the active leases database for this scope
  607. Author: EricDav
  608. ---------------------------------------------------------------------------*/
  609. HRESULT
  610. CDhcpMScope::OnReconcileScope
  611. (
  612. ITFSNode * pNode
  613. )
  614. {
  615. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  616. CReconcileDlg dlgRecon(pNode);
  617. dlgRecon.m_bMulticast = TRUE;
  618. dlgRecon.DoModal();
  619. return hrOK;
  620. }
  621. /*---------------------------------------------------------------------------
  622. CDhcpMScope::OnShowScopeStats()
  623. Description
  624. Author: EricDav
  625. ---------------------------------------------------------------------------*/
  626. HRESULT
  627. CDhcpMScope::OnShowScopeStats
  628. (
  629. ITFSNode * pNode
  630. )
  631. {
  632. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  633. HRESULT hr = S_OK;
  634. CString strScopeAddress;
  635. // Fill in some information in the stats object.
  636. // CreateNewStatisticsWindow handles the case if the window is
  637. // already visible.
  638. m_dlgStats.SetNode(pNode);
  639. m_dlgStats.SetServer(GetServerIpAddress());
  640. m_dlgStats.SetScopeId(GetScopeId());
  641. m_dlgStats.SetName(GetName());
  642. CreateNewStatisticsWindow(&m_dlgStats,
  643. ::FindMMCMainWindow(),
  644. IDD_STATS_NARROW);
  645. return hr;
  646. }
  647. /*---------------------------------------------------------------------------
  648. CDhcpMScope::OnDelete()
  649. Description
  650. Author: EricDav
  651. ---------------------------------------------------------------------------*/
  652. HRESULT
  653. CDhcpMScope::OnDelete(ITFSNode * pNode)
  654. {
  655. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  656. HRESULT hr = S_OK;
  657. SPITFSNode spParent;
  658. BOOL fAbortDelete = FALSE;
  659. BOOL fDeactivated = FALSE;
  660. LONG err = 0 ;
  661. if (::DhcpMessageBox( IsEnabled() ?
  662. IDS_MSG_DELETE_ACTIVE : IDS_MSG_DELETE_SCOPE,
  663. MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION) == IDYES)
  664. {
  665. pNode->GetParent(&spParent);
  666. CDhcpServer * pServer = GETHANDLER(CDhcpServer, spParent);
  667. err = pServer->DeleteMScope(pNode);
  668. }
  669. return hr;
  670. }
  671. /*---------------------------------------------------------------------------
  672. Background thread functionality
  673. ---------------------------------------------------------------------------*/
  674. /*---------------------------------------------------------------------------
  675. CDhcpMScope:OnHaveData
  676. Description
  677. Author: EricDav
  678. ---------------------------------------------------------------------------*/
  679. void
  680. CDhcpMScope::OnHaveData
  681. (
  682. ITFSNode * pParentNode,
  683. ITFSNode * pNewNode
  684. )
  685. {
  686. LPARAM dwType = pNewNode->GetData(TFS_DATA_TYPE);
  687. UpdateToolbarStates();
  688. switch (dwType)
  689. {
  690. case DHCPSNAP_MSCOPE_LEASES:
  691. pParentNode->AddChild(pNewNode);
  692. m_spActiveLeases.Set(pNewNode);
  693. break;
  694. case DHCPSNAP_ADDRESS_POOL:
  695. pParentNode->AddChild(pNewNode);
  696. m_spAddressPool.Set(pNewNode);
  697. break;
  698. }
  699. // now tell the view to update themselves
  700. ExpandNode(pParentNode, TRUE);
  701. }
  702. /*---------------------------------------------------------------------------
  703. CDhcpMScope::OnHaveData
  704. Description
  705. Author: EricDav
  706. ---------------------------------------------------------------------------*/
  707. void
  708. CDhcpMScope::OnHaveData
  709. (
  710. ITFSNode * pParentNode,
  711. LPARAM Data,
  712. LPARAM Type
  713. )
  714. {
  715. // This is how we get non-node data back from the background thread.
  716. if (Type == DHCP_QDATA_SUBNET_INFO)
  717. {
  718. LONG_PTR changeMask = 0;
  719. LPDHCP_MSCOPE_INFO pdhcpSubnetInfo = reinterpret_cast<LPDHCP_MSCOPE_INFO>(Data);
  720. // update the scope name and state based on the info
  721. if (pdhcpSubnetInfo->MScopeName &&
  722. m_SubnetInfo.SubnetName.CompareNoCase(pdhcpSubnetInfo->MScopeName) != 0)
  723. {
  724. SetName(pdhcpSubnetInfo->MScopeName);
  725. changeMask = SCOPE_PANE_CHANGE_ITEM;
  726. }
  727. // update the comment
  728. if (m_SubnetInfo.SubnetComment.CompareNoCase(pdhcpSubnetInfo->MScopeComment) != 0)
  729. {
  730. SetComment(pdhcpSubnetInfo->MScopeComment);
  731. }
  732. if (m_SubnetInfo.SubnetState != pdhcpSubnetInfo->MScopeState)
  733. {
  734. DHCP_SUBNET_STATE dhcpOldState = m_SubnetInfo.SubnetState;
  735. m_SubnetInfo.SubnetState = pdhcpSubnetInfo->MScopeState;
  736. pParentNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
  737. pParentNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
  738. // Update the toolbar button
  739. UpdateToolbarStates();
  740. SendUpdateToolbar(pParentNode, TRUE);
  741. changeMask = SCOPE_PANE_CHANGE_ITEM;
  742. }
  743. // Update our internal struct
  744. m_SubnetInfo.Set(pdhcpSubnetInfo);
  745. if (pdhcpSubnetInfo)
  746. ::DhcpRpcFreeMemory(pdhcpSubnetInfo);
  747. if (changeMask)
  748. VERIFY(SUCCEEDED(pParentNode->ChangeNode(changeMask)));
  749. }
  750. }
  751. /*---------------------------------------------------------------------------
  752. CDhcpMScope::OnCreateQuery()
  753. Description
  754. Author: EricDav
  755. ---------------------------------------------------------------------------*/
  756. ITFSQueryObject*
  757. CDhcpMScope::OnCreateQuery(ITFSNode * pNode)
  758. {
  759. CDhcpMScopeQueryObj* pQuery = new CDhcpMScopeQueryObj(m_spTFSCompData, m_spNodeMgr);
  760. if ( pQuery == NULL )
  761. return pQuery;
  762. pQuery->m_strServer = GetServerObject(pNode)->GetIpAddress();
  763. pQuery->m_strName = GetName();
  764. return pQuery;
  765. }
  766. /*---------------------------------------------------------------------------
  767. CDhcpMScopeQueryObj::Execute()
  768. Description
  769. Author: EricDav
  770. ---------------------------------------------------------------------------*/
  771. STDMETHODIMP
  772. CDhcpMScopeQueryObj::Execute()
  773. {
  774. HRESULT hr = hrOK;
  775. DWORD dwReturn;
  776. LPDHCP_MSCOPE_INFO pMScopeInfo = NULL;
  777. dwReturn = ::DhcpGetMScopeInfo(((LPWSTR) (LPCTSTR)m_strServer),
  778. ((LPWSTR) (LPCTSTR)m_strName),
  779. &pMScopeInfo);
  780. if (dwReturn == ERROR_SUCCESS && pMScopeInfo)
  781. {
  782. AddToQueue((LPARAM) pMScopeInfo, DHCP_QDATA_SUBNET_INFO);
  783. }
  784. else
  785. {
  786. Trace1("CDhcpMScopeQueryObj::Execute - DhcpGetMScopeInfo failed! %d\n", dwReturn);
  787. PostError(dwReturn);
  788. return hrFalse;
  789. }
  790. CreateSubcontainers();
  791. return hrFalse;
  792. }
  793. /*---------------------------------------------------------------------------
  794. CDhcpMScope::CreateSubcontainers()
  795. Description
  796. Author: EricDav
  797. ---------------------------------------------------------------------------*/
  798. HRESULT
  799. CDhcpMScopeQueryObj::CreateSubcontainers()
  800. {
  801. HRESULT hr = hrOK;
  802. SPITFSNode spNode;
  803. //
  804. // create the address pool Handler
  805. //
  806. CMScopeAddressPool *pAddressPool = new CMScopeAddressPool(m_spTFSCompData);
  807. CreateContainerTFSNode(&spNode,
  808. &GUID_DhcpMCastAddressPoolNodeType,
  809. pAddressPool,
  810. pAddressPool,
  811. m_spNodeMgr);
  812. // Tell the handler to initialize any specific data
  813. pAddressPool->InitializeNode((ITFSNode *) spNode);
  814. // Add the node as a child to this node
  815. AddToQueue(spNode);
  816. pAddressPool->Release();
  817. spNode.Set(NULL);
  818. //
  819. // create the Active Leases Handler
  820. //
  821. CMScopeActiveLeases *pActiveLeases = new CMScopeActiveLeases(m_spTFSCompData);
  822. CreateContainerTFSNode(&spNode,
  823. &GUID_DhcpMCastActiveLeasesNodeType,
  824. pActiveLeases,
  825. pActiveLeases,
  826. m_spNodeMgr);
  827. // Tell the handler to initialize any specific data
  828. pActiveLeases->InitializeNode((ITFSNode *) spNode);
  829. // Add the node as a child to this node
  830. AddToQueue(spNode);
  831. pActiveLeases->Release();
  832. return hr;
  833. }
  834. /*---------------------------------------------------------------------------
  835. Helper functions
  836. ---------------------------------------------------------------------------*/
  837. HRESULT
  838. CDhcpMScope::BuildDisplayName
  839. (
  840. CString * pstrDisplayName,
  841. LPCTSTR pName
  842. )
  843. {
  844. if (pstrDisplayName)
  845. {
  846. CString strStandard, strName;
  847. strName = pName;
  848. strStandard.LoadString(IDS_MSCOPE_FOLDER);
  849. *pstrDisplayName = strStandard + _T(" [") + strName + _T("] ");
  850. }
  851. return hrOK;
  852. }
  853. HRESULT
  854. CDhcpMScope::SetName
  855. (
  856. LPCWSTR pName
  857. )
  858. {
  859. if (pName != NULL)
  860. {
  861. m_SubnetInfo.SubnetName = pName;
  862. }
  863. CString strDisplayName;
  864. //
  865. // Create the display name for this scope
  866. // Convert DHCP_IP_ADDRES to a string and initialize this object
  867. //
  868. BuildDisplayName(&strDisplayName, pName);
  869. SetDisplayName(strDisplayName);
  870. return hrOK;
  871. }
  872. /*---------------------------------------------------------------------------
  873. CDhcpMScope::GetServerIpAddress()
  874. Description
  875. Author: EricDav
  876. ---------------------------------------------------------------------------*/
  877. LPCWSTR
  878. CDhcpMScope::GetServerIpAddress()
  879. {
  880. CDhcpServer * pServer = GetServerObject();
  881. return pServer->GetIpAddress();
  882. }
  883. /*---------------------------------------------------------------------------
  884. CDhcpMScope::GetServerIpAddress
  885. Description
  886. Author: EricDav
  887. ---------------------------------------------------------------------------*/
  888. void
  889. CDhcpMScope::GetServerIpAddress(DHCP_IP_ADDRESS * pdhcpIpAddress)
  890. {
  891. CDhcpServer * pServer = GetServerObject();
  892. pServer->GetIpAddress(pdhcpIpAddress);
  893. }
  894. /*---------------------------------------------------------------------------
  895. CDhcpMScope::GetServerVersion
  896. Description
  897. Author: EricDav
  898. ---------------------------------------------------------------------------*/
  899. void
  900. CDhcpMScope::GetServerVersion
  901. (
  902. LARGE_INTEGER& liVersion
  903. )
  904. {
  905. CDhcpServer * pServer = GetServerObject();
  906. pServer->GetVersion(liVersion);
  907. }
  908. /*---------------------------------------------------------------------------
  909. CDhcpMScope::InitMScopeInfo()
  910. Updates the scope's information
  911. Author: EricDav
  912. ---------------------------------------------------------------------------*/
  913. HRESULT
  914. CDhcpMScope::InitMScopeInfo
  915. (
  916. LPDHCP_MSCOPE_INFO pMScopeInfo
  917. )
  918. {
  919. HRESULT hr = hrOK;
  920. m_SubnetInfo.Set(pMScopeInfo);
  921. return hr;
  922. }
  923. /*---------------------------------------------------------------------------
  924. CDhcpMScope::InitMScopeInfo()
  925. Updates the scope's information
  926. Author: EricDav
  927. ---------------------------------------------------------------------------*/
  928. HRESULT
  929. CDhcpMScope::InitMScopeInfo
  930. (
  931. CSubnetInfo & subnetInfo
  932. )
  933. {
  934. HRESULT hr = hrOK;
  935. m_SubnetInfo = subnetInfo;
  936. return hr;
  937. }
  938. /*---------------------------------------------------------------------------
  939. CDhcpMScope::SetInfo()
  940. Updates the scope's information
  941. Author: EricDav
  942. ---------------------------------------------------------------------------*/
  943. DWORD
  944. CDhcpMScope::SetInfo
  945. (
  946. LPCTSTR pNewName
  947. )
  948. {
  949. DWORD err = ERROR_SUCCESS;
  950. DHCP_MSCOPE_INFO dhcpMScopeInfo = {0};
  951. dhcpMScopeInfo.MScopeName = (pNewName) ? (LPWSTR) pNewName : (LPTSTR) ((LPCTSTR) m_SubnetInfo.SubnetName);
  952. dhcpMScopeInfo.MScopeComment = (LPTSTR) ((LPCTSTR) m_SubnetInfo.SubnetComment);
  953. dhcpMScopeInfo.MScopeId = m_SubnetInfo.SubnetAddress;
  954. dhcpMScopeInfo.MScopeAddressPolicy = m_SubnetInfo.MScopeAddressPolicy;
  955. dhcpMScopeInfo.MScopeState = m_SubnetInfo.SubnetState;
  956. dhcpMScopeInfo.MScopeFlags = 0;
  957. dhcpMScopeInfo.ExpiryTime = m_SubnetInfo.ExpiryTime;
  958. dhcpMScopeInfo.TTL = m_SubnetInfo.TTL;
  959. // gotta fill in the language ID based on the name
  960. GetLangTag(m_SubnetInfo.LangTag);
  961. dhcpMScopeInfo.LangTag = (LPWSTR) ((LPCTSTR) m_SubnetInfo.LangTag);
  962. GetServerIpAddress(&dhcpMScopeInfo.PrimaryHost.IpAddress);
  963. // Review : ericdav - do we need to fill these in?
  964. dhcpMScopeInfo.PrimaryHost.NetBiosName = NULL;
  965. dhcpMScopeInfo.PrimaryHost.HostName = NULL;
  966. err = ::DhcpSetMScopeInfo(GetServerIpAddress(),
  967. (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName),
  968. &dhcpMScopeInfo,
  969. FALSE);
  970. // update the scope name if we are changing the name
  971. if (err == ERROR_SUCCESS &&
  972. pNewName)
  973. {
  974. m_SubnetInfo.SubnetName = pNewName;
  975. }
  976. return err;
  977. }
  978. /*---------------------------------------------------------------------------
  979. CDhcpMScope::GetLeaseTime
  980. Gets the lease time for this scope
  981. Author: EricDav
  982. ---------------------------------------------------------------------------*/
  983. DWORD
  984. CDhcpMScope::GetLeaseTime
  985. (
  986. LPDWORD pdwLeaseTime
  987. )
  988. {
  989. //
  990. // Check option -- the lease duration
  991. //
  992. DWORD dwLeaseTime = 0;
  993. DWORD err = ERROR_SUCCESS;
  994. DHCP_OPTION_VALUE * poptValue = NULL;
  995. err = GetOptionValue(MADCAP_OPTION_LEASE_TIME, &poptValue);
  996. if (err != ERROR_SUCCESS)
  997. {
  998. Trace1("CDhcpScope::GetLeaseTime - couldn't get lease duration!! %d \n", err);
  999. dwLeaseTime = 0;
  1000. }
  1001. else
  1002. {
  1003. if (poptValue->Value.Elements != NULL)
  1004. dwLeaseTime = poptValue->Value.Elements[0].Element.DWordOption;
  1005. if (poptValue)
  1006. ::DhcpRpcFreeMemory(poptValue);
  1007. }
  1008. *pdwLeaseTime = dwLeaseTime;
  1009. return err;
  1010. }
  1011. /*---------------------------------------------------------------------------
  1012. CDhcpMScope::SetLeaseTime
  1013. Sets the lease time for this scope
  1014. Author: EricDav
  1015. ---------------------------------------------------------------------------*/
  1016. DWORD
  1017. CDhcpMScope::SetLeaseTime
  1018. (
  1019. DWORD dwLeaseTime
  1020. )
  1021. {
  1022. DWORD err = 0;
  1023. //
  1024. // Set lease duration
  1025. //
  1026. CDhcpOption dhcpOption (MADCAP_OPTION_LEASE_TIME, DhcpDWordOption , _T(""), _T(""));
  1027. dhcpOption.QueryValue().SetNumber(dwLeaseTime);
  1028. err = SetOptionValue(&dhcpOption);
  1029. return err;
  1030. }
  1031. /*---------------------------------------------------------------------------
  1032. CDhcpMScope::GetLifetime
  1033. Gets the madcap scope lifetime
  1034. Author: EricDav
  1035. ---------------------------------------------------------------------------*/
  1036. DWORD
  1037. CDhcpMScope::GetLifetime
  1038. (
  1039. DATE_TIME * pdtLifetime
  1040. )
  1041. {
  1042. DWORD err = ERROR_SUCCESS;
  1043. if (pdtLifetime)
  1044. {
  1045. pdtLifetime->dwLowDateTime = m_SubnetInfo.ExpiryTime.dwLowDateTime;
  1046. pdtLifetime->dwHighDateTime = m_SubnetInfo.ExpiryTime.dwHighDateTime;
  1047. }
  1048. return err;
  1049. }
  1050. /*---------------------------------------------------------------------------
  1051. CDhcpMScope::SetLifetime
  1052. Sets the madcap scope lifetime
  1053. Author: EricDav
  1054. ---------------------------------------------------------------------------*/
  1055. DWORD
  1056. CDhcpMScope::SetLifetime
  1057. (
  1058. DATE_TIME * pdtLifetime
  1059. )
  1060. {
  1061. DWORD err = 0;
  1062. if (pdtLifetime)
  1063. {
  1064. m_SubnetInfo.ExpiryTime.dwLowDateTime = pdtLifetime->dwLowDateTime;
  1065. m_SubnetInfo.ExpiryTime.dwHighDateTime = pdtLifetime->dwHighDateTime;
  1066. }
  1067. return err;
  1068. }
  1069. /*---------------------------------------------------------------------------
  1070. CDhcpMScope::GetTTL
  1071. Gets the TTL for this multicast scope
  1072. Author: EricDav
  1073. ---------------------------------------------------------------------------*/
  1074. DWORD
  1075. CDhcpMScope::GetTTL
  1076. (
  1077. LPBYTE pbTTL
  1078. )
  1079. {
  1080. DWORD err = 0;
  1081. if (pbTTL)
  1082. *pbTTL = m_SubnetInfo.TTL;
  1083. return err;
  1084. }
  1085. /*---------------------------------------------------------------------------
  1086. CDhcpMScope::SetTTL
  1087. Sets the least time for this scope
  1088. Author: EricDav
  1089. ---------------------------------------------------------------------------*/
  1090. DWORD
  1091. CDhcpMScope::SetTTL
  1092. (
  1093. BYTE TTL
  1094. )
  1095. {
  1096. DWORD err = 0;
  1097. m_SubnetInfo.TTL = TTL;
  1098. return err;
  1099. }
  1100. /*---------------------------------------------------------------------------
  1101. CDhcpMScope::DeleteClient
  1102. Description
  1103. Author: EricDav
  1104. ---------------------------------------------------------------------------*/
  1105. DWORD
  1106. CDhcpMScope::DeleteClient
  1107. (
  1108. DHCP_IP_ADDRESS dhcpClientIpAddress
  1109. )
  1110. {
  1111. DWORD dwErr = ERROR_SUCCESS;
  1112. DHCP_SEARCH_INFO dhcpClientInfo;
  1113. dhcpClientInfo.SearchType = DhcpClientIpAddress;
  1114. dhcpClientInfo.SearchInfo.ClientIpAddress = dhcpClientIpAddress;
  1115. dwErr = ::DhcpDeleteMClientInfo((LPWSTR) GetServerIpAddress(),
  1116. &dhcpClientInfo);
  1117. return dwErr;
  1118. }
  1119. /*---------------------------------------------------------------------------
  1120. CDhcpMScope::SetOptionValue
  1121. Sets the least time for this scope
  1122. Author: EricDav
  1123. ---------------------------------------------------------------------------*/
  1124. DWORD
  1125. CDhcpMScope::SetOptionValue
  1126. (
  1127. CDhcpOption * pdhcType
  1128. )
  1129. {
  1130. DWORD err = 0;
  1131. DHCP_OPTION_DATA * pdhcOptionData;
  1132. DHCP_OPTION_SCOPE_INFO dhcScopeInfo;
  1133. CDhcpOptionValue * pcOptionValue = NULL;
  1134. ZeroMemory( & dhcScopeInfo, sizeof(dhcScopeInfo) );
  1135. CATCH_MEM_EXCEPTION
  1136. {
  1137. pcOptionValue = new CDhcpOptionValue( & pdhcType->QueryValue() ) ;
  1138. if ( pcOptionValue )
  1139. {
  1140. dhcScopeInfo.ScopeType = DhcpMScopeOptions;
  1141. dhcScopeInfo.ScopeInfo.MScopeInfo = (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName);
  1142. pcOptionValue->CreateOptionDataStruct(&pdhcOptionData, TRUE);
  1143. err = (DWORD) ::DhcpSetOptionValue(GetServerIpAddress(),
  1144. pdhcType->QueryId(),
  1145. &dhcScopeInfo,
  1146. pdhcOptionData);
  1147. }
  1148. delete pcOptionValue ;
  1149. }
  1150. END_MEM_EXCEPTION(err) ;
  1151. return err ;
  1152. }
  1153. /*---------------------------------------------------------------------------
  1154. CDhcpScope::GetOptionValue
  1155. Gets an option value for this scope
  1156. Author: EricDav
  1157. ---------------------------------------------------------------------------*/
  1158. DWORD
  1159. CDhcpMScope::GetOptionValue
  1160. (
  1161. DHCP_OPTION_ID OptionID,
  1162. DHCP_OPTION_VALUE ** ppdhcOptionValue
  1163. )
  1164. {
  1165. DWORD err = 0 ;
  1166. DHCP_OPTION_SCOPE_INFO dhcScopeInfo ;
  1167. ZeroMemory( &dhcScopeInfo, sizeof(dhcScopeInfo) );
  1168. CATCH_MEM_EXCEPTION
  1169. {
  1170. dhcScopeInfo.ScopeType = DhcpMScopeOptions;
  1171. dhcScopeInfo.ScopeInfo.MScopeInfo = (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName);
  1172. err = (DWORD) ::DhcpGetOptionValue(GetServerIpAddress(),
  1173. OptionID,
  1174. &dhcScopeInfo,
  1175. ppdhcOptionValue );
  1176. }
  1177. END_MEM_EXCEPTION(err) ;
  1178. return err ;
  1179. }
  1180. /*---------------------------------------------------------------------------
  1181. CDhcpMScope::RemoveValue
  1182. Removes an option
  1183. Author: EricDav
  1184. ---------------------------------------------------------------------------*/
  1185. DWORD
  1186. CDhcpMScope::RemoveOptionValue
  1187. (
  1188. DHCP_OPTION_ID dhcOptId
  1189. )
  1190. {
  1191. DWORD dwErr = ERROR_SUCCESS;
  1192. DHCP_OPTION_SCOPE_INFO dhcScopeInfo;
  1193. ZeroMemory( &dhcScopeInfo, sizeof(dhcScopeInfo) );
  1194. dhcScopeInfo.ScopeType = DhcpMScopeOptions;
  1195. dhcScopeInfo.ScopeInfo.MScopeInfo = (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName);
  1196. dwErr = ::DhcpRemoveOptionValue(GetServerIpAddress(),
  1197. dhcOptId,
  1198. &dhcScopeInfo);
  1199. return dwErr;
  1200. }
  1201. /*---------------------------------------------------------------------------
  1202. CDhcpMScope::AddElement
  1203. Description
  1204. Author: EricDav
  1205. ---------------------------------------------------------------------------*/
  1206. DWORD
  1207. CDhcpMScope::AddElement
  1208. (
  1209. LPDHCP_SUBNET_ELEMENT_DATA_V4 pdhcpSubnetElementData
  1210. )
  1211. {
  1212. DWORD dwErr = ERROR_SUCCESS;
  1213. dwErr = ::DhcpAddMScopeElement((LPWSTR) GetServerIpAddress(),
  1214. (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName),
  1215. pdhcpSubnetElementData);
  1216. return dwErr;
  1217. }
  1218. /*---------------------------------------------------------------------------
  1219. CDhcpMScope::RemoveElement
  1220. Description
  1221. Author: EricDav
  1222. ---------------------------------------------------------------------------*/
  1223. DWORD
  1224. CDhcpMScope::RemoveElement
  1225. (
  1226. LPDHCP_SUBNET_ELEMENT_DATA_V4 pdhcpSubnetElementData,
  1227. BOOL bForce
  1228. )
  1229. {
  1230. DWORD dwErr = ERROR_SUCCESS;
  1231. dwErr = ::DhcpRemoveMScopeElement((LPWSTR) GetServerIpAddress(),
  1232. (LPWSTR) ((LPCTSTR) m_SubnetInfo.SubnetName),
  1233. pdhcpSubnetElementData,
  1234. bForce ? DhcpFullForce : DhcpNoForce);
  1235. return dwErr;
  1236. }
  1237. /*---------------------------------------------------------------------------
  1238. CDhcpMScope::GetIpRange()
  1239. returns the scope's allocation range. Connects to the server
  1240. to get the information
  1241. Author: EricDav
  1242. ---------------------------------------------------------------------------*/
  1243. DWORD
  1244. CDhcpMScope::GetIpRange
  1245. (
  1246. DHCP_IP_RANGE * pdhipr
  1247. )
  1248. {
  1249. BOOL bAlloced = FALSE;
  1250. DWORD dwError = ERROR_SUCCESS;
  1251. pdhipr->StartAddress = 0;
  1252. pdhipr->EndAddress = 0;
  1253. CMScopeAddressPool * pAddressPool = GetAddressPoolObject();
  1254. if (pAddressPool == NULL)
  1255. {
  1256. // the address pool folder isn't there yet...
  1257. // Create a temporary one for now...
  1258. pAddressPool = new CMScopeAddressPool(m_spTFSCompData);
  1259. bAlloced = TRUE;
  1260. }
  1261. // Get a query object from the address pool handler
  1262. CMScopeAddressPoolQueryObj * pQueryObject =
  1263. reinterpret_cast<CMScopeAddressPoolQueryObj *>(pAddressPool->OnCreateQuery(m_spAddressPool));
  1264. // if we created an address pool handler, then free it up now
  1265. if (bAlloced)
  1266. {
  1267. pQueryObject->m_strServer = GetServerIpAddress();
  1268. pQueryObject->m_strName = GetName();
  1269. pAddressPool->Release();
  1270. }
  1271. // tell the query object to get the ip ranges
  1272. pQueryObject->EnumerateIpRanges();
  1273. // check to see if there was any problems getting the information
  1274. dwError = pQueryObject->m_dwError;
  1275. if (dwError != ERROR_SUCCESS)
  1276. {
  1277. return dwError;
  1278. }
  1279. LPQUEUEDATA pQD;
  1280. while (pQD = pQueryObject->RemoveFromQueue())
  1281. {
  1282. Assert (pQD->Type == QDATA_PNODE);
  1283. SPITFSNode p;
  1284. p = reinterpret_cast<ITFSNode *>(pQD->Data);
  1285. delete pQD;
  1286. CDhcpAllocationRange * pAllocRange = GETHANDLER(CDhcpAllocationRange, p);
  1287. pdhipr->StartAddress = pAllocRange->QueryAddr(TRUE);
  1288. pdhipr->EndAddress = pAllocRange->QueryAddr(FALSE);
  1289. p.Release();
  1290. }
  1291. pQueryObject->Release();
  1292. return dwError;
  1293. }
  1294. /*---------------------------------------------------------------------------
  1295. CDhcpMScope::UpdateIpRange()
  1296. This function updates the IP range on the server. We also need
  1297. to remove any exclusion ranges that fall outside of the new
  1298. allocation range.
  1299. Author: EricDav
  1300. ---------------------------------------------------------------------------*/
  1301. DWORD
  1302. CDhcpMScope::UpdateIpRange
  1303. (
  1304. DHCP_IP_RANGE * pdhipr
  1305. )
  1306. {
  1307. return SetIpRange(pdhipr, TRUE);
  1308. }
  1309. /*---------------------------------------------------------------------------
  1310. CDhcpMScope::QueryIpRange()
  1311. Returns the scope's allocation range (doesn't talk to the server
  1312. directly, only returns internally cached information).
  1313. Author: EricDav
  1314. ---------------------------------------------------------------------------*/
  1315. void
  1316. CDhcpMScope::QueryIpRange
  1317. (
  1318. DHCP_IP_RANGE * pdhipr
  1319. )
  1320. {
  1321. pdhipr->StartAddress = 0;
  1322. pdhipr->EndAddress = 0;
  1323. SPITFSNodeEnum spNodeEnum;
  1324. SPITFSNode spCurrentNode;
  1325. ULONG nNumReturned = 0;
  1326. m_spAddressPool->GetEnum(&spNodeEnum);
  1327. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1328. while (nNumReturned)
  1329. {
  1330. if (spCurrentNode->GetData(TFS_DATA_TYPE) == DHCPSNAP_ALLOCATION_RANGE)
  1331. {
  1332. // found the address
  1333. //
  1334. CDhcpAllocationRange * pAllocRange = GETHANDLER(CDhcpAllocationRange, spCurrentNode);
  1335. pdhipr->StartAddress = pAllocRange->QueryAddr(TRUE);
  1336. pdhipr->EndAddress = pAllocRange->QueryAddr(FALSE);
  1337. }
  1338. spCurrentNode.Release();
  1339. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1340. }
  1341. }
  1342. /*---------------------------------------------------------------------------
  1343. CDhcpMScope::SetIpRange
  1344. Set's the allocation range for this scope
  1345. Author: EricDav
  1346. ---------------------------------------------------------------------------*/
  1347. DWORD
  1348. CDhcpMScope::SetIpRange
  1349. (
  1350. DHCP_IP_RANGE * pdhcpIpRange,
  1351. BOOL bUpdateOnServer
  1352. )
  1353. {
  1354. CDhcpIpRange dhcpIpRange = *pdhcpIpRange;
  1355. return SetIpRange(dhcpIpRange, bUpdateOnServer);
  1356. }
  1357. /*---------------------------------------------------------------------------
  1358. CDhcpMScope::SetIpRange
  1359. Set's the allocation range for this scope
  1360. Author: EricDav
  1361. ---------------------------------------------------------------------------*/
  1362. DWORD
  1363. CDhcpMScope::SetIpRange
  1364. (
  1365. const CDhcpIpRange & dhcpIpRange,
  1366. BOOL bUpdateOnServer
  1367. )
  1368. {
  1369. DWORD err = 0;
  1370. if (bUpdateOnServer)
  1371. {
  1372. DHCP_SUBNET_ELEMENT_DATA_V4 dhcSubElData;
  1373. DHCP_IP_RANGE dhipOldRange;
  1374. err = GetIpRange(&dhipOldRange);
  1375. if (err != ERROR_SUCCESS)
  1376. {
  1377. return err;
  1378. }
  1379. dhcSubElData.ElementType = DhcpIpRanges;
  1380. dhcSubElData.Element.IpRange = &dhipOldRange;
  1381. //
  1382. // First update the information on the server
  1383. //
  1384. // Remove the old IP range; allow "not found" error in new scope.
  1385. //
  1386. (void)RemoveElement(&dhcSubElData);
  1387. //if ( err == 0 || err == ERROR_FILE_NOT_FOUND )
  1388. //{
  1389. DHCP_IP_RANGE dhcpNewIpRange = dhcpIpRange;
  1390. dhcSubElData.Element.IpRange = &dhcpNewIpRange;
  1391. if ( (err = AddElement( & dhcSubElData )) == 0 )
  1392. {
  1393. //m_ip_range = dhipr ;
  1394. }
  1395. else
  1396. {
  1397. Trace1("SetIpRange - AddElement failed %lx\n", err);
  1398. // something bad happened, try to put the old range back
  1399. dhcSubElData.Element.IpRange = &dhipOldRange;
  1400. if (AddElement(&dhcSubElData) != ERROR_SUCCESS)
  1401. {
  1402. Trace0("SetIpRange - cannot return ip range back to old state!!");
  1403. }
  1404. }
  1405. //}
  1406. }
  1407. //
  1408. // Find the address pool folder and update the UI object
  1409. //
  1410. SPITFSNodeEnum spNodeEnum;
  1411. SPITFSNode spCurrentNode;
  1412. ULONG nNumReturned = 0;
  1413. if (m_spAddressPool == NULL)
  1414. return err;
  1415. m_spAddressPool->GetEnum(&spNodeEnum);
  1416. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1417. while (nNumReturned)
  1418. {
  1419. if (spCurrentNode->GetData(TFS_DATA_TYPE) == DHCPSNAP_ALLOCATION_RANGE)
  1420. {
  1421. // found the address
  1422. //
  1423. CDhcpAllocationRange * pAllocRange = GETHANDLER(CDhcpAllocationRange, spCurrentNode);
  1424. // now set them
  1425. //
  1426. pAllocRange->SetAddr(dhcpIpRange.QueryAddr(TRUE), TRUE);
  1427. pAllocRange->SetAddr(dhcpIpRange.QueryAddr(FALSE), FALSE);
  1428. // tell the UI to update
  1429. spCurrentNode->ChangeNode(RESULT_PANE_CHANGE_ITEM_DATA);
  1430. }
  1431. spCurrentNode.Release();
  1432. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1433. }
  1434. return err ;
  1435. }
  1436. /*---------------------------------------------------------------------------
  1437. CDhcpMScope::IsOverlappingRange
  1438. determines if the exclusion overlaps an existing range
  1439. Author: EricDav
  1440. ---------------------------------------------------------------------------*/
  1441. BOOL
  1442. CDhcpMScope::IsOverlappingRange
  1443. (
  1444. CDhcpIpRange & dhcpIpRange
  1445. )
  1446. {
  1447. SPITFSNodeEnum spNodeEnum;
  1448. SPITFSNode spCurrentNode;
  1449. ULONG nNumReturned = 0;
  1450. BOOL bOverlap = FALSE;
  1451. m_spActiveLeases->GetEnum(&spNodeEnum);
  1452. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1453. while (nNumReturned)
  1454. {
  1455. if (spCurrentNode->GetData(TFS_DATA_TYPE) == DHCPSNAP_EXCLUSION_RANGE)
  1456. {
  1457. // found the address
  1458. //
  1459. CDhcpExclusionRange * pExclusion = GETHANDLER(CDhcpExclusionRange, spCurrentNode);
  1460. if ( bOverlap = pExclusion->IsOverlap( dhcpIpRange ) )
  1461. {
  1462. spCurrentNode.Release();
  1463. break;
  1464. }
  1465. }
  1466. spCurrentNode.Release();
  1467. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1468. }
  1469. return bOverlap ;
  1470. }
  1471. /*---------------------------------------------------------------------------
  1472. CDhcpMScope::IsValidExclusion
  1473. determines if the exclusion is valid for this scope
  1474. Author: EricDav
  1475. ---------------------------------------------------------------------------*/
  1476. DWORD
  1477. CDhcpMScope::IsValidExclusion
  1478. (
  1479. CDhcpIpRange & dhcpExclusionRange
  1480. )
  1481. {
  1482. DWORD err = 0;
  1483. DHCP_IP_RANGE dhcpIpRange;
  1484. err = GetIpRange (&dhcpIpRange);
  1485. CDhcpIpRange dhcpScopeRange(dhcpIpRange);
  1486. //
  1487. // Get the data into a range object.
  1488. //
  1489. if ( IsOverlappingRange( dhcpExclusionRange ) )
  1490. {
  1491. //
  1492. // Walk the current list, determining if the new range is valid.
  1493. // Then, if OK, verify that it's really a sub-range of the current range.
  1494. //
  1495. err = IDS_ERR_IP_RANGE_OVERLAP ;
  1496. }
  1497. else if ( ! dhcpExclusionRange.IsSubset( dhcpScopeRange ) )
  1498. {
  1499. //
  1500. // Guarantee that the new range is an (improper) subset of the scope's range
  1501. //
  1502. err = IDS_ERR_IP_RANGE_NOT_SUBSET ;
  1503. }
  1504. return err;
  1505. }
  1506. /*---------------------------------------------------------------------------
  1507. CDhcpMScope::StoreExceptionList
  1508. Adds a bunch of exclusions to the scope
  1509. Author: EricDav
  1510. ---------------------------------------------------------------------------*/
  1511. DWORD
  1512. CDhcpMScope::StoreExceptionList
  1513. (
  1514. CExclusionList * plistExclusions
  1515. )
  1516. {
  1517. DHCP_SUBNET_ELEMENT_DATA dhcElement ;
  1518. DHCP_IP_RANGE dhipr ;
  1519. CDhcpIpRange * pobIpRange ;
  1520. DWORD err = 0, err1 = 0;
  1521. POSITION pos;
  1522. pos = plistExclusions->GetHeadPosition();
  1523. while ( pos )
  1524. {
  1525. pobIpRange = plistExclusions->GetNext(pos);
  1526. err1 = AddExclusion( *pobIpRange ) ;
  1527. if ( err1 != 0 )
  1528. {
  1529. err = err1;
  1530. Trace1("CDhcpScope::StoreExceptionList error adding range %d\n", err);
  1531. }
  1532. }
  1533. return err ;
  1534. }
  1535. /*---------------------------------------------------------------------------
  1536. CDhcpMScope::AddExclusion
  1537. Adds an individual exclusion to the server
  1538. Author: EricDav
  1539. ---------------------------------------------------------------------------*/
  1540. DWORD
  1541. CDhcpMScope::AddExclusion
  1542. (
  1543. CDhcpIpRange & dhcpIpRange,
  1544. BOOL bAddToUI
  1545. )
  1546. {
  1547. DHCP_SUBNET_ELEMENT_DATA_V4 dhcElement ;
  1548. DHCP_IP_RANGE dhipr ;
  1549. DWORD err = 0;
  1550. dhcElement.ElementType = DhcpExcludedIpRanges ;
  1551. dhipr = dhcpIpRange ;
  1552. dhcElement.Element.ExcludeIpRange = & dhipr ;
  1553. Trace2("CDhcpMScope::AddExclusion add excluded range %lx %lx\n", dhipr.StartAddress, dhipr.EndAddress );
  1554. err = AddElement( & dhcElement ) ;
  1555. //if ( err != 0 && err != ERROR_DHCP_INVALID_RANGE)
  1556. if ( err != 0 )
  1557. {
  1558. Trace1("CDhcpMScope::AddExclusion error removing range %d\n", err);
  1559. }
  1560. if (m_spAddressPool != NULL)
  1561. {
  1562. CMScopeAddressPool * pAddrPool = GETHANDLER(CMScopeAddressPool, m_spAddressPool);
  1563. if (!err && bAddToUI && pAddrPool->m_bExpanded)
  1564. {
  1565. SPITFSNode spNewExclusion;
  1566. CDhcpExclusionRange * pExclusion =
  1567. new CDhcpExclusionRange(m_spTFSCompData, &((DHCP_IP_RANGE) dhcpIpRange));
  1568. CreateLeafTFSNode(&spNewExclusion,
  1569. &GUID_DhcpExclusionNodeType,
  1570. pExclusion,
  1571. pExclusion,
  1572. m_spNodeMgr);
  1573. // Tell the handler to initialize any specific data
  1574. pExclusion->InitializeNode((ITFSNode *) spNewExclusion);
  1575. // Add the node as a child to this node
  1576. m_spAddressPool->AddChild(spNewExclusion);
  1577. pExclusion->Release();
  1578. }
  1579. }
  1580. return err;
  1581. }
  1582. /*---------------------------------------------------------------------------
  1583. CDhcpMScope::RemoveExclusion
  1584. Removes and exclusion from the server
  1585. Author: EricDav
  1586. ---------------------------------------------------------------------------*/
  1587. DWORD
  1588. CDhcpMScope::RemoveExclusion
  1589. (
  1590. CDhcpIpRange & dhcpIpRange
  1591. )
  1592. {
  1593. DHCP_SUBNET_ELEMENT_DATA_V4 dhcElement ;
  1594. DHCP_IP_RANGE dhipr ;
  1595. DWORD err = 0;
  1596. dhcElement.ElementType = DhcpExcludedIpRanges ;
  1597. dhipr = dhcpIpRange ;
  1598. dhcElement.Element.ExcludeIpRange = & dhipr ;
  1599. Trace2("CDhcpMScope::RemoveExclusion remove excluded range %lx %lx\n", dhipr.StartAddress, dhipr.EndAddress);
  1600. err = RemoveElement( & dhcElement ) ;
  1601. //if ( err != 0 && err != ERROR_DHCP_INVALID_RANGE)
  1602. if ( err != 0 )
  1603. {
  1604. Trace1("CDhcpMScope::RemoveExclusion error removing range %d\n", err);
  1605. }
  1606. return err;
  1607. }
  1608. /////////////////////////////////////////////////////////////////////
  1609. //
  1610. // CMScopeActiveLeases implementation
  1611. //
  1612. /////////////////////////////////////////////////////////////////////
  1613. /*---------------------------------------------------------------------------
  1614. Function Name Here
  1615. Description
  1616. Author: EricDav
  1617. ---------------------------------------------------------------------------*/
  1618. CMScopeActiveLeases::CMScopeActiveLeases
  1619. (
  1620. ITFSComponentData * pComponentData
  1621. ) : CMTDhcpHandler(pComponentData)
  1622. {
  1623. }
  1624. CMScopeActiveLeases::~CMScopeActiveLeases()
  1625. {
  1626. }
  1627. /*!--------------------------------------------------------------------------
  1628. CMScopeActiveLeases::InitializeNode
  1629. Initializes node specific data
  1630. Author: EricDav
  1631. ---------------------------------------------------------------------------*/
  1632. HRESULT
  1633. CMScopeActiveLeases::InitializeNode
  1634. (
  1635. ITFSNode * pNode
  1636. )
  1637. {
  1638. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1639. HRESULT hr = hrOK;
  1640. //
  1641. // Create the display name for this scope
  1642. //
  1643. CString strTemp;
  1644. strTemp.LoadString(IDS_ACTIVE_LEASES_FOLDER);
  1645. SetDisplayName(strTemp);
  1646. // Make the node immediately visible
  1647. pNode->SetVisibilityState(TFS_VIS_SHOW);
  1648. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED);
  1649. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN);
  1650. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  1651. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  1652. pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_MSCOPE_LEASES);
  1653. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  1654. SetColumnStringIDs(&aColumns[DHCPSNAP_MSCOPE_LEASES][0]);
  1655. SetColumnWidths(&aColumnWidths[DHCPSNAP_MSCOPE_LEASES][0]);
  1656. return hr;
  1657. }
  1658. /*---------------------------------------------------------------------------
  1659. CMScopeActiveLeases::OnCreateNodeId2
  1660. Returns a unique string for this node
  1661. Author: EricDav
  1662. ---------------------------------------------------------------------------*/
  1663. HRESULT CMScopeActiveLeases::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  1664. {
  1665. const GUID * pGuid = pNode->GetNodeType();
  1666. CString strNode, strGuid;
  1667. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  1668. strGuid.ReleaseBuffer();
  1669. // id string is server name, scope name and guid.
  1670. strNode = GetServerName(pNode);
  1671. strNode += GetScopeObject(pNode)->GetName() + strGuid;
  1672. strId = strNode;
  1673. return hrOK;
  1674. }
  1675. /*---------------------------------------------------------------------------
  1676. CMScopeActiveLeases::GetImageIndex
  1677. Description
  1678. Author: EricDav
  1679. ---------------------------------------------------------------------------*/
  1680. int
  1681. CMScopeActiveLeases::GetImageIndex(BOOL bOpenImage)
  1682. {
  1683. int nIndex = -1;
  1684. switch (m_nState)
  1685. {
  1686. case notLoaded:
  1687. case loaded:
  1688. if (bOpenImage)
  1689. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN;
  1690. else
  1691. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED;
  1692. break;
  1693. case loading:
  1694. if (bOpenImage)
  1695. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_BUSY;
  1696. else
  1697. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_BUSY;
  1698. break;
  1699. case unableToLoad:
  1700. if (bOpenImage)
  1701. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_OPEN_LOST_CONNECTION;
  1702. else
  1703. nIndex = ICON_IDX_ACTIVE_LEASES_FOLDER_CLOSED_LOST_CONNECTION;
  1704. break;
  1705. default:
  1706. ASSERT(FALSE);
  1707. }
  1708. return nIndex;
  1709. }
  1710. /*---------------------------------------------------------------------------
  1711. Overridden base handler functions
  1712. ---------------------------------------------------------------------------*/
  1713. /*---------------------------------------------------------------------------
  1714. CMScopeActiveLeases::OnAddMenuItems
  1715. Adds entries to the context sensitive menu
  1716. Author: EricDav
  1717. ---------------------------------------------------------------------------*/
  1718. STDMETHODIMP
  1719. CMScopeActiveLeases::OnAddMenuItems
  1720. (
  1721. ITFSNode * pNode,
  1722. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  1723. LPDATAOBJECT lpDataObject,
  1724. DATA_OBJECT_TYPES type,
  1725. DWORD dwType,
  1726. long * pInsertionAllowed
  1727. )
  1728. {
  1729. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1730. LONG fFlags = 0;
  1731. HRESULT hr = S_OK;
  1732. CString strMenuText;
  1733. if ( (m_nState != loaded) )
  1734. {
  1735. fFlags |= MF_GRAYED;
  1736. }
  1737. if (type == CCT_SCOPE)
  1738. {
  1739. }
  1740. return hr;
  1741. }
  1742. /*---------------------------------------------------------------------------
  1743. CMScopeActiveLeases::OnCommand
  1744. Description
  1745. Author: EricDav
  1746. ---------------------------------------------------------------------------*/
  1747. STDMETHODIMP
  1748. CMScopeActiveLeases::OnCommand
  1749. (
  1750. ITFSNode * pNode,
  1751. long nCommandId,
  1752. DATA_OBJECT_TYPES type,
  1753. LPDATAOBJECT pDataObject,
  1754. DWORD dwType
  1755. )
  1756. {
  1757. HRESULT hr = S_OK;
  1758. switch (nCommandId)
  1759. {
  1760. case IDS_REFRESH:
  1761. OnRefresh(pNode, pDataObject, dwType, 0, 0);
  1762. break;
  1763. default:
  1764. break;
  1765. }
  1766. return hr;
  1767. }
  1768. /*---------------------------------------------------------------------------
  1769. CMScopeActiveLeases::OnResultDelete
  1770. This function is called when we are supposed to delete result
  1771. pane items. We build a list of selected items and then delete them.
  1772. Author: EricDav
  1773. ---------------------------------------------------------------------------*/
  1774. HRESULT
  1775. CMScopeActiveLeases::OnResultDelete
  1776. (
  1777. ITFSComponent * pComponent,
  1778. LPDATAOBJECT pDataObject,
  1779. MMC_COOKIE cookie,
  1780. LPARAM arg,
  1781. LPARAM param
  1782. )
  1783. {
  1784. HRESULT hr = hrOK;
  1785. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1786. // translate the cookie into a node pointer
  1787. SPITFSNode spActiveLeases, spSelectedNode;
  1788. m_spNodeMgr->FindNode(cookie, &spActiveLeases);
  1789. pComponent->GetSelectedNode(&spSelectedNode);
  1790. Assert(spSelectedNode == spActiveLeases);
  1791. if (spSelectedNode != spActiveLeases)
  1792. return hr;
  1793. // build the list of selected nodes
  1794. CTFSNodeList listNodesToDelete;
  1795. hr = BuildSelectedItemList(pComponent, &listNodesToDelete);
  1796. //
  1797. // Confirm with the user
  1798. //
  1799. CString strMessage, strTemp;
  1800. int nNodes = (int)listNodesToDelete.GetCount();
  1801. if (nNodes > 1)
  1802. {
  1803. strTemp.Format(_T("%d"), nNodes);
  1804. AfxFormatString1(strMessage, IDS_DELETE_ITEMS, (LPCTSTR) strTemp);
  1805. }
  1806. else
  1807. {
  1808. strMessage.LoadString(IDS_DELETE_ITEM);
  1809. }
  1810. if (AfxMessageBox(strMessage, MB_YESNO) == IDNO)
  1811. {
  1812. return NOERROR;
  1813. }
  1814. //
  1815. // Loop through all items deleting
  1816. //
  1817. BEGIN_WAIT_CURSOR;
  1818. while (listNodesToDelete.GetCount() > 0)
  1819. {
  1820. SPITFSNode spActiveLeaseNode;
  1821. spActiveLeaseNode = listNodesToDelete.RemoveHead();
  1822. CDhcpMCastLease * pActiveLease = GETHANDLER(CDhcpMCastLease, spActiveLeaseNode);
  1823. //
  1824. // delete the node, check to see if it is a reservation
  1825. //
  1826. DWORD dwError = GetScopeObject(spActiveLeases)->DeleteClient(pActiveLease->GetIpAddress());
  1827. if (dwError == ERROR_SUCCESS)
  1828. {
  1829. //
  1830. // Client gone, now remove from UI
  1831. //
  1832. spActiveLeases->RemoveChild(spActiveLeaseNode);
  1833. }
  1834. else
  1835. {
  1836. ::DhcpMessageBox(dwError);
  1837. RESTORE_WAIT_CURSOR;
  1838. Trace1("DeleteClient failed %lx\n", dwError);
  1839. hr = E_FAIL;
  1840. }
  1841. spActiveLeaseNode.Release();
  1842. }
  1843. END_WAIT_CURSOR;
  1844. return hr;
  1845. }
  1846. /*!--------------------------------------------------------------------------
  1847. CMScopeActiveLeases::OnGetResultViewType
  1848. MMC calls this to get the result view information
  1849. Author: EricDav
  1850. ---------------------------------------------------------------------------*/
  1851. HRESULT CMScopeActiveLeases::OnGetResultViewType
  1852. (
  1853. ITFSComponent * pComponent,
  1854. MMC_COOKIE cookie,
  1855. LPOLESTR * ppViewType,
  1856. long * pViewOptions
  1857. )
  1858. {
  1859. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  1860. // we still want the default MMC result pane view, we just want
  1861. // multiselect, so return S_FALSE
  1862. return S_FALSE;
  1863. }
  1864. /*---------------------------------------------------------------------------
  1865. CMScopeActiveLeases::CompareItems
  1866. Description
  1867. Author: EricDav
  1868. ---------------------------------------------------------------------------*/
  1869. STDMETHODIMP_(int)
  1870. CMScopeActiveLeases::CompareItems
  1871. (
  1872. ITFSComponent * pComponent,
  1873. MMC_COOKIE cookieA,
  1874. MMC_COOKIE cookieB,
  1875. int nCol
  1876. )
  1877. {
  1878. SPITFSNode spNode1, spNode2;
  1879. m_spNodeMgr->FindNode(cookieA, &spNode1);
  1880. m_spNodeMgr->FindNode(cookieB, &spNode2);
  1881. int nCompare = 0;
  1882. CDhcpMCastLease *pDhcpAL1 = GETHANDLER(CDhcpMCastLease, spNode1);
  1883. CDhcpMCastLease *pDhcpAL2 = GETHANDLER(CDhcpMCastLease, spNode2);
  1884. switch (nCol)
  1885. {
  1886. case 0:
  1887. {
  1888. // IP address compare
  1889. //
  1890. nCompare = CompareIpAddresses(pDhcpAL1, pDhcpAL2);
  1891. }
  1892. break;
  1893. case 1:
  1894. {
  1895. // Client Name compare
  1896. //
  1897. CString strAL1 = pDhcpAL1->GetString(pComponent, cookieA, nCol);
  1898. CString strAL2 = pDhcpAL2->GetString(pComponent, cookieA, nCol);
  1899. // Compare should not be case sensitive
  1900. //
  1901. nCompare = strAL1.CompareNoCase(strAL2);
  1902. }
  1903. break;
  1904. case 2:
  1905. {
  1906. // Lease start compare
  1907. //
  1908. CTime timeAL1, timeAL2;
  1909. pDhcpAL1->GetLeaseStartTime(timeAL1);
  1910. pDhcpAL2->GetLeaseStartTime(timeAL2);
  1911. if (timeAL1 < timeAL2)
  1912. nCompare = -1;
  1913. else
  1914. if (timeAL1 > timeAL2)
  1915. nCompare = 1;
  1916. }
  1917. break;
  1918. case 3:
  1919. {
  1920. // Lease expiration compare
  1921. //
  1922. CTime timeAL1, timeAL2;
  1923. pDhcpAL1->GetLeaseExpirationTime(timeAL1);
  1924. pDhcpAL2->GetLeaseExpirationTime(timeAL2);
  1925. if (timeAL1 < timeAL2)
  1926. nCompare = -1;
  1927. else
  1928. if (timeAL1 > timeAL2)
  1929. nCompare = 1;
  1930. }
  1931. break;
  1932. case 4:
  1933. {
  1934. CString strClientId1 = pDhcpAL1->GetClientId();
  1935. nCompare = strClientId1.CompareNoCase(pDhcpAL2->GetClientId());
  1936. }
  1937. break;
  1938. }
  1939. return nCompare;
  1940. }
  1941. /*---------------------------------------------------------------------------
  1942. Function Name Here
  1943. Description
  1944. Author: EricDav
  1945. ---------------------------------------------------------------------------*/
  1946. int
  1947. CMScopeActiveLeases::CompareIpAddresses
  1948. (
  1949. CDhcpMCastLease * pDhcpAL1,
  1950. CDhcpMCastLease * pDhcpAL2
  1951. )
  1952. {
  1953. int nCompare = 0;
  1954. DHCP_IP_ADDRESS dhcpIp1 = pDhcpAL1->GetIpAddress();
  1955. DHCP_IP_ADDRESS dhcpIp2 = pDhcpAL2->GetIpAddress();
  1956. if (dhcpIp1 < dhcpIp2)
  1957. nCompare = -1;
  1958. else
  1959. if (dhcpIp1 > dhcpIp2)
  1960. nCompare = 1;
  1961. return nCompare;
  1962. }
  1963. /*---------------------------------------------------------------------------
  1964. Background thread functionality
  1965. ---------------------------------------------------------------------------*/
  1966. /*---------------------------------------------------------------------------
  1967. CMScopeActiveLeases::OnCreateQuery()
  1968. Description
  1969. Author: EricDav
  1970. ---------------------------------------------------------------------------*/
  1971. ITFSQueryObject*
  1972. CMScopeActiveLeases::OnCreateQuery(ITFSNode * pNode)
  1973. {
  1974. CMScopeActiveLeasesQueryObj* pQuery =
  1975. new CMScopeActiveLeasesQueryObj(m_spTFSCompData, m_spNodeMgr);
  1976. if ( pQuery == NULL )
  1977. return pQuery;
  1978. pQuery->m_strServer = GetServerIpAddress(pNode);
  1979. pQuery->m_dhcpResumeHandle = NULL;
  1980. pQuery->m_dwPreferredMax = 200;
  1981. CDhcpMScope * pScope = GetScopeObject(pNode);
  1982. if (pScope)
  1983. pQuery->m_strName = pScope->GetName();
  1984. else
  1985. Panic0("no scope in MScopeActiveLease::OnCreateQuery!");
  1986. GetServerVersion(pNode, pQuery->m_liDhcpVersion);
  1987. return pQuery;
  1988. }
  1989. /*---------------------------------------------------------------------------
  1990. CMScopeActiveLeasesQueryObj::Execute()
  1991. Description
  1992. Author: EricDav
  1993. ---------------------------------------------------------------------------*/
  1994. STDMETHODIMP
  1995. CMScopeActiveLeasesQueryObj::Execute()
  1996. {
  1997. HRESULT hr = hrOK;
  1998. hr = EnumerateLeases();
  1999. return hr;
  2000. }
  2001. /*---------------------------------------------------------------------------
  2002. CMScopeActiveLeasesQueryObj::EnumerateLeases()
  2003. Description
  2004. Author: EricDav
  2005. ---------------------------------------------------------------------------*/
  2006. HRESULT
  2007. CMScopeActiveLeasesQueryObj::EnumerateLeases()
  2008. {
  2009. DWORD dwError = ERROR_MORE_DATA;
  2010. LPDHCP_MCLIENT_INFO_ARRAY pdhcpClientArray = NULL;
  2011. DWORD dwClientsRead = 0, dwClientsTotal = 0;
  2012. DWORD dwEnumedClients = 0;
  2013. while (dwError == ERROR_MORE_DATA)
  2014. {
  2015. if (m_strName.IsEmpty())
  2016. Panic0("CMScopeActiveLeasesQueryObj::EnumerateLeases() - m_strName is empty!!");
  2017. dwError = ::DhcpEnumMScopeClients(((LPWSTR) (LPCTSTR)m_strServer),
  2018. (LPWSTR) ((LPCTSTR) m_strName),
  2019. &m_dhcpResumeHandle,
  2020. m_dwPreferredMax,
  2021. &pdhcpClientArray,
  2022. &dwClientsRead,
  2023. &dwClientsTotal);
  2024. if (dwClientsRead && pdhcpClientArray)
  2025. {
  2026. //
  2027. // loop through all of the elements that were returned
  2028. //
  2029. for (DWORD i = 0; i < pdhcpClientArray->NumElements; i++)
  2030. {
  2031. CDhcpMCastLease * pDhcpMCastLease;
  2032. //
  2033. // Create the result pane item for this element
  2034. //
  2035. SPITFSNode spNode;
  2036. pDhcpMCastLease =
  2037. new CDhcpMCastLease(m_spTFSCompData);
  2038. CreateLeafTFSNode(&spNode,
  2039. &GUID_DhcpMCastLeaseNodeType,
  2040. pDhcpMCastLease,
  2041. pDhcpMCastLease,
  2042. m_spNodeMgr);
  2043. // Tell the handler to initialize any specific data
  2044. pDhcpMCastLease->InitMCastInfo(pdhcpClientArray->Clients[i]);
  2045. pDhcpMCastLease->InitializeNode(spNode);
  2046. AddToQueue(spNode);
  2047. pDhcpMCastLease->Release();
  2048. }
  2049. ::DhcpRpcFreeMemory(pdhcpClientArray);
  2050. dwEnumedClients += dwClientsRead;
  2051. dwClientsRead = 0;
  2052. dwClientsTotal = 0;
  2053. pdhcpClientArray = NULL;
  2054. }
  2055. // Check the abort flag on the thread
  2056. if (FCheckForAbort() == hrOK)
  2057. break;
  2058. // check to see if we have an error and post it to the main thread if we do..
  2059. if (dwError != ERROR_NO_MORE_ITEMS &&
  2060. dwError != ERROR_SUCCESS &&
  2061. dwError != ERROR_MORE_DATA)
  2062. {
  2063. Trace1("DHCP snapin: EnumerateLeases error: %d\n", dwError);
  2064. m_dwErr = dwError;
  2065. PostError(dwError);
  2066. }
  2067. }
  2068. Trace1("DHCP snpain: Leases enumerated: %d\n", dwEnumedClients);
  2069. return hrFalse;
  2070. }
  2071. /*---------------------------------------------------------------------------
  2072. Class CMScopeAddressPool implementation
  2073. ---------------------------------------------------------------------------*/
  2074. /*---------------------------------------------------------------------------
  2075. Function Name Here
  2076. Description
  2077. Author: EricDav
  2078. ---------------------------------------------------------------------------*/
  2079. CMScopeAddressPool::CMScopeAddressPool
  2080. (
  2081. ITFSComponentData * pComponentData
  2082. ) : CMTDhcpHandler(pComponentData)
  2083. {
  2084. }
  2085. CMScopeAddressPool::~CMScopeAddressPool()
  2086. {
  2087. }
  2088. /*!--------------------------------------------------------------------------
  2089. CMScopeAddressPool::InitializeNode
  2090. Initializes node specific data
  2091. Author: EricDav
  2092. ---------------------------------------------------------------------------*/
  2093. HRESULT
  2094. CMScopeAddressPool::InitializeNode
  2095. (
  2096. ITFSNode * pNode
  2097. )
  2098. {
  2099. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  2100. HRESULT hr = hrOK;
  2101. //
  2102. // Create the display name for this scope
  2103. //
  2104. CString strTemp;
  2105. strTemp.LoadString(IDS_ADDRESS_POOL_FOLDER);
  2106. SetDisplayName(strTemp);
  2107. // Make the node immediately visible
  2108. pNode->SetVisibilityState(TFS_VIS_SHOW);
  2109. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_ADDR_POOL_FOLDER_CLOSED);
  2110. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_ADDR_POOL_FOLDER_OPEN);
  2111. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  2112. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  2113. pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_ADDRESS_POOL);
  2114. pNode->SetData(TFS_DATA_SCOPE_LEAF_NODE, TRUE);
  2115. SetColumnStringIDs(&aColumns[DHCPSNAP_ADDRESS_POOL][0]);
  2116. SetColumnWidths(&aColumnWidths[DHCPSNAP_ADDRESS_POOL][0]);
  2117. return hr;
  2118. }
  2119. /*---------------------------------------------------------------------------
  2120. CMScopeAddressPool::OnCreateNodeId2
  2121. Returns a unique string for this node
  2122. Author: EricDav
  2123. ---------------------------------------------------------------------------*/
  2124. HRESULT CMScopeAddressPool::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  2125. {
  2126. const GUID * pGuid = pNode->GetNodeType();
  2127. CString strNode, strGuid;
  2128. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  2129. strGuid.ReleaseBuffer();
  2130. // id string is server name, scope name and guid.
  2131. strNode = GetServerName(pNode);
  2132. strNode += GetScopeObject(pNode)->GetName() + strGuid;
  2133. strId = strNode;
  2134. return hrOK;
  2135. }
  2136. /*---------------------------------------------------------------------------
  2137. CMScopeAddressPool::GetImageIndex
  2138. Description
  2139. Author: EricDav
  2140. ---------------------------------------------------------------------------*/
  2141. int
  2142. CMScopeAddressPool::GetImageIndex(BOOL bOpenImage)
  2143. {
  2144. int nIndex = -1;
  2145. switch (m_nState)
  2146. {
  2147. case notLoaded:
  2148. case loaded:
  2149. if (bOpenImage)
  2150. nIndex = ICON_IDX_ADDR_POOL_FOLDER_OPEN;
  2151. else
  2152. nIndex = ICON_IDX_ADDR_POOL_FOLDER_CLOSED;
  2153. break;
  2154. case loading:
  2155. if (bOpenImage)
  2156. nIndex = ICON_IDX_ADDR_POOL_FOLDER_OPEN_BUSY;
  2157. else
  2158. nIndex = ICON_IDX_ADDR_POOL_FOLDER_CLOSED_BUSY;
  2159. break;
  2160. case unableToLoad:
  2161. if (bOpenImage)
  2162. nIndex = ICON_IDX_ADDR_POOL_FOLDER_OPEN_LOST_CONNECTION;
  2163. else
  2164. nIndex = ICON_IDX_ADDR_POOL_FOLDER_CLOSED_LOST_CONNECTION;
  2165. break;
  2166. default:
  2167. ASSERT(FALSE);
  2168. }
  2169. return nIndex;
  2170. }
  2171. /*---------------------------------------------------------------------------
  2172. Overridden base handler functions
  2173. ---------------------------------------------------------------------------*/
  2174. /*---------------------------------------------------------------------------
  2175. CMScopeAddressPool::OnAddMenuItems
  2176. Adds entries to the context sensitive menu
  2177. Author: EricDav
  2178. ---------------------------------------------------------------------------*/
  2179. STDMETHODIMP
  2180. CMScopeAddressPool::OnAddMenuItems
  2181. (
  2182. ITFSNode * pNode,
  2183. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  2184. LPDATAOBJECT lpDataObject,
  2185. DATA_OBJECT_TYPES type,
  2186. DWORD dwType,
  2187. long * pInsertionAllowed
  2188. )
  2189. {
  2190. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  2191. LONG fFlags = 0;
  2192. HRESULT hr = S_OK;
  2193. CString strMenuText;
  2194. if ( (m_nState != loaded) )
  2195. {
  2196. fFlags |= MF_GRAYED;
  2197. }
  2198. if (type == CCT_SCOPE)
  2199. {
  2200. // these menu items go in the new menu,
  2201. // only visible from scope pane
  2202. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  2203. {
  2204. strMenuText.LoadString(IDS_CREATE_NEW_EXCLUSION);
  2205. hr = LoadAndAddMenuItem( pContextMenuCallback,
  2206. strMenuText,
  2207. IDS_CREATE_NEW_EXCLUSION,
  2208. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  2209. fFlags );
  2210. ASSERT( SUCCEEDED(hr) );
  2211. }
  2212. }
  2213. return hr;
  2214. }
  2215. /*---------------------------------------------------------------------------
  2216. CMScopeAddressPool::OnCommand
  2217. Description
  2218. Author: EricDav
  2219. ---------------------------------------------------------------------------*/
  2220. STDMETHODIMP
  2221. CMScopeAddressPool::OnCommand
  2222. (
  2223. ITFSNode * pNode,
  2224. long nCommandId,
  2225. DATA_OBJECT_TYPES type,
  2226. LPDATAOBJECT pDataObject,
  2227. DWORD dwType
  2228. )
  2229. {
  2230. HRESULT hr = S_OK;
  2231. switch (nCommandId)
  2232. {
  2233. case IDS_CREATE_NEW_EXCLUSION:
  2234. OnCreateNewExclusion(pNode);
  2235. break;
  2236. case IDS_REFRESH:
  2237. OnRefresh(pNode, pDataObject, dwType, 0, 0);
  2238. break;
  2239. default:
  2240. break;
  2241. }
  2242. return hr;
  2243. }
  2244. /*---------------------------------------------------------------------------
  2245. Message handlers
  2246. ---------------------------------------------------------------------------*/
  2247. /*---------------------------------------------------------------------------
  2248. CMScopeAddressPool::OnCreateNewExclusion
  2249. Description
  2250. Author: EricDav
  2251. ---------------------------------------------------------------------------*/
  2252. DWORD
  2253. CMScopeAddressPool::OnCreateNewExclusion
  2254. (
  2255. ITFSNode * pNode
  2256. )
  2257. {
  2258. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  2259. SPITFSNode spScopeNode;
  2260. pNode->GetParent(&spScopeNode);
  2261. CAddExclusion dlgAddExclusion(spScopeNode, TRUE /* multicast */);
  2262. dlgAddExclusion.DoModal();
  2263. return 0;
  2264. }
  2265. /*---------------------------------------------------------------------------
  2266. CMScopeAddressPool::OnResultDelete
  2267. This function is called when we are supposed to delete result
  2268. pane items. We build a list of selected items and then delete them.
  2269. Author: EricDav
  2270. ---------------------------------------------------------------------------*/
  2271. HRESULT
  2272. CMScopeAddressPool::OnResultDelete
  2273. (
  2274. ITFSComponent * pComponent,
  2275. LPDATAOBJECT pDataObject,
  2276. MMC_COOKIE cookie,
  2277. LPARAM arg,
  2278. LPARAM lParam
  2279. )
  2280. {
  2281. HRESULT hr = NOERROR;
  2282. BOOL bIsRes, bIsActive, bBadAddress;
  2283. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  2284. // translate the cookie into a node pointer
  2285. SPITFSNode spAddressPool, spSelectedNode;
  2286. m_spNodeMgr->FindNode(cookie, &spAddressPool);
  2287. pComponent->GetSelectedNode(&spSelectedNode);
  2288. Assert(spSelectedNode == spAddressPool);
  2289. if (spSelectedNode != spAddressPool)
  2290. return hr;
  2291. // build the list of selected nodes
  2292. CTFSNodeList listNodesToDelete;
  2293. hr = BuildSelectedItemList(pComponent, &listNodesToDelete);
  2294. //
  2295. // Confirm with the user
  2296. //
  2297. CString strMessage, strTemp;
  2298. int nNodes = (int)listNodesToDelete.GetCount();
  2299. if (nNodes > 1)
  2300. {
  2301. strTemp.Format(_T("%d"), nNodes);
  2302. AfxFormatString1(strMessage, IDS_DELETE_ITEMS, (LPCTSTR) strTemp);
  2303. }
  2304. else
  2305. {
  2306. strMessage.LoadString(IDS_DELETE_ITEM);
  2307. }
  2308. if (AfxMessageBox(strMessage, MB_YESNO) == IDNO)
  2309. {
  2310. return NOERROR;
  2311. }
  2312. //
  2313. // Loop through all items deleting
  2314. //
  2315. BEGIN_WAIT_CURSOR;
  2316. while (listNodesToDelete.GetCount() > 0)
  2317. {
  2318. SPITFSNode spExclusionRangeNode;
  2319. spExclusionRangeNode = listNodesToDelete.RemoveHead();
  2320. CDhcpExclusionRange * pExclusion = GETHANDLER(CDhcpExclusionRange, spExclusionRangeNode);
  2321. if (spExclusionRangeNode->GetData(TFS_DATA_TYPE) == DHCPSNAP_ALLOCATION_RANGE)
  2322. {
  2323. //
  2324. // This is the allocation range, can't delete
  2325. //
  2326. AfxMessageBox(IDS_CANNOT_DELETE_ALLOCATION_RANGE);
  2327. spExclusionRangeNode.Release();
  2328. continue;
  2329. }
  2330. //
  2331. // Try to remove it from the server
  2332. //
  2333. CDhcpIpRange dhcpIpRange((DHCP_IP_RANGE) *pExclusion);
  2334. DWORD dwError = GetScopeObject(spAddressPool)->RemoveExclusion(dhcpIpRange);
  2335. if (dwError != 0)
  2336. {
  2337. ::DhcpMessageBox(dwError);
  2338. RESTORE_WAIT_CURSOR;
  2339. hr = E_FAIL;
  2340. continue;
  2341. }
  2342. //
  2343. // Remove from UI now
  2344. //
  2345. spAddressPool->RemoveChild(spExclusionRangeNode);
  2346. spExclusionRangeNode.Release();
  2347. }
  2348. END_WAIT_CURSOR;
  2349. return hr;
  2350. }
  2351. /*!--------------------------------------------------------------------------
  2352. CMScopeAddressPool::OnGetResultViewType
  2353. MMC calls this to get the result view information
  2354. Author: EricDav
  2355. ---------------------------------------------------------------------------*/
  2356. HRESULT
  2357. CMScopeAddressPool::OnGetResultViewType
  2358. (
  2359. ITFSComponent * pComponent,
  2360. MMC_COOKIE cookie,
  2361. LPOLESTR * ppViewType,
  2362. long * pViewOptions
  2363. )
  2364. {
  2365. *pViewOptions = MMC_VIEW_OPTIONS_MULTISELECT;
  2366. // we still want the default MMC result pane view, we just want
  2367. // multiselect, so return S_FALSE
  2368. return S_FALSE;
  2369. }
  2370. /*---------------------------------------------------------------------------
  2371. CMScopeAddressPool::CompareItems
  2372. Description
  2373. Author: EricDav
  2374. ---------------------------------------------------------------------------*/
  2375. STDMETHODIMP_(int)
  2376. CMScopeAddressPool::CompareItems
  2377. (
  2378. ITFSComponent * pComponent,
  2379. MMC_COOKIE cookieA,
  2380. MMC_COOKIE cookieB,
  2381. int nCol
  2382. )
  2383. {
  2384. SPITFSNode spNode1, spNode2;
  2385. m_spNodeMgr->FindNode(cookieA, &spNode1);
  2386. m_spNodeMgr->FindNode(cookieB, &spNode2);
  2387. int nCompare = 0;
  2388. CDhcpAllocationRange *pDhcpAR1 = GETHANDLER(CDhcpAllocationRange, spNode1);
  2389. CDhcpAllocationRange *pDhcpAR2 = GETHANDLER(CDhcpAllocationRange, spNode2);
  2390. switch (nCol)
  2391. {
  2392. case 0:
  2393. {
  2394. // Start IP address compare
  2395. //
  2396. DHCP_IP_ADDRESS dhcpIp1 = pDhcpAR1->QueryAddr(TRUE);
  2397. DHCP_IP_ADDRESS dhcpIp2 = pDhcpAR2->QueryAddr(TRUE);
  2398. if (dhcpIp1 < dhcpIp2)
  2399. nCompare = -1;
  2400. else
  2401. if (dhcpIp1 > dhcpIp2)
  2402. nCompare = 1;
  2403. // default is that they are equal
  2404. }
  2405. break;
  2406. case 1:
  2407. {
  2408. // End IP address compare
  2409. //
  2410. DHCP_IP_ADDRESS dhcpIp1 = pDhcpAR1->QueryAddr(FALSE);
  2411. DHCP_IP_ADDRESS dhcpIp2 = pDhcpAR2->QueryAddr(FALSE);
  2412. if (dhcpIp1 < dhcpIp2)
  2413. nCompare = -1;
  2414. else
  2415. if (dhcpIp1 > dhcpIp2)
  2416. nCompare = 1;
  2417. // default is that they are equal
  2418. }
  2419. break;
  2420. case 2:
  2421. {
  2422. // Description compare
  2423. //
  2424. CString strRange1 = pDhcpAR1->GetString(pComponent, cookieA, nCol);
  2425. CString strRange2 = pDhcpAR2->GetString(pComponent, cookieA, nCol);
  2426. // Compare should not be case sensitive
  2427. //
  2428. strRange1.MakeUpper();
  2429. strRange2.MakeUpper();
  2430. nCompare = strRange1.Compare(strRange2);
  2431. }
  2432. break;
  2433. }
  2434. return nCompare;
  2435. }
  2436. /*---------------------------------------------------------------------------
  2437. Background thread functionality
  2438. ---------------------------------------------------------------------------*/
  2439. /*---------------------------------------------------------------------------
  2440. CMScopeAddressPool::OnCreateQuery()
  2441. Description
  2442. Author: EricDav
  2443. ---------------------------------------------------------------------------*/
  2444. ITFSQueryObject*
  2445. CMScopeAddressPool::OnCreateQuery(ITFSNode * pNode)
  2446. {
  2447. CMScopeAddressPoolQueryObj* pQuery =
  2448. new CMScopeAddressPoolQueryObj(m_spTFSCompData, m_spNodeMgr);
  2449. if ( pQuery == NULL )
  2450. return pQuery;
  2451. pQuery->m_strServer = GetServerIpAddress(pNode);
  2452. CDhcpMScope * pScope = GetScopeObject(pNode);
  2453. if (pScope)
  2454. pQuery->m_strName = pScope->GetName();
  2455. pQuery->m_dhcpExclResumeHandle = NULL;
  2456. pQuery->m_dwExclPreferredMax = 0xFFFFFFFF;
  2457. pQuery->m_dhcpIpResumeHandle = NULL;
  2458. pQuery->m_dwIpPreferredMax = 0xFFFFFFFF;
  2459. return pQuery;
  2460. }
  2461. /*---------------------------------------------------------------------------
  2462. CMScopeAddressPoolQueryObj::Execute()
  2463. Description
  2464. Author: EricDav
  2465. ---------------------------------------------------------------------------*/
  2466. STDMETHODIMP
  2467. CMScopeAddressPoolQueryObj::Execute()
  2468. {
  2469. HRESULT hr1 = EnumerateIpRanges();
  2470. HRESULT hr2 = EnumerateExcludedIpRanges();
  2471. if (hr1 == hrOK || hr2 == hrOK)
  2472. return hrOK;
  2473. else
  2474. return hrFalse;
  2475. }
  2476. /*---------------------------------------------------------------------------
  2477. Function Name Here
  2478. Description
  2479. Author: EricDav
  2480. ---------------------------------------------------------------------------*/
  2481. HRESULT
  2482. CMScopeAddressPoolQueryObj::EnumerateExcludedIpRanges()
  2483. {
  2484. DWORD dwError = ERROR_MORE_DATA;
  2485. DHCP_RESUME_HANDLE dhcpResumeHandle = 0;
  2486. LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 pdhcpSubnetElementArray = NULL;
  2487. DWORD dwElementsRead = 0, dwElementsTotal = 0;
  2488. while (dwError == ERROR_MORE_DATA)
  2489. {
  2490. dwError = ::DhcpEnumMScopeElements((LPWSTR) ((LPCTSTR) m_strServer),
  2491. (LPWSTR) ((LPCTSTR) m_strName),
  2492. DhcpExcludedIpRanges,
  2493. &m_dhcpExclResumeHandle,
  2494. m_dwExclPreferredMax,
  2495. &pdhcpSubnetElementArray,
  2496. &dwElementsRead,
  2497. &dwElementsTotal);
  2498. Trace3("Scope %s Excluded Ip Ranges read %d, total %d\n", m_strName, dwElementsRead, dwElementsTotal);
  2499. if (dwElementsRead && dwElementsTotal && pdhcpSubnetElementArray)
  2500. {
  2501. //
  2502. // loop through all of the elements that were returned
  2503. //
  2504. for (DWORD i = 0; i < pdhcpSubnetElementArray->NumElements; i++)
  2505. {
  2506. //
  2507. // Create the result pane item for this element
  2508. //
  2509. SPITFSNode spNode;
  2510. CDhcpExclusionRange * pDhcpExclusionRange =
  2511. new CDhcpExclusionRange(m_spTFSCompData,
  2512. pdhcpSubnetElementArray->Elements[i].Element.ExcludeIpRange);
  2513. CreateLeafTFSNode(&spNode,
  2514. &GUID_DhcpExclusionNodeType,
  2515. pDhcpExclusionRange,
  2516. pDhcpExclusionRange,
  2517. m_spNodeMgr);
  2518. // Tell the handler to initialize any specific data
  2519. pDhcpExclusionRange->InitializeNode(spNode);
  2520. AddToQueue(spNode);
  2521. pDhcpExclusionRange->Release();
  2522. }
  2523. // Free up the memory from the RPC call
  2524. //
  2525. ::DhcpRpcFreeMemory(pdhcpSubnetElementArray);
  2526. }
  2527. // Check the abort flag on the thread
  2528. if (FCheckForAbort() == hrOK)
  2529. break;
  2530. // check to see if we have an error and post it to the main thread if we do..
  2531. if (dwError != ERROR_NO_MORE_ITEMS &&
  2532. dwError != ERROR_SUCCESS &&
  2533. dwError != ERROR_MORE_DATA)
  2534. {
  2535. Trace1("DHCP snapin: EnumerateExcludedIpRanges error: %d\n", dwError);
  2536. m_dwErr = dwError;
  2537. PostError(dwError);
  2538. }
  2539. }
  2540. return hrFalse;
  2541. }
  2542. /*---------------------------------------------------------------------------
  2543. Function Name Here
  2544. Description
  2545. Author: EricDav
  2546. ---------------------------------------------------------------------------*/
  2547. HRESULT
  2548. CMScopeAddressPoolQueryObj::EnumerateIpRanges()
  2549. {
  2550. DWORD dwError = ERROR_MORE_DATA;
  2551. LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 pdhcpSubnetElementArray = NULL;
  2552. DWORD dwElementsRead = 0, dwElementsTotal = 0;
  2553. while (dwError == ERROR_MORE_DATA)
  2554. {
  2555. dwError = ::DhcpEnumMScopeElements((LPWSTR) ((LPCTSTR) m_strServer),
  2556. (LPWSTR) ((LPCTSTR) m_strName),
  2557. DhcpIpRanges,
  2558. &m_dhcpIpResumeHandle,
  2559. m_dwIpPreferredMax,
  2560. &pdhcpSubnetElementArray,
  2561. &dwElementsRead,
  2562. &dwElementsTotal);
  2563. Trace4("Scope %s allocation ranges read %d, total %d, dwError = %lx\n",
  2564. m_strName, dwElementsRead, dwElementsTotal, dwError);
  2565. if ((dwError == ERROR_MORE_DATA) ||
  2566. ( (dwElementsRead) && (dwError == ERROR_SUCCESS) ))
  2567. {
  2568. //
  2569. // Loop through the array that was returned
  2570. //
  2571. for (DWORD i = 0; i < pdhcpSubnetElementArray->NumElements; i++)
  2572. {
  2573. //
  2574. // Create the result pane item for this element
  2575. //
  2576. SPITFSNode spNode;
  2577. CDhcpAllocationRange * pDhcpAllocRange =
  2578. new CDhcpAllocationRange(m_spTFSCompData,
  2579. pdhcpSubnetElementArray->Elements[i].Element.IpRange);
  2580. CreateLeafTFSNode(&spNode,
  2581. &GUID_DhcpAllocationNodeType,
  2582. pDhcpAllocRange,
  2583. pDhcpAllocRange,
  2584. m_spNodeMgr);
  2585. // Tell the handler to initialize any specific data
  2586. pDhcpAllocRange->InitializeNode(spNode);
  2587. AddToQueue(spNode);
  2588. pDhcpAllocRange->Release();
  2589. }
  2590. ::DhcpRpcFreeMemory(pdhcpSubnetElementArray);
  2591. }
  2592. else
  2593. if (dwError != ERROR_SUCCESS &&
  2594. dwError != ERROR_NO_MORE_ITEMS)
  2595. {
  2596. // set the error variable so that it can be looked at later
  2597. m_dwError = dwError;
  2598. }
  2599. // Check the abort flag on the thread
  2600. if (FCheckForAbort() == hrOK)
  2601. break;
  2602. // check to see if we have an error and post it to the main thread if we do..
  2603. if (dwError != ERROR_NO_MORE_ITEMS &&
  2604. dwError != ERROR_SUCCESS &&
  2605. dwError != ERROR_MORE_DATA)
  2606. {
  2607. Trace1("DHCP snapin: EnumerateAllocationRanges error: %d\n", dwError);
  2608. m_dwErr = dwError;
  2609. PostError(dwError);
  2610. }
  2611. }
  2612. return hrFalse;
  2613. }