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