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.
 
 
 
 
 
 

3113 lines
93 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1991 **/
/**********************************************************************/
/*
tcpipcpl.CXX:
SNMP and tcpip dialog call up
FILE HISTORY:
terryk 4/02/92 Created
terryk 4/20/92 Added SNMP
terryk 11/11/93 Added Option dialogs.
*/
#include "pch.h"
#pragma hdrstop
extern "C"
{
#include "ipaddr.h"
};
#include "const.h"
#include "button.h"
#include "odb.h"
#include "listview.h"
#include "resource.h"
#include "tcpsht.h"
#include "setupapi.h"
#include "tcphelp.h"
APIERR RunTcpipAlteredCheck(BOOL bDHCPTest);
APIERR SilentModeCheck();
BOOL ConfigureAdapters(LPCTSTR lpszUnAttendPath, LPCTSTR lpszSection, CTcpSheet* tcpip);
extern "C"
{
BOOL FAR PASCAL TcpBootRelayCfgCheck(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult); // Result variable storage
BOOL FAR PASCAL CPlTcpip (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) ; // Result variable storage
BOOL FAR PASCAL CPlSnmp (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) ; // Result variable storage
#define INCLUDE_FTPD
#ifdef INCLUDE_FTPD
BOOL FAR PASCAL CPlFtpd (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) ; // Result variable storage
BOOL FAR PASCAL CPlFtpdConfirmInstall (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) ; // Result variable storage
#endif // INCLUDE_FTPD
BOOL FAR PASCAL TcpCfgCheck (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ); // Result variable storage
BOOL FAR PASCAL TcpCheckAdaptersForDHCP(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ); // Result variable storage
BOOL FAR PASCAL TcpEnableRipSilentMode(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ); // Result variable storage
BOOL FAR PASCAL ConvertHostname(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ); // Result variable storage
BOOL FAR PASCAL DelFiles(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ); // Result variable storage
}
extern HINSTANCE hTcpCfgInstance;
#define DLG_NM_SNMP MAKEINTRESOURCE(IDD_DLG_NM_SNMPSERVICE)
#define DLG_NM_TCPIP MAKEINTRESOURCE(IDD_DLG_NM_TCPIP)
#define DLG_ASNT_INSTALL MAKEINTRESOURCE(IDD_DLG_AS_OPTION)
#define DLG_WINNT_INSTALL MAKEINTRESOURCE(IDD_DLG_WINNT_OPTION)
#define H_NODE 8
#define P_NODE 2
#define B_NODE 1
static CHAR achBuff[2000];
/*******************************************************************
NAME: DHCP_OPTIONS::DHCP_OPTIONS
SYNOPSIS: constructor to get all the DHCP distributed optioned
HISTORY:
terryk 04-Aug-1994 Created
********************************************************************/
DHCP_OPTIONS::DHCP_OPTIONS()
{
APIERR err = NERR_Success;
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
do {
ALIAS_STR nlsDhcpOptions = RGAS_DHCP_OPTIONS;
REG_KEY RegKeyDHCPOptions( rkLocalMachine, nlsDhcpOptions, MAXIMUM_ALLOWED );
if (( err = RegKeyDHCPOptions.QueryError()) != NERR_Success )
{
ReportError( err );
break;
}
REG_ENUM regOptions( RegKeyDHCPOptions );
if (( err = RegKeyDHCPOptions.QueryError()) != NERR_Success )
{
ReportError( err );
break;
}
REG_KEY_INFO_STRUCT reginfo;
NLS_STR nlsLocation;
// enum all the option keys
while ( regOptions.NextSubKey( &reginfo ) == NERR_Success )
{
REG_KEY RegKeyDHCPOption( RegKeyDHCPOptions, reginfo.nlsName, MAXIMUM_ALLOWED );
if ( RegKeyDHCPOption.QueryError() != NERR_Success )
{
continue;
}
RegKeyDHCPOption.QueryValue( RGAS_REG_LOCATION, &nlsLocation );
ISTR istr( nlsLocation );
NLS_STR *pTmp = new NLS_STR(nlsLocation);
if ( pTmp != NULL )
{
if ( nlsLocation.strchr( &istr, TCH_QUESTION_MARK ))
{
// per adapter
PerAdapterOptions.Append( pTmp );
} else
{
// global
GlobalOptions.Append( pTmp );
}
}
}
} while ( FALSE );
if ( err == NERR_Success )
{
// Add two default PerAdapterOption
PerAdapterOptions.Append( new NLS_STR( RGAS_DHCP_OPTION_IPADDRESS ));
PerAdapterOptions.Append( new NLS_STR( RGAS_DHCP_OPTION_SUBNETMASK ));
PerAdapterOptions.Append( new NLS_STR( RGAS_DHCP_OPTION_NAMESERVERBACKUP ));
}
}
/*******************************************************************
NAME: GetNodeNum
SYNOPSIS: Get an IP Address and return the 4 numbers in the IP address.
ENTRY: NLS_STR & nlsAddress - IP Address
DWORD *dw1, *dw2, *dw3, *dw4 - the 4 numbers in the IP Address
HISTORY:
terryk 20-Oct-1992 Created
********************************************************************/
VOID GetNodeNum( NLS_STR & nlsAddress, DWORD ardw[4] )
{
ALIAS_STR nlsDot(SZ_DOT);
STRLIST strlst( nlsAddress, nlsDot );
ITER_STRLIST iter( strlst );
NLS_STR *pnlsField = iter.Next();
// Go through each field and get the number value
if ( pnlsField != NULL )
{
ardw[0] = pnlsField->atoul();
pnlsField = iter.Next();
if ( pnlsField != NULL )
{
ardw[1] = pnlsField->atoul();
pnlsField = iter.Next();
if ( pnlsField != NULL )
{
ardw[2] = pnlsField->atoul();
pnlsField = iter.Next();
if ( pnlsField != NULL )
{
ardw[3] = pnlsField->atoul();
pnlsField = iter.Next();
}
}
}
}
}
VOID GetNodeString( NLS_STR * pnlsAddress, DWORD ardw[4] )
{
DEC_STR nlsAddress0( ardw[0] );
DEC_STR nlsAddress1( ardw[1] );
DEC_STR nlsAddress2( ardw[2] );
DEC_STR nlsAddress3( ardw[3] );
ALIAS_STR nlsDot = SZ_DOT;
*pnlsAddress = nlsAddress0;
pnlsAddress->strcat( nlsDot );
pnlsAddress->strcat( nlsAddress1 );
pnlsAddress->strcat( nlsDot );
pnlsAddress->strcat( nlsAddress2 );
pnlsAddress->strcat( nlsDot );
pnlsAddress->strcat( nlsAddress3 );
}
/*******************************************************************
NAME: GetRegKey
SYNOPSIS: get the value data from registry ( string ver )
ENTRY: const REG_KEY & regkey - registry key handle
const TCHAR * pszName - parameter name
NLS_STR * pnls - string buffer
NLS_STR nlsDefault - if the default value string
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR GetRegKey( REG_KEY & regkey, const TCHAR * pszName, NLS_STR * pnls, const NLS_STR & nlsDefault, APIERR *perr)
{
APIERR err = regkey.QueryValue( pszName, pnls );
if ( perr != NULL )
{
*perr = err;
}
if (( err != NERR_Success ) )
{
*pnls = nlsDefault;
}
return pnls->QueryError();
}
APIERR GetRegKey( REG_KEY & regkey, const TCHAR * pszName, STRLIST ** ppstrlist, APIERR *perr)
{
APIERR err = regkey.QueryValue( pszName, ppstrlist );
if ( perr != NULL )
{
*perr = err;
}
if ( err != NERR_Success )
{
*ppstrlist = NULL;
}
return NERR_Success;
}
/*******************************************************************
NAME: GetRegKey
SYNOPSIS: Get the value data from the registry ( dword ver )
ENTRY: const REG_KEY & regkey - registry key handle
const TCHAR * pszName - parameter name
const DWORD * dw - DWORD data buffer
DWORD dw - default
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR GetRegKey( REG_KEY & regkey, const TCHAR * pszName, DWORD * dw, DWORD dwDefault, APIERR *perr)
{
APIERR err = regkey.QueryValue( pszName, dw );
if ( perr != NULL )
{
*perr = err;
}
if ( err != NERR_Success )
{
*dw = dwDefault;
}
return NERR_Success;
}
/*******************************************************************
NAME: SaveRegKey
SYNOPSIS: Save the given value data into the given registry (string ver)
ENTRY: const REG_KEY & regkey - registry key handle
const TCHAR * pszName - parameter name
const NLS_STR nls - string data
BOOL fExpandSz - Expand string flag
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR SaveRegKey( REG_KEY & regkey, const TCHAR * pszName, const NLS_STR & nls, BOOL fExpandSz)
{
return regkey.SetValue( pszName, nls, 0, NULL, fExpandSz );
}
/*******************************************************************
NAME: SaveRegKey
SYNOPSIS: Save the given value data into the given registry ( dword ver )
ENTRY: const REG_KEY & regkey - registry key handle
const TCHAR * pszName - parameter name
const DWORD dw - DWORD data
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR SaveRegKey( REG_KEY & regkey, const TCHAR * pszName, const DWORD dw)
{
return regkey.SetValue( pszName, dw );
}
APIERR SaveRegKey( REG_KEY & regkey, const TCHAR * pszName, const STRLIST *pstrlist)
{
return regkey.SetValue( pszName, pstrlist );
}
APIERR QueryNetworkRegName(REG_KEY & rkLocalMachine, NLS_STR & nlsService, NLS_STR * pnlsLocation)
{
APIERR err = NERR_Success;
HKEY key;
TCHAR buf[256];
FILETIME time;
NLS_STR loc;
unsigned long lSize = _countof(buf);
int i = 0;
if ((err = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, RGAS_ADAPTER_HOME, 0, KEY_ALL_ACCESS, &key)) == ERROR_SUCCESS)
{
while ((err = RegEnumKeyEx(key, i, buf, &lSize, NULL, NULL, NULL, &time)) == ERROR_SUCCESS)
{
// Set for next iteration
++i;
lSize = _countof(buf);
// Construct key canidate
NLS_STR nlsServiceName;
loc = RGAS_ADAPTER_HOME;
loc.strcat(_T("\\"));
loc.strcat(buf);
{
// Open the key under this section and see if it's the adapter we're looking for
REG_KEY RegKeyNetworkCards(rkLocalMachine, loc, MAXIMUM_ALLOWED);
if (((err = RegKeyNetworkCards.QueryError()) != NERR_Success) ||
((err = RegKeyNetworkCards.QueryValue(RGAS_SERVICE_NAME, &nlsServiceName)) != NERR_Success))
{
break;
}
// Is it the adapter?
if (nlsServiceName._stricmp(nlsService)==0)
{
*pnlsLocation = loc;
break;
}
}
}
}
// Close the SOFTWARE key
::RegCloseKey(key);
return err;
}
/*******************************************************************
NAME: LoadRegistry
SYNOPSIS: Load the tcpip information to the registry
ENTRY: const TCHAR * pszParms - bind network card list
GLOBAL_INFO GlobalInfo - global tcpip info data structure
ADAPTER_INFO *arAdapterInfo - array of adapter information
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR LoadRegistry( const TCHAR * pszParms,
NLS_STR nlsHostName,
NLS_STR nlsDomainName,
GLOBAL_INFO *pGlobalInfo,
ADAPTER_INFO **parAdapterInfo,
INT *cInfo,
BOOL fIgnoreAutoIP,
BOOL fCallFromRas )
{
APIERR err = NERR_Success;
do {
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
REG_KEY_CREATE_STRUCT regCreate;
if ( err = rkLocalMachine.QueryError() )
{
break;
}
regCreate.dwTitleIndex = 0;
regCreate.ulOptions = REG_OPTION_NON_VOLATILE;
regCreate.nlsClass = RGAS_GENERIC_CLASS;
regCreate.regSam = MAXIMUM_ALLOWED;
regCreate.pSecAttr = NULL;
regCreate.ulDisposition = 0;
NLS_STR nlsTcpipParameter = RGAS_SERVICES_HOME;
nlsTcpipParameter.strcat( RGAS_TCPIP_PARAMETERS );
//
// create the registry key and get the information
//
REG_KEY RegKeyTcpipParam( rkLocalMachine, nlsTcpipParameter, & regCreate );
if (( err = RegKeyTcpipParam.QueryError()) != NERR_Success )
{
break;
}
DWORD dwDNSEnableWINS;
ALIAS_STR nlsNULL = RGAS_SZ_NULL;
ALIAS_STR nlsZeroAddressString = ZERO_ADDRESS;
ALIAS_STR nlsTransient = RGAS_TRANSIENT;
DWORD dwEnableRouter;
DWORD dwEnableRip;
DWORD dwEnableSecurity;
// if it is called from RAS, get the transient key
if ( fCallFromRas )
{
pGlobalInfo->nlsNameServer = nlsNULL;
REG_KEY regTransient( RegKeyTcpipParam, nlsTransient );
if ( regTransient.QueryError() == NERR_Success )
{
// if the transient key exists, use it. Otherwise, default to
// NULL
GetRegKey( regTransient, RGAS_NAMESERVER,
&(pGlobalInfo->nlsNameServer), nlsNULL);
}
} else
{
// if not from RAS, do the normal stuff and get the
// name server value
if (( err = GetRegKey( RegKeyTcpipParam, RGAS_NAMESERVER,
&(pGlobalInfo->nlsNameServer), nlsNULL)) != NERR_Success )
{
break;
}
}
if ((( err = GetRegKey( RegKeyTcpipParam, RGAS_HOSTNAME,
&(pGlobalInfo->nlsHostName), nlsHostName )) != NERR_Success ) ||
(( err = GetRegKey( RegKeyTcpipParam, RGAS_DOMAIN,
&(pGlobalInfo->nlsDomain), nlsDomainName)) != NERR_Success ) ||
(( err = GetRegKey( RegKeyTcpipParam, RGAS_SEARCHLIST,
&(pGlobalInfo->nlsSearchList), nlsNULL)) != NERR_Success ) ||
(( err = GetRegKey( RegKeyTcpipParam, RGAS_DNSENABLEWINS,
&(dwDNSEnableWINS), 0)) != NERR_Success ) ||
(( err = GetRegKey( RegKeyTcpipParam, RGAS_ENABLE_ROUTER,
& dwEnableRouter, 0 )) != NERR_Success ) ||
(( err = GetRegKey(RegKeyTcpipParam, RGAS_SECURITY_ENABLE,
&dwEnableSecurity, 0 )) != NERR_Success ))
{
break;
}
pGlobalInfo->fEnableRouter = ( dwEnableRouter != 0 );
pGlobalInfo->m_bEnableSecurity = (dwEnableSecurity != 0);
// NetBT stuff
NLS_STR nlsNetBTParameter = RGAS_SERVICES_HOME;
nlsNetBTParameter.strcat( RGAS_NETBT_PARAMETERS );
NLS_STR nlsNetBTAdapters = RGAS_SERVICES_HOME;
nlsNetBTAdapters.strcat( RGAS_NETBT_ADAPTERS );
//
// construct the registry key and get the information
//
REG_KEY RegKeyNetBTParam( rkLocalMachine, nlsNetBTParameter, & regCreate );
REG_KEY RegKeyNetBTAdapters( rkLocalMachine, nlsNetBTAdapters, & regCreate );
if ((( err = RegKeyNetBTParam.QueryError()) != NERR_Success ) ||
(( err = RegKeyNetBTAdapters.QueryError()) != NERR_Success ))
{
break;
}
DWORD dwEnableWINSProxy;
DWORD dwLMHOSTS;
if ((( err = GetRegKey( RegKeyNetBTParam, RGAS_ENABLE_DNS,
& dwDNSEnableWINS, 0 )) != NERR_Success ) ||
(( err = GetRegKey( RegKeyNetBTParam, RGAS_ENABLE_LMHOSTS,
& dwLMHOSTS, 1 )) != NERR_Success ) ||
(( err = GetRegKey( RegKeyNetBTParam, RGAS_ENABLE_PROXY,
&dwEnableWINSProxy, 0 )) != NERR_Success ) ||
(( err = GetRegKey( RegKeyNetBTParam, RGAS_SCOPEID,
& pGlobalInfo->nlsScopeID, nlsDomainName )) != NERR_Success ))
{
break;
}
pGlobalInfo->fDNSEnableWINS = ( dwDNSEnableWINS != 0 );
pGlobalInfo->fEnableLMHOSTS = ( dwLMHOSTS != 0 );
pGlobalInfo->fEnableWINSProxy = ( dwEnableWINSProxy != 0 );
// Get adapter card info
STRLIST strlst( pszParms, SEPARATOR );
*cInfo = strlst.QueryNumElem() + 1;
pGlobalInfo->nNumCard = strlst.QueryNumElem();
ADAPTER_INFO *arAdapterInfo = new ADAPTER_INFO[ *cInfo ];
*parAdapterInfo = arAdapterInfo;
ITER_STRLIST iter( strlst );
NLS_STR *pnlsAdapterName = NULL;
INT i = 0;
DWORD dwEnablePPTP;
for( ; ( pnlsAdapterName = iter.Next()) != NULL ; i++ )
{
// open the NetBT\Adapters\<Something> to get the
// Primary and Secondary server
NLS_STR nlsAdapter = nlsNetBTAdapters;
nlsAdapter.AppendChar( BACK_SLASH );
nlsAdapter.strcat( *pnlsAdapterName );
REG_KEY RegKeyAdapter( rkLocalMachine, nlsAdapter, & regCreate );
if (( err = RegKeyAdapter.QueryError()) == NERR_Success )
{
GetRegKey( RegKeyAdapter, RGAS_PRIMARY_WINS,
& arAdapterInfo[i].nlsPrimaryWINS, nlsNULL );
GetRegKey( RegKeyAdapter, RGAS_SECONDARY_WINS,
& arAdapterInfo[i].nlsSecondaryWINS, nlsNULL );
GetRegKey( RegKeyAdapter, RGAS_NODETYPE,
& arAdapterInfo[i].dwNodeType, P_NODE );
}
// get other tcpip info
NLS_STR nlsTcpip = RGAS_SERVICES_HOME;
nlsTcpip.AppendChar( TCH('\\'));
nlsTcpip.strcat( *pnlsAdapterName );
NLS_STR nlsParameter = nlsTcpip;
nlsParameter.strcat ( SZ_PARAMETERS );
REG_KEY RegKeyNetCardParameter( rkLocalMachine, nlsParameter,
&regCreate );
if (( err = RegKeyNetCardParameter.QueryError()) != NERR_Success )
{
break;
}
nlsTcpip.strcat( RGAS_PARAMETERS_TCPIP );
//
// get the software or hardware location from \ServiceName\SCManager\linkage
//
REG_KEY RegKeyTcpip( rkLocalMachine, nlsTcpip, & regCreate );
if (( err = RegKeyTcpip.QueryError()) != NERR_Success )
{
break;
}
// check for autoipaddress value
DWORD dwAutoIPAddress = 0;
err = RegKeyNetCardParameter.QueryValue( RGAS_AUTOIPADDRESS, &(dwAutoIPAddress));
if (( dwAutoIPAddress == 1 ) && (!fIgnoreAutoIP ))
{
// skip this;
pGlobalInfo->nNumCard --;
i--;
continue;
}
if (fCallFromRas == TRUE && dwAutoIPAddress == 1)
arAdapterInfo[i].m_bIsWanAdapter = TRUE;
else
arAdapterInfo[i].m_bIsWanAdapter = FALSE;
if (( err == NERR_Success ) && ( !fIgnoreAutoIP ))
{
arAdapterInfo[i].fAutoIP = TRUE;
} else
{
arAdapterInfo[i].fAutoIP = FALSE;
}
NLS_STR nlsLocation;
if (( err = QueryNetworkRegName( rkLocalMachine, *pnlsAdapterName, &nlsLocation)) != NERR_Success )
{
break;
}
REG_KEY RegKeyNetCard( rkLocalMachine, nlsLocation, &regCreate );
if (( err = RegKeyNetCard.QueryError()) != NERR_Success )
{
break;
}
NLS_STR nlsUnknown ;
ALIAS_STR nlsEther = SZ_ETHER;
ALIAS_STR nlsToken = SZ_TOKEN;
ALIAS_STR nlsZeroAddressString = ZERO_ADDRESS;
if ( (err = nlsUnknown.QueryError()) == 0 )
{
// If string load fails, default to static English string
if ( err = nlsUnknown.Load( IDS_UNKNOWN_NETWORK_CARD ) )
err = nlsUnknown.CopyFrom( SZ_UNKNOWN );
}
if ( err )
break;
NLS_STR nlsIPAddress;
NLS_STR nlsSubnetMask;
APIERR IPerr = NERR_Success;
DWORD dwEnableDHCP;
ALIAS_STR nlsDHCPServer = RGAS_DHCP_SERVER;
REG_KEY RegKeyDHCPServer( rkLocalMachine, nlsDHCPServer );
pGlobalInfo->fDHCPServerInstalled = (RegKeyDHCPServer.QueryError() == NERR_Success);
if ((( err = GetRegKey( RegKeyNetCard, RGAS_TITLE,
&(arAdapterInfo[i].nlsTitle), nlsUnknown ))!= NERR_Success ) ||
(( err = GetRegKey( RegKeyTcpip, RGAS_ENABLE_DHCP,
&(dwEnableDHCP), 0)) != NERR_Success ))
{
break;
}
STRLIST *pstrlstTmp = NULL;
IPerr = RegKeyTcpip.QueryValue( RGAS_IPADDRESS, &pstrlstTmp);
if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].strlstIPAddresses, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
} else
{
arAdapterInfo[i].strlstIPAddresses.Clear();
IPerr = (IPerr == NERR_Success ) ? ERROR_INVALID_DATA : IPerr;
}
// set subnet mask information
if (( RegKeyTcpip.QueryValue( RGAS_SUBNETMASK, &pstrlstTmp) != NERR_Success ) || ( pstrlstTmp == NULL ) || ( pstrlstTmp->QueryNumElem() == 0))
{
arAdapterInfo[i].fUpdateMask = TRUE;
arAdapterInfo[i].strlstSubnetMask.Clear();
} else if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].strlstSubnetMask, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
arAdapterInfo[i].fUpdateMask = FALSE;
}
// set default gateway
RegKeyTcpip.QueryValue( RGAS_DEFAULTGATEWAY, &pstrlstTmp);
if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].strlstDefaultGateway, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
} else
{
arAdapterInfo[i].strlstDefaultGateway.Clear();
}
arAdapterInfo[i].fChange = FALSE;
if (pGlobalInfo->fDHCPServerInstalled)
{
// disable DHCP client
dwEnableDHCP=0;
}
arAdapterInfo[i].fEnableDHCP = (dwEnableDHCP!=0);
arAdapterInfo[i].nlsServiceName = *pnlsAdapterName;
arAdapterInfo[i].fNeedIP = ( (!dwEnableDHCP) && (IPerr != NERR_Success));
// Get security info
if (fCallFromRas == FALSE)
{
if ((err = GetRegKey(RegKeyTcpip, RGAS_SECURITY_PPTP, &dwEnablePPTP, 0 )) != NERR_Success)
{
break;
}
arAdapterInfo[i].m_bEnablePPTP = (dwEnablePPTP != 0);
// TCP port filter
RegKeyTcpip.QueryValue(RGAS_SECURITY_TCP, &pstrlstTmp);
if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].m_strListTcp, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
}
else
{
arAdapterInfo[i].m_strListTcp.Clear();
arAdapterInfo[i].m_strListTcp.Append(new NLS_STR(_T("0")));
}
// UDP Port filter
RegKeyTcpip.QueryValue(RGAS_SECURITY_UDP, &pstrlstTmp);
if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].m_strListUdp, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
}
else
{
arAdapterInfo[i].m_strListUdp.Clear();
arAdapterInfo[i].m_strListUdp.Append(new NLS_STR(_T("0")));
}
// IP protocol filters
RegKeyTcpip.QueryValue(RGAS_SECURITY_IP, &pstrlstTmp);
if ( pstrlstTmp != NULL )
{
CopyStrList( pstrlstTmp, &arAdapterInfo[i].m_strListIp, fCallFromRas);
delete pstrlstTmp;
pstrlstTmp = NULL;
}
else
{
arAdapterInfo[i].m_strListIp.Clear();
arAdapterInfo[i].m_strListIp.Append(new NLS_STR(_T("0")));
}
// There must be at least an "" in each security list
{
ITER_STRLIST itr(arAdapterInfo[i].m_strListTcp);
NLS_STR* pstr = itr.Next();
if (pstr == NULL)
arAdapterInfo[i].m_strListTcp.Append(new NLS_STR(_T("")));
}
{
ITER_STRLIST itr(arAdapterInfo[i].m_strListUdp);
NLS_STR* pstr = itr.Next();
if (pstr == NULL)
arAdapterInfo[i].m_strListUdp.Append(new NLS_STR(_T("")));
}
{
ITER_STRLIST itr(arAdapterInfo[i].m_strListIp);
NLS_STR* pstr = itr.Next();
if (pstr == NULL)
arAdapterInfo[i].m_strListIp.Append(new NLS_STR(_T("")));
}
}
}
// EnableRip stuff
NLS_STR nlsProductType;
ALIAS_STR nlsWinnt = RGAS_WINNT;
NLS_STR nlsProductOption = RGAS_PRODUCT_OPTION;
REG_KEY RegKeyProductOption( rkLocalMachine, nlsProductOption );
GetRegKey( RegKeyProductOption, RGAS_PRODUCT_TYPE,
&nlsProductType, nlsWinnt );
pGlobalInfo->fWorkstation = (nlsProductType._stricmp( nlsWinnt ) == 0 );
NLS_STR nlsIPRip = RGAS_IPRIP;
REG_KEY RegKeyIPRip( rkLocalMachine, nlsIPRip );
if ( RegKeyIPRip.QueryError() != NERR_Success )
{
pGlobalInfo->fRipInstalled = FALSE;
pGlobalInfo->fEnableRip = 0;
} else
{
pGlobalInfo->fRipInstalled = TRUE;
pGlobalInfo->fEnableRip = 0;
SC_MANAGER ScManager( NULL, GENERIC_ALL );
if ( ScManager.QueryError() == NERR_Success )
{
SC_SERVICE sIPRip( ScManager, RGAS_IPRIP_SERVICE );
if ( sIPRip.QueryError() == NERR_Success )
{
LPQUERY_SERVICE_CONFIG pConfig;
if ( sIPRip.QueryConfig( &pConfig ) == NERR_Success )
{
pGlobalInfo->fEnableRip = (( pConfig->dwStartType != SERVICE_DISABLED ) && pGlobalInfo->nNumCard);
}
}
}
}
// check for relay agent
NLS_STR nlsRelayAgent = RGAS_RELAY_AGENT;
REG_KEY RegKeyRelayAgent( rkLocalMachine, nlsRelayAgent );
if ( RegKeyRelayAgent.QueryError() != NERR_Success )
{
pGlobalInfo->fRelayAgentInstalled = FALSE;
pGlobalInfo->fEnableRelayAgent = FALSE;
} else
{
pGlobalInfo->fRelayAgentInstalled = TRUE;
pGlobalInfo->fEnableRelayAgent = FALSE;
SC_MANAGER ScManager( NULL, GENERIC_ALL );
if ( ScManager.QueryError() == NERR_Success )
{
SC_SERVICE sRelayAgent( ScManager, RGAS_RELAY_AGENT_SERVICE );
if ( sRelayAgent.QueryError() == NERR_Success )
{
LPQUERY_SERVICE_CONFIG pConfig;
if ( sRelayAgent.QueryConfig( &pConfig ) == NERR_Success )
{
pGlobalInfo->fEnableRelayAgent = (( pConfig->dwStartType != SERVICE_DISABLED ) && ( pGlobalInfo->nNumCard > 1 ));
}
}
}
}
} while (FALSE);
return err;
}
/*
* Merge the contents of *pslOther onto *pslMain.
* Each string is fully duplicated.
*/
static APIERR mergeStrLists ( STRLIST * pslMain, STRLIST * pslOther )
{
APIERR err = 0 ;
ITER_STRLIST islOther( *pslOther ) ;
NLS_STR * pnlsNext,
* pnlsDup = NULL ;
// This unfortunate code is based on the fact that STRLIST
// iteration/removal is not reliable.
while ( pnlsNext = islOther.Next() )
{
pnlsDup = new NLS_STR( *pnlsNext ) ;
err = pnlsDup == NULL
? ERROR_NOT_ENOUGH_MEMORY
: pnlsDup->QueryError() ;
if ( err )
break ;
err = pslMain->Append( pnlsDup ) ;
pnlsDup = NULL ;
if ( err )
break ;
}
delete pnlsDup ; // Precaution if failure.
return err ;
}
/*******************************************************************
NAME: ActivateBindings
SYNOPSIS: Given a list of bindings to preserve,
activate them and disable all other bindings.
ENTRY: REG_KEY * prkNetBTLinkage pointer to NetBT linkage
registry key
-- or --
const TCHAR * pszServiceName name of service to
fiddle with
const TCHAR * apszBinds NULL-terminated list
of binding names
EXIT: Nothing
RETURNS: APIERR if failure or zero if successful
NOTES: Enabled (active) bindings are listed under the "Linkage"
key; disabled (inactive) bindings are listed under
the "Linkage\Disabled" key.
Due to the fact that iterating a STRLIST while removing
items is not reliable, this code does more string
duplication than would seem necessary at first glance.
The algorithm is:
Query the active and inactive binding data from
the Registry.
Merge active and inactive bindings into a new set
of STRLISTs; clear the disabled STRLISTs.
Iterate over the merged lists, duplicating each
set of strings. If the Bind value matches the
function argument, make it active; all others
become inactive.
Set all Registry values.
HISTORY:
********************************************************************/
APIERR ActivateBindings (
REG_KEY * prkNetBTLinkage,
const TCHAR * * apszBinds )
{
APIERR err = 0 ;
NLS_STR nlsDisabled( RGAS_DISABLED_KEY_NAME ) ;
STRLIST * pslActBind = NULL,
* pslActExport = NULL,
* pslActRoute = NULL,
* pslDisBind = NULL,
* pslDisExport = NULL,
* pslDisRoute = NULL,
* pslMergeBind = NULL,
* pslMergeExport = NULL,
* pslMergeRoute = NULL ;
if ( err = nlsDisabled.QueryError() )
{
return err ;
}
REG_KEY rkDisabled ( *prkNetBTLinkage, nlsDisabled, MAXIMUM_ALLOWED ) ;
if ( err = rkDisabled.QueryError() )
{
return err ;
}
do // Pseudo-loop
{
// Suck in all the values.
// Allocate an empty list for anything not found.
if ( prkNetBTLinkage->QueryValue( RGAS_BIND_VALUE_NAME, & pslMergeBind ) )
pslMergeBind = new STRLIST ;
if ( prkNetBTLinkage->QueryValue( RGAS_EXPORT_VALUE_NAME, & pslMergeExport ) )
pslMergeExport = new STRLIST ;
if ( prkNetBTLinkage->QueryValue( RGAS_ROUTE_VALUE_NAME, & pslMergeRoute ) )
pslMergeRoute = new STRLIST ;
if ( rkDisabled.QueryValue( RGAS_BIND_VALUE_NAME, & pslDisBind ) )
pslDisBind = new STRLIST ;
if ( rkDisabled.QueryValue( RGAS_EXPORT_VALUE_NAME, & pslDisExport ) )
pslDisExport = new STRLIST ;
if ( rkDisabled.QueryValue( RGAS_ROUTE_VALUE_NAME, & pslDisRoute ) )
pslDisRoute = new STRLIST ;
// Allocate new "active" STRLISTs
pslActBind = new STRLIST ;
pslActExport = new STRLIST ;
pslActRoute = new STRLIST ;
if ( pslActBind == NULL
|| pslActExport == NULL
|| pslActRoute == NULL
|| pslDisBind == NULL
|| pslDisExport == NULL
|| pslDisRoute == NULL
|| pslMergeBind == NULL
|| pslMergeExport == NULL
|| pslMergeRoute == NULL
)
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
// Merge the active and inactive lists; clear the inactive lists.
if ( err = mergeStrLists( pslMergeBind, pslDisBind ) )
break ;
if ( err = mergeStrLists( pslMergeExport, pslDisExport ) )
break ;
if ( err = mergeStrLists( pslMergeRoute, pslDisRoute ) )
break ;
pslDisBind->Clear() ;
pslDisExport->Clear() ;
pslDisRoute->Clear() ;
// Loop through the merged lists. When we find the target, make it
// active; make all others inactive.
NLS_STR * pnlsBind,
* pnlsExport,
* pnlsRoute,
* pnlsDupBind = NULL,
* pnlsDupExport = NULL,
* pnlsDupRoute = NULL ;
ITER_STRLIST islBind( *pslMergeBind ) ;
ITER_STRLIST islExport( *pslMergeExport ) ;
ITER_STRLIST islRoute( *pslMergeRoute ) ;
for ( ; pnlsBind = islBind.Next() ; )
{
pnlsExport = islExport.Next() ;
pnlsRoute = islRoute.Next() ;
if ( pnlsExport == NULL || pnlsRoute == NULL )
{
// BOGUS: the lists are internally out of sync!
err = ERROR_GEN_FAILURE ;
}
// Duplicate this set of strings. This method of
// operation is due to problems in removing SLIST
// items while iterating.
pnlsDupBind = new NLS_STR( *pnlsBind ) ;
pnlsDupExport = new NLS_STR( *pnlsExport ) ;
pnlsDupRoute = new NLS_STR( *pnlsRoute ) ;
if ( pnlsDupBind == NULL
|| pnlsDupExport == NULL
|| pnlsDupRoute == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
delete pnlsDupBind ;
delete pnlsDupExport ;
delete pnlsDupRoute ;
break ;
}
// If this is an active binding, make it so;
// otherwise, add it to the inactive set
for ( INT iBind = 0 ; apszBinds[iBind] ; iBind++ )
{
if ( ::stricmpf( pnlsBind->QueryPch(), apszBinds[iBind] ) == 0 )
break ;
}
if ( apszBinds[iBind] )
{
pslActBind->Append( pnlsDupBind ) ;
pslActExport->Append( pnlsDupExport ) ;
pslActRoute->Append( pnlsDupRoute ) ;
TRACEEOL( SZ("NCPA/TCPIP: ActivateBindings; binding found: ")
<< apszBinds[iBind] ) ;
}
else
{
pslDisBind->Append( pnlsDupBind ) ;
pslDisExport->Append( pnlsDupExport ) ;
pslDisRoute->Append( pnlsDupRoute ) ;
}
}
// Write out the modified REG_MULTI_SZs
prkNetBTLinkage->SetValue( RGAS_BIND_VALUE_NAME, pslActBind ) ;
prkNetBTLinkage->SetValue( RGAS_EXPORT_VALUE_NAME, pslActExport ) ;
prkNetBTLinkage->SetValue( RGAS_ROUTE_VALUE_NAME, pslActRoute ) ;
rkDisabled.SetValue( RGAS_BIND_VALUE_NAME, pslDisBind ) ;
rkDisabled.SetValue( RGAS_EXPORT_VALUE_NAME, pslDisExport ) ;
rkDisabled.SetValue( RGAS_ROUTE_VALUE_NAME, pslDisRoute ) ;
} while ( FALSE ) ;
delete pslActBind ;
delete pslActRoute ;
delete pslActExport ;
delete pslDisBind ;
delete pslDisExport ;
delete pslDisRoute ;
delete pslMergeBind ;
delete pslMergeRoute ;
delete pslMergeExport ;
return err ;
}
// Variant which opens the Linkage key given the
// name of the service.
APIERR ActivateBindings (
const TCHAR * pszServiceName,
const TCHAR * * apszBinds )
{
APIERR err ;
TCHAR achLinkage [MAX_PATH] ;
::wsprintf( achLinkage, SZ("%s\\%s\\%s"),
RGAS_SERVICES_HOME,
pszServiceName,
RGAS_LINKAGE_NAME ) ;
ALIAS_STR nlsLinkageKeyName( achLinkage ) ;
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
if ( err = rkLocalMachine.QueryError() )
{
return err ;
}
REG_KEY rkLinkage( rkLocalMachine,
nlsLinkageKeyName ) ;
if ( err = rkLinkage.QueryError() )
{
return err ;
}
return ActivateBindings( & rkLinkage, apszBinds ) ;
}
// Activate a single binding.
APIERR ActivateBinding (
REG_KEY * prkLinkage,
const TCHAR * pszBind )
{
const TCHAR * apszBinds [2] ;
apszBinds[0] = pszBind ;
apszBinds[1] = NULL ;
return ActivateBindings( prkLinkage, apszBinds ) ;
}
// Exported versions: UNICODE and ANSI.
LONG FAR PASCAL CPlActivateBindingsW (
const TCHAR * pszServiceName,
const TCHAR * * apszBinds )
{
return ActivateBindings( pszServiceName, apszBinds ) ;
}
LONG FAR PASCAL CPlActivateBindingsA (
const CHAR * pszServiceName,
const CHAR * * apszBinds )
{
NLS_STR nlsServiceName ;
const TCHAR * * apwchBinds = NULL ;
INT cBind ;
APIERR err ;
do
{
if ( err = nlsServiceName.QueryError() )
break ;
if ( err = nlsServiceName.MapCopyFrom( pszServiceName ) )
break ;
// Count the number of bindings given; use the
// ANSI string vector to create a UNICODE vector.
for ( cBind = 0 ; apszBinds[cBind++] ; ) ;
if ( (apwchBinds = (const TCHAR **) CvtArgs( (const LPSTR *) apszBinds, cBind )) == NULL )
{
err = ERROR_NOT_ENOUGH_MEMORY ;
break ;
}
// Call the worker function
err = ActivateBindings( nlsServiceName.QueryPch(), apwchBinds ) ;
FreeArgs( (TCHAR **) apwchBinds, cBind ) ;
}
while ( FALSE ) ;
return err ;
}
/*******************************************************************
NAME: DeleteRegValue
SYNOPSIS: By given a registry value, this routine will remove the
value in the registry.
ENTRY: NLS_STR &nls - registry value to be deleted.
RETURNS: VOID
NOTES:
HISTORY:
terryk 06-Aug-1994 Created
********************************************************************/
VOID DeleteRegValue( NLS_STR &nls )
{
// cut it into key name and value name
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
NLS_STR TmpOption = nls;
ISTR istrStart( TmpOption );
ISTR istrEnd( TmpOption );
TmpOption.strrchr( &istrEnd, BACK_SLASH );
INT Pos = istrEnd - istrStart;
++istrEnd;
NLS_STR *pValueName = TmpOption.QuerySubStr( istrEnd );
istrEnd.Reset();
istrEnd += Pos;
NLS_STR *pKeyName = TmpOption.QuerySubStr( istrStart, istrEnd );
REG_KEY RegKeyOption( rkLocalMachine, *pKeyName, MAXIMUM_ALLOWED );
if ( RegKeyOption.QueryError() == NERR_Success )
{
RegKeyOption.DeleteValue( *pValueName );
}
delete pValueName ;
delete pKeyName;
}
/*******************************************************************
NAME: SaveRegistry
SYNOPSIS: Save the tcpip information to the registry
ENTRY: GLOBAL_INFO GlobalInfo - global tcpip info data structure
ADAPTER_INFO *arAdapterInfo - array of adapter information
RETURNS: APIERR
NOTES:
HISTORY:
terryk 06-Apr-1992 Created
********************************************************************/
APIERR SaveRegistry( GLOBAL_INFO *pGlobalInfo, ADAPTER_INFO *arAdapterInfo, BOOL fCallFromRas)
{
APIERR err = NERR_Success;
BOOL fGlobalDisableDHCP = TRUE;
NLS_STR nlsTcpipParameter = RGAS_SERVICES_HOME;
nlsTcpipParameter.strcat( RGAS_TCPIP_PARAMETERS );
REG_KEY rkLocalMachine( HKEY_LOCAL_MACHINE ) ;
DHCP_OPTIONS DhcpOptions;
if ( err = rkLocalMachine.QueryError() )
{
return err;
}
//
// create the registry key and get the information
//
REG_KEY RegKeyTcpipParam( rkLocalMachine, nlsTcpipParameter, MAXIMUM_ALLOWED );
if (( err = RegKeyTcpipParam.QueryError()) != NERR_Success )
{
return err;
}
if ((( err = SaveRegKey( RegKeyTcpipParam, RGAS_HOSTNAME, pGlobalInfo->nlsHostName)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpipParam, RGAS_DOMAIN, pGlobalInfo->nlsDomain)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpipParam, RGAS_SEARCHLIST, pGlobalInfo->nlsSearchList)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpipParam, RGAS_ENABLE_ROUTER, (DWORD)pGlobalInfo->fEnableRouter)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpipParam, RGAS_SECURITY_ENABLE, (DWORD)pGlobalInfo->m_bEnableSecurity)) != NERR_Success ))
{
return err;
}
// save iprip key
if ( pGlobalInfo->fRipInstalled )
{
SC_MANAGER ScManager( NULL, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE );
if ( ScManager.QueryError() == NERR_Success )
{
SC_SERVICE sIPRip( ScManager, RGAS_IPRIP_SERVICE,
GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE );
if ( sIPRip.QueryError() == NERR_Success )
{
QUERY_SERVICE_CONFIG config;
if (sIPRip.ChangeConfig( SERVICE_NO_CHANGE,
pGlobalInfo->fEnableRip ? SERVICE_AUTO_START :
SERVICE_DISABLED, SERVICE_NO_CHANGE ) == NERR_Success)
{
// no problem to update the start type
}
}
}
}
TRACE(_T("RIP installed:%s\n"), (pGlobalInfo->fRipInstalled ? _T("TRUE") : _T("FALSE")));
// save relay agent key
if (pGlobalInfo->fRelayAgentInstalled)
{
SC_MANAGER ScManager( NULL, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE );
if ( ScManager.QueryError() == NERR_Success )
{
SC_SERVICE sRelayAgent(ScManager, RGAS_RELAY_AGENT_SERVICE,
GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE);
if (sRelayAgent.QueryError() == NERR_Success)
{
QUERY_SERVICE_CONFIG config;
if ( sRelayAgent.ChangeConfig( SERVICE_NO_CHANGE,
pGlobalInfo->fEnableRelayAgent ? SERVICE_AUTO_START :
SERVICE_DISABLED, SERVICE_NO_CHANGE ) == NERR_Success)
{
// no problem to update the start type
}
}
}
}
TRACE(_T("RelayAgent installed:%s\n"), (pGlobalInfo->fRelayAgentInstalled ? _T("TRUE") : _T("FALSE")));
// if called from RAS, save to the transient key
// otherwise, just do the standard stuff
if ( fCallFromRas )
{
REG_KEY_CREATE_STRUCT regTransientStruct;
// set up the create registry structure
regTransientStruct.dwTitleIndex = 0;
regTransientStruct.ulOptions = REG_OPTION_VOLATILE;
regTransientStruct.nlsClass = RGAS_GENERIC_CLASS;
regTransientStruct.regSam = MAXIMUM_ALLOWED;
regTransientStruct.pSecAttr = NULL;
regTransientStruct.ulDisposition = 0;
REG_KEY regTransient( RegKeyTcpipParam, RGAS_TRANSIENT, &regTransientStruct );
if (( err = regTransient.QueryError()) != NERR_Success )
{
return(err);
}
// check whether the value is non-space string or not
// if yes, add it. if no, delete it
ISTR istr( pGlobalInfo->nlsNameServer );
ALIAS_STR nlsSpace( SZ(" ") );
if ( pGlobalInfo->nlsNameServer.strspn( &istr, nlsSpace ))
{
// contain non space
if (( err = SaveRegKey( regTransient, RGAS_NAMESERVER, pGlobalInfo->nlsNameServer)) != NERR_Success )
{
return(err);
}
} else
{
// delete the key
regTransient.DeleteTree();
}
} else
{
// do the normal stuff and save the value
if (( err = SaveRegKey( RegKeyTcpipParam, RGAS_NAMESERVER, pGlobalInfo->nlsNameServer)) != NERR_Success )
{
return(err);
}
}
NLS_STR nlsNetBTParameter = RGAS_SERVICES_HOME;
nlsNetBTParameter.strcat( RGAS_NETBT_PARAMETERS );
NLS_STR nlsNetBTAdapters = RGAS_SERVICES_HOME;
nlsNetBTAdapters.strcat( RGAS_NETBT_ADAPTERS );
//
// create the registry key and get the information
//
REG_KEY RegKeyNetBTParam( rkLocalMachine, nlsNetBTParameter, MAXIMUM_ALLOWED);
REG_KEY RegKeyNetBTAdapters( rkLocalMachine, nlsNetBTAdapters, MAXIMUM_ALLOWED);
if ((( err = RegKeyNetBTParam.QueryError()) != NERR_Success ) ||
(( err = RegKeyNetBTAdapters.QueryError()) != NERR_Success ))
{
return err;
}
/* get the ip address of the PermanentName */
if ((( err = SaveRegKey( RegKeyNetBTParam, RGAS_SCOPEID, pGlobalInfo->nlsScopeID)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyNetBTParam, RGAS_ENABLE_DNS, pGlobalInfo->fDNSEnableWINS)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyNetBTParam, RGAS_ENABLE_LMHOSTS, pGlobalInfo->fEnableLMHOSTS)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyNetBTParam, RGAS_ENABLE_PROXY, pGlobalInfo->fEnableWINSProxy)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyNetBTParam, RGAS_SCOPEID, pGlobalInfo->nlsScopeID)) != NERR_Success ))
{
DBGEOL ("save reg key tcpip error");
return err;
}
BOOL DHCPEnabled = FALSE;
INT i;
for( i=0; i < pGlobalInfo->nNumCard; i++ )
{
NLS_STR nlsAdapter = nlsNetBTAdapters;
nlsAdapter.AppendChar( BACK_SLASH );
nlsAdapter.strcat( arAdapterInfo[i].nlsServiceName );
REG_KEY RegKeyAdapter( rkLocalMachine, nlsAdapter, MAXIMUM_ALLOWED );
if (( err = RegKeyAdapter.QueryError()) != NERR_Success )
{
break;
}
if ((( err = SaveRegKey( RegKeyAdapter, RGAS_PRIMARY_WINS,
arAdapterInfo[i].nlsPrimaryWINS )) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyAdapter, RGAS_SECONDARY_WINS,
arAdapterInfo[i].nlsSecondaryWINS )) != NERR_Success ))
{
DBGEOL ("save reg key tcpip error");
return err;
}
DWORD dwOldNodeType;
GetRegKey( RegKeyAdapter, RGAS_NODETYPE, &dwOldNodeType, P_NODE );
if ( dwOldNodeType != arAdapterInfo[i].dwNodeType )
{
if (( err = SaveRegKey( RegKeyAdapter, RGAS_NODETYPE,
arAdapterInfo[i].dwNodeType )) != NERR_Success )
{
DBGEOL ("save reg key tcpip error");
return err;
}
}
NLS_STR nlsTcpip = RGAS_SERVICES_HOME;
nlsTcpip.AppendChar( BACK_SLASH );
nlsTcpip.strcat( arAdapterInfo[i].nlsServiceName );
nlsTcpip.strcat( RGAS_PARAMETERS_TCPIP );
//
// get the software or hardware location from \ServiceName\SCManager\linkage
//
REG_KEY RegKeyTcpip( rkLocalMachine, nlsTcpip, MAXIMUM_ALLOWED );
if (( err = RegKeyTcpip.QueryError()) != NERR_Success )
{
TRACE(_T("KeyError: %s\n"), nlsTcpip.QueryPch());
return err;
}
TRACE(_T("Adapter: %s DHCP:%d WAN:%d Changed:%d \n"), arAdapterInfo[i].nlsTitle.QueryPch(),
arAdapterInfo[i].fEnableDHCP, arAdapterInfo[i].m_bIsWanAdapter,
arAdapterInfo[i].m_bChanged);
if (arAdapterInfo[i].fEnableDHCP)
{
arAdapterInfo[i].strlstIPAddresses.Clear();
arAdapterInfo[i].strlstIPAddresses.Append(new NLS_STR( ZERO_ADDRESS));
arAdapterInfo[i].strlstSubnetMask.Clear();
arAdapterInfo[i].strlstSubnetMask.Append( new NLS_STR( ZERO_ADDRESS ));
DHCPEnabled = TRUE;
}
if (fCallFromRas == FALSE)
{
if ((err = SaveRegKey(RegKeyTcpip, RGAS_SECURITY_PPTP, (DWORD)arAdapterInfo[i].m_bEnablePPTP)) != NERR_Success)
{
return err;
}
if (((err = SaveRegKey( RegKeyTcpip, RGAS_IPADDRESS, &arAdapterInfo[i].strlstIPAddresses)) != NERR_Success ) ||
((err = SaveRegKey( RegKeyTcpip, RGAS_SUBNETMASK, &arAdapterInfo[i].strlstSubnetMask)) != NERR_Success ))
{
return err;
}
if (((err = SaveRegKey(RegKeyTcpip, RGAS_SECURITY_TCP, &arAdapterInfo[i].m_strListTcp)) != NERR_Success ) ||
(( err = SaveRegKey(RegKeyTcpip, RGAS_SECURITY_UDP, &arAdapterInfo[i].m_strListUdp)) != NERR_Success ) ||
(( err = SaveRegKey(RegKeyTcpip, RGAS_SECURITY_IP, &arAdapterInfo[i].m_strListIp)) != NERR_Success ))
{
return err;
}
}
else if (arAdapterInfo[i].m_bChanged == TRUE) // called from RAS and changed
{
// RAS has its information in the IPAddress and Subnet but it needs to be written to
// The DHCPIPAddress and DHCPSubnet, so create a list and swap the data
NLS_STR zero = ZERO_ADDRESS;
ITER_STRLIST iterTmp(arAdapterInfo[i].strlstIPAddresses);
ITER_STRLIST iterTmp1(arAdapterInfo[i].strlstSubnetMask);
NLS_STR* pStr = iterTmp.Next();
NLS_STR* pStr1 = iterTmp1.Next();
if (pStr && pStr1)
{
if ((( err = SaveRegKey(RegKeyTcpip, RGAS_DHCP_IPADDRESS, *pStr)) != NERR_Success ) ||
(( err = SaveRegKey(RegKeyTcpip, RGAS_DHCP_SUBNETMASK, *pStr1)) != NERR_Success ))
{
return err;
}
}
// Force IP and subnet to 0.0.0.0
arAdapterInfo[i].strlstIPAddresses.Clear();
arAdapterInfo[i].strlstIPAddresses.Append(new NLS_STR( ZERO_ADDRESS));
arAdapterInfo[i].strlstSubnetMask.Clear();
arAdapterInfo[i].strlstSubnetMask.Append( new NLS_STR( ZERO_ADDRESS ));
if ((( err = SaveRegKey( RegKeyTcpip, RGAS_IPADDRESS, &arAdapterInfo[i].strlstIPAddresses)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpip, RGAS_SUBNETMASK, &arAdapterInfo[i].strlstSubnetMask)) != NERR_Success ))
{
return err;
}
}
if ((( err = SaveRegKey( RegKeyTcpip, RGAS_DEFAULTGATEWAY, &arAdapterInfo[i].strlstDefaultGateway)) != NERR_Success ) ||
(( err = SaveRegKey( RegKeyTcpip, RGAS_ENABLE_DHCP, (DWORD)arAdapterInfo[i].fEnableDHCP)) != NERR_Success ))
{
return err;
}
if (arAdapterInfo[i].fEnableDHCP)
{
// we don't want to remove the global DHCP scope id and node type
fGlobalDisableDHCP = FALSE;
}
// Remove the keys when RAS is disconnecting or the adapter is not DHCP
else if (fCallFromRas == FALSE ||
(arAdapterInfo[i].m_bDisconnect && arAdapterInfo[i].m_bChanged))
{
// remove all the per adapter DHCP stuff
NLS_STR *pOption;
ITER_STRLIST istrlist( DhcpOptions.PerAdapterOptions );
while (( pOption = istrlist.Next()) != NULL)
{
NLS_STR TmpOption = *pOption;
ISTR istrStartRepl( TmpOption );
ISTR istrEndRepl( TmpOption );
TmpOption.strchr( &istrStartRepl, TCH_QUESTION_MARK );
istrEndRepl = istrStartRepl;
++istrEndRepl;
TmpOption.ReplSubStr( arAdapterInfo[i].nlsServiceName, istrStartRepl, istrEndRepl );
DeleteRegValue( TmpOption );
}
}
}
// Were there any adapter that had DHCP enabled?
if (fCallFromRas == FALSE && fGlobalDisableDHCP)
{
// No, remove the global DHCP scope id and node type
NLS_STR *pOption;
ITER_STRLIST istrlist( DhcpOptions.GlobalOptions );
while ( ( pOption = istrlist.Next()) != NULL )
{
DeleteRegValue( *pOption );
}
}
return err;
}
/*******************************************************************
NAME: CallDHCPConfig
SYNOPSIS: Worker function for NotifyDHCP. This function will do
the actual call to the DHCP server.
ENTRY: LPWSTR ServerName - always NULL
LPWSTR AdapterName - adapter to be changed
BOOL IsNewIpAddress - always yes
DWORD IpIndex - 0 based index for the ip address
DWORD IpAddress - new ip address
DWORD Subnetmask - new subnet mask
SERVICE_ENABLE - notify flag
RETURNS: APIERR
NOTES:
HISTORY:
terryk 16-Apr-1994 Created
********************************************************************/
typedef DWORD (APIENTRY *T_DhcpNotifyConfigChange)(
LPWSTR ServerName,
LPWSTR AdapterName,
BOOL IsNewIpAddress,
DWORD IpIndex,
DWORD IpAddress,
DWORD SubnetMask,
SERVICE_ENABLE DhcpServiceEnabled
);
APIERR CallDHCPConfig(
LPWSTR ServerName,
LPWSTR AdapterName,
BOOL IsNewIpAddress,
DWORD IpIndex,
DWORD IpAddress,
DWORD SubnetMask,
SERVICE_ENABLE DhcpServiceEnabled
)
{
APIERR err = NERR_Success;
HINSTANCE hDll = NULL;
//REVIEW wait cursor AUTO_CURSOR cursorWait;
//cursorWait.TurnOn();
do {
// check to make sure that tcpip is running
SC_MANAGER scMgr( NULL, GENERIC_READ | GENERIC_EXECUTE );
if (( err = scMgr.QueryError()) != NERR_Success )
break;
SC_SERVICE svTcpip( scMgr, RGAS_TCPIP );
if (( err = svTcpip.QueryError()) != NERR_Success )
break;
SERVICE_STATUS sStatus;
if (( err = svTcpip.QueryStatus( & sStatus )) != NERR_Success )
break;
if ( sStatus.dwCurrentState != SERVICE_RUNNING )
{
err = ERROR_SERVICE_NOT_ACTIVE;
break;
}
// load the library
hDll = ::LoadLibrary( SZ("dhcpcsvc.dll") );
if ( hDll == NULL )
{
err = ::GetLastError();
break;
}
FARPROC pDHCPConfig = ::GetProcAddress( hDll, "DhcpNotifyConfigChange");
if ( pDHCPConfig == NULL )
{
err = ::GetLastError();
break;
}
// call the DHCP Notification API
err = (*(T_DhcpNotifyConfigChange)pDHCPConfig)( ServerName,
AdapterName, IsNewIpAddress, IpIndex, IpAddress, SubnetMask,
DhcpServiceEnabled );
} while (FALSE);
if ( hDll )
::FreeLibrary( hDll );
//REVIEW cursorWait.TurnOff();
return err;
}
/*******************************************************************
NAME: RunTcpip
SYNOPSIS: Invoke the Tcpip Setup dialog
ENTRY: HWND hWnd window handle of parent window.
TCHAR * pszParms command line parameters from SETUP;
EXIT:
RETURNS: APIERR
NOTES:
HISTORY:
********************************************************************/
APIERR RunTcpip (HWND hWnd, const TCHAR * pszParms, NLS_STR nlsHostName,
NLS_STR nlsDomainName, BOOL bServer, LPCTSTR lpszUnAttendPath, LPCTSTR lpszSection, INT *pnReturn)
{
APIERR err = NERR_Success;
INT cInfo; // REVIEW to remove //Old C++ does not support array count
// REVIEW addhelp file as last paramter
CTcpSheet tcpip(hWnd, hTcpCfgInstance, lpszHelpFile);
String txt;
txt.LoadString(hTcpCfgInstance, IDS_MSFT_TCP_TEXT);
tcpip.Create(txt,PSH_PROPTITLE);
tcpip.m_general.Create(IDD_TCP_IPADDR, PSP_DEFAULT, NULL, &a101HelpIDs[0]);
tcpip.m_dns.Create(IDD_TCP_DNS, PSP_DEFAULT, NULL, &a105HelpIDs[0]);
tcpip.m_wins.Create(IDD_TCP_WINS, PSP_DEFAULT, NULL, &a111HelpIDs[0]);
if (bServer)
tcpip.m_bootp.Create(IDD_BOOTP, PSP_DEFAULT, NULL, &a121HelpIDs[0]);
#if TEMP_ROUTING
tcpip.m_routing.Create(IDD_ROUTE, PSP_DEFAULT, NULL, &a125HelpIDs[0]);
#endif
// REVIEW this is done when the dll in inited, this seems redundant
if (!IPAddrInit( hTcpCfgInstance ))
{
return err;
}
if ((err = LoadRegistry( pszParms, nlsHostName, nlsDomainName,
&tcpip.m_globalInfo, &tcpip.m_pAdapterInfo, & cInfo)) != NERR_Success )
{
String mess, mess1;
String title;
title.LoadString(hTcpCfgInstance, IDS_MSFT_TCP_TEXT);
mess.LoadString(hTcpCfgInstance, IDS_LOADREG_ERROR);
mess1.Format(mess, err);
if (mess.GetLength())
::MessageBox(::GetActiveWindow(), mess1, title, MB_APPLMODAL|MB_OK|MB_ICONSTOP);
delete [] tcpip.m_pAdapterInfo;
return err;
}
tcpip.m_globalInfo.nReturn = 0;
// REVIEW set new handler
tcpip.m_pAdapterDhcpInfo = new ADAPTER_DHCP_INFO[tcpip.m_globalInfo.nNumCard];
// save old informatio first
for (INT i = 0; i < tcpip.m_globalInfo.nNumCard; i++)
{
// Also, remember some DHCP information
if ((tcpip.m_pAdapterDhcpInfo[i].fEnableDHCP = tcpip.m_pAdapterInfo[i].fEnableDHCP ) == TRUE )
{
tcpip.m_pAdapterDhcpInfo[i].nlsIP = RGAS_SZ_NULL;
tcpip.m_pAdapterDhcpInfo[i].nlsSubnet = RGAS_SZ_NULL;
} else
{
ITER_STRLIST istrIP(tcpip.m_pAdapterInfo[i].strlstIPAddresses );
NLS_STR *pnlsIPTmp = istrIP.Next();
if (pnlsIPTmp != NULL)
tcpip.m_pAdapterDhcpInfo[i].nlsIP = *pnlsIPTmp;
ITER_STRLIST istrSubnet(tcpip.m_pAdapterInfo[i].strlstSubnetMask );
NLS_STR *pnlsSubnetTmp = istrSubnet.Next();
if ( pnlsSubnetTmp != NULL )
tcpip.m_pAdapterDhcpInfo[i].nlsSubnet = *pnlsSubnetTmp;
}
}
BOOL result = FALSE;
// Only call the Property Sheet if we are not in unattended mode and there isn't a config problem
if (lpszUnAttendPath != NULL)
result = ConfigureAdapters(lpszUnAttendPath, lpszSection, &tcpip);
if (result == FALSE)
tcpip.DoModal();
delete [] tcpip.m_pAdapterInfo;
delete [] tcpip.m_pAdapterDhcpInfo;
*pnReturn = ((tcpip.IsModified() == TRUE) ? 2 : 0); // REVIEW
return err;
}
int TMessageBox(int nID, DWORD dwButtons)
{
String mess;
String title;
title.LoadString(hTcpCfgInstance, IDS_UNATTEND_SETUP);
int response = -1;
mess.LoadString(hTcpCfgInstance, nID);
if (mess.GetLength())
response = ::MessageBox(::GetActiveWindow(), mess, title, dwButtons);
return response;
}
int TMessageBox(LPCTSTR lpszMess, DWORD dwButtons)
{
int response = -1;
String title;
title.LoadString(hTcpCfgInstance, IDS_UNATTEND_SETUP);
ASSERT(lpszMess);
if (_tcslen(lpszMess))
response = ::MessageBox(::GetActiveWindow(), lpszMess, title, dwButtons);
return response;
}
BOOL ValidateIPAddress(LPCTSTR lpszIPAddress)
{
// Needs 3 dots
// No Alphas
// Needs 4 Octets
if (_tcslen(lpszIPAddress) > MAX_IP_SIZE -1)
return FALSE;
TCHAR buf[MAX_IP_SIZE];
LPTSTR pToken;
_tcscpy(buf, lpszIPAddress);
pToken = _tcstok(buf , _T("."));
int octet;
int i = 0;
for (;((i < 4) && (pToken != NULL)); i++)
{
// Make sure it is a valid number
if (_tcsspn(pToken, _T("0123456789")) != _tcslen(pToken))
return FALSE;
octet = _wtoi(pToken);
// MSO must be <= 223
if (i == 0)
{
if (octet < 1 || octet > 223)
return FALSE;
}
else if(octet < 0 || octet > 255)
{
return FALSE;
}
pToken = _tcstok(NULL , _T("."));
}
if (i != 4)
return FALSE;
return TRUE;
}
// Return the number of paramters read;
// -1 == error
int GetParameters(HINF hInf, LPCTSTR lpszSection, TCPIP_PARAMTERS& params)
{
int n = 0;
int nr = 0;
DWORD lpSize;
TCHAR* pType;
ASSERT(hInf != INVALID_HANDLE_VALUE);
TCHAR buf[512];
buf[0] = NULL;
// TCPIP -- IP, SUBNET, GATEWAY, DNS Server, WINSPrimary, WINSSecondary
for (int i=0; i < NUM_OF_MEMBERS;i++)
{
if (SetupGetLineText(NULL, hInf, lpszSection, szKeys[i],
buf, _countof(params.m_data[i]), &lpSize) == TRUE)
{
_tcscpy(params.m_data[i], buf);
++nr;
}
buf[0] = NULL;
}
return nr;
}
BOOL ConfigureAdapters(LPCTSTR lpszUnAttendPath, LPCTSTR lpszSection, CTcpSheet* tcpip)
{
ASSERT(lpszUnAttendPath != NULL);
TCHAR buf[MAX_PATH];
DWORD lpSize;
TCPIP_PARAMTERS ipInfo;
if (tcpip->m_globalInfo.nNumCard < 1)
{
// This is a slient error. Report nothing to the user
return FALSE; // at least 1 adapter needs to be installed
}
HINF hInf = SetupOpenInfFile(lpszUnAttendPath, NULL, INF_STYLE_OLDNT, NULL);
if (hInf == INVALID_HANDLE_VALUE)
{
TMessageBox(IDS_UNATTEND_OPEN_FAILED, MSGBOX_STOP);
return FALSE; // something is wrong with the inf file
}
memset(&ipInfo, 0, sizeof(ipInfo));
// Get all the parameters from the default section
GetParameters(hInf, lpszSection, ipInfo);
// overlay the parameters from the computer specific section
// See if the registry contains a computer specific section
buf[0] = NULL;
if (GetUnattendSection(buf, _countof(buf)) == TRUE)
GetParameters(hInf, buf, ipInfo);
SetupCloseInfFile(hInf);
BOOL bResult = TRUE;
BOOL bDHCPEnabled = FALSE;
if (ipInfo.m_tcp.m_useDHCP[0] != NULL)
bDHCPEnabled = !_tcsicmp(ipInfo.m_tcp.m_useDHCP, _T("YES"));
// Validate the Data
for (int i=0; i < NUM_OF_MEMBERS;i++)
{
// Validate the data
if (ipInfo.m_data[i][0] == NULL && bDHCPEnabled == FALSE)
{
switch(i)
{
default:
break;
// Require these
case 0:
case 1:
String fmt, msg;
fmt.LoadString(hTcpCfgInstance, IDS_UNATTEND_MISSING_DATA);
msg.Format(fmt, szKeys[i]);
TMessageBox(msg, MSGBOX_BANG);
bResult = FALSE;
break;
}
}
else
{
switch(i)
{
// Ignore these
case 1:
case 3:
case 6:
case 7:
case 8:
break;
default:
if (ipInfo.m_data[i][0] != NULL && ValidateIPAddress(ipInfo.m_data[i]) == FALSE)
{
String fmt, msg;
fmt.LoadString(hTcpCfgInstance, IDS_UNATTEND_KEY_HAS_BAD_IP);
msg.Format(fmt, szKeys[i]);
TMessageBox(msg, MSGBOX_BANG);
bResult = FALSE;
}
break;
}
}
}
// Validate the DNS Servers
LPTSTR pToken;
TCHAR dnsAddress[NUM_SERVER_LIMIT][MAX_IP_SIZE];
dnsAddress[0][0] = NULL;
dnsAddress[1][0] = NULL;
dnsAddress[2][0] = NULL;
buf[0] = NULL;
_tcscpy(buf, ipInfo.m_tcp.m_dnsServer);
pToken = _tcstok(buf , _T(","));
for (i = 0; ((i < NUM_SERVER_LIMIT) && (pToken != NULL)); i++)
{
_tcscpy(dnsAddress[i], pToken);
pToken = _tcstok(NULL , _T(","));
}
for (i = 0; ((i < NUM_SERVER_LIMIT) && (dnsAddress[i] != NULL)); i++)
{
if (dnsAddress[i][0] != 0 && ValidateIPAddress(dnsAddress[i]) == FALSE)
{
String fmt, msg;
fmt.LoadString(hTcpCfgInstance, IDS_UNATTEND_DNS_IP_BAD);
msg.Format(fmt, dnsAddress[i]);
TMessageBox(msg, MSGBOX_BANG);
bResult = FALSE;
}
}
// replace all ',' with spaces
pToken = ipInfo.m_tcp.m_dnsServer;
while(*pToken)
{
if (*pToken == _T(','))
*pToken = _T(' ');
++pToken;
}
tcpip->m_pAdapterInfo[0].fEnableDHCP = bDHCPEnabled;
NLS_STR gateway = ipInfo.m_tcp.m_gateway;
if (bDHCPEnabled == FALSE)
{
// Got all the parameters, now stuff the 1st adapter
NLS_STR ip = ipInfo.m_tcp.m_ipAddress;
NLS_STR subnet = ipInfo.m_tcp.m_subnet;
if (IsValidIPandSubnet(ip, subnet) == FALSE)
{
TMessageBox(IDS_UNATTEND_INVALID_SUBNET, MSGBOX_STOP);
bResult = FALSE;
}
// Not using DHCP
tcpip->m_pAdapterInfo[0].fEnableDHCP = bDHCPEnabled;
ReplaceFirstAddress(tcpip->m_pAdapterInfo[0].strlstIPAddresses, ip);
ReplaceFirstAddress(tcpip->m_pAdapterInfo[0].strlstSubnetMask, subnet);
}
// Domain Name, Scope ID and servers
ReplaceFirstAddress(tcpip->m_pAdapterInfo[0].strlstDefaultGateway, gateway);
tcpip->m_pAdapterInfo[0].nlsPrimaryWINS = ipInfo.m_tcp.m_winsPrimary;
tcpip->m_pAdapterInfo[0].nlsSecondaryWINS = ipInfo.m_tcp.m_winsSecondary;
tcpip->m_globalInfo.nlsDomain = ipInfo.m_tcp.m_DNSName;
tcpip->m_globalInfo.nlsScopeID = ipInfo.m_tcp.m_scopeID;
tcpip->m_globalInfo.nlsNameServer = ipInfo.m_tcp.m_dnsServer;
SaveRegistry(&tcpip->m_globalInfo, tcpip->m_pAdapterInfo);
return bResult;
}
/*******************************************************************
NAME: ConvertHostname
SYNOPSIS: Convert the hostname from upper case to lower case.
It is used by TCP/IP setup inf file
ENTRY: DWORD nArgs
LPSTR apszArgs [] - the first parameter must be the hostname
LPSTR * ppszResult
RETURNS: return the lower case hostname.
HISTORY: terryk 1/13/1994 created
********************************************************************/
BOOL FAR PASCAL ConvertHostname(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) // Result variable storage
{
::strcpy( achBuff, apszArgs[0] );
// Hostnames are usually all lowercase. and must contain only
// valid characters.
::CharLowerBuffA( (CHAR *)achBuff, ::lstrlenA( (CHAR *)achBuff ) ) ;
for ( CHAR * pch = (CHAR*)achBuff; *pch != '\0'; pch++ )
{
if ( *pch != '-' && *pch != '.'
&& !(( *pch >= 'a' && *pch <= 'z')
|| ( *pch >= '0' && *pch <= '9') ) )
{
*pch = '-';
}
}
*ppszResult = achBuff;
return TRUE;
}
/*******************************************************************
NAME: CPlTcpip
SYNOPSIS: Exported function to invoke Tcpip Setup Dialog
ENTRY: DWORD nArgs
LPSTR apszArgs []
LPSTR * ppszResult
EXIT: return the Tcpip setup parameters
RETURNS: SETUP INF list form, starting with error code
E.g.: 0
NOTES:
HISTORY:
********************************************************************/
BOOL FAR PASCAL CPlTcpip (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) // Result variable storage
{
APIERR err = NERR_Success ;
HWND hWnd = NULL;
TCHAR **patchArgs;
INT nReturn = 0;
if ( nArgs != 8 || ((patchArgs = CvtArgs(apszArgs, nArgs)) == NULL))
{
ASSERT(FALSE);
wsprintfA( achBuff, "{\"0\"}" );
*ppszResult = achBuff;
return TRUE;
}
if (nArgs > 0 && patchArgs[0][0] != NULL_CHARACTER)
{
hWnd = (HWND) CvtHex(patchArgs[0]);
// Is the hwnd a valid hwnd
if(::IsWindow(hWnd) == FALSE)
hWnd = ::GetActiveWindow();
}
else
{
hWnd = ::GetActiveWindow() ;
}
if (( patchArgs[1] == NULL ) || ( patchArgs[1][0] == TCH('\0')))
{
wsprintfA( achBuff, "{\"%d\"}", ERROR_INVALID_PARAMETER );
*ppszResult = achBuff;
FreeArgs( patchArgs, nArgs );
// we must have binding information
return FALSE;
}
TCHAR szComputerName [UNCLEN*3] ;
szComputerName[0] = '\0';
DWORD dwCch = sizeof szComputerName;
BOOL fOk = ::GetComputerName( szComputerName, & dwCch );
if ( fOk )
{
szComputerName[dwCch] = 0;
}
// Hostnames are usually all lowercase. and must contain only
// valid characters.
::CharLowerBuff( szComputerName, ::strlenf( szComputerName ) ) ;
for ( TCHAR * pch = szComputerName; *pch != TCH('\0'); pch++ )
{
if ( *pch != TCH('-') && *pch != TCH('.')
&& !(( *pch >= TCH('a') && *pch <= TCH('z'))
|| ( *pch >= TCH('0') && *pch <= TCH('9')) ) )
{
*pch = TCH('-');
}
}
NLS_STR nlsDomainName = RGAS_SZ_NULL;
BOOL bServer = _tcsicmp(patchArgs[4], _T("WINNT"));
LPCTSTR lpszUnattendPath = NULL;
LPCTSTR lpszSection = NULL;
// Argument 5 != '0' means unattend mode
// Argument 6 == Unattend.txt path
if (_tcsicmp(patchArgs[5], _T("YES")) == 0)
{
lpszUnattendPath = patchArgs[6];
lpszSection = patchArgs[7];
}
err = RunTcpip( hWnd,
nArgs > 1 ? patchArgs[1] : NULL,
szComputerName,
nlsDomainName, bServer, lpszUnattendPath, lpszSection,
&nReturn);
wsprintfA( achBuff, "{\"%d\"}", nReturn);
*ppszResult = achBuff;
FreeArgs( patchArgs, nArgs );
return err == NERR_Success;
}
BOOL FAR PASCAL CPlSnmp(
DWORD nArgs,
LPSTR apszArgs[],
LPSTR * ppszResult )
{
APIERR err = NERR_Success;
HWND hWnd = NULL;
TCHAR **patchArgs;
if (nArgs != 4 || (patchArgs = CvtArgs( apszArgs, nArgs )) == NULL)
{
::wsprintfA(achBuff,"{\"%d\"}", ERROR_INVALID_PARAMETER);
*ppszResult = achBuff;
return FALSE;
}
// arg[0] = HWND
// arg[1] = Unattend Mode
// arg[2] = Unattend Path
// arg[3] = Default Section
//
if ((patchArgs[0][0] != NULL_CHARACTER))
{
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
}
else
{
hWnd = ::GetActiveWindow() ;
}
LPCTSTR lpszUnattendPath = NULL;
LPCTSTR lpszSection = NULL;
// Arg 1 != '0' means unattend mode
// Arg 2 == Unattend.txt path
if (_tcsicmp(patchArgs[1], _T("YES")) == 0)
{
lpszUnattendPath = patchArgs[2];
lpszSection = patchArgs[3];
}
err = RunSnmp(hWnd, lpszUnattendPath, lpszSection);
::wsprintfA(achBuff,"{\"%d\"}", err);
*ppszResult = achBuff;
::FreeArgs( patchArgs, nArgs );
return err == NERR_Success;
}
#ifdef INCLUDE_FTPD
BOOL RunFtpd (HWND hWnd);
BOOL FAR PASCAL CPlFtpd(DWORD nArgs,LPSTR apszArgs[], LPSTR *ppszResult)
{
HWND hWnd = NULL;
TCHAR **patchArgs;
if ((patchArgs = CvtArgs( apszArgs, nArgs )) == NULL)
{
::wsprintfA(achBuff,"{\"%d\"}", ERROR_INVALID_PARAMETER);
*ppszResult = achBuff;
return FALSE;
}
if ((nArgs > 0 ) && ( patchArgs[0][0] != NULL_CHARACTER))
{
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
}
else
{
hWnd = ::GetActiveWindow();
}
BOOL bResult = RunFtpd(hWnd);
::wsprintfA(achBuff,"{\"%d\"}", bResult );
*ppszResult = achBuff;
::FreeArgs(patchArgs, nArgs);
return (bResult == 0);
}
/*
Given a starting and ending MSGID, concatenate
messages from the resource fork. If midEnd == 0,
then the termination condition is failure of
NLS_STR::Load(); i.e., no such string.
*/
APIERR ConcatMsgs (
NLS_STR * pnlsBig,
MSGID midBase,
MSGID midEnd )
{
NLS_STR nlsMsg ;
APIERR err = 0 ;
INT cMsgs = 0 ;
for ( ; midEnd == 0 || midBase <= midEnd ; midBase++, cMsgs++ )
{
if ( err = nlsMsg.Load( midBase ) )
{
break ;
}
pnlsBig->Append( nlsMsg ) ;
}
// If we loaded at least one msg string, it's OK.
if ( cMsgs > 0 )
err = 0 ;
return err ? err : pnlsBig->QueryError();
}
BOOL FAR PASCAL CPlFtpdConfirmInstall(
DWORD nArgs,
LPSTR apszArgs[],
LPSTR * ppszResult )
{
APIERR err = NERR_Success;
HWND hWnd = NULL;
TCHAR **patchArgs;
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
{
::wsprintfA(achBuff,"{\"%d\"}", ERROR_INVALID_PARAMETER);
*ppszResult = achBuff;
return FALSE;
}
if (( nArgs > 0 ) && ( patchArgs[0][0] != NULL_CHARACTER ))
{
hWnd = (HWND) CvtHex( patchArgs[0] ) ;
}
else
{
hWnd = ::GetActiveWindow() ;
}
String title;
String mess;
title.LoadString(hTcpCfgInstance, FTP_TITLE);
mess.LoadString(hTcpCfgInstance, IDS_FTP_PASSWORD_WARNING);
if (MessageBox(hWnd, mess, title, MB_YESNO|MB_APPLMODAL|MB_ICONEXCLAMATION) == IDNO)
err = TRUE; // same as cancel
::wsprintfA(achBuff,"{\"%d\"}", err);
*ppszResult = achBuff;
::FreeArgs( patchArgs, nArgs );
return err == NERR_Success;
}
#endif // INCLUDE_FTPD
/*******************************************************************
NAME: getAdapterList
SYNOPSIS: Given the name of a service, return a STRLIST
consisting of the names of the adapters to which
the service is currently bound.
ENTRY: REG_KEY * prkMachine REG_KEY for
HKEY_LOCAL_MACHINE
const TCHAR * name of service
STRLIST * * location to store ptr
to created STRLIST
EXIT: STRLIST * * updated
RETURNS: APIERR if failure
NOTES:
HISTORY:
********************************************************************/
static APIERR getAdapterList (
REG_KEY * prkMachine,
const TCHAR * pszServiceName,
STRLIST ** ppslResult,
BOOL bIncludeWAN)
{
APIERR err ;
TCHAR tchKeyName [MAX_PATH] ;
NLS_STR nlsKeyName ;
*ppslResult = NULL ;
wsprintf( tchKeyName,
SZ("%s%c%s%c%s"),
RGAS_SERVICES_HOME,
TCH('\\'),
pszServiceName,
TCH('\\'),
RGAS_LINKAGE_NAME ) ;
if ( err = nlsKeyName.CopyFrom( tchKeyName ) )
return err ;
REG_KEY rkLinkage( *prkMachine, nlsKeyName ) ;
if ( err = rkLinkage.QueryError() )
return err ;
err = rkLinkage.QueryValue( RGAS_ROUTE_VALUE_NAME, ppslResult ) ;
if ( err == 0 )
{
ITER_STRLIST isl( **ppslResult ) ;
NLS_STR * pnlsNext ;
// Iterate over the strings. Locate the last double-quoted
// substring; remove all but the enclosed substring from each
// string.
pnlsNext = isl.Next();
for ( ; (err == 0) && (pnlsNext != NULL) ; )
{
int cQuote = 0, i = 0 ;
const TCHAR * pch = pnlsNext->QueryPch(),
* pch2 = NULL ;
TCHAR tchAdapterName [MAX_PATH] ;
// Iterate over the string, remembering the start of the
// last sub-string enclosed in double quotes.
for ( ; *pch ; pch++ )
{
if ( *pch == TCH('\"') )
{
if ( ++cQuote & 1 )
pch2 = pch ;
}
}
// Extact just the adapter name from the string; if not
// found, leave the string empty.
if ( pch2 )
{
for ( pch2++ ; *pch2 && *pch2 != TCH('\"') ; )
{
tchAdapterName[i++] = *pch2++ ;
if ( i >= sizeof tchAdapterName - 1 )
break ;
}
}
tchAdapterName[i] = 0 ;
// Open the adapter's parameter key and see if its a WAN adapter
{
NLS_STR nlsTcpip = RGAS_SERVICES_HOME;
nlsTcpip.AppendChar( TCH('\\'));
nlsTcpip.strcat(tchAdapterName); // "SYSTEM\CurrentControlSet\<adapter>
nlsTcpip.strcat (SZ_PARAMETERS); // "SYSTEM\CurrentControlSet\<adapter>\Parameters
REG_KEY rkLocalMachine(HKEY_LOCAL_MACHINE);
REG_KEY RegKeyNetCardParameter(rkLocalMachine, nlsTcpip);
DWORD dwAutoIPAddress = 0;
// Key exist, don't add it to the list and/or its 1
RegKeyNetCardParameter.QueryValue(RGAS_AUTOIPADDRESS, &dwAutoIPAddress);
if (dwAutoIPAddress == 0 || bIncludeWAN == TRUE)
{
TRACE(_T("adapter name[%s] extracted from %s AutoIP:0 && bIncludeWan:FALSE\n"), tchAdapterName, pnlsNext->QueryPch());
err = pnlsNext->CopyFrom( tchAdapterName );
pnlsNext = isl.Next(); // goto next item
}
else
{
TRACE(_T("Removing adapter name[%s] extracted from %s AutoIP:%d && bIncludeWan: %d\n"), tchAdapterName,
pnlsNext->QueryPch(),
dwAutoIPAddress,
bIncludeWAN);
(*ppslResult)->Remove(*pnlsNext); // Removes and goto next item
pnlsNext = isl.QueryProp();
}
}
}
}
if ( err )
{
delete *ppslResult ;
*ppslResult = NULL ;
}
return err ;
}
APIERR SilentModeCheck()
{
APIERR err = 0 ;
STRLIST * pslAdapters = NULL;
TCHAR * pszTcp = RGAS_TCPIP;
NLS_STR * pnlsNext ;
REG_KEY rkMachine(HKEY_LOCAL_MACHINE);
if (err = rkMachine.QueryError())
return TRUE;
// The last peraneter is TRUE to indicate we want the WAN adapters in the list.
// WAN adapters count in RIP
if (err = getAdapterList(&rkMachine, pszTcp, &pslAdapters, TRUE))
return TRUE;
int nCount = pslAdapters->QueryNumElem();
delete pslAdapters;
return !(nCount > 1);
}
BOOL FAR PASCAL TcpBootRelayCfgCheck(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult) // Result variable storage
{
BOOL bResult = FALSE; // No need to configure bootp
// see if it is installed
HKEY hkeyParams;
DWORD dwErr, dwSize, dwType;
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGKEY_SERVICES REG_CONNECT_STR REGKEY_RELAYPARAMS,
0, KEY_READ, &hkeyParams);
// key exist
if (dwErr == ERROR_SUCCESS)
{
do
{
// the key is exist, is there at least 1 DHCP server
dwErr = RegQueryValueEx(hkeyParams, REGVAL_DHCPSERVERS,NULL, &dwType, NULL, &dwSize);
if (dwErr != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
break; // there is an error with the install,
if (dwSize <= 2) // empty multi-sz is double null terminated
{
if (TMessageBox(IDS_BOOTP_NEED_DHCP_SERVER, MB_YESNO|MB_APPLMODAL|MB_ICONQUESTION) == IDYES)
bResult = TRUE; // no servers installed, need to configure
break;
}
} while (FALSE);
}
RegCloseKey(hkeyParams);
::wsprintfA(achBuff, "{\"%ld\"}", bResult);
*ppszResult = achBuff ;
return TRUE;
}
BOOL FAR PASCAL TcpEnableRipSilentMode(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) // Result variable storage
{
::wsprintfA(achBuff, "{\"%ld\"}", SilentModeCheck());
*ppszResult = achBuff ;
return TRUE;
}
/*******************************************************************
NAME: RunTcpipAlteredCheck
SYNOPSIS: See if TCP/IP's "bindings review" phase should
bring up the configuration dialog. In other
words, has anything substantive changed?
ENTRY: if TRUE we are testing if any adapters have DHCP enabled
EXIT: Nothing.
RETURNS: APIERR: 0 (NO_ERROR) implies no reconfiguration
required; any other value causes IP Address
configuration dialog to appear.
NOTES: The criteria are as follows:
1) All adapters bound to TCP/IP must have
IP addresses.
X 2) NetBT must be bound at least one
adapter.
X 3) The adapter over which NetBT is running
is still in use by TCP/IP.
X 4) NetBT/parameters/permanentname must exist
HISTORY:
********************************************************************/
APIERR RunTcpipAlteredCheck (BOOL bDHCPTest)
{
APIERR err = 0 ;
STRLIST * pslAdapters = NULL,
* pslNbtAdapters = NULL ;
TCHAR * pszTcp = RGAS_TCPIP ;
NLS_STR * pnlsNext ;
NLS_STR nlsIpAddr ;
NLS_STR nlsKeyName ;
TCHAR tchBuffer [ MAX_PATH ] ;
REG_KEY rkMachine( HKEY_LOCAL_MACHINE ) ;
NLS_STR nlsDHCPServer = RGAS_DHCP_SERVER;
REG_KEY RegKeyDHCPServer(rkMachine, nlsDHCPServer);
BOOL dhcpServer = (RegKeyDHCPServer.QueryError() == NERR_Success);
do
{
if ( err = rkMachine.QueryError() )
return err ;
TRACE(_T("Calling getAdapterList\n"));
// Get a STRLIST of adapter names.
if ( err = getAdapterList(&rkMachine, pszTcp, &pslAdapters, FALSE))
break ;
// Iterate over the adapter list checking that each has an IP address.
ITER_STRLIST isl( *pslAdapters ) ;
for ( ; (err == 0) && (pnlsNext = isl.Next()) ; )
{
TRACE(_T("Checking for IP address for adapter named %s\n"), pnlsNext->QueryPch());
wsprintf( tchBuffer,
SZ("%s%c%s%s"),
RGAS_SERVICES_HOME,
BACK_SLASH,
pnlsNext->QueryPch(),
RGAS_PARAMETERS_TCPIP );
// Criterion 1: if any bound adapter lacks an IP address,
// configuration dialog is mandatory.
if ( err = nlsKeyName.CopyFrom( tchBuffer ) )
break ;
REG_KEY rkAdapter( rkMachine, nlsKeyName, KEY_READ ) ;
if ( (err = rkAdapter.QueryError()) == 0 )
{
STRLIST *pslstIPAddress = NULL;
STRLIST *pslstSubnetMask = NULL;
// Read the DHCP flag
DWORD t_dhcpEnabled=0;
if (err = rkAdapter.QueryValue(RGAS_ENABLE_DHCP, &t_dhcpEnabled))
{
break;
}
if (bDHCPTest == FALSE)
{
if (((err = rkAdapter.QueryValue( RGAS_IPADDRESS, &pslstIPAddress )) == NERR_Success ) &&
((err = rkAdapter.QueryValue( RGAS_SUBNETMASK, &pslstSubnetMask )) == NERR_Success ))
{
if (( pslstIPAddress->QueryNumElem() < 1 ) ||
( pslstSubnetMask->QueryNumElem() < 1 ))
{
err = ERROR_INVALID_PARAMETER;
}
ITER_STRLIST ipl(*pslstIPAddress);
for (int i ; (err == 0) && (pnlsNext = ipl.Next());)
{
TRACE(_T("Adapter %s has DHCP:%d DHCPServer:%d, \n"), pnlsNext->QueryPch(), t_dhcpEnabled, dhcpServer);
// Don't validate if DHCP enabled and the DHCP server is not installed
if ((!t_dhcpEnabled || dhcpServer) &&
ValidateIPAddress(*pnlsNext) == FALSE)
{
TRACE(_T("Adapter %s has has an error\n"), pnlsNext->QueryPch());
err = ERROR_INVALID_PARAMETER;
}
}
}
}
else
{
// if any adapter has DHCP enabled return an ERROR
if (t_dhcpEnabled != 0) // enabled and more than 1 adapter.
{
if (pslAdapters->QueryNumElem())
{
String mess;
mess.LoadString(hTcpCfgInstance, IDS_DHCP_REQUIRED_ON_ALL);
String title;
title.LoadString(hTcpCfgInstance, IDS_TCPIP_TITLE);
// REVEIW rember to change
MessageBox(GetDesktopWindow(), mess, title, MB_ICONEXCLAMATION|MB_APPLMODAL|MB_OK);
err = ERROR_INVALID_PARAMETER;
}
}
}
delete pslstIPAddress;
delete pslstSubnetMask;
}
}
if (err)
break ;
}
while (FALSE);
delete pslAdapters ;
delete pslNbtAdapters ;
return err ;
}
BOOL FAR PASCAL TcpCfgCheck (
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) // Result variable storage
{
APIERR err = 0 ;
err = RunTcpipAlteredCheck(FALSE);
::wsprintfA( achBuff, "{\"%ld\"", err ) ;
::strcat( achBuff, "}" );
*ppszResult = achBuff ;
return err == 0 ;
}
BOOL FAR PASCAL TcpCheckAdaptersForDHCP(
DWORD nArgs, // Number of string arguments
LPSTR apszArgs[], // The arguments, NULL-terminated
LPSTR * ppszResult ) // Result variable storage
{
APIERR err = 0 ;
err = RunTcpipAlteredCheck(TRUE);
::wsprintfA( achBuff, "{\"%ld\"", err ) ;
::strcat( achBuff, "}" );
*ppszResult = achBuff ;
return err == 0 ;
}
VOID AddRemoveDHCP( STRLIST *pslt, BOOL fEnableDHCP )
{
ITER_STRLIST iter( *pslt );
NLS_STR *pnlsTmp = NULL;
ALIAS_STR nlsDHCP = RGAS_DHCP;
BOOL fFindIt = FALSE;
for ( ; (pnlsTmp = iter.Next()) != NULL; )
{
if ( pnlsTmp->_stricmp( nlsDHCP ) == 0 )
{
// find it
fFindIt = TRUE;
if ( !fEnableDHCP )
{
// remove the dhcp dependencies
pslt->Remove( iter );
delete pnlsTmp;
}
break;
}
}
if (( pnlsTmp == NULL ) && ( fEnableDHCP ) && (!fFindIt))
{
// added dhcp into the dependencies list
NLS_STR *pnlsNew = new NLS_STR(RGAS_DHCP);
pslt->Append( pnlsNew );
}
}
/*******************************************************************
NAME: DelFiles
SYNOPSIS: Delete all the specified files in the directory
ENTRY: apszArgs[0] - wild card name with path. ie: a:\i386\*.*
apszArgs[1] - just the path. ie: a:\i386
HISTORY:
terryk 20-Jul-1994 Created
********************************************************************/
BOOL FAR PASCAL DelFiles(
DWORD nArgs,
LPSTR apszArgs[],
LPSTR * ppszResult )
{
APIERR err = NERR_Success;
HWND hWnd = NULL;
TCHAR **patchArgs;
// convert parameters to unicode
if (( patchArgs = CvtArgs( apszArgs, nArgs )) == NULL )
{
::wsprintfA(achBuff,"{\"%d\"}", ERROR_INVALID_PARAMETER);
*ppszResult = achBuff;
return FALSE;
}
// get all the related file names
WIN32_FIND_DATA ffd;
HANDLE hFind = ::FindFirstFileW( patchArgs[0], &ffd);
if ( hFind != INVALID_HANDLE_VALUE )
{
do
{
// delete them
TCHAR Path[MAX_PATH];
wsprintf( Path, SZ("%s\\%s"), patchArgs[1], ffd.cFileName );
::DeleteFileW( Path );
} while ( ::FindNextFileW( hFind, &ffd));
FindClose(hFind);
}
wsprintfA( achBuff, "{\"0\"}" );
*ppszResult = achBuff;
::FreeArgs( patchArgs, nArgs );
return err == NERR_Success;
}
static const WCHAR pszActiveComputerNameKey[] = L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
static const WCHAR pszPendingComputerNameKey[] = L"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName";
static const WCHAR pszComputerNameValue[] = L"ComputerName";
LONG QueryPendingComputerName( PWSTR pszComputerName, DWORD& cchComputerName )
{
HKEY hkeyPending;
DWORD cbSize;
DWORD dwType;
LONG lrt;
lrt = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
pszPendingComputerNameKey,
0,
KEY_ALL_ACCESS,
&hkeyPending );
if (ERROR_SUCCESS == lrt)
{
// read computer name
cbSize = sizeof( WCHAR ) * cchComputerName;
lrt = RegQueryValueEx( hkeyPending,
pszComputerNameValue,
NULL,
&dwType,
(LPBYTE)pszComputerName,
&cbSize );
cchComputerName = cbSize / sizeof( WCHAR );
}
return( lrt );
}
//----------------------------------------------------------------------------
//
//
//----------------------------------------------------------------------------
APIERR DNSValidateHostName( PWSTR pszComputerName, PWSTR pszHostName, PDWORD pcchHostName )
{
APIERR err = ERROR_INVALID_PARAMETER;
DWORD nLen;
do
{
// validate all the params
if ((NULL == pszComputerName) ||
(NULL == pszHostName) ||
(NULL == pcchHostName))
{
break;
}
// hostname cannot be zero
nLen = lstrlen( pszComputerName );
if ((nLen == 0) || (nLen > HOST_LIMIT))
{
break;
}
// hostname buffer has to be the same size or larger as the computer name
if (nLen >= *pcchHostName)
{
err = ERROR_MORE_DATA;
break;
}
WCHAR ch;
BOOL fAlNum;
DWORD i;
err = ERROR_SUCCESS;
for (i = 0; i < nLen; i++)
{
ch = pszComputerName[i];
fAlNum = iswalpha(ch) || iswdigit(ch);
if ( (i == 0 && !fAlNum) ||
// first letter must be a digit or a letter
(i == (nLen - 1) && !fAlNum) ||
// last letter must be a letter or a digit
(!fAlNum && ch != L'-' && ch != L'_') )
// must be letter, digit, '-', '_'
{
err = ERROR_INVALID_COMPUTERNAME;
pszHostName[i] = L'-';
}
else
{
pszHostName[i] = pszComputerName[i];
}
}
pszHostName[i] = L'\0';
// change the name to a lower case version
CharLower( pszHostName );
*pcchHostName = nLen;
} while (FALSE);
return( err );
}
//----------------------------------------------------------------------------
//
//
//----------------------------------------------------------------------------
APIERR DNSChangeHostName( PWSTR pszHostName )
{
HKEY hkey;
LONG lrt;
lrt = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
RGAS_FULL_TCPIP_PARAMETERS,
0,
KEY_WRITE,
&hkey );
if (ERROR_SUCCESS == lrt)
{
lrt = RegSetValueEx( hkey,
RGAS_HOSTNAME,
0,
REG_SZ,
(PBYTE)pszHostName,
(lstrlen( pszHostName ) + 1) * sizeof( WCHAR ) );
RegCloseKey( hkey );
}
return( lrt );
}
// End of tcpipcpl.CXX