567 lines
17 KiB
C++
567 lines
17 KiB
C++
/******************************************************************
|
|
SNetFn.cpp -- Properties action functions (GET/SET)
|
|
|
|
MODULE:
|
|
DhcpProv.dll
|
|
|
|
DESCRIPTION:
|
|
Contains the definition for the action functions associated to
|
|
each manageable property from the class CDHCP_Server
|
|
|
|
REVISION:
|
|
08/03/98 - created
|
|
|
|
******************************************************************/
|
|
#include <stdafx.h>
|
|
|
|
#include "SNetScal.h" // needed for DHCP_Subnet_Property[] (for retrieving the property's name, for SET's)
|
|
#include "SNetFn.h" // own header
|
|
|
|
/*****************************************************************
|
|
* The definition of the class CDHCP_Subnet_Parameters
|
|
*****************************************************************/
|
|
// by default, all the data structures are NULL (and dw variables are 0'ed)
|
|
// those values indicates that no data is cached from the server.
|
|
CDHCP_Subnet_Parameters::CDHCP_Subnet_Parameters(DHCP_IP_ADDRESS dwSubnetAddress)
|
|
{
|
|
m_dwSubnetAddress = dwSubnetAddress;
|
|
m_pMibInfo = NULL;
|
|
m_pScopeMibInfo = NULL;
|
|
m_pSubnetInfo = NULL;
|
|
}
|
|
|
|
CDHCP_Subnet_Parameters::CDHCP_Subnet_Parameters(DHCP_IP_ADDRESS dwSubnetAddress, DHCP_IP_ADDRESS dwSubnetMask)
|
|
{
|
|
m_dwSubnetAddress = dwSubnetAddress;
|
|
m_pMibInfo = NULL;
|
|
m_pScopeMibInfo = NULL;
|
|
m_pSubnetInfo = NULL;
|
|
|
|
CheckExistsInfoPtr();
|
|
if (m_pSubnetInfo != NULL)
|
|
m_pSubnetInfo->SubnetMask = dwSubnetMask;
|
|
}
|
|
|
|
// the DHCP API calls are allocating memory for which the caller is responsible
|
|
// to release. We are releasing this memory upon the destruction of this object's instance.
|
|
CDHCP_Subnet_Parameters::~CDHCP_Subnet_Parameters()
|
|
{
|
|
if (m_pMibInfo != NULL)
|
|
{
|
|
if (m_pMibInfo->ScopeInfo != NULL)
|
|
DhcpRpcFreeMemory(m_pMibInfo->ScopeInfo);
|
|
|
|
DhcpRpcFreeMemory(m_pMibInfo);
|
|
}
|
|
|
|
// LPDHCP_CONFIG_INFO_V4 contains pointers to memory allocated by the DHCP server and
|
|
// which should be released by the caller.
|
|
if (m_pSubnetInfo!= NULL)
|
|
{
|
|
if (m_pSubnetInfo->SubnetName != NULL)
|
|
DhcpRpcFreeMemory(m_pSubnetInfo->SubnetName);
|
|
|
|
if (m_pSubnetInfo->SubnetComment != NULL)
|
|
DhcpRpcFreeMemory(m_pSubnetInfo->SubnetComment);
|
|
|
|
DhcpRpcFreeMemory(m_pSubnetInfo);
|
|
}
|
|
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Checks the m_pConfigInfoV4 pointer to insure it points to a valid buffer.
|
|
// It allocates the DHCP_SUBNET_INFO if needed.
|
|
BOOL CDHCP_Subnet_Parameters::CheckExistsInfoPtr()
|
|
{
|
|
if (m_pSubnetInfo != NULL)
|
|
return TRUE;
|
|
|
|
m_pSubnetInfo = (LPDHCP_SUBNET_INFO)MIDL_user_allocate(sizeof(DHCP_SUBNET_INFO));
|
|
|
|
if (m_pSubnetInfo != NULL)
|
|
{
|
|
m_pSubnetInfo->SubnetAddress = m_dwSubnetAddress;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Provides the data structure filled in through the DhcpGetMibInfo API
|
|
// If this data is cached and the caller is not forcing the refresh,
|
|
// returns the internal cache.
|
|
BOOL CDHCP_Subnet_Parameters::GetMibInfo(LPDHCP_MIB_INFO& pMibInfo, LPSCOPE_MIB_INFO& pScopeMibInfo, BOOL fRefresh)
|
|
{
|
|
if (m_pMibInfo == NULL)
|
|
fRefresh = TRUE;
|
|
|
|
if (fRefresh)
|
|
{
|
|
pMibInfo = NULL;
|
|
|
|
if (DhcpGetMibInfo(SERVER_IP_ADDRESS, &pMibInfo) != ERROR_SUCCESS)
|
|
return FALSE;
|
|
|
|
if (m_pMibInfo != NULL)
|
|
DhcpRpcFreeMemory(m_pMibInfo);
|
|
|
|
m_pMibInfo = pMibInfo;
|
|
|
|
pScopeMibInfo = NULL;
|
|
for (int i=0; i<pMibInfo->Scopes; i++)
|
|
{
|
|
LPSCOPE_MIB_INFO pLocal = &pMibInfo->ScopeInfo[i];
|
|
|
|
if (pLocal != NULL && pLocal->Subnet == m_dwSubnetAddress)
|
|
{
|
|
pScopeMibInfo = pLocal;
|
|
break;
|
|
}
|
|
}
|
|
|
|
m_pScopeMibInfo = pScopeMibInfo;
|
|
}
|
|
else
|
|
{
|
|
pMibInfo = m_pMibInfo;
|
|
pScopeMibInfo = m_pScopeMibInfo;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Provides the data structure filled in through the DhcpSubnetInfo API
|
|
// If this data is cached and the caller is not forcing the refresh,
|
|
// return the internal cache. Otherwise, the internal cache is refreshed as well.
|
|
BOOL CDHCP_Subnet_Parameters::GetSubnetInfo(LPDHCP_SUBNET_INFO& pSubnetInfo, BOOL fRefresh)
|
|
{
|
|
if (m_pSubnetInfo == NULL)
|
|
fRefresh = TRUE;
|
|
|
|
if (fRefresh)
|
|
{
|
|
pSubnetInfo = NULL;
|
|
|
|
if (DhcpGetSubnetInfo(SERVER_IP_ADDRESS, m_dwSubnetAddress, &pSubnetInfo) != ERROR_SUCCESS)
|
|
return FALSE;
|
|
|
|
if (m_pSubnetInfo != NULL)
|
|
DhcpRpcFreeMemory(m_pSubnetInfo);
|
|
m_pSubnetInfo = pSubnetInfo;
|
|
}
|
|
else
|
|
pSubnetInfo = m_pSubnetInfo;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Creates a new subnet.
|
|
// Assumes that all the fields from the DHCP_SUBNET_INFO structure are valid, and filled with
|
|
// the data to be set. Calls the underlying API and returns TRUE (on success) or FALSE (on failure)
|
|
BOOL CDHCP_Subnet_Parameters::CommitNew(DWORD &returnCode)
|
|
{
|
|
if (m_pSubnetInfo == NULL)
|
|
return FALSE;
|
|
|
|
returnCode = DhcpCreateSubnet(
|
|
SERVER_IP_ADDRESS,
|
|
m_pSubnetInfo->SubnetAddress,
|
|
m_pSubnetInfo );
|
|
|
|
return returnCode == ERROR_SUCCESS;
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Modifies info on an existing subnet.
|
|
// Assumes that all the fields from the DHCP_SUBNET_INFO structure are valid, and filled with
|
|
// the data to be set. Calls the underlying API and returns TRUE (on success) or FALSE (on failure)
|
|
BOOL CDHCP_Subnet_Parameters::CommitSet(DWORD &returnCode)
|
|
{
|
|
if (m_pSubnetInfo == NULL)
|
|
return FALSE;
|
|
|
|
returnCode = DhcpSetSubnetInfo(
|
|
SERVER_IP_ADDRESS,
|
|
m_pSubnetInfo->SubnetAddress,
|
|
m_pSubnetInfo );
|
|
|
|
return returnCode == ERROR_SUCCESS;
|
|
}
|
|
|
|
// DESCRIPTION:
|
|
// Assumes the m_dwSubnet is initialized, case in which it calls the DHCPAPI to delete that subnet
|
|
// from the server.
|
|
BOOL CDHCP_Subnet_Parameters::DeleteSubnet()
|
|
{
|
|
if (DhcpDeleteSubnet(SERVER_IP_ADDRESS, m_dwSubnetAddress, DhcpFullForce) == ERROR_SUCCESS)
|
|
{
|
|
m_dwSubnetAddress = 0;
|
|
// don't look below :o)
|
|
// It's only an exotic way of calling the destructor without destroying the object itself
|
|
this->~CDHCP_Subnet_Parameters();
|
|
m_pSubnetInfo = NULL;
|
|
m_pScopeMibInfo = NULL;
|
|
m_pMibInfo = NULL;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/*------------------------Property Action Functions below-----------------------*/
|
|
// unlike for SrvScal, we expect the pParams to be not-null, or otherwise this call fails.
|
|
// we do this because pParams is the one holding the subnet address which must be known
|
|
// in order to call the DHCP api (it has to be filled in by the caller).
|
|
// This applies to all 'GET' functions.
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetAddress, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_SUBNET_INFO pSubnetInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
|
|
|
|
if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
|
|
pSubnetInfo != NULL)
|
|
{
|
|
// nothing special to do here, the property (Address) should be just there!
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetMask, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_SUBNET_INFO pSubnetInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
|
|
|
|
if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
|
|
pSubnetInfo != NULL)
|
|
{
|
|
WCHAR szMask[16]; // should be enough for holding 'xxx.yyy.zzz.uuu\0'
|
|
|
|
swprintf(szMask, L"%u.%u.%u.%u",(pSubnetInfo->SubnetMask & 0xff000000) >> 24,
|
|
(pSubnetInfo->SubnetMask & 0x00ff0000) >> 16,
|
|
(pSubnetInfo->SubnetMask & 0x0000ff00) >> 8,
|
|
(pSubnetInfo->SubnetMask & 0x000000ff));
|
|
|
|
pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Mask].m_wsPropName, szMask);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetName, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_SUBNET_INFO pSubnetInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
|
|
|
|
if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
|
|
pSubnetInfo != NULL)
|
|
{
|
|
pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Name].m_wsPropName, pSubnetInfo->SubnetName);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
// Set functions require the SubnetAddress which can be taken only from pParams.
|
|
// The changes are applied instantly only if pOut is not NULL (so the caller wants and
|
|
// gets a return code)
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetSetName, pParams, pIn, pOut)
|
|
{
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
CHString wsName;
|
|
|
|
// pParams and pIn have to be valid to provide the SubnetAddress and the Name to set
|
|
if (pParams == NULL || pIn == NULL)
|
|
return FALSE;
|
|
|
|
// get the CDHCP_Subnet_Parameters out of pParams
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
// make sure there is a buffer for holding all this info.
|
|
pSubnetParams->CheckExistsInfoPtr();
|
|
|
|
// get the value to set from the pIn parameter
|
|
if (!pIn->GetCHString(DHCP_Subnet_Property[IDX_SNET_Name].m_wsPropName, wsName))
|
|
return FALSE;
|
|
|
|
// release any old buffer
|
|
if (pSubnetParams->m_pSubnetInfo->SubnetName != NULL)
|
|
DhcpRpcFreeMemory(pSubnetParams->m_pSubnetInfo->SubnetName);
|
|
|
|
// allocate a new buffer able to hold this new name
|
|
pSubnetParams->m_pSubnetInfo->SubnetName = (WCHAR*)MIDL_user_allocate(sizeof(WCHAR)*wsName.GetLength()+sizeof(WCHAR));
|
|
|
|
// make sure the allocation succeeded
|
|
if (pSubnetParams->m_pSubnetInfo->SubnetName == NULL)
|
|
return FALSE;
|
|
|
|
// copy the name to the new buffer
|
|
#ifdef _UNICODE
|
|
wcscpy(pSubnetParams->m_pSubnetInfo->SubnetName, wsName);
|
|
#else
|
|
swprintf(pSubnetParams->m_pSubnetInfo->SubnetName, L"%S", wsName);
|
|
#endif
|
|
|
|
// if this is a request for 'instant apply', do it now
|
|
if (pOut != NULL)
|
|
{
|
|
DWORD errCode;
|
|
|
|
pSubnetParams->CommitSet(errCode);
|
|
// fill back the code returned by the underlying level
|
|
if (pOut != NULL)
|
|
pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
|
|
}
|
|
|
|
// the API call succeeded
|
|
return TRUE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetComment, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_SUBNET_INFO pSubnetInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
|
|
|
|
if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
|
|
pSubnetInfo != NULL)
|
|
{
|
|
pOut->SetCHString(DHCP_Subnet_Property[IDX_SNET_Comment].m_wsPropName, pSubnetInfo->SubnetComment);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
// Set functions require the SubnetAddress which can be taken only from pParams.
|
|
// The changes are applied instantly only if pOut is not NULL (so the caller wants and
|
|
// gets a return code)
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetSetComment, pParams, pIn, pOut)
|
|
{
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
CHString wsComment;
|
|
|
|
// pIn has to be not-null to provide the comment
|
|
if (pParams == NULL || pIn == NULL)
|
|
return FALSE;
|
|
|
|
// get the pSubnetParams out of pParams
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
// make sure there is a buffer for holding all this info.
|
|
pSubnetParams->CheckExistsInfoPtr();
|
|
|
|
// get the value to set from the pIn parameter
|
|
if (!pIn->GetCHString(DHCP_Subnet_Property[IDX_SNET_Comment].m_wsPropName, wsComment))
|
|
return FALSE;
|
|
|
|
// release any old buffer
|
|
if (pSubnetParams->m_pSubnetInfo->SubnetComment != NULL)
|
|
DhcpRpcFreeMemory(pSubnetParams->m_pSubnetInfo->SubnetComment);
|
|
|
|
// allocate a new buffer able to hold the new comment
|
|
pSubnetParams->m_pSubnetInfo->SubnetComment = (WCHAR*)MIDL_user_allocate(sizeof(WCHAR)*wsComment.GetLength()+sizeof(WCHAR));
|
|
|
|
if (pSubnetParams->m_pSubnetInfo->SubnetComment == NULL)
|
|
return FALSE;
|
|
|
|
// copy the comment to the new buffer
|
|
#ifdef _UNICODE
|
|
wcscpy(pSubnetParams->m_pSubnetInfo->SubnetComment, wsComment);
|
|
#else
|
|
swprintf(pSubnetParams->m_pSubnetInfo->SubnetComment, L"%S", wsComment);
|
|
#endif
|
|
|
|
// if this is a request for 'instant apply', do it now
|
|
if (pOut != NULL)
|
|
{
|
|
DWORD errCode;
|
|
|
|
pSubnetParams->CommitSet(errCode);
|
|
// fill back the code returned by the underlying level
|
|
if (pOut != NULL)
|
|
pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
|
|
}
|
|
|
|
// the API call succeeded
|
|
return TRUE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetState, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_SUBNET_INFO pSubnetInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pSubnetInfo == NULL;
|
|
|
|
if (pSubnetParams->GetSubnetInfo(pSubnetInfo, fRefresh) &&
|
|
pSubnetInfo != NULL)
|
|
{
|
|
pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_State].m_wsPropName, pSubnetInfo->SubnetState);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
// Set functions require the SubnetAddress which can be taken only from pParams.
|
|
// The changes are applied instantly only if pOut is not NULL (so the caller wants and
|
|
// gets a return code)
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetSetState, pParams, pIn, pOut)
|
|
{
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
DWORD dwState;
|
|
|
|
// pIn has to be not-null to provide the new State
|
|
if (pParams == NULL || pIn == NULL)
|
|
return FALSE;
|
|
|
|
// get pSubnetParams out of pParams
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
// make sure there is a buffer for holding all this info.
|
|
pSubnetParams->CheckExistsInfoPtr();
|
|
|
|
// get the value to set from the pIn parameter
|
|
if (!pIn->GetDWORD(DHCP_Subnet_Property[IDX_SNET_State].m_wsPropName, dwState))
|
|
return FALSE;
|
|
|
|
// test roughly if the new value matches the range of admissible values
|
|
switch((DHCP_SUBNET_STATE)dwState)
|
|
{
|
|
case DhcpSubnetEnabled:
|
|
pSubnetParams->m_pSubnetInfo->SubnetState = DhcpSubnetEnabled;
|
|
break;
|
|
case DhcpSubnetDisabled:
|
|
pSubnetParams->m_pSubnetInfo->SubnetState = DhcpSubnetDisabled;
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
// if the request is for an 'instant apply', do it now
|
|
if (pOut != NULL)
|
|
{
|
|
DWORD errCode;
|
|
|
|
pSubnetParams->CommitSet(errCode);
|
|
// fill back the code returned by the underlying level
|
|
if (pOut != NULL)
|
|
pOut->SetDWORD(RETURN_CODE_PROPERTY_NAME, errCode);
|
|
}
|
|
|
|
// the API call succeeded
|
|
return TRUE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfAddressesInUse, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_MIB_INFO pMibInfo;
|
|
LPSCOPE_MIB_INFO pScopeMibInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pMibInfo == NULL;
|
|
|
|
if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
|
|
pScopeMibInfo != NULL)
|
|
{
|
|
pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbAddrInUse].m_wsPropName, pScopeMibInfo->NumAddressesInuse);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfAddressesFree, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_MIB_INFO pMibInfo;
|
|
LPSCOPE_MIB_INFO pScopeMibInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pMibInfo == NULL;
|
|
|
|
if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
|
|
pScopeMibInfo != NULL)
|
|
{
|
|
pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbAddrFree].m_wsPropName, pScopeMibInfo->NumAddressesFree);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|
|
|
|
MFN_PROPERTY_ACTION_DEFN(fnSNetGetNumberOfPendingOffers, pParams, pIn, pOut)
|
|
{
|
|
BOOL fRefresh;
|
|
CDHCP_Subnet_Parameters *pSubnetParams;
|
|
LPDHCP_MIB_INFO pMibInfo;
|
|
LPSCOPE_MIB_INFO pScopeMibInfo;
|
|
|
|
if (pParams == NULL || pOut == NULL)
|
|
return FALSE;
|
|
|
|
pSubnetParams = (CDHCP_Subnet_Parameters *)pParams;
|
|
fRefresh = pSubnetParams->m_pMibInfo == NULL;
|
|
|
|
if (pSubnetParams->GetMibInfo(pMibInfo, pScopeMibInfo, fRefresh) &&
|
|
pScopeMibInfo != NULL)
|
|
{
|
|
pOut->SetDWORD(DHCP_Subnet_Property[IDX_SNET_NbPendingOffers].m_wsPropName, pScopeMibInfo->NumPendingOffers);
|
|
return TRUE;
|
|
}
|
|
|
|
// the API call failed
|
|
return FALSE;
|
|
}
|