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.
 
 
 
 
 
 

350 lines
12 KiB

#include "precomp.h"
#pragma hdrstop
#include <stdio.h>
#include <process.h>
#include "IpSubnetMaskControl.h"
#include "wlbsconfig.h"
#include "wlbsutil.h"
/* Limitations for IP address fields. */
#define WLBS_FIELD_EMPTY -1
#define WLBS_FIELD_LOW 0
#define WLBS_FIELD_HIGH 255
#define WLBS_BLANK_HPRI -1
void PrintIPRangeError(HINSTANCE hInstance, HWND hWnd, unsigned int ids, int value, int low, int high);
CIpSubnetMaskControl::CIpSubnetMaskControl(DWORD dwIpAddressId, DWORD dwSubnetMaskId)
{
m_dwIpAddressId = dwIpAddressId;
m_dwSubnetMaskId = dwSubnetMaskId;
m_hWndDialog = NULL;
m_hInstance = NULL;
ZeroMemory(&m_IPFieldChangeState, sizeof(m_IPFieldChangeState));
}
//+----------------------------------------------------------------------------
//
// Function: CIpSubnetMaskControl::OnInitDialog
//
// Description: Called upon WM_INITDIALOG message.
//
// Arguments: HWND hWnd - the parent dialog window
// HINSTANCE hInstance - instance handle for resources
//
// Returns: Nothing
//
// History: fengsun Created Header 1/10/01
//
//+----------------------------------------------------------------------------
void CIpSubnetMaskControl::OnInitDialog(HWND hWnd, HINSTANCE hInstance)
{
m_hWndDialog = hWnd;
m_hInstance = hInstance;
/* Limit the field ranges for the address fields. */
::SendDlgItemMessage(hWnd, m_dwIpAddressId, EM_SETLIMITTEXT, CVY_MAX_CL_IP_ADDR, 0);
::SendDlgItemMessage(hWnd, m_dwSubnetMaskId, EM_SETLIMITTEXT, CVY_MAX_CL_NET_MASK, 0);
/* Limit the zeroth field of the dedicated IP address between 1 and 223. */
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, IPM_SETRANGE, 0, (LPARAM)MAKEIPRANGE(WLBS_IP_FIELD_ZERO_LOW, WLBS_IP_FIELD_ZERO_HIGH));
}
/*
* Method: OnSubnetMask
* Description: Called when the user modifies the host netmask.
*/
LRESULT CIpSubnetMaskControl::OnSubnetMask(WORD wNotifyCode)
{
WCHAR wszIpAddress [CVY_MAX_CL_IP_ADDR + 1];
WCHAR wszSubnetMask [CVY_MAX_CL_NET_MASK + 1];
switch (wNotifyCode)
{
case EN_SETFOCUS:
/* Only generate a netmask if the netmask is currently empty and the IP address is not. */
if (::SendMessage(::GetDlgItem(m_hWndDialog, m_dwSubnetMaskId), IPM_ISBLANK, 0, 0) &&
!::SendMessage(::GetDlgItem(m_hWndDialog, m_dwIpAddressId), IPM_ISBLANK, 0, 0))
{
/* Retrieve the cluster IP address. */
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, WM_GETTEXT, CVY_MAX_CL_IP_ADDR + 1, (LPARAM)wszIpAddress);
/* Fill the subnet mask. */
ParamsGenerateSubnetMask(wszIpAddress, wszSubnetMask, ASIZECCH(wszSubnetMask));
/* Set the cluster subnet mask. */
::SendDlgItemMessage(m_hWndDialog, m_dwSubnetMaskId, WM_SETTEXT, 0, (LPARAM)wszSubnetMask);
break;
}
}
return 0;
}
/*
* Method: OnIpFieldChange
* Description: Called wnen a field (byte) of the IP address/subnetmask changes. We use this
* to make sure the first byte of the IP is not < 1 or > 223.
*/
LRESULT CIpSubnetMaskControl::OnIpFieldChange(int idCtrl, LPNMHDR pnmh)
{
LPNMIPADDRESS Ip;
int low = WLBS_FIELD_LOW;
int high = WLBS_FIELD_HIGH;
Ip = (LPNMIPADDRESS)pnmh;
if (idCtrl == m_dwIpAddressId)
{
/* Field zero of the cluster IP address has different limits. */
if (!Ip->iField)
{
low = WLBS_IP_FIELD_ZERO_LOW;
high = WLBS_IP_FIELD_ZERO_HIGH;
}
}
/* The notifier may call us twice for the same change, so we have to do the bookkeeping to make
sure we only alert the user once. Use static variables to keep track of our state. This will
allow us to ignore duplicate alerts. */
if ((m_IPFieldChangeState.IpControl != Ip->hdr.idFrom) || (m_IPFieldChangeState.Field != Ip->iField) ||
(m_IPFieldChangeState.Value != Ip->iValue) || (m_IPFieldChangeState.RejectTimes > 0)) {
m_IPFieldChangeState.RejectTimes = 0;
m_IPFieldChangeState.IpControl = Ip->hdr.idFrom;
m_IPFieldChangeState.Field = Ip->iField;
m_IPFieldChangeState.Value = Ip->iValue;
/* Check the field value against its limits. */
if ((Ip->iValue != WLBS_FIELD_EMPTY) && ((Ip->iValue < low) || (Ip->iValue > high)))
{
/* Alert the user. */
PrintIPRangeError(m_hInstance, m_hWndDialog,
(idCtrl == m_dwIpAddressId) ? IDS_PARM_CL_IP_FIELD : IDS_PARM_CL_NM_FIELD,
Ip->iValue, low, high);
}
} else m_IPFieldChangeState.RejectTimes++;
return 0;
}
//+----------------------------------------------------------------------------
//
// Function: CIpSubnetMaskControl::SetInfo
//
// Description: Set the value to the control
//
// Arguments: const WCHAR* pszIpAddress -
// const WCHAR* pszSubnetMask -
//
// Returns: Nothing
//
// History: shouse initial code
// fengsun Created Header 1/10/01
//
//+----------------------------------------------------------------------------
void CIpSubnetMaskControl::SetInfo(const WCHAR* pszIpAddress, const WCHAR* pszSubnetMask)
{
/* If the cluster IP address or subnet mask are the default values, set them to NUL strings. */
/* If the dedicated IP address is empty, then clear the entry box. Otherwise, populate it with the IP address. */
if (!pszIpAddress[0] || !wcscmp(pszIpAddress, CVY_DEF_CL_IP_ADDR))
::SendMessage(::GetDlgItem(m_hWndDialog, m_dwIpAddressId), IPM_CLEARADDRESS, 0, 0);
else
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, WM_SETTEXT, 0, (LPARAM)pszIpAddress);
/* If the host subnet mask is empty, then clear the entry box. Otherwise, populate it with the netmask. */
if (!pszSubnetMask[0] || !wcscmp(pszSubnetMask, CVY_DEF_CL_NET_MASK))
::SendMessage(::GetDlgItem(m_hWndDialog, m_dwSubnetMaskId), IPM_CLEARADDRESS, 0, 0);
else
::SendDlgItemMessage(m_hWndDialog, m_dwSubnetMaskId, WM_SETTEXT, 0, (LPARAM)pszSubnetMask);
}
//+----------------------------------------------------------------------------
//
// Function: CIpSubnetMaskControl::UpdateInfo
//
// Description: Retrieve value from control
//
// Arguments: OUT WCHAR* pszIpAddress -
// OUT WCHAR* pszSubnetMask -
//
// Returns: Nothing
//
// History: shouse initial code
// fengsun Created Header 1/10/01
//
//+----------------------------------------------------------------------------
void CIpSubnetMaskControl::UpdateInfo(OUT WCHAR* pszIpAddress, OUT WCHAR* pszSubnetMask)
/*
We expect that outparams are of
(CVY_MAX_CL_IP_ADDR + 1) and (CVY_MAX_CL_NET_MASK + 1)
characters each, respectively.
*/
{
/* If the dedicated IP entry box is empty, then the dedicated IP address is NUL. Otherwise, grab it from the UI. */
if (::SendMessage(::GetDlgItem(m_hWndDialog, m_dwIpAddressId), IPM_ISBLANK, 0, 0))
{
StringCchCopy(pszIpAddress, CVY_MAX_CL_IP_ADDR+1, CVY_DEF_CL_IP_ADDR);
}
else
{
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, WM_GETTEXT, CVY_MAX_CL_IP_ADDR, (LPARAM)pszIpAddress);
}
/* If the host net mask entry box is empty, then the host net mask is NUL. Otherwise, grab it from the UI. */
if (::SendMessage(::GetDlgItem(m_hWndDialog, m_dwSubnetMaskId), IPM_ISBLANK, 0, 0))
{
StringCchCopy(pszSubnetMask, CVY_MAX_CL_NET_MASK+1, CVY_DEF_CL_NET_MASK);
}
else
{
::SendDlgItemMessage(m_hWndDialog, m_dwSubnetMaskId, WM_GETTEXT, CVY_MAX_CL_NET_MASK, (LPARAM)pszSubnetMask);
}
}
//+----------------------------------------------------------------------------
//
// Function: CIpSubnetMaskControl::ValidateInfo
//
// Description: Validate whether user input is valid
//
// Arguments: None
//
// Returns: bool - TRUE if valid
//
// History: shouse initial code
// fengsun Created Header 1/10/01
//
//+----------------------------------------------------------------------------
bool CIpSubnetMaskControl::ValidateInfo()
{
DWORD IPAddr;
/* Check for blank IP address */
if (::SendMessage(::GetDlgItem(m_hWndDialog, m_dwIpAddressId), IPM_ISBLANK, 0, 0))
{
/* Alert the user. */
NcMsgBox(m_hInstance, ::GetActiveWindow(), IDS_PARM_ERROR, IDS_PARM_CL_IP_BLANK,
MB_APPLMODAL | MB_ICONSTOP | MB_OK);
SetFocus(::GetDlgItem(m_hWndDialog, m_dwIpAddressId));
/* An error occurred. */
return false;
}
/* Check for blank netmask */
if (::SendMessage(::GetDlgItem(m_hWndDialog, m_dwSubnetMaskId), IPM_ISBLANK, 0, 0))
{
/* Fill in the netmask for the user. */
OnSubnetMask(EN_SETFOCUS);
/* Alert the user. */
NcMsgBox(m_hInstance, ::GetActiveWindow(), IDS_PARM_ERROR, IDS_PARM_CL_NM_BLANK,
MB_APPLMODAL | MB_ICONSTOP | MB_OK);
/* An error occurred. */
return false;
}
/* Only perform the rest of the IP checking if the user has specified both a dedicated
IP address and a corresponding netmask. */
if (!::SendMessage(::GetDlgItem(m_hWndDialog, m_dwIpAddressId), IPM_ISBLANK, 0, 0) &&
!::SendMessage(::GetDlgItem(m_hWndDialog, m_dwSubnetMaskId), IPM_ISBLANK, 0, 0)) {
/* Get the dedicated IP address. */
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, IPM_GETADDRESS, 0, (LPARAM)&IPAddr);
/* Make sure that the first octet is not zero. If it is, make it 1 and alter the user. */
if (!FIRST_IPADDRESS(IPAddr)) {
/* Make the first octet 1 instead of the erroneous 0. */
IPAddr = IPAddr | (DWORD)(WLBS_IP_FIELD_ZERO_LOW << 24);
/* Set the IP address and update our dedicated IP address string. */
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, IPM_SETADDRESS, 0, (LPARAM)IPAddr);
/* Alert the user. */
PrintIPRangeError(m_hInstance, m_hWndDialog, IDS_PARM_CL_IP_FIELD, 0,
WLBS_IP_FIELD_ZERO_LOW, WLBS_IP_FIELD_ZERO_HIGH);
SetFocus(::GetDlgItem(m_hWndDialog, m_dwIpAddressId));
return false;
}
WCHAR szIpAddress [CVY_MAX_CL_IP_ADDR + 1];
WCHAR szSubnetMask [CVY_MAX_CL_IP_ADDR + 1];
::SendDlgItemMessage(m_hWndDialog, m_dwIpAddressId, WM_GETTEXT, CVY_MAX_CL_IP_ADDR, (LPARAM)szIpAddress);
::SendDlgItemMessage(m_hWndDialog, m_dwSubnetMaskId, WM_GETTEXT, CVY_MAX_CL_NET_MASK, (LPARAM)szSubnetMask);
/* Check for valid dedicated IP address/netmask pairs. */
if (!IsValidIPAddressSubnetMaskPair(szIpAddress, szSubnetMask)) {
/* Alert the user. */
NcMsgBox(m_hInstance, ::GetActiveWindow(), IDS_PARM_ERROR, IDS_PARM_INVAL_CL_IP,
MB_APPLMODAL | MB_ICONSTOP | MB_OK);
SetFocus(::GetDlgItem(m_hWndDialog, m_dwIpAddressId));
/* An error occurred. */
return false;
}
/* Check to make sure that the netmask is contiguous. */
if (!IsContiguousSubnetMask(szSubnetMask)) {
/* Alert the user. */
NcMsgBox(m_hInstance, ::GetActiveWindow(), IDS_PARM_ERROR, IDS_PARM_INVAL_CL_MASK,
MB_APPLMODAL | MB_ICONSTOP | MB_OK);
SetFocus(::GetDlgItem(m_hWndDialog, m_dwIpAddressId));
/* An error occurred. */
return false;
}
}
return true; // no error
}
/*
* Method: PrintIPRangeError
* Description: Displays a message box warning the user of an out-of-range entry in
* an IP address octet.
*/
void PrintIPRangeError (HINSTANCE hInstance, HWND hWnd, unsigned int ids, int value, int low, int high)
{
WCHAR szCurrent[12];
WCHAR szLow[12];
WCHAR szHigh[12];
/* Fill in the range and the offending value. */
StringCbPrintf(szHigh, sizeof(szHigh), L"%d", high);
StringCbPrintf(szCurrent, sizeof(szCurrent), L"%d", value);
StringCbPrintf(szLow, sizeof(szLow), L"%d", low);
/* Pop-up a message box. */
NcMsgBox(hInstance, hWnd, IDS_PARM_ERROR, ids, MB_APPLMODAL | MB_ICONSTOP | MB_OK, szCurrent, szLow, szHigh);
}