Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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