567 lines
16 KiB
C++
567 lines
16 KiB
C++
//*********************************************************************
|
|
//* Microsoft Windows **
|
|
//* Copyright(c) Microsoft Corp., 1994 **
|
|
//*********************************************************************
|
|
|
|
//
|
|
// 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 WINAPI 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 WINAPI 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)
|
|
{
|
|
LoadSz(IDS_ERRReadConfig, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
//
|
|
// vyung - PPPBound TCP is not able to be installed through
|
|
// ICW. So here we only check the TCPIP flag.
|
|
if (!ClientConfig.fTcpip)
|
|
{
|
|
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 WINAPI 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)
|
|
{
|
|
LoadSz(IDS_ERRReadConfig, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
{
|
|
LoadSz(IDS_ERRInstallFiles, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
{
|
|
LoadSz(IDS_ERRInstallFiles, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
{
|
|
LoadSz(IDS_ERRInstallPPPMAC, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
{
|
|
CLIENTCONFIG newClientConfig;
|
|
|
|
// read the client configuration again, since installing PPP might have
|
|
// installed TCP/IP
|
|
ZeroMemory(&newClientConfig,sizeof(CLIENTCONFIG));
|
|
DWORD dwErrCls;
|
|
UINT err=GetConfig(&newClientConfig,&dwErrCls);
|
|
if (err != OK)
|
|
{
|
|
LoadSz(IDS_ERRReadConfig, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
return err;
|
|
}
|
|
|
|
// figure out if we need to install TCP/IP
|
|
// BUGBUG - 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,
|
|
fNeedTCPIP = !newClientConfig.fPPPBoundTCP;
|
|
if (fNeedTCPIP && newClientConfig.fNetcard &&
|
|
!newClientConfig.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 (newClientConfig.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)
|
|
{
|
|
LoadSz(IDS_ERRInstallTCPIP, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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)
|
|
{
|
|
LoadSz(IDS_ERRReadConfig, gpszLastErrorText, MAX_ERROR_TEXT);
|
|
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;
|
|
}
|
|
|