Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

577 lines
16 KiB

//*********************************************************************
//* Microsoft Windows **
//* Copyright (c) 1994-1999 Microsoft Corporation
//*********************************************************************
//
// CFGAPI.C - Functions for exported config API.
//
// HISTORY:
//
// 96/05/22 markdu Created (from inetcfg.dll)
// 96/05/25 markdu Use ICFG_ flags for lpNeedDrivers and lpInstallDrivers.
// 96/05/27 markdu Added lpGetLastInstallErrorText.
//
#include "pch.hpp"
UINT DetectModifyTCPIPBindings(DWORD dwCardFlags,LPCSTR pszBoundTo,BOOL fRemove,BOOL * pfBound);
//*******************************************************************
//
// FUNCTION: IcfgGetLastInstallErrorText
//
// PURPOSE: Get a text string that describes the last installation
// error that occurred. The string should be suitable
// for display in a message box with no further formatting.
//
// PARAMETERS: lpszErrorDesc - points to buffer to receive the string.
// cbErrorDesc - size of buffer.
//
// RETURNS: The length of the string returned.
//
//*******************************************************************
extern "C" DWORD IcfgGetLastInstallErrorText(LPSTR lpszErrorDesc, DWORD cbErrorDesc)
{
if (lpszErrorDesc)
{
lstrcpyn(lpszErrorDesc, gpszLastErrorText, cbErrorDesc);
return lstrlen(lpszErrorDesc);
}
else
{
return 0;
}
}
//*******************************************************************
//
// FUNCTION: IcfgNeedInetComponents
//
// PURPOSE: Detects whether the specified system components are
// installed or not.
//
// PARAMETERS: dwfOptions - a combination of ICFG_ flags that specify
// which components to detect as follows:
//
// ICFG_INSTALLTCP - is TCP/IP needed?
// ICFG_INSTALLRAS - is RAS needed?
// ICFG_INSTALLMAIL - is exchange or internet mail needed?
//
// lpfNeedComponents - TRUE if any specified component needs
// to be installed.
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
// History: 5/8/97 ChrisK Added INSTALLLAN,INSTALLDIALUP,INSTALLTCPONLY
//
//*******************************************************************
extern "C" HRESULT IcfgNeedInetComponents(DWORD dwfOptions, LPBOOL lpfNeedComponents)
{
CLIENTCONFIG ClientConfig;
DEBUGMSG("cfgapi.c::IcfgNeedInetComponents()");
ASSERT(lpfNeedComponents);
// read client configuration
ZeroMemory(&ClientConfig,sizeof(CLIENTCONFIG));
DWORD dwErrCls;
UINT err=GetConfig(&ClientConfig,&dwErrCls);
if (err != OK)
{
PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
dwErrCls,MB_ICONEXCLAMATION);
return err;
}
// check if we are allowed to install TCP/IP
if (dwfOptions & ICFG_INSTALLTCP)
{
// need TCP/IP present and bound to PPP driver
if (!ClientConfig.fPPPBoundTCP)
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
}
// check if we are allowed to install RNA
if (dwfOptions & ICFG_INSTALLRAS)
{
// need PPPMAC and RNA files if using modem
if (!ClientConfig.fRNAInstalled ||
!ClientConfig.fPPPDriver)
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
}
// need Exchange if not installed and user wants to install mail
if ((dwfOptions & ICFG_INSTALLMAIL) &&
(!ClientConfig.fMailInstalled || !ClientConfig.fInetMailInstalled))
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
//
// ChrisK 5/8/97
// check if we have a bound LAN adapter
//
if (dwfOptions & ICFG_INSTALLLAN)
{
if (!ClientConfig.fNetcard ||
!ClientConfig.fNetcardBoundTCP)
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
}
//
// ChrisK 5/8/97
// Check if we have a bound Dial up adapter
//
if (dwfOptions & ICFG_INSTALLDIALUP)
{
if (!ClientConfig.fPPPDriver ||
!ClientConfig.fPPPBoundTCP)
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
}
//
// ChrisK 5/8/97
// Check if TCP is install at all on this system
//
if (dwfOptions & ICFG_INSTALLTCPONLY)
{
if (!ClientConfig.fTcpip)
{
if (lpfNeedComponents)
{
*lpfNeedComponents = TRUE;
}
return ERROR_SUCCESS;
}
}
// no extra drivers needed
if (lpfNeedComponents)
{
*lpfNeedComponents = FALSE;
}
return ERROR_SUCCESS;
}
//*******************************************************************
//
// FUNCTION: IcfgInstallInetComponents
//
// PURPOSE: Install the specified system components.
//
// PARAMETERS: hwndParent - Parent window handle.
// dwfOptions - a combination of ICFG_ flags that controls
// the installation and configuration as follows:
//
// ICFG_INSTALLTCP - install TCP/IP (if needed)
// ICFG_INSTALLRAS - install RAS (if needed)
// ICFG_INSTALLMAIL - install exchange and internet mail
//
// lpfNeedsRestart - if non-NULL, then on return, this will be
// TRUE if windows must be restarted to complete the installation.
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
//*******************************************************************
extern "C" HRESULT IcfgInstallInetComponents(HWND hwndParent, DWORD dwfOptions,
LPBOOL lpfNeedsRestart)
{
RETERR err;
DWORD dwFiles = 0;
BOOL fInitNetMAC = FALSE;
BOOL fNeedTCPIP=FALSE;
BOOL fNeedPPPMAC=FALSE;
BOOL fNeedToRemoveTCPIP=FALSE;
BOOL fNeedReboot = FALSE;
DWORD dwErrCls;
CLIENTCONFIG ClientConfig;
DEBUGMSG("cfgapi.c::IcfgInstallInetComponents()");
// read client configuration
ZeroMemory(&ClientConfig,sizeof(CLIENTCONFIG));
err=GetConfig(&ClientConfig,&dwErrCls);
if (err != OK)
{
PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
dwErrCls,MB_ICONEXCLAMATION);
return err;
}
// see if we initially have any kind of net card
fInitNetMAC = (ClientConfig.fNetcard | ClientConfig.fPPPDriver);
// install files we need
// install mail if user wants it and not already installed
if (dwfOptions & ICFG_INSTALLMAIL)
{
// need mail files (capone)?
if (!ClientConfig.fMailInstalled)
{
DEBUGMSG("Installing Exchange files");
dwFiles |= ICIF_MAIL;
}
// need internet mail files (rt 66)?
if (!ClientConfig.fInetMailInstalled)
{
DEBUGMSG("Installing Internet Mail files");
dwFiles |= ICIF_INET_MAIL;
}
}
// check if we are allowed to install RNA
if (dwfOptions & ICFG_INSTALLRAS)
{
// install RNA if user is connecting over modem and RNA
// not already installed
if (!ClientConfig.fRNAInstalled)
{
DEBUGMSG("Installing RNA files");
dwFiles |= ICIF_RNA;
}
}
if (dwFiles)
{
{
WAITCURSOR WaitCursor; // show hourglass
// install the component files
err = InstallComponent(hwndParent,IC_INSTALLFILES,
dwFiles);
if (err == NEED_RESTART)
{
DEBUGMSG("Setting restart flag");
// set restart flag so we restart the system at end
fNeedReboot = TRUE;
// NEED_REBOOT also implies success, so set ret code to OK
err = OK;
}
// force an update of the dialog
if (hwndParent)
{
HWND hParent = GetParent(hwndParent);
UpdateWindow(hParent ? hParent : hwndParent);
}
// runonce.exe may get run at next boot, twiddle the
// registry to work around a bug where it trashes the wallpaper
PrepareForRunOnceApp();
}
if (err != OK)
{
PrepareErrorMessage(IDS_ERRInstallFiles,(UINT) err,
ERRCLS_SETUPX,MB_ICONEXCLAMATION);
return err;
}
WAITCURSOR WaitCursor; // show hourglass
// do some extra stuff if we just installed mail
if (dwFiles & ICIF_MAIL)
{
// .inf file leaves an entry in the registry to run
// MS Exchange wizard, which we don't need since we'll be
// configuring exchange ourselves. Remove the registry
// entry.
RemoveRunOnceEntry(IDS_MAIL_WIZARD_REG_VAL);
// run mlset32, Exchange setup app that it needs to have run.
// need to display error if this fails, this is fairly important.
err=RunMlsetExe(hwndParent);
if (err != ERROR_SUCCESS)
{
PrepareErrorMessage(IDS_ERRInstallFiles,(UINT) err,
ERRCLS_STANDARD,MB_ICONEXCLAMATION);
return err;
}
}
// run the group converter to put the Inbox icon on desktop,
// put Exchange, RNA et al on start menu
CHAR szExecGrpconv[SMALL_BUF_LEN],szParam[SMALL_BUF_LEN];
LoadSz(IDS_EXEC_GRPCONV,szExecGrpconv,sizeof(szExecGrpconv));
LoadSz(IDS_EXEC_GRPCONV_PARAM,szParam,sizeof(szParam));
ShellExecute(NULL,NULL,szExecGrpconv,szParam,NULL,SW_SHOW);
}
// only install PPPMAC if we are allowed to install RNA
if (dwfOptions & ICFG_INSTALLRAS)
{
// install PPPMAC if not already installed
// Note that we have to install PPPMAC *before* TCP/IP, to work
// in the case where the user has no net installed to start with.
// Otherwise when we install TCP/IP, user gets prompted by net setup
// for their net card; net setup doesn't like the idea of TCP/IP lying
// around without something to bind it to.
fNeedPPPMAC = (!ClientConfig.fPPPDriver);
if (fNeedPPPMAC)
{
DEBUGMSG("Installing PPPMAC");
// make up a computer and workgroup name if not already set, so
// user doesn't get prompted
GenerateComputerNameIfNeeded();
err = InstallPPPMAC(hwndParent);
// 96/05/20 markdu MSN BUG 8551 Check for reboot when installing PPPMAC.
//
// ChrisK 5/29/97 Olympus 4692
// Even if we just rebind PPPMAC we still need to restart the machine.
//
if (err == NEED_RESTART || err == OK)
{
// set restart flag so we restart the system at end
DEBUGMSG("Setting restart flag");
fNeedReboot = TRUE;
// NEED_REBOOT also implies success, so set ret code to OK
err = OK;
}
if (err != OK)
{
PrepareErrorMessage(IDS_ERRInstallPPPMAC,(UINT) err,
ERRCLS_SETUPX,MB_ICONEXCLAMATION);
return err;
}
// when we install PPPMAC, if there is another net card then PPPMAC
// will automatically "grow" all the protocols that were bound to the
// net card. Strip these off... (netbeui and IPX)
RETERR errTmp = RemoveProtocols(hwndParent,INSTANCE_PPPDRIVER,
PROT_NETBEUI | PROT_IPX);
ASSERT(errTmp == OK);
}
}
// check if we are allowed to install TCP/IP
if (dwfOptions & ICFG_INSTALLTCP)
{
// figure out if we need to install TCP/IP
// we should only put TCP/IP on appropriate type of card (net card
// or PPP adapter)
// user is connecting via modem, need TCP if not already present
// and bound to PPPMAC. Want to bind to PPP adapters,
//
// As of W98, PPPMAC install also binds TCP/IP to dial-up adapter. Re-read
// the config using a temporary instance of the structure to determine if
// we still need the binding.
// nickball - 03/03/99 - Olympus #49008, Memphis #88375, NT #180684.
//
CLIENTCONFIG TmpConfig;
ZeroMemory(&TmpConfig,sizeof(CLIENTCONFIG));
err=GetConfig(&TmpConfig,&dwErrCls);
if (err != OK)
{
PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
dwErrCls,MB_ICONEXCLAMATION);
return err;
}
fNeedTCPIP = !TmpConfig.fPPPBoundTCP;
if (fNeedTCPIP && ClientConfig.fNetcard &&
!ClientConfig.fNetcardBoundTCP)
{
// if we have to add TCP to PPP driver, then check if TCP is already
// on netcard. If not, then TCP is going to glom on to netcard as
// well as PPP driver when we install it, need to remove it from
// netcard later.
fNeedToRemoveTCPIP= TRUE;
}
// special case: if there were any existing instances of TCP/IP and
// we just added PPPMAC then we don't need to install TCP/IP --
// when the PPPMAC adapter got added it automatically gets an instance
// of all installed protocols (incl. TCP/IP) created for it
if (ClientConfig.fTcpip && fNeedPPPMAC)
{
fNeedTCPIP = FALSE;
}
} // if (dwfOptions & ICFG_INSTALLTCP)
// install TCP/IP if necessary
if (fNeedTCPIP)
{
DEBUGMSG("Installing TCP/IP");
// call out to device manager to install TCP/IP
err = InstallTCPIP(hwndParent);
// 96/05/20 markdu MSN BUG 8551 Check for reboot when installing TCP/IP.
if (err == NEED_RESTART)
{
// NEED_REBOOT also implies success, so set ret code to OK
// Reboot flag is set below ALWAYS. Should really be set here,
// but we don't want to suddenly stop rebooting in cases
// where we used to reboot, even if not needed.
err = OK;
}
if (err != OK)
{
PrepareErrorMessage(IDS_ERRInstallTCPIP,(UINT) err,
ERRCLS_SETUPX,MB_ICONEXCLAMATION);
return err;
}
if (fNeedToRemoveTCPIP)
{
// remove TCPIP that may have glommed onto net drivers other
// than the one we intend it for
UINT uErrTmp;
uErrTmp=RemoveProtocols(hwndParent,INSTANCE_NETDRIVER,PROT_TCPIP);
ASSERT(uErrTmp == OK);
}
DEBUGMSG("Setting restart flag");
// set restart flag so we restart the system at end
fNeedReboot = TRUE;
}
// if we just installed TCP/IP or PPPMAC, then adjust bindings
if (fNeedPPPMAC || fNeedTCPIP)
{
UINT uErrTmp;
// if file sharing (vserver) is installed, TCP/IP will bind
// to it by default. This is bad, user could be sharing
// files to Internet without knowing it. Unbind VSERVER
// from TCP/IP instances that may used to connect to Internet
// (instances of type INSTANCE_PPPDRIVER)
uErrTmp = IcfgTurnOffFileSharing(INSTANCE_PPPDRIVER, hwndParent);
ASSERT (uErrTmp == ERROR_SUCCESS);
// unbind TCP/IP from VREDIR, if bound on this card type
BOOL fBound;
uErrTmp = DetectModifyTCPIPBindings(INSTANCE_PPPDRIVER,szVREDIR,
TRUE,&fBound);
ASSERT(uErrTmp == ERROR_SUCCESS);
}
// refresh the client configuration info
err = GetConfig(&ClientConfig,&dwErrCls);
if (err != OK)
{
PrepareErrorMessage(IDS_ERRReadConfig,(UINT) err,
dwErrCls,MB_ICONEXCLAMATION);
return err;
}
// do some special handling if there were *no* netcard devices
// (net cards or PPP drivers) initially installed
if (!fInitNetMAC)
{
ASSERT(fNeedPPPMAC); // should have just installed PPPMAC
// net setup adds some extra net components "by default" when
// we add PPPMAC and there are no net card devices, go kill them
// off.
RETERR reterr = RemoveUnneededDefaultComponents(hwndParent);
ASSERT(reterr == OK);
// since there were no net card devices to begin with, we need
// to restart the system later. (the NDIS VxD is a static VxD
// which needs to run, only gets added when you install a net card.)
DEBUGMSG("Setting restart flag");
// set restart flag so we restart the system at end
fNeedReboot = TRUE;
}
// tell caller whether we need to reboot or not
if (lpfNeedsRestart)
{
*lpfNeedsRestart = fNeedReboot;
}
return ERROR_SUCCESS;
}
/*******************************************************************
NAME: GetConfig
SYNOPSIS: Retrieves client configuration
********************************************************************/
UINT GetConfig(CLIENTCONFIG * pClientConfig,DWORD * pdwErrCls)
{
ASSERT(pClientConfig);
ASSERT(pdwErrCls);
// get most the client configuration from 16-bit dll
UINT uRet = GetClientConfig(pClientConfig);
if (uRet != OK) {
// GetClientConfig returns SETUPX error codes
*pdwErrCls = ERRCLS_SETUPX;
}
return uRet;
}
//*******************************************************************
//
// FUNCTION: IcfgStartServices
//
// PURPOSE: This is a NOP designed to maintain parity with the NT
// version (icfgnt.dll).
//
// PARAMETERS: none
//
// RETURNS: HRESULT code, ERROR_SUCCESS if no errors occurred
//
//*******************************************************************
extern "C" HRESULT IcfgStartServices()
{
return ERROR_SUCCESS;
}