Windows2003-3790/net/mmc/dhcp/nodes.cpp
2020-09-30 16:53:55 +02:00

1890 lines
61 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
nodes.h
This file contains all of the implementation for the DHCP
objects that appear in the result pane of the MMC framework.
The objects are:
CDhcpActiveLease
CDhcpConflicAddress
CDhcpAllocationRange
CDhcpExclusionRange
CDhcpBootpTableEntry
CDhcpOption
FILE HISTORY:
*/
#include "stdafx.h"
#include "nodes.h"
#include "server.h"
#include "scope.h"
#include "optcfg.h"
#include "intltime.h"
CString g_szClientTypeUnspecified;
CString g_szClientTypeNone;
CString g_szClientTypeUnknown;
const TCHAR g_szClientTypeDhcp[] = _T("DHCP");
const TCHAR g_szClientTypeBootp[] = _T("BOOTP");
const TCHAR g_szClientTypeBoth[] = _T("DHCP/BOOTP");
/*---------------------------------------------------------------------------
Class CDhcpActiveLease implementation
---------------------------------------------------------------------------*/
DEBUG_DECLARE_INSTANCE_COUNTER(CDhcpActiveLease);
/*---------------------------------------------------------------------------
CDhcpActiveLease constructor/destructor
Takes the NT5 client info struct
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpActiveLease::CDhcpActiveLease
(
ITFSComponentData * pTFSCompData,
LPDHCP_CLIENT_INFO_V5 pDhcpClientInfo
) : CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpActiveLease);
if (g_szClientTypeUnspecified.IsEmpty())
{
g_szClientTypeUnspecified.LoadString(IDS_UNSPECIFIED);
g_szClientTypeNone.LoadString(IDS_NONE);
g_szClientTypeUnknown.LoadString(IDS_UNKNOWN);
}
//
// Reset our flags for this lease
//
m_dwTypeFlags = 0;
//
// Intialize our client type variable
//
m_bClientType = pDhcpClientInfo->bClientType;
//
// Initialize does everything but initialize the client type
// since there are two versions of the client info struct, one
// contains the type, the other doesn't. So we need to save it
// away after the call.
//
InitInfo((LPDHCP_CLIENT_INFO) pDhcpClientInfo);
// now check NT5 specific flags
if (pDhcpClientInfo->AddressState & V5_ADDRESS_BIT_UNREGISTERED)
{
if (pDhcpClientInfo->AddressState & V5_ADDRESS_BIT_DELETED)
{
// this lease is pending DNS unregistration
m_dwTypeFlags |= TYPE_FLAG_DNS_UNREG;
}
else
{
// this lease is pending DNS registration
m_dwTypeFlags |= TYPE_FLAG_DNS_REG;
}
}
else
if ((pDhcpClientInfo->AddressState & 0x03) == V5_ADDRESS_STATE_DOOM)
{
m_dwTypeFlags |= TYPE_FLAG_DOOMED;
}
}
/*---------------------------------------------------------------------------
CDhcpActiveLease constructor/destructor
Takes the NT4 SP2 client info struct
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpActiveLease::CDhcpActiveLease
(
ITFSComponentData * pTFSCompData,
LPDHCP_CLIENT_INFO_V4 pDhcpClientInfo
) : CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpActiveLease);
//
// Reset our flags for this lease
//
m_dwTypeFlags = 0;
//
// Intialize our client type variable
//
m_bClientType = pDhcpClientInfo->bClientType;
//
// Initialize does everything but initialize the client type
// since there are two versions of the client info struct, one
// contains the type, the other doesn't. So we need to save it
// away after the call.
//
InitInfo((LPDHCP_CLIENT_INFO) pDhcpClientInfo);
}
/*---------------------------------------------------------------------------
CDhcpActiveLease constructor/destructor
Takes the pre-NT4 SP2 client info struct
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpActiveLease::CDhcpActiveLease
(
ITFSComponentData * pTFSCompData,
LPDHCP_CLIENT_INFO pDhcpClientInfo
) : CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpActiveLease);
//m_verbDefault = MMC_VERB_PROPERTIES;
//
// Reset our flags for this lease
//
m_dwTypeFlags = 0;
//
// Intialize our client type variable
//
m_bClientType = CLIENT_TYPE_DHCP;
InitInfo((LPDHCP_CLIENT_INFO) pDhcpClientInfo);
}
CDhcpActiveLease::CDhcpActiveLease
(
ITFSComponentData * pTFSCompData,
CDhcpClient & dhcpClient
) : CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpActiveLease);
//
// Reset our flags for this lease
//
m_dwTypeFlags = 0;
//
// Intialize our client type variable
//
m_bClientType = CLIENT_TYPE_NONE;
m_dhcpClientIpAddress = dhcpClient.QueryIpAddress();
m_strClientName = dhcpClient.QueryName();
m_strComment = dhcpClient.QueryComment();
//
// Check to see if this lease has an infinite expiration. If so, it's
// an active reservation. If the expiration is zero, then it's an inactive reservation.
//
DATE_TIME dt = dhcpClient.QueryExpiryDateTime();
m_leaseExpires.dwLowDateTime = dt.dwLowDateTime;
m_leaseExpires.dwHighDateTime = dt.dwHighDateTime;
if ( (dhcpClient.QueryExpiryDateTime().dwLowDateTime == DHCP_DATE_TIME_INFINIT_LOW) &&
(dhcpClient.QueryExpiryDateTime().dwHighDateTime == DHCP_DATE_TIME_INFINIT_HIGH) )
{
CString strBadAddress;
strBadAddress.LoadString(IDS_DHCP_BAD_ADDRESS);
//
// Bad addresses show up as active reservations, so we need to do the right thing.
//
if (strBadAddress.Compare(m_strClientName) == 0)
{
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_dwTypeFlags |= TYPE_FLAG_BAD_ADDRESS;
m_strLeaseExpires.LoadString(IDS_DHCP_LEASE_NOT_APPLICABLE);
}
else
{
//
// Assume infinite lease clients
//
m_strLeaseExpires.LoadString(IDS_INFINTE);
}
}
else
if ( (dhcpClient.QueryExpiryDateTime().dwLowDateTime == 0) &&
(dhcpClient.QueryExpiryDateTime().dwHighDateTime == 0) )
{
//
// This is an inactive reservation
//
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_strLeaseExpires.LoadString(IDS_DHCP_INFINITE_LEASE_INACTIVE);
}
else
{
//
// Generate the time the lease expires in a nicely formatted string
//
CTime timeTemp(m_leaseExpires);
m_timeLeaseExpires = timeTemp;
FormatDateTime(m_strLeaseExpires, &m_leaseExpires);
SYSTEMTIME st;
GetLocalTime(&st);
CTime systemTime(st);
if (systemTime > m_timeLeaseExpires)
m_dwTypeFlags |= TYPE_FLAG_GHOST;
}
if (dhcpClient.QueryHardwareAddress().GetSize() >= 3 &&
dhcpClient.QueryHardwareAddress()[0] == 'R' &&
dhcpClient.QueryHardwareAddress()[1] == 'A' &&
dhcpClient.QueryHardwareAddress()[2] == 'S')
{
m_dwTypeFlags |= TYPE_FLAG_RAS;
m_strUID = RAS_UID;
}
else
{
// build the client UID string
UtilCvtByteArrayToString(dhcpClient.QueryHardwareAddress(), m_strUID);
}
}
CDhcpActiveLease::~CDhcpActiveLease()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(CDhcpActiveLease);
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpActiveLease::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CString strTemp;
BOOL bIsRes, bActive, bBad;
UtilCvtIpAddrToWstr (m_dhcpClientIpAddress,
&strTemp);
SetDisplayName(strTemp);
bIsRes = IsReservation(&bActive, &bBad);
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_ACTIVE_LEASE);
int nImage = ICON_IDX_CLIENT;
// Figure out if we need a different icon for this lease
if (m_dwTypeFlags & TYPE_FLAG_RAS) {
nImage = ICON_IDX_CLIENT_RAS;
}
else if (m_dwTypeFlags & TYPE_FLAG_DNS_REG) {
nImage = ICON_IDX_CLIENT_DNS_REGISTERING;
}
else if (bIsRes) {
nImage = ICON_IDX_RES_CLIENT;
}
if (( m_dwTypeFlags & TYPE_FLAG_DNS_UNREG) ||
( m_dwTypeFlags & TYPE_FLAG_DOOMED) ||
( m_dwTypeFlags & TYPE_FLAG_GHOST)) {
nImage = ICON_IDX_CLIENT_EXPIRED;
}
pNode->SetData(TFS_DATA_IMAGEINDEX, nImage);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, nImage);
//SetColumnStringIDs(&aColumns[DHCPSNAP_ACTIVE_LEASES][0]);
//SetColumnWidths(&aColumnWidths[DHCPSNAP_ACTIVE_LEASES][0]);
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::InitInfo
Helper to initialize data
Author: EricDav
---------------------------------------------------------------------------*/
void
CDhcpActiveLease::InitInfo(LPDHCP_CLIENT_INFO pDhcpClientInfo)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
m_dhcpClientIpAddress = pDhcpClientInfo->ClientIpAddress;
//
// Copy the client name if it has one
//
if (pDhcpClientInfo->ClientName)
{
m_strClientName = pDhcpClientInfo->ClientName;
//m_strClientName.MakeLower();
}
if (pDhcpClientInfo->ClientComment)
{
m_strComment = pDhcpClientInfo->ClientComment;
}
//
// Check to see if this lease has an infinite expiration. If so, it's
// an active reservation. If the expiration is zero, then it's an inactive reservation.
//
DATE_TIME dt = pDhcpClientInfo->ClientLeaseExpires;
m_leaseExpires.dwLowDateTime = dt.dwLowDateTime;
m_leaseExpires.dwHighDateTime = dt.dwHighDateTime;
if ( (pDhcpClientInfo->ClientLeaseExpires.dwLowDateTime == DHCP_DATE_TIME_INFINIT_LOW) &&
(pDhcpClientInfo->ClientLeaseExpires.dwHighDateTime == DHCP_DATE_TIME_INFINIT_HIGH) )
{
CString strBadAddress;
strBadAddress.LoadString(IDS_DHCP_BAD_ADDRESS);
//
// Bad addresses show up as active reservations, so we need to do the right thing.
//
if (strBadAddress.Compare(m_strClientName) == 0)
{
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_dwTypeFlags |= TYPE_FLAG_BAD_ADDRESS;
m_strLeaseExpires.LoadString(IDS_DHCP_LEASE_NOT_APPLICABLE);
}
else
{
//
// Assume infinite lease clients
//
m_strLeaseExpires.LoadString(IDS_INFINTE);
}
}
else
if ( (pDhcpClientInfo->ClientLeaseExpires.dwLowDateTime == 0) &&
(pDhcpClientInfo->ClientLeaseExpires.dwHighDateTime == 0) )
{
//
// This is an inactive reservation
//
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_strLeaseExpires.LoadString(IDS_DHCP_INFINITE_LEASE_INACTIVE);
}
else
{
//
// Generate the time the lease expires in a nicely formatted string
//
CTime timeTemp(m_leaseExpires);
m_timeLeaseExpires = timeTemp;
FormatDateTime(m_strLeaseExpires, &m_leaseExpires);
CTime timeCurrent = CTime::GetCurrentTime();
if (timeCurrent > m_timeLeaseExpires)
m_dwTypeFlags |= TYPE_FLAG_GHOST;
}
if (pDhcpClientInfo->ClientHardwareAddress.DataLength >= 3 &&
pDhcpClientInfo->ClientHardwareAddress.Data[0] == 'R' &&
pDhcpClientInfo->ClientHardwareAddress.Data[1] == 'A' &&
pDhcpClientInfo->ClientHardwareAddress.Data[2] == 'S')
{
m_dwTypeFlags |= TYPE_FLAG_RAS;
m_strUID = RAS_UID;
}
else
{
// build the client UID string
CByteArray baUID;
for (DWORD i = 0; i < pDhcpClientInfo->ClientHardwareAddress.DataLength; i++)
{
baUID.Add(pDhcpClientInfo->ClientHardwareAddress.Data[i]);
}
UtilCvtByteArrayToString(baUID, m_strUID);
}
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::AddMenuItems
Implementation of ITFSResultHandler::AddMenuItems
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CDhcpActiveLease::AddMenuItems
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr;
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::Command
Implementation of ITFSResultHandler::Command
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CDhcpActiveLease::Command
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCommandID,
LPDATAOBJECT pDataObject
)
{
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::CreatePropertyPages
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CDhcpActiveLease::CreatePropertyPages
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
SPITFSNode spNode;
m_spNodeMgr->FindNode(cookie, &spNode);
hr = DoPropSheet(spNode, lpProvider, handle);
return hr;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpActiveLease::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
switch (nCol)
{
case 0:
return GetDisplayName();
case 1:
return m_strClientName;
case 2:
return (LPCWSTR)m_strLeaseExpires;
case 3:
return GetClientType();
case 4:
return m_strUID;
case 5:
return m_strComment;
}
return NULL;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
LPCTSTR
CDhcpActiveLease::GetClientType()
{
// set the default return value
LPCTSTR pszReturn = g_szClientTypeUnknown;
// this one must come before the check for DHCP or BOOTP
// because it is a combination of both flags
if ((m_bClientType & CLIENT_TYPE_BOTH) == CLIENT_TYPE_BOTH)
{
pszReturn = g_szClientTypeBoth;
}
else
if (m_bClientType & CLIENT_TYPE_DHCP)
{
pszReturn = g_szClientTypeDhcp;
}
else
if (m_bClientType & CLIENT_TYPE_BOOTP)
{
pszReturn = g_szClientTypeBootp;
}
else
if (m_bClientType & CLIENT_TYPE_NONE)
{
pszReturn = g_szClientTypeNone;
}
else
if (m_bClientType & CLIENT_TYPE_UNSPECIFIED)
{
pszReturn = g_szClientTypeUnspecified;
}
else
{
Assert1(FALSE, "CDhcpActiveLease::GetClientType - Unknown client type %d", m_bClientType);
}
return pszReturn;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CDhcpActiveLease::GetLeaseExpirationTime
(
CTime & time
)
{
time = m_timeLeaseExpires;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
CDhcpActiveLease::IsReservation
(
BOOL * pbIsActive,
BOOL * pbIsBad
)
{
BOOL bIsReservation = FALSE;
*pbIsBad = FALSE;
/* if ( (m_dhcpClientInfo.ClientLeaseExpires.dwLowDateTime == DHCP_DATE_TIME_INFINIT_LOW) &&
(m_dhcpClientInfo.ClientLeaseExpires.dwHighDateTime == DHCP_DATE_TIME_INFINIT_HIGH) )
{
//
// This is an active reservation
//
bIsReservation = TRUE;
*pbIsActive = TRUE;
*pbIsBad = IsBadAddress();
}
else
if ( (m_dhcpClientInfo.ClientLeaseExpires.dwLowDateTime == 0) &&
(m_dhcpClientInfo.ClientLeaseExpires.dwHighDateTime == 0) )
{
//
// This is an inactive reservation
//
bIsReservation = TRUE;
*pbIsActive = FALSE;
}
*/
*pbIsActive = m_dwTypeFlags & TYPE_FLAG_ACTIVE;
*pbIsBad = m_dwTypeFlags & TYPE_FLAG_BAD_ADDRESS;
return bIsReservation = m_dwTypeFlags & TYPE_FLAG_RESERVATION;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpActiveLease::DoPropSheet
(
ITFSNode * pNode,
LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
return hr;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpActiveLease::SetClientName
(
LPCTSTR pName
)
{
if (pName != NULL)
{
m_strClientName = pName;
}
else
{
m_strClientName.Empty();
}
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::SetReservation
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
CDhcpActiveLease::SetReservation(BOOL fReservation)
{
if (fReservation)
{
if ( (m_leaseExpires.dwLowDateTime == DHCP_DATE_TIME_INFINIT_LOW) &&
(m_leaseExpires.dwHighDateTime == DHCP_DATE_TIME_INFINIT_HIGH) )
{
//
// This is an active reservation
//
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_dwTypeFlags |= TYPE_FLAG_ACTIVE;
m_strLeaseExpires.LoadString(IDS_DHCP_INFINITE_LEASE_ACTIVE);
}
else
if ( (m_leaseExpires.dwLowDateTime == 0) &&
(m_leaseExpires.dwHighDateTime == 0) )
{
m_dwTypeFlags |= TYPE_FLAG_RESERVATION;
m_strLeaseExpires.LoadString(IDS_DHCP_INFINITE_LEASE_INACTIVE);
}
else
{
Trace1("CDhcpActiveLease::SetReservation - %lx does not have a valid reservation lease time!", m_dhcpClientIpAddress);
}
}
else
{
m_dwTypeFlags &= ~TYPE_FLAG_RESERVATION;
m_dwTypeFlags &= ~TYPE_FLAG_ACTIVE;
}
}
/*!--------------------------------------------------------------------------
CDhcpActiveLease::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpActiveLease::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}
/*---------------------------------------------------------------------------
Class CDhcpAllocationRange implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpAllocationRange::CDhcpAllocationRange
(
ITFSComponentData * pTFSCompData,
DHCP_IP_RANGE * pdhcpIpRange
) : CDhcpHandler(pTFSCompData)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SetAddr (pdhcpIpRange->StartAddress, TRUE);
SetAddr (pdhcpIpRange->EndAddress, FALSE);
// now do the ending IP address
//
UtilCvtIpAddrToWstr (pdhcpIpRange->EndAddress,
&m_strEndIpAddress);
// and finally the description
//
m_strDescription.LoadString(IDS_ALLOCATION_RANGE_DESCRIPTION);
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpAllocationRange::CDhcpAllocationRange
(
ITFSComponentData * pTFSCompData,
DHCP_BOOTP_IP_RANGE * pdhcpIpRange
) : CDhcpHandler(pTFSCompData)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SetAddr (pdhcpIpRange->StartAddress, TRUE);
SetAddr (pdhcpIpRange->EndAddress, FALSE);
m_BootpAllocated = pdhcpIpRange->BootpAllocated;
m_MaxBootpAllowed = pdhcpIpRange->MaxBootpAllowed;
// now do the ending IP address
//
UtilCvtIpAddrToWstr (pdhcpIpRange->EndAddress,
&m_strEndIpAddress);
// and finally the description
//
m_strDescription.LoadString(IDS_ALLOCATION_RANGE_DESCRIPTION);
}
/*!--------------------------------------------------------------------------
CDhcpAllocationRange::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpAllocationRange::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CString strTemp;
UtilCvtIpAddrToWstr (QueryAddr(TRUE), &strTemp);
SetDisplayName(strTemp);
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_ALLOCATION_RANGE);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_ALLOCATION_RANGE);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_ALLOCATION_RANGE);
//SetColumnStringIDs(&aColumns[DHCPSNAP_ACTIVE_LEASES][0]);
//SetColumnWidths(&aColumnWidths[DHCPSNAP_ACTIVE_LEASES][0]);
return hrOK;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpAllocationRange::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
switch (nCol)
{
case 0:
return GetDisplayName();
case 1:
return (LPCWSTR)m_strEndIpAddress;
case 2:
return (LPCWSTR)m_strDescription;
}
return NULL;
}
/*!--------------------------------------------------------------------------
CDhcpAllocationRange::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpAllocationRange::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}
/*---------------------------------------------------------------------------
Class CDhcpExclusionRange implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpExclusionRange::CDhcpExclusionRange
(
ITFSComponentData * pTFSCompData,
DHCP_IP_RANGE * pdhcpIpRange
) : CDhcpHandler(pTFSCompData)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SetAddr (pdhcpIpRange->StartAddress, TRUE);
SetAddr (pdhcpIpRange->EndAddress, FALSE);
// now do the ending IP address
//
UtilCvtIpAddrToWstr (pdhcpIpRange->EndAddress,
&m_strEndIpAddress);
// and finally the description
//
m_strDescription.LoadString(IDS_EXCLUSION_RANGE_DESCRIPTION);
}
/*!--------------------------------------------------------------------------
CDhcpExclusionRange::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpExclusionRange::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CString strTemp;
UtilCvtIpAddrToWstr (QueryAddr(TRUE), &strTemp);
SetDisplayName(strTemp);
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_EXCLUSION_RANGE);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_EXCLUSION_RANGE);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_EXCLUSION_RANGE);
//SetColumnStringIDs(&aColumns[DHCPSNAP_ACTIVE_LEASES][0]);
//SetColumnWidths(&aColumnWidths[DHCPSNAP_ACTIVE_LEASES][0]);
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpExclusionRange::OnResultSelect
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpExclusionRange::OnResultSelect
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM lParam
)
{
HRESULT hr = hrOK;
SPIConsoleVerb spConsoleVerb;
SPITFSNode spNode;
CTFSNodeList listSelectedNodes;
BOOL bEnable = FALSE;
BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
int i;
CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
CORg (m_spNodeMgr->FindNode(cookie, &spNode));
// build the list of selected nodes
hr = BuildSelectedItemList(pComponent, &listSelectedNodes);
// walk the list of selected items. Make sure an allocation range isn't
// selected. If it is, don't enable the delete key
if (listSelectedNodes.GetCount() > 0)
{
BOOL bAllocRangeSelected = FALSE;
POSITION pos;
ITFSNode * pNode;
pos = listSelectedNodes.GetHeadPosition();
while (pos)
{
pNode = listSelectedNodes.GetNext(pos);
if (pNode->GetData(TFS_DATA_TYPE) == DHCPSNAP_ALLOCATION_RANGE)
{
bAllocRangeSelected = TRUE;
break;
}
}
if (!bAllocRangeSelected)
bEnable = TRUE;
}
for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = bEnable);
EnableVerbs(spConsoleVerb, g_ConsoleVerbStates[spNode->GetData(TFS_DATA_TYPE)], bStates);
Error:
return hr;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpExclusionRange::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
switch (nCol)
{
case 0:
return GetDisplayName();
case 1:
return (LPCWSTR)m_strEndIpAddress;
case 2:
return (LPCWSTR)m_strDescription;
}
return NULL;
}
/*!--------------------------------------------------------------------------
CDhcpExclusionRange::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpExclusionRange::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}
/*---------------------------------------------------------------------------
Class CDhcpBootpEntry implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
Constructor
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpBootpEntry::CDhcpBootpEntry
(
ITFSComponentData * pTFSCompData
) : CDhcpHandler(pTFSCompData)
{
}
/*!--------------------------------------------------------------------------
CDhcpBootpEntry::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpBootpEntry::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
SetDisplayName(m_strBootImage);
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_BOOTP_ENTRY);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_BOOTP_ENTRY);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_BOOTP_ENTRY);
//SetColumnStringIDs(&aColumns[DHCPSNAP_ACTIVE_LEASES][0]);
//SetColumnWidths(&aColumnWidths[DHCPSNAP_ACTIVE_LEASES][0]);
return hrOK;
}
/*---------------------------------------------------------------------------
CDhcpBootpEntry::OnPropertyChange
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpBootpEntry::OnResultPropertyChange
(
ITFSComponent * pComponent,
LPDATAOBJECT pDataObject,
MMC_COOKIE cookie,
LPARAM arg,
LPARAM param
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
SPITFSNode spNode;
m_spNodeMgr->FindNode(cookie, &spNode);
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpBootpEntry::GetString
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpBootpEntry::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
switch (nCol)
{
case 0:
return QueryBootImage();
case 1:
return QueryFileName();
case 2:
return QueryFileServer();
}
return NULL;
}
/*!--------------------------------------------------------------------------
CDhcpBootpEntry::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpBootpEntry::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpBootpEntry::operator ==
Description
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
CDhcpBootpEntry::operator ==
(
CDhcpBootpEntry & bootpEntry
)
{
CString strBootImage, strFileName, strFileServer;
strBootImage = bootpEntry.QueryBootImage();
strFileName = bootpEntry.QueryFileName();
strFileServer = bootpEntry.QueryFileServer();
if ( (m_strBootImage.CompareNoCase(strBootImage) == 0) &&
(m_strFileName.CompareNoCase(strFileName) == 0) &&
(m_strFileServer.CompareNoCase(strFileServer) == 0) )
{
return TRUE;
}
else
{
return FALSE;
}
}
/*!--------------------------------------------------------------------------
CDhcpBootpEntry::InitData
Description
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
CDhcpBootpEntry::InitData
(
CONST WCHAR grszwBootTable[], // IN: Group of strings for the boot table
DWORD dwLength
)
{
ASSERT(grszwBootTable != NULL);
CONST WCHAR * pszw;
pszw = PchParseUnicodeString(IN grszwBootTable, dwLength, OUT m_strBootImage);
ASSERT(*pszw == BOOT_FILE_STRING_DELIMITER_W);
dwLength -= ((m_strBootImage.GetLength() + 1) * sizeof(TCHAR));
pszw = PchParseUnicodeString(IN pszw + 1, dwLength, OUT m_strFileServer);
ASSERT(*pszw == BOOT_FILE_STRING_DELIMITER_W);
dwLength -= ((m_strFileServer.GetLength() + 1) * sizeof(TCHAR));
pszw = PchParseUnicodeString(IN pszw + 1, dwLength, OUT m_strFileName);
ASSERT(*pszw == '\0');
dwLength -= (m_strFileName.GetLength() * sizeof(TCHAR));
Assert(dwLength >= 0);
return const_cast<WCHAR *>(pszw + 1);
}
/*!--------------------------------------------------------------------------
Function
Compute the length (number of characters) necessary
to store the BOOTP entry. Additional characters
are added for extra security.
Author: EricDav
---------------------------------------------------------------------------*/
int
CDhcpBootpEntry::CchGetDataLength()
{
return 16 + m_strBootImage.GetLength() + m_strFileName.GetLength() + m_strFileServer.GetLength();
}
/*!--------------------------------------------------------------------------
Function
Write the data into a formatted string.
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
CDhcpBootpEntry::PchStoreData
(
OUT WCHAR szwBuffer[]
)
{
int cch;
cch = wsprintfW(OUT szwBuffer, L"%s,%s,%s",
(LPCTSTR)m_strBootImage,
(LPCTSTR)m_strFileServer,
(LPCTSTR)m_strFileName);
ASSERT(cch > 0);
ASSERT(cch + 4 < CchGetDataLength());
return const_cast<WCHAR *>(szwBuffer + cch + 1);
}
/*---------------------------------------------------------------------------
Class CDhcpOptionItem implementation
---------------------------------------------------------------------------*/
DEBUG_DECLARE_INSTANCE_COUNTER(CDhcpOptionItem);
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpOptionItem::CDhcpOptionItem
(
ITFSComponentData * pTFSCompData,
LPDHCP_OPTION_VALUE pOptionValue,
int nOptionImage
) : CDhcpOptionValue(*pOptionValue),
CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpOptionItem);
//
// initialize this node
//
m_nOptionImage = nOptionImage;
m_dhcpOptionId = pOptionValue->OptionID;
// assume non-vendor option
SetVendor(NULL);
m_verbDefault = MMC_VERB_PROPERTIES;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpOptionItem::CDhcpOptionItem
(
ITFSComponentData * pTFSCompData,
CDhcpOption * pOption,
int nOptionImage
) : CDhcpOptionValue(pOption->QueryValue()),
CDhcpHandler(pTFSCompData)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(CDhcpOptionItem);
//
// initialize this node
//
m_nOptionImage = nOptionImage;
m_dhcpOptionId = pOption->QueryId();
// assume non-vendor option
if (pOption->IsVendor())
SetVendor(pOption->GetVendor());
else
SetVendor(NULL);
SetClassName(pOption->GetClassName());
m_verbDefault = MMC_VERB_PROPERTIES;
}
CDhcpOptionItem::~CDhcpOptionItem()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(CDhcpOptionItem);
}
/*!--------------------------------------------------------------------------
CDhcpOptionItem::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpOptionItem::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_IMAGEINDEX, m_nOptionImage);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, m_nOptionImage);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_OPTION_ITEM);
//SetColumnStringIDs(&aColumns[DHCPSNAP_ACTIVE_LEASES][0]);
//SetColumnWidths(&aColumnWidths[DHCPSNAP_ACTIVE_LEASES][0]);
return hrOK;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpOptionItem::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
SPITFSNode spNode;
m_spNodeMgr->FindNode(cookie, &spNode);
CDhcpOption * pOptionInfo = FindOptionDefinition(pComponent, spNode);
switch (nCol)
{
case 0:
{
if (pOptionInfo)
pOptionInfo->QueryDisplayName(m_strName);
else
m_strName.LoadString(IDS_UNKNOWN);
return m_strName;
}
case 1:
return m_strVendorDisplay;
case 2:
{
if (pOptionInfo)
{
// special case the CSR option
BOOL fRouteArray = (
!pOptionInfo->IsClassOption() &&
(DHCP_OPTION_ID_CSR == pOptionInfo->QueryId()) &&
DhcpUnaryElementTypeOption ==
pOptionInfo->QueryOptType() &&
DhcpBinaryDataOption == pOptionInfo->QueryDataType()
);
if( !fRouteArray )
QueryDisplayString(m_strValue, FALSE);
else
QueryRouteArrayDisplayString(m_strValue);
}
else
m_strName.LoadString(IDS_UNKNOWN);
return m_strValue;
}
case 3:
if (IsClassOption())
return m_strClassName;
else
{
if (g_szClientTypeNone.IsEmpty())
g_szClientTypeNone.LoadString(IDS_NONE);
return g_szClientTypeNone;
}
}
return NULL;
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
CDhcpOptionItem::CreatePropertyPages
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
LPPROPERTYSHEETCALLBACK lpProvider,
LPDATAOBJECT pDataObject,
LONG_PTR handle
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//
// Create the property page
//
CPropertyPageHolderBase * pPropSheet;
SPITFSNode spSelectedNode, spNode, spOptCfgNode, spServerNode;
CString strOptCfgTitle, strOptType;
COptionValueEnum * pOptionValueEnum = NULL;
m_spNodeMgr->FindNode(cookie, &spNode);
SPIComponentData spComponentData;
m_spNodeMgr->GetComponentData(&spComponentData);
pComponent->GetSelectedNode(&spSelectedNode);
switch (spSelectedNode->GetData(TFS_DATA_TYPE))
{
case DHCPSNAP_GLOBAL_OPTIONS:
{
SPITFSNode spGlobalOptions;
// get some node information
spNode->GetParent(&spGlobalOptions);
spGlobalOptions->GetParent(&spServerNode);
CDhcpGlobalOptions * pGlobalOptions = GETHANDLER(CDhcpGlobalOptions, spGlobalOptions);
if (pGlobalOptions->HasPropSheetsOpen())
{
pGlobalOptions->GetOpenPropSheet(0, &pPropSheet);
pPropSheet->SetActiveWindow();
::PostMessage(PropSheet_GetCurrentPageHwnd(pPropSheet->GetSheetWindow()), WM_SELECTOPTION, (WPARAM) this, 0);
return E_FAIL;
}
// get some context info
pOptionValueEnum = pGlobalOptions->GetServerObject(spGlobalOptions)->GetOptionValueEnum();
spOptCfgNode.Set(spGlobalOptions);
// setup the page title
strOptType.LoadString(IDS_CONFIGURE_OPTIONS_GLOBAL);
AfxFormatString1(strOptCfgTitle, IDS_CONFIGURE_OPTIONS_TITLE, strOptType);
}
break;
case DHCPSNAP_SCOPE_OPTIONS:
{
// only the option type of this node can be configured here...
if (spNode->GetData(TFS_DATA_IMAGEINDEX) != ICON_IDX_SCOPE_OPTION_LEAF)
{
AfxMessageBox(IDS_CONNOT_CONFIGURE_OPTION_SCOPE);
return E_FAIL;
}
SPITFSNode spScopeOptions;
spNode->GetParent(&spScopeOptions);
// check to see if the page is already open, if so just activate it and
// set the current option to this one.
CDhcpScopeOptions * pScopeOptions = GETHANDLER(CDhcpScopeOptions, spScopeOptions);
spServerNode = pScopeOptions->GetServerNode(spScopeOptions);
if (pScopeOptions->HasPropSheetsOpen())
{
// found it, activate
pScopeOptions->GetOpenPropSheet(0, &pPropSheet);
pPropSheet->SetActiveWindow();
::PostMessage(PropSheet_GetCurrentPageHwnd(pPropSheet->GetSheetWindow()), WM_SELECTOPTION, (WPARAM) this, 0);
return E_FAIL;
}
// prepare to create a new page
pOptionValueEnum = pScopeOptions->GetScopeObject(spScopeOptions)->GetOptionValueEnum();
spOptCfgNode.Set(spScopeOptions);
strOptType.LoadString(IDS_CONFIGURE_OPTIONS_SCOPE);
AfxFormatString1(strOptCfgTitle, IDS_CONFIGURE_OPTIONS_TITLE, strOptType);
}
break;
case DHCPSNAP_RESERVATION_CLIENT:
{
// only the option type of this node can be configured here...
if (spNode->GetData(TFS_DATA_IMAGEINDEX) != ICON_IDX_CLIENT_OPTION_LEAF)
{
AfxMessageBox(IDS_CONNOT_CONFIGURE_OPTION_RES);
return E_FAIL;
}
SPITFSNode spResClient;
spNode->GetParent(&spResClient);
CDhcpReservationClient * pResClient = GETHANDLER(CDhcpReservationClient, spResClient);
spServerNode = pResClient->GetServerNode(spResClient, TRUE);
strOptType.LoadString(IDS_CONFIGURE_OPTIONS_CLIENT);
AfxFormatString1(strOptCfgTitle, IDS_CONFIGURE_OPTIONS_TITLE, strOptType);
// search the open prop pages to see if the option config page is up
// since the option config page is technically a property sheet for the node.
for (int i = 0; i < pResClient->HasPropSheetsOpen(); i++)
{
pResClient->GetOpenPropSheet(i, &pPropSheet);
HWND hwnd = pPropSheet->GetSheetWindow();
CString strTitle;
::GetWindowText(hwnd, strTitle.GetBuffer(256), 256);
strTitle.ReleaseBuffer();
if (strTitle == strOptCfgTitle)
{
// found it, activate
pPropSheet->SetActiveWindow();
::PostMessage(PropSheet_GetCurrentPageHwnd(pPropSheet->GetSheetWindow()), WM_SELECTOPTION, (WPARAM) this, 0);
return E_FAIL;
}
}
// no page up, get ready to create one
pOptionValueEnum = pResClient->GetOptionValueEnum();
spOptCfgNode.Set(spResClient);
}
break;
}
COptionsConfig * pOptionsConfig =
new COptionsConfig(spOptCfgNode, spServerNode, spComponentData, m_spTFSCompData, pOptionValueEnum, strOptCfgTitle, this);
//
// Object gets deleted when the page is destroyed
//
Assert(lpProvider != NULL);
return pOptionsConfig->CreateModelessSheet(lpProvider, handle);
}
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpOption *
CDhcpOptionItem::FindOptionDefinition
(
ITFSComponent * pComponent,
ITFSNode * pNode
)
{
SPITFSNode spSelectedNode;
CDhcpServer * pServer = NULL;
pComponent->GetSelectedNode(&spSelectedNode);
switch (spSelectedNode->GetData(TFS_DATA_TYPE))
{
case DHCPSNAP_GLOBAL_OPTIONS:
{
SPITFSNode spServer;
spSelectedNode->GetParent(&spServer);
pServer = GETHANDLER(CDhcpServer, spServer);
}
break;
case DHCPSNAP_SCOPE_OPTIONS:
{
CDhcpScopeOptions * pScopeOptions = GETHANDLER(CDhcpScopeOptions, spSelectedNode);
CDhcpScope * pScopeObject = pScopeOptions->GetScopeObject(spSelectedNode);
pServer = pScopeObject->GetServerObject();
}
break;
case DHCPSNAP_RESERVATION_CLIENT:
{
CDhcpReservationClient * pResClient = GETHANDLER(CDhcpReservationClient, spSelectedNode);
CDhcpScope * pScopeObject = pResClient->GetScopeObject(spSelectedNode, TRUE);
pServer = pScopeObject->GetServerObject();
}
break;
default:
//ASSERT(FALSE);
break;
}
if (pServer)
{
return pServer->FindOption(m_dhcpOptionId, GetVendor());
}
else
{
return NULL;
}
}
void
CDhcpOptionItem::SetVendor
(
LPCTSTR pszVendor
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
if (pszVendor == NULL)
m_strVendorDisplay.LoadString (IDS_VENDOR_STANDARD);
else
m_strVendorDisplay = pszVendor;
m_strVendor = pszVendor;
}
/*!--------------------------------------------------------------------------
CDhcpOptionItem::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpOptionItem::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}
/*---------------------------------------------------------------------------
Class CDhcpMCastLease implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
Function
Description
Author: EricDav
---------------------------------------------------------------------------*/
CDhcpMCastLease::CDhcpMCastLease
(
ITFSComponentData * pTFSCompData
) : CDhcpHandler(pTFSCompData)
{
//m_verbDefault = MMC_VERB_PROPERTIES;
m_dwTypeFlags = 0;
}
/*!--------------------------------------------------------------------------
CDhcpMCastLease::InitializeNode
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpMCastLease::InitializeNode
(
ITFSNode * pNode
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
int nImageIndex = ICON_IDX_CLIENT;
// Make the node immediately visible
pNode->SetVisibilityState(TFS_VIS_SHOW);
pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
pNode->SetData(TFS_DATA_USER, (LPARAM) this);
pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_MCAST_LEASE);
if (m_dwTypeFlags & TYPE_FLAG_GHOST)
{
nImageIndex = ICON_IDX_CLIENT_EXPIRED;
}
pNode->SetData(TFS_DATA_IMAGEINDEX, nImageIndex);
pNode->SetData(TFS_DATA_OPENIMAGEINDEX, nImageIndex);
return hrOK;
}
/*!--------------------------------------------------------------------------
CDhcpMCastLease::InitMCastInfo
Initializes node specific data
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
CDhcpMCastLease::InitMCastInfo
(
LPDHCP_MCLIENT_INFO pMClientInfo
)
{
HRESULT hr = hrOK;
BOOL fInfinite = FALSE;
m_dhcpClientIpAddress = pMClientInfo->ClientIpAddress;
UtilCvtIpAddrToWstr(m_dhcpClientIpAddress, &m_strIp);
m_strName = pMClientInfo->ClientName;
if ( (pMClientInfo->ClientLeaseEnds.dwLowDateTime == DHCP_DATE_TIME_INFINIT_LOW) &&
(pMClientInfo->ClientLeaseEnds.dwHighDateTime == DHCP_DATE_TIME_INFINIT_HIGH) )
{
fInfinite = TRUE;
}
CTime timeStart( (FILETIME&) pMClientInfo->ClientLeaseStarts );
FILETIME ft = {0};
if (!fInfinite)
{
ft.dwLowDateTime = pMClientInfo->ClientLeaseEnds.dwLowDateTime;
ft.dwHighDateTime = pMClientInfo->ClientLeaseEnds.dwHighDateTime;
}
CTime timeStop( ft );
m_timeStart = timeStart;
FormatDateTime(m_strLeaseStart, (FILETIME *) &pMClientInfo->ClientLeaseStarts);
m_timeStop = timeStop;
if (!fInfinite)
{
FormatDateTime(m_strLeaseStop, (FILETIME *) &pMClientInfo->ClientLeaseEnds);
}
else
{
m_strLeaseStop.LoadString(IDS_INFO_TIME_INFINITE);
}
// build the UID string
if (pMClientInfo->ClientId.DataLength >= 3 &&
pMClientInfo->ClientId.Data[0] == 'R' &&
pMClientInfo->ClientId.Data[1] == 'A' &&
pMClientInfo->ClientId.Data[2] == 'S')
{
m_strUID = RAS_UID;
}
else
{
// build the client UID string
CByteArray baUID;
for (DWORD i = 0; i < pMClientInfo->ClientId.DataLength; i++)
{
baUID.Add(pMClientInfo->ClientId.Data[i]);
}
UtilCvtByteArrayToString(baUID, m_strUID);
}
// check to see if this lease has expired
SYSTEMTIME st;
GetLocalTime(&st);
CTime systemTime(st);
if ( (systemTime > timeStop) &&
(!fInfinite) )
{
Trace2("CDhcpMCastLease::InitMCastInfo - expired lease SysTime %s, StopTime %s\n", systemTime.Format(_T("%#c")), m_strLeaseStop);
m_dwTypeFlags |= TYPE_FLAG_GHOST;
}
return hr;
}
/*!--------------------------------------------------------------------------
CDhcpMCastLease::GetString
Description
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP_(LPCTSTR)
CDhcpMCastLease::GetString
(
ITFSComponent * pComponent,
MMC_COOKIE cookie,
int nCol
)
{
SPITFSNode spNode;
m_spNodeMgr->FindNode(cookie, &spNode);
switch (nCol)
{
case 0:
return m_strIp;
case 1:
return m_strName;
case 2:
return m_strLeaseStart;
case 3:
return m_strLeaseStop;
case 4:
return m_strUID;
}
return NULL;
}
/*!--------------------------------------------------------------------------
CDhcpMCastLease::OnResultRefresh
Forwards refresh to parent to handle
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT CDhcpMCastLease::OnResultRefresh(ITFSComponent * pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
{
HRESULT hr = hrOK;
SPITFSNode spNode, spParent;
SPITFSResultHandler spParentRH;
m_spNodeMgr->FindNode(cookie, &spNode);
// forward this command to the parent to handle
CORg (spNode->GetParent(&spParent));
CORg (spParent->GetResultHandler(&spParentRH));
CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_REFRESH, arg, lParam));
Error:
return hrOK;
}