|
|
/******************************************************************
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; }
|