Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

734 lines
18 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corp., 1995 **/
/**********************************************************************/
/*
addstati.cpp
Purpose : Dialog used when adding static mappings
to the currently open WINS server.
Multiple mappings can be added, as
the dialog does not get dismissed until
the "Close" button is pressed.
FILE HISTORY:
*/
#include "stdafx.h"
#include "winsadmn.h"
#include "addstati.h"
#include "mainfrm.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
/////////////////////////////////////////////////////////////////////////////
static const char rgchHex[16*2+1] = "00112233445566778899aAbBcCdDeEfF";
/////////////////////////////////////////////////////////////////////////////
// FGetByte()
//
// Return the byte value of a string.
// Return TRUE pbNum is set to the byte value (only if the string contains
// valid digits)
// Return FALSE if string has unrecognized digits or byte overflow.
//
// eg:
// szNum = "xFF" => return TRUE
// szNum = "255" => return TRUE
// szNum = "256" => return FALSE (overflow)
// szNum = "26a" => return TRUE (*pbNum = 26, *ppchNext = "a")
// szNum = "ab" => return FALSE (unrecognized digits)
//
BOOL FGetByte(IN const char szNum[], OUT BYTE * pbNum, OUT const char ** ppchNext)
{
ASSERT(szNum);
ASSERT(pbNum);
ASSERT(ppchNext);
int nResult;
char * pchNum = (char *)szNum;
int iBase = 10; // Assume a decimal base
if (*pchNum == 'x' || *pchNum == 'X') // Check if we are using hexadecimal base
{
iBase = 16;
pchNum++;
}
char * pchDigit = strchr(rgchHex, *pchNum++);
if (pchDigit == NULL)
return FALSE;
int iDigit = (pchDigit - rgchHex) >> 1;
if (iDigit >= iBase)
{
// Hexadecimal character in a decimal integer
return FALSE;
}
nResult = iDigit;
pchDigit = strchr(rgchHex, *pchNum);
iDigit = (pchDigit - rgchHex) >> 1;
if (pchDigit == NULL || iDigit >= iBase)
{
// Only one character was valid
*pbNum = nResult;
*ppchNext = pchNum;
return TRUE;
}
pchNum++;
nResult = (nResult * iBase) + iDigit;
ASSERT(nResult < 256);
if (iBase == 16)
{
// Hexadecimal value, stop there
*pbNum = nResult;
*ppchNext = pchNum;
return TRUE;
}
// Decimal digit, so search for an optional third character
pchDigit = strchr(rgchHex, *pchNum);
iDigit = (pchDigit - rgchHex) >> 1;
if (pchDigit == NULL || iDigit >= iBase)
{
*pbNum = nResult;
*ppchNext = pchNum;
return TRUE;
}
nResult = (nResult * iBase) + iDigit;
if (nResult >= 256)
return FALSE;
pchNum++;
*pbNum = nResult;
*ppchNext = pchNum;
return TRUE;
} // FGetByte
/////////////////////////////////////////////////////////////////////////////
// CAddStaticMappingDlg dialog
CAddStaticMappingDlg::CAddStaticMappingDlg(
CWnd* pParent /*=NULL*/
)
: CDialog(CAddStaticMappingDlg::IDD, pParent),
m_nMappingsAdded(0)
{
//
// Configure the up/down bitmap buttons.
//
if (!m_bbutton_Up.LoadBitmaps(MAKEINTRESOURCE(IDB_UP),
MAKEINTRESOURCE(IDB_UPINV),
MAKEINTRESOURCE(IDB_UPFOC),
MAKEINTRESOURCE(IDB_UPDIS))
|| !m_bbutton_Down.LoadBitmaps(MAKEINTRESOURCE(IDB_DOWN),
MAKEINTRESOURCE(IDB_DOWNINV),
MAKEINTRESOURCE(IDB_DOWNFOC),
MAKEINTRESOURCE(IDB_DOWNDIS)) ||
!m_strMultiplePrompt.LoadString(IDS_IPADDRESS_MULTIPLE))
{
AfxThrowResourceException();
}
m_iMappingType = WINSINTF_E_UNIQUE;
m_fInternetGroup = FALSE;
//{{AFX_DATA_INIT(CAddStaticMappingDlg)
//}}AFX_DATA_INIT
}
void
CAddStaticMappingDlg::DoDataExchange(
CDataExchange* pDX
)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddStaticMappingDlg)
DDX_Control(pDX, IDC_STATIC_IPADDRESS, m_static_Prompt);
DDX_Control(pDX, IDC_BUTTON_ADD, m_button_Add);
DDX_Control(pDX, IDC_EDIT_NETBIOSNAME, m_edit_NetBIOSName);
//}}AFX_DATA_MAP
DDX_Control(pDX, IDC_IPA_IPADDRESS, m_ipa_IpAddress);
}
BEGIN_MESSAGE_MAP(CAddStaticMappingDlg, CDialog)
//{{AFX_MSG_MAP(CAddStaticMappingDlg)
ON_EN_CHANGE(IDC_EDIT_NETBIOSNAME, OnChangeEditNetbiosname)
ON_BN_CLICKED(IDC_BUTTON_PLUS, OnClickedButtonPlus)
ON_BN_CLICKED(IDC_BUTTON_ADD, OnClickedButtonAdd)
ON_BN_CLICKED(IDC_BUTTON_MINUS, OnClickedButtonMinus)
ON_LBN_ERRSPACE(IDC_LIST_IP_ADDRESSES, OnErrspaceListIpAddresses)
ON_LBN_DBLCLK(IDC_LIST_IP_ADDRESSES, OnDblclkListIpAddresses)
ON_LBN_SELCHANGE(IDC_LIST_IP_ADDRESSES, OnSelchangeListIpAddresses)
ON_BN_CLICKED(IDC_RADIO_GROUP, OnClickedRadioGroup)
ON_BN_CLICKED(IDC_RADIO_MULTIHOMED, OnClickedRadioMultihomed)
ON_BN_CLICKED(IDC_RADIO_SPECIALGROUP, OnClickedRadioSpecialgroup)
ON_BN_CLICKED(IDC_RADIO_INTERNETGROUP, OnClickedRadioInternetGroup)
ON_BN_CLICKED(IDC_RADIO_UNIQUE, OnClickedRadioUnique)
ON_WM_VKEYTOITEM()
//}}AFX_MSG_MAP
ON_EN_CHANGE(IDC_IPA_IPADDRESS, OnChangeIpControl)
END_MESSAGE_MAP()
//
// Update the static message containing the number
// of ip addresses contained in the listbox
//
void
CAddStaticMappingDlg::UpdateMultipleCount()
{
TRY
{
CString strPrompt;
::wsprintf(strPrompt.GetBuffer(128), m_strMultiplePrompt,
m_list_IpAddresses.GetCount());
strPrompt.ReleaseBuffer();
m_static_Prompt.SetWindowText(strPrompt);
}
CATCH_ALL(e)
{
//theApp.MessageBox(ERROR_NOT_ENOUGH_MEMORY);
theApp.MessageBox(::GetLastError());
}
END_CATCH_ALL
}
//
// Set the state of the dialog depending on whether this
// we're adding a mapping with a single ip address or
// multiple IP addresses.
//
void
CAddStaticMappingDlg::SetConfig(
BOOL fSingle
)
{
TRY
{
if (fSingle)
{
CString strPrompt;
strPrompt.LoadString(IDS_IPADDRESS_SINGLE);
m_static_Prompt.SetWindowText(strPrompt);
m_bbutton_Up.ShowWindow(SW_HIDE);
m_bbutton_Down.ShowWindow(SW_HIDE);
m_list_IpAddresses.ShowWindow(SW_HIDE);
HandleControlStates();
return;
}
m_bbutton_Up.ShowWindow(SW_NORMAL);
m_bbutton_Down.ShowWindow(SW_NORMAL);
m_list_IpAddresses.ShowWindow(SW_NORMAL);
HandleControlStates();
}
CATCH_ALL(e)
{
theApp.MessageBox(ERROR_NOT_ENOUGH_MEMORY);
}
END_CATCH_ALL
}
//
// Set the state of the dialog controls depending
// on the current selections, etc.
//
void
CAddStaticMappingDlg::HandleControlStates()
{
CString str;
m_edit_NetBIOSName.GetWindowText(str);
theApp.CleanString(str);
DWORD dwIp;
BOOL f = m_ipa_IpAddress.GetAddress(&dwIp);
//
// The following is done only for multiple
// IP address adding.
//
if (m_list_IpAddresses.IsWindowVisible())
{
UpdateMultipleCount();
m_button_Add.EnableWindow(!str.IsEmpty() && m_list_IpAddresses.GetCount()>0);
m_bbutton_Up.EnableWindow(m_list_IpAddresses.GetCurSel() != LB_ERR);
m_bbutton_Down.EnableWindow(f);
}
else
{
m_button_Add.EnableWindow(!str.IsEmpty() && f);
}
if (m_fInternetGroup)
{
// Allow Internet Group to have the IpList empty
m_button_Add.EnableWindow(!str.IsEmpty());
}
}
/////////////////////////////////////////////////////////////////////////////
// CAddStaticMappingDlg message handlers
BOOL
CAddStaticMappingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_bbutton_Down.SubclassDlgItem(IDC_BUTTON_PLUS, this);
m_bbutton_Up.SubclassDlgItem(IDC_BUTTON_MINUS, this);
m_bbutton_Down.SizeToContent();
m_bbutton_Up.SizeToContent();
m_list_IpAddresses.SubclassDlgItem(IDC_LIST_IP_ADDRESSES, this);
::CheckDlgButton(m_hWnd, IDC_RADIO_UNIQUE, TRUE);
//
// Set the maximum allowable length of the netbios name,
// depending on whether we're adding lanman compatible
// names or not.
//
m_edit_NetBIOSName.LimitText(100);
// m_edit_NetBIOSName.LimitText(theApp.m_wpPreferences.IsLanmanCompatible()
// ? LM_NAME_MAX_LENGTH : NB_NAME_MAX_LENGTH);
SetConfig(TRUE);
return TRUE;
}
void
CAddStaticMappingDlg::OnChangeEditNetbiosname()
{
HandleControlStates();
}
void
CAddStaticMappingDlg::OnChangeIpControl()
{
HandleControlStates();
}
//
// Add the ip address in the ip address custom control
// to the listbox of ip addresses.
//
void
CAddStaticMappingDlg::OnClickedButtonPlus()
{
LONG l;
if (!m_ipa_IpAddress.GetAddress((DWORD *)&l))
{
//
// No address in the control.
//
theApp.MessageBeep();
m_ipa_IpAddress.SetFocus();
return;
}
if (m_list_IpAddresses.GetCount() == WINSINTF_MAX_MEM)
{
//
// Too many addresses currently in the listbox.
//
theApp.MessageBox(IDS_ERR_TOOMANY_IP);
m_ipa_IpAddress.SetFocus();
return;
}
CIpAddress ip(l);
if (m_list_IpAddresses.FindItem(&ip) != -1)
{
//
// The given ip address already exists in
// the listbox
//
theApp.MessageBox(IDS_ERR_IP_EXISTS);
m_ipa_IpAddress.SetFocus();
return;
}
TRY
{
int n = m_list_IpAddresses.AddItem(ip);
ASSERT(n!=-1);
m_list_IpAddresses.SetCurSel(n);
m_ipa_IpAddress.ClearAddress();
m_ipa_IpAddress.SetFocus();
HandleControlStates();
}
CATCH_ALL(e)
{
//theApp.MessageBox(ERROR_NOT_ENOUGH_MEMORY);
theApp.MessageBox(::GetLastError());
}
END_CATCH_ALL
}
//
// Remove the currently selected address from the
// listbox of ip addresses, and place it in
// the ip address custom control (for easy editing)
//
void
CAddStaticMappingDlg::OnClickedButtonMinus()
{
int n = m_list_IpAddresses.GetCurSel();
ASSERT(n != LB_ERR);
//
// Set the currently selected item in the ip control
//
CIpAddress * p = m_list_IpAddresses.GetItem(n);
ASSERT(p != NULL);
m_ipa_IpAddress.SetAddress((LONG)*p);
m_list_IpAddresses.DeleteString(n);
m_list_IpAddresses.SetCurSel(-1);
m_ipa_IpAddress.SetFocus();
HandleControlStates();
}
//
// Add the current static mapping, and (if succesful), blank
// out the controls for the next mapping to be added.
//
void
CAddStaticMappingDlg::OnClickedButtonAdd()
{
CString strAddress;
UpdateData();
APIERR err = IDS_ERR_BAD_NB_NAME;
m_edit_NetBIOSName.GetWindowText(strAddress);
theApp.CleanString(strAddress);
// Address may have been cleaned up in validation,
// so it should be re-displayed at once.
m_edit_NetBIOSName.SetWindowText(strAddress);
int ichNetBIOSNameSelStart = 0;
int ichNetBIOSNameSelEnd = -1;
// Parse the string
BOOL fValid = TRUE;
BOOL fBrackets = FALSE;
BYTE rgbData[100];
BYTE bDataT;
int cbData = 0;
const char * pch = (LPCSTR)strAddress;
while (*pch)
{
if (fBrackets)
{
fValid = FALSE;
goto Done;
}
if (cbData > 16)
goto Done;
switch (*pch)
{
case '\\':
pch++;
if (*pch == '\\' || *pch == '[')
{
rgbData[cbData++] = *pch++;
break;
}
if (!FGetByte(pch, &bDataT, &pch) || !bDataT)
{
fValid = FALSE;
goto Done;
}
rgbData[cbData++] = bDataT;
break;
case '[':
{
char szT[4] = { 0 };
const char * pchT;
fBrackets = TRUE;
pch++;
if (*(pch + 1) == 'h' || *(pch + 1) == 'H')
{
szT[0] = 'x';
szT[1] = *pch;
pch += 2;
}
else if (*(pch + 2) == 'h' || *(pch + 2) == 'H')
{
szT[0] = 'x';
szT[1] = *pch;
szT[2] = *(pch + 1);
pch += 3;
}
if (szT[0])
{
if (!FGetByte(szT, &bDataT, &pchT) || !bDataT || *pchT)
{
fValid = FALSE;
goto Done;
}
}
else if (!FGetByte(pch, &bDataT, &pch) || !bDataT)
{
fValid = FALSE;
goto Done;
}
if (*pch++ != ']')
{
fValid = FALSE;
goto Done;
}
while (cbData < 15)
rgbData[cbData++] = ' ';
rgbData[cbData++] = bDataT;
}
break;
default:
rgbData[cbData++] = *pch++;
} // switch
} // while
Done:
if (m_fInternetGroup)
while (cbData <= 15)
rgbData[cbData++] = ' ';
// Put a null-terminator at end of string
rgbData[cbData] = 0;
if (!cbData || cbData > 16)
{
ichNetBIOSNameSelStart = (pch - (LPCSTR)strAddress - 1);
ichNetBIOSNameSelEnd = 200;
ASSERT(ichNetBIOSNameSelStart >= 0);
goto BadNetbiosName;
}
if (!fValid)
{
ichNetBIOSNameSelStart = (pch - (LPCSTR)strAddress - 1);
ASSERT(ichNetBIOSNameSelStart >= 0);
ichNetBIOSNameSelEnd = ichNetBIOSNameSelStart + 1;
goto BadNetbiosName;
}
if (m_fInternetGroup && rgbData[15] == 0x1C)
{
err = IDS_INVALID_INTERNETGROUPNAME;
goto BadNetbiosName;
}
strAddress = rgbData;
if (theApp.IsValidNetBIOSName(strAddress,
theApp.m_wpPreferences.IsLanmanCompatible(), FALSE))
{
m_Multiples.SetNetBIOSName(strAddress);
m_Multiples.SetNetBIOSNameLength(strAddress.GetLength());
int cMappings = 0;
int i;
switch(m_iMappingType)
{
case WINSINTF_E_UNIQUE:
case WINSINTF_E_NORM_GROUP:
cMappings = 1;
LONG l;
if (!m_ipa_IpAddress.GetAddress((DWORD *)&l))
{
//
// Improper address in the control
//
m_ipa_IpAddress.SetFocus();
theApp.MessageBeep();
return;
}
m_Multiples.SetIpAddress(l);
break;
case WINSINTF_E_SPEC_GROUP:
case WINSINTF_E_MULTIHOMED:
cMappings = m_list_IpAddresses.GetCount();
ASSERT(cMappings <= WINSINTF_MAX_MEM);
if (!m_fInternetGroup && cMappings == 0)
{
//
// No mappings in the listbox
//
m_ipa_IpAddress.SetFocus();
theApp.MessageBeep();
return;
}
for (i = 0; i < cMappings; ++i)
{
CIpAddress * p = m_list_IpAddresses.GetItem(i);
ASSERT(p != NULL);
m_Multiples.SetIpAddress(i, (LONG)*p);
}
break;
default:
ASSERT(0 && "Invalid mapping type!");
}
theApp.SetStatusBarText(IDS_STATUS_ADD_MAPPING);
theApp.BeginWaitCursor();
err = theApp.AddMapping(m_iMappingType, cMappings, m_Multiples);
theApp.EndWaitCursor();
theApp.SetStatusBarText();
if (err == ERROR_SUCCESS)
{
//
// Added succesfully
//
++m_nMappingsAdded;
}
else
{
//
// WINS disallowed the mapping. Put up the
// error message, and highlight the name
//
theApp.MessageBox(err);
m_edit_NetBIOSName.SetSel(0,-1);
return;
}
//
// The mapping was added succesfully, now
// refresh the stats on the screen to show the change
//
theApp.GetFrameWnd()->GetStatistics();
//
// Clean out the controls, ready for the next
// mapping to be added.
//
m_edit_NetBIOSName.SetWindowText("");
m_edit_NetBIOSName.SetFocus();
m_list_IpAddresses.ResetContent();
m_ipa_IpAddress.ClearAddress();
HandleControlStates();
return;
}
BadNetbiosName:
//
// Invalid netbios name in the editbox.
// Highlight it, and put up an error.
//
theApp.MessageBox(err);
m_edit_NetBIOSName.SetFocus();
m_edit_NetBIOSName.SetSel(ichNetBIOSNameSelStart, ichNetBIOSNameSelEnd);
}
void
CAddStaticMappingDlg::OnErrspaceListIpAddresses()
{
theApp.MessageBox(IDS_ERR_ERRSPACE);
}
void
CAddStaticMappingDlg::OnDblclkListIpAddresses()
{
theApp.MessageBeep();
}
void
CAddStaticMappingDlg::OnSelchangeListIpAddresses()
{
HandleControlStates();
}
void
CAddStaticMappingDlg::OnClickedRadioUnique()
{
m_iMappingType = WINSINTF_E_UNIQUE;
m_fInternetGroup = FALSE;
SetConfig(TRUE);
}
void
CAddStaticMappingDlg::OnClickedRadioGroup()
{
m_iMappingType = WINSINTF_E_NORM_GROUP;
m_fInternetGroup = FALSE;
SetConfig(TRUE);
}
void
CAddStaticMappingDlg::OnClickedRadioSpecialgroup()
{
m_iMappingType = WINSINTF_E_SPEC_GROUP;
m_fInternetGroup = FALSE;
SetConfig(FALSE);
}
void
CAddStaticMappingDlg::OnClickedRadioInternetGroup()
{
m_iMappingType = WINSINTF_E_SPEC_GROUP;
m_fInternetGroup = TRUE;
SetConfig(FALSE);
}
void
CAddStaticMappingDlg::OnClickedRadioMultihomed()
{
m_iMappingType = WINSINTF_E_MULTIHOMED;
m_fInternetGroup = FALSE;
SetConfig(FALSE);
}
//
// Key pressed in the listbox of ip addresses. "DEL" is
// is mapped to removing the entry from the listbox.
//
int
CAddStaticMappingDlg::OnVKeyToItem(
UINT nKey, // Key pressed
CListBox* pListBox, // Pointer to listbox
UINT nIndex // Current selection in the listbox
)
{
switch(nKey)
{
case VK_DELETE:
if (m_list_IpAddresses.GetCurSel() != LB_ERR)
{
OnClickedButtonMinus();
}
else
{
//
// Pressed del without a current selection
//
theApp.MessageBeep();
}
break;
default:
//
// Not completely handled by this function, let
// windows handle the remaining default action.
//
return -1;
}
//
// No further action is neccesary.
//
return -2;
}