|
|
//----------------------------------------------------------------------------
//
// Copyright (c) 1997-1999 Microsoft Corporation
// All rights reserved.
//
// File Name:
// tcpip.c
//
// Description:
// This file contains the dialog procedure for the base TCP/IP page
// (IDD_TCP_IPADDR). Let's the user set DHCP or specific IPs or go to
// Advanced TCP/IP settings.
//
//----------------------------------------------------------------------------
#include "pch.h"
#include "resource.h"
BOOL Create_TCPIPProp_PropertySheet( HWND hwndParent );
BOOL ValidateIPAddress( IN TCHAR szIPAddress[] );
BOOL ValidateSubnetMask( IN TCHAR szIPAddress[] );
UINT CALLBACK TCPIP_PropertiesPageProc( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp );
INT_PTR CALLBACK TCPIP_PropertiesDlgProc( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam );
static PROPSHEETHEADER pshead; static PROPSHEETPAGE pspage;
static const TCHAR Period = _T('.');
//----------------------------------------------------------------------------
//
// Function: ValidatePage
//
// Purpose: tests to see if the contents of the TCP/IP page are valid ( to
// see if it is safe to move off this page )
//
// Arguments: IN HWND hwnd - handle to the dialog
//
// Returns: BOOL - TRUE if all fields are valid
// False if some are not valid
//
//----------------------------------------------------------------------------
BOOL ValidatePage( IN HWND hwnd ) {
INT_PTR iNumBlankFields; DWORD dwIpValue;
//
// If using DHCP, then no need to check any of the settings
//
if( IsDlgButtonChecked( hwnd, IDC_IP_DHCP ) ) {
return( TRUE );
} else {
//
// Check that the IP and Subnet mask fields are completely
// filled-out. I only check these 2 fields because that is all the
// system checks to get off this dialog.
//
iNumBlankFields = 4 - SendDlgItemMessage( hwnd, IDC_IPADDR_IP, IPM_GETADDRESS, (WPARAM) 0, (LPARAM) &dwIpValue );
if( iNumBlankFields > 0 ) {
ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERROR_NEED_IP_ADDRESS );
return( FALSE );
}
iNumBlankFields = 4 - SendDlgItemMessage( hwnd, IDC_IPADDR_SUB, IPM_GETADDRESS, (WPARAM) 0, (LPARAM) &dwIpValue );
if( iNumBlankFields > 0 ) {
ReportErrorId( hwnd, MSGTYPE_ERR, IDS_ERROR_NEED_SUB_ADDRESS );
return( FALSE );
}
}
return( TRUE );
}
//----------------------------------------------------------------------------
//
// Function: StoreIPSettings
//
// Purpose: takes the values currently in the IP edit boxes and stores them
// into the NetSettings global variable
//
// Arguments: IN HWND hwnd - handle to the dialog
//
// Returns: BOOL - TRUE if all the IP address are valid and they get stored
// FALSE if there was an error
//
//----------------------------------------------------------------------------
BOOL StoreIPSettings( IN HWND hwnd ) {
INT_PTR iIsBlank; INT iFoundStatus;
if( IsDlgButtonChecked( hwnd, IDC_IP_DHCP ) == BST_CHECKED ) {
NetSettings.pCurrentAdapter->bObtainIPAddressAutomatically = TRUE;
} else {
TCHAR szIpBuffer[IPSTRINGLENGTH + 1];
HWND hIPEditBox = GetDlgItem( hwnd, IDC_IPADDR_IP ); HWND hSubnetEditBox = GetDlgItem( hwnd, IDC_IPADDR_SUB ); HWND hGatewayEditBox = GetDlgItem( hwnd, IDC_IPADDR_GATE );
NetSettings.pCurrentAdapter->bObtainIPAddressAutomatically = FALSE;
//
// Only store the data if the IP isn't blank
// - if it's not blank then grab it and store it in a buffer
// - if the IP is not already in the list then add it to the front
// - if it is already in the list, remove it and add it to the front
//
iIsBlank = SendMessage( hIPEditBox, IPM_ISBLANK, 0, 0 );
if( ! iIsBlank ) {
GetWindowText( hIPEditBox, szIpBuffer, IPSTRINGLENGTH + 1 ); // +1 for null character
iFoundStatus = FindNameInNameList( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses, szIpBuffer );
if( iFoundStatus != NOT_FOUND ) {
RemoveNameFromNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses, iFoundStatus );
RemoveNameFromNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_SubnetMaskAddresses, iFoundStatus );
}
AddNameToNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses, szIpBuffer, 0 );
}
iIsBlank = SendMessage( hSubnetEditBox, IPM_ISBLANK, 0, 0 );
if( ! iIsBlank ) {
GetWindowText( hSubnetEditBox, szIpBuffer, IPSTRINGLENGTH + 1 ); // +1 for null character
AddNameToNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_SubnetMaskAddresses, szIpBuffer, 0 );
}
iIsBlank = SendMessage( hGatewayEditBox, IPM_ISBLANK, 0, 0 );
if( ! iIsBlank ) {
GetWindowText( hGatewayEditBox, szIpBuffer, IPSTRINGLENGTH + 1 ); // +1 for null character
iFoundStatus = FindNameInNameList( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses, szIpBuffer );
if( iFoundStatus != NOT_FOUND ) {
RemoveNameFromNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses, iFoundStatus );
}
AddNameToNameListIdx( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses, szIpBuffer, 0 );
}
}
if( IsDlgButtonChecked(hwnd, IDC_DNS_DHCP) == BST_CHECKED ) {
NetSettings.bObtainDNSServerAutomatically = TRUE;
} else {
TCHAR szDnsBuffer[IPSTRINGLENGTH + 1]; HWND hPrimaryDNSEditBox = GetDlgItem( hwnd, IDC_DNS_PRIMARY ); HWND hSecondaryDNSEditBox = GetDlgItem( hwnd, IDC_DNS_SECONDARY );
NetSettings.bObtainDNSServerAutomatically = FALSE;
//
// Only store the data if the IP isn't blank
//
iIsBlank = SendMessage( hSecondaryDNSEditBox, IPM_ISBLANK, 0, 0 );
if( ! iIsBlank ) {
GetWindowText( hSecondaryDNSEditBox, szDnsBuffer, IPSTRINGLENGTH + 1 ); // +1 for null character
TcpipNameListInsertIdx( &NetSettings.pCurrentAdapter->Tcpip_DnsAddresses, szDnsBuffer, 0 );
}
iIsBlank = SendMessage( hPrimaryDNSEditBox, IPM_ISBLANK, 0, 0 );
if( ! iIsBlank ) {
GetWindowText( hPrimaryDNSEditBox, szDnsBuffer, IPSTRINGLENGTH + 1 ); // +1 for null character
TcpipNameListInsertIdx( &NetSettings.pCurrentAdapter->Tcpip_DnsAddresses, szDnsBuffer, 0 );
}
}
return( TRUE );
}
//----------------------------------------------------------------------------
//
// Function: EnableIPAddressControls
//
// Purpose: Greys or ungreys the IP Address text and edit boxes
//
// Arguments: IN HWND hwnd - handle to the dialog
// IN BOOL bVisible - TRUE to enable the IP address controls
// FALSE to grey them
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID EnableIPAddressControls( IN HWND hwnd, IN BOOL bVisible ) {
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_IPTEXT ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_SUBTEXT ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_GATETEXT ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_IP ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_SUB ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_IPADDR_GATE ), bVisible );
}
//----------------------------------------------------------------------------
//
// Function: EnableServerAddressControls
//
// Purpose: Greys or ungreys the Server Address text and edit boxes
//
// Arguments: IN HWND hwnd - handle to the dialog
// IN BOOL bVisible - TRUE to enable the Server address controls
// FALSE to grey them
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID EnableServerAddressControls( IN HWND hwnd, IN BOOL bVisible ) {
EnableWindow( GetDlgItem( hwnd, IDC_DNS_PRIMARY_TEXT ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_DNS_SECONDARY_TEXT ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_DNS_PRIMARY ), bVisible );
EnableWindow( GetDlgItem( hwnd, IDC_DNS_SECONDARY ), bVisible );
}
//----------------------------------------------------------------------------
//
// Function: SetTCPIPControls
//
// Purpose: uses settings in global variable NetSettings to set the TCP/IP
// window states appropriately and fill the edit boxes with data
// where appropriate
//
// Arguments: IN HWND hwnd - handle to the dialog
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID SetTCPIPControls( IN HWND hwnd ) {
//
// Set the button and window states for IP
//
if( NetSettings.pCurrentAdapter->bObtainIPAddressAutomatically ) {
CheckRadioButton( hwnd, IDC_IP_DHCP, IDC_IP_FIXED, IDC_IP_DHCP );
//
// Gray out the IP address strings and boxes
//
EnableIPAddressControls( hwnd, FALSE );
} else {
CheckRadioButton( hwnd, IDC_IP_DHCP, IDC_IP_FIXED, IDC_IP_FIXED );
//
// Fill in the IP, Subnet Mask and Gateway data
//
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_IP ), GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses, 0 ) );
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_SUB ), GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_SubnetMaskAddresses, 0 ) );
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_GATE ), GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses, 0 ) );
}
//
// Set the button and window states for DNS
//
if( NetSettings.bObtainDNSServerAutomatically ) {
CheckRadioButton( hwnd, IDC_DNS_DHCP, IDC_DNS_FIXED, IDC_DNS_DHCP );
//
// Gray out the IP address strings and boxes
//
EnableServerAddressControls( hwnd, FALSE );
} else {
TCHAR *szDns;
CheckRadioButton( hwnd, IDC_DNS_DHCP, IDC_DNS_FIXED, IDC_DNS_FIXED );
//
// Ensure the controls are visible and fill in the strings for
// Primary and Secondary DNS
//
EnableServerAddressControls( hwnd, TRUE );
szDns = GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_DnsAddresses, 0 );
SetWindowText( GetDlgItem( hwnd, IDC_DNS_PRIMARY ), szDns );
szDns = GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_DnsAddresses, 1 );
SetWindowText( GetDlgItem( hwnd, IDC_DNS_SECONDARY ), szDns );
}
}
//----------------------------------------------------------------------------
//
// Function: OnAdvancedClicked
//
// Purpose: Creates the Advanced TCP/IP property sheet for the user to specify
// additional TCP/IP settings.
//
// Arguments: standard Win32 dialog proc arguments passed through from the
// dialog proc
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID OnAdvancedClicked( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) {
HWND hGatewayEditBox = GetDlgItem( hwnd, IDC_IPADDR_GATE );
//
// store the IP settings in the NetSettings global variable so the
// advanced pages can access data in it
//
StoreIPSettings( hwnd );
Create_TCPIPProp_PropertySheet( hwnd );
//
// Fill boxes with (potentially) new data from the TCP/IP Advanced screens
//
SetTCPIPControls( hwnd );
//
// always set the gateway because a user can still set this even if they
// have DHCP enabled
//
SetWindowText( hGatewayEditBox, GetNameListName( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses, 0 ) );
}
//----------------------------------------------------------------------------
//
// Function: OnDNSRadioButtonsClicked
//
// Purpose: Grey/Ungrey the DNS controls appropriately and clear DNS entries,
// as necessary.
//
// Arguments: standard Win32 dialog proc arguments passed through from the
// dialog proc
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID OnDNSRadioButtonsClicked( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) {
INT nButtonId = LOWORD( wParam );
if ( HIWORD( wParam ) == BN_CLICKED ) {
CheckRadioButton( hwnd, IDC_DNS_DHCP, IDC_DNS_FIXED, nButtonId );
if( nButtonId == IDC_DNS_FIXED ) {
//
// User clicked the radio button to have fixed DNS servers so
// Un-grey the DNS strings and boxes so the user can
// edit them
//
EnableServerAddressControls( hwnd, TRUE );
} else {
//
// User clicked the radio button to have assigned DNS servers so
// Grey the DNS strings and boxes so the user can not
// edit them
//
EnableServerAddressControls( hwnd, FALSE );
//
// clear the DNS Address list
//
ResetNameList( &NetSettings.pCurrentAdapter->Tcpip_DnsAddresses );
//
// clear the contents of the Primary and Secondary edit boxes
//
SetWindowText( GetDlgItem( hwnd, IDC_DNS_PRIMARY ), _T("") );
SetWindowText( GetDlgItem( hwnd, IDC_DNS_SECONDARY ), _T("") );
}
}
}
//----------------------------------------------------------------------------
//
// Function: OnIPRadioButtonsClicked
//
// Purpose: Grey/Ungrey the IP controls appropriately and clear the IP data
// structures, as necessary.
//
// Arguments: standard Win32 dialog proc arguments passed through from the
// dialog proc
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID OnIPRadioButtonsClicked( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) {
INT nButtonId = LOWORD(wParam);
if ( HIWORD(wParam) == BN_CLICKED ) {
CheckRadioButton( hwnd, IDC_IP_DHCP, IDC_IP_FIXED, nButtonId );
if ( nButtonId == IDC_IP_FIXED ) {
//
// User chose the radio button to specify and IP, Subnet Mask
// and Gateway
//
// Un-grey the IP address strings and boxes
// so the user can specify them
//
EnableIPAddressControls( hwnd, TRUE );
//
// If the user is going to specify their IP addresses then
// they must specify their DNS server addresses so force
// the manual radio box to be checked and un-grey the boxes
//
CheckRadioButton( hwnd, IDC_DNS_DHCP, IDC_DNS_FIXED, IDC_DNS_FIXED );
EnableServerAddressControls( hwnd, TRUE );
//
// clear the list to avoid the string "DHCP enabled" from being
// placed in the IP edit box
//
ResetNameList( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses );
//
// Don't allow user to click the 'obtain DNS server automatically'
//
EnableWindow( GetDlgItem( hwnd, IDC_DNS_DHCP ), FALSE );
} else {
//
// User to chose DHCP (have an IP assigned automatically)
//
// Grey out the IP address strings and boxes because they are
// using DHCP
//
EnableIPAddressControls( hwnd, FALSE );
//
// clear the contents of the IP, Subnet and Gateway edit boxes
// because using DHCP
//
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_IP ), _T("") );
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_SUB ), _T("") );
SetWindowText( GetDlgItem( hwnd, IDC_IPADDR_GATE ), _T("") );
//
// Clear the lists that contain the IP, Subnet and
// Gateway data
//
ResetNameList( &NetSettings.pCurrentAdapter->Tcpip_IpAddresses );
ResetNameList( &NetSettings.pCurrentAdapter->Tcpip_SubnetMaskAddresses );
ResetNameList( &NetSettings.pCurrentAdapter->Tcpip_GatewayAddresses );
//
// Allow the user to be able to select 'obtain DNS server
// automatically'
//
EnableWindow( GetDlgItem( hwnd, IDC_DNS_DHCP ), TRUE );
}
}
}
//----------------------------------------------------------------------------
//
// Function: OnTcpipInitDialog
//
// Purpose: Sets the text limits on the edit boxes and fills in initial data
// and greys controls appropriately.
//
// Arguments: IN HWND hwnd - handle to the dialog box
//
// Returns: VOID
//
//----------------------------------------------------------------------------
VOID OnTcpipInitDialog( IN HWND hwnd ) {
//
// Set the text limit on the edit boxes to IPSTRINGLENGTH
//
SendDlgItemMessage( hwnd, IDC_IPADDR_IP, EM_LIMITTEXT, (WPARAM) IPSTRINGLENGTH, (LPARAM) 0 );
SendDlgItemMessage( hwnd, IDC_IPADDR_SUB, EM_LIMITTEXT, (WPARAM) IPSTRINGLENGTH, (LPARAM) 0 );
SendDlgItemMessage( hwnd, IDC_IPADDR_GATE, EM_LIMITTEXT, (WPARAM) IPSTRINGLENGTH, (LPARAM) 0 );
SendDlgItemMessage( hwnd, IDC_DNS_PRIMARY, EM_LIMITTEXT, (WPARAM) IPSTRINGLENGTH, (LPARAM) 0 );
SendDlgItemMessage( hwnd, IDC_DNS_SECONDARY, EM_LIMITTEXT, (WPARAM) IPSTRINGLENGTH, (LPARAM) 0 );
SetTCPIPControls( hwnd );
}
//----------------------------------------------------------------------------
//
// Function: TCPIP_PropertiesDlgProc
//
// Purpose:
//
// Arguments: standard Win32 dialog proc arguments
//
// Returns:
//
//----------------------------------------------------------------------------
INT_PTR CALLBACK TCPIP_PropertiesDlgProc( IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) {
BOOL bStatus = TRUE;
switch( uMsg ) {
case WM_INITDIALOG:
OnTcpipInitDialog( hwnd );
break;
case WM_NOTIFY: {
LPNMHDR pnmh = (LPNMHDR) lParam;
switch( pnmh->code ) {
case PSN_APPLY: {
//
// store the IP settings in the NetSettings global variable
//
if( ValidatePage( hwnd ) ) {
StoreIPSettings( hwnd );
} else {
//
// if the validation fails then stay on this page
//
SetWindowLongPtr( hwnd, DWLP_MSGRESULT, -1 );
return( PSNRET_INVALID_NOCHANGEPAGE );
}
}
}
} // end case WM_NOTIFY
case WM_COMMAND: { int nButtonId;
switch ( nButtonId = LOWORD(wParam) ) {
case IDC_IP_DHCP: case IDC_IP_FIXED:
OnIPRadioButtonsClicked( hwnd, uMsg, wParam, lParam );
break;
case IDC_DNS_DHCP: case IDC_DNS_FIXED:
OnDNSRadioButtonsClicked( hwnd, uMsg, wParam, lParam );
break;
case IDC_IPADDR_ADVANCED: {
OnAdvancedClicked( hwnd, uMsg, wParam, lParam );
break;
} default:
bStatus = FALSE;
break;
}
break;
}
default:
bStatus = FALSE;
break;
}
return( bStatus );
}
//----------------------------------------------------------------------------
//
// Function: TCPIP_PropertySheetProc
//
// Purpose: Standard Property Sheet dialog proc. Very boring.
//
//----------------------------------------------------------------------------
int CALLBACK TCPIP_PropertySheetProc( HWND hwndDlg, UINT uMsg, LPARAM lParam ) {
switch( uMsg ) {
case PSCB_INITIALIZED : // Process PSCB_INITIALIZED
break;
case PSCB_PRECREATE : // Process PSCB_PRECREATE
break;
default : // Unknown message
break;
}
return( 0 );
}
//----------------------------------------------------------------------------
//
// Function: TCPIP_PropertiesPageProc
//
// Purpose: Standard Property Page dialog proc.
//
//----------------------------------------------------------------------------
UINT CALLBACK TCPIP_PropertiesPageProc( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp ) {
switch( uMsg ) {
case PSPCB_CREATE : return( TRUE );
case PSPCB_RELEASE : return( 0 ); }
return( 0 );
}
//----------------------------------------------------------------------------
//
// Function: Create_TCPIP_PropertySheet
//
// Purpose: Sets up settings for the property sheet and the TCP/IP page (in
// this case the property sheet is just 1 page). Lastly, calls the
// PropertySheet function to display the property sheet, the return
// value of this function is what is passed back as the return value
//
// Arguments: IN HWND hwndParent - handle to the dialog that is spawning the
// property sheet
//
// Returns: BOOL - the returned value from the Property Sheet
//
//----------------------------------------------------------------------------
BOOL Create_TCPIP_PropertySheet( IN HWND hwndParent ) {
INT i;
// Initialize property sheet HEADER data
ZeroMemory (&pshead, sizeof (PROPSHEETHEADER)) ; pshead.dwSize = sizeof (PROPSHEETHEADER) ; pshead.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_USEHICON | PSH_NOAPPLYNOW; pshead.hwndParent = hwndParent ; pshead.hInstance = FixedGlobals.hInstance; pshead.pszCaption = g_StrTcpipTitle; pshead.nPages = 1 ; pshead.nStartPage = 0 ; pshead.ppsp = &pspage ; pshead.pfnCallback = TCPIP_PropertySheetProc ;
// Zero out property PAGE data
ZeroMemory (&pspage, 1 * sizeof (PROPSHEETPAGE)) ;
pspage.dwSize = sizeof (PROPSHEETPAGE) ; pspage.dwFlags = PSP_USECALLBACK ; pspage.hInstance = FixedGlobals.hInstance; pspage.pszTemplate = MAKEINTRESOURCE(IDD_TCP_IPADDR) ; pspage.pfnDlgProc = TCPIP_PropertiesDlgProc ; pspage.pfnCallback = TCPIP_PropertiesPageProc ;
// --------- Create & display property sheet ---------
return( PropertySheet( &pshead ) ? TRUE : FALSE);
}
|