/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corp., 1991 **/ /**********************************************************************/ /* Install.Cxx OLDNAME - NCPDINST.CXX: Windows/NT Network Control Panel Applet; New product installation and reconfiguration dialogs. FILE HISTORY: DavidHov 2/9/92 Created */ #include "pch.hxx" // Precompiled header #pragma hdrstop static const int MAX_TEMP = 1024; // inf types static const WCHAR PSZ_NETADAPTER[] = L"NetAdapter"; static const WCHAR PSZ_NETSERVICE[] = L"NetService"; static const WCHAR PSZ_NETPROTOCOL[] = L"NetTransport"; static const WCHAR PSZ_NETWORK[] = L"Network"; static const WCHAR PSZ_NETPROVIDER[] = L"NetProvider"; static const WCHAR PSZ_NETDRIVER[] = L"NetDriver"; // services names const TCHAR * pszWkstaName = SZ("LanmanWorkstation"); // This simple structure contains all that is needed to be remembered // about the origin of the executing slave process and what to do // when it completes. enum NCPA_ACTION_CTL { NCAC_NoOp = 0x0000, // NCAC_Rebind = 0x0001, // rebind NCAC_Reboot = 0x0002, // reboot NCAC_Both = 0x0003, // reboot and rebind NCAC_Refill = 0x0004, // refill main listboxes NCAC_FillBind= 0x0005, // refill, rebind NCAC_FillBoot= 0x0006, // refill, reboot NCAC_All = 0x0007 // refill, reboot, rebind. }; NCPA_ACTION_CTL nacResultControl [ NCFG_FUNC_MAX ] [ NCFG_EC_MAX ] = { /** ACTION -->RESULT: SUCCESS CANCELLED FAILED NO EFFECT REBIND REBOOT **/ /* Remove */ { NCAC_All, NCAC_Refill, NCAC_Refill, NCAC_Refill, NCAC_FillBind, NCAC_FillBoot }, /* Configure */ { NCAC_All, NCAC_NoOp, NCAC_NoOp, NCAC_Refill, NCAC_FillBind, NCAC_FillBoot }, /* Update */ { NCAC_Both, NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_Rebind, NCAC_Reboot }, /* Bind */ { NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_Reboot }, /* Install */ { NCAC_All, NCAC_NoOp, NCAC_NoOp, NCAC_Refill, NCAC_FillBind, NCAC_FillBoot }, /* Review */ { NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_NoOp, NCAC_Reboot } }; APIERR errResultControl [ NCFG_EC_MAX ] = { NO_ERROR, // success IDS_NCPA_SETUP_CANCELLED, // cancelled IDS_NCPA_SETUP_FAILED, // failed NO_ERROR, // no_effect NO_ERROR, // rebind NO_ERROR // reboot }; /******************************************************************* NAME: NCP::RunInstaller SYNOPSIS: ENTRY: EXIT: RETURNS: NOTES: HISTORY: ********************************************************************/ BOOL NCP :: RunInstaller ( HWND hwndParent, NLS_STR nlsInfName, NLS_STR nlsInfOption, NLS_STR nlsTitle, NLS_STR nlsPath ) { SetupInterpreter siConfig; do { _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndParent )) { break; } if (!siConfig.SetNetShellModes( SIM_INSTALL )) { break; } if (_dwError = siConfig.SetNetComponent( nlsInfOption.QueryPch(), nlsInfName.QueryPch() )) { break; } // if the path is filled in, use it if (nlsPath.QueryTextLength()) { if (!siConfig.IncludeSymbol( PSZ_NETSRCPATH, nlsPath.QueryPch(), TRUE )) { break; } } if (_dwError = siConfig.Run()) { break; } _dwError = InfCompleted( siConfig.QueryReturnValue(), NCFG_INSTALL ); } while ( FALSE ) ; return ((_dwError == 0) || _fRefill); } /******************************************************************* NAME: NCP::RunInstallAndCopy SYNOPSIS: ENTRY: EXIT: RETURNS: NOTES: HISTORY: ********************************************************************/ BOOL NCP :: RunInstallAndCopy( HWND hwndParent, HWND hwndNotify, PCWSTR pchInfs, PCWSTR pchOptions, PCWSTR pchText, PCWSTR pchDetectInfo, PCWSTR pchOemPaths, PCWSTR pchSections, PCWSTR pszSrcPath , PCWSTR pchRegBases , BOOL fExpress, BOOL fUnattended, PCWSTR pszUnattendFile , SETUP_INSTALL_MODE simMode, BOOL fUpgradeWarn) { SetupInterpreter siConfig; do { _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndNotify )) { break; } if (simMode == SIM_UPDATE) { if (!siConfig.SetNetShellModes( SIM_INSTALL, SIO_INSTALL )) { break; } } else { if (!siConfig.SetNetShellModes( simMode, SIO_INSTALL )) { break; } } if (!siConfig.SetNetInf( PSZ_NETINSTALLANDCOPYSECTION )) { break; } // add the source path if (!siConfig.IncludeSymbol( PSZ_NETSRCPATH, pszSrcPath, TRUE )) { break; } // add our specific parameters if (!siConfig.IncludeSymbol( PSZ_NETOPTIONS, pchOptions )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETINFS, pchInfs )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETTEXT, pchText )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETDETECTINFOS, pchDetectInfo )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETOEMPATHS, pchOemPaths )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETSECTIONS, pchSections )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETNOTIFYHWND, (DWORD)hwndNotify, TRUE )) { break; } // express mode? if (fExpress) { if (!siConfig.IncludeSymbol( PSZ_NETINSTALLMODE, L"EXPRESS" )) { break; } } else { if (!siConfig.IncludeSymbol( PSZ_NETINSTALLMODE, L"CUSTOM" )) { break; } } // add reg bases, used only for upgrade, though if (simMode == SIM_UPDATE) { if (!siConfig.IncludeSymbol( PSZ_NETREGBASES, pchRegBases )) { break; } } // whether in upgrade mode if (simMode == SIM_UPDATE) { if (!siConfig.IncludeSymbol( PSZ_NETUPGRADEMODE, L"YES" )) { break; } } else { if (!siConfig.IncludeSymbol( PSZ_NETUPGRADEMODE, L"NO" )) { break; } } // Whether Warnings are to be displayed during // upgrade. Unattended mode will ignore this if (fUpgradeWarn) { if (!siConfig.IncludeSymbol( PSZ_NETUPGRADEWARN, L"YES" )) { break; } } else { if (!siConfig.IncludeSymbol( PSZ_NETUPGRADEWARN, L"NO" )) { break; } } // unattended mode? if (simMode == SIM_UPDATE) { if (!siConfig.IncludeSymbol( PSZ_GUIUNATTENDED, L"NO" )) { break; } if (fUnattended) { if (!siConfig.IncludeSymbol( PSZ_UNATTENDED, L"YES")) { break; } } else { if (!siConfig.IncludeSymbol( PSZ_UNATTENDED, L"NO")) { break; } } } else { if (fUnattended) { if (!siConfig.IncludeSymbol( PSZ_GUIUNATTENDED, L"YES" )) { break; } if (!siConfig.IncludeSymbol( PSZ_UNATTENDED, pszUnattendFile, TRUE )) { break; } } else { if (!siConfig.IncludeSymbol( PSZ_GUIUNATTENDED, L"NO" )) { break; } if (!siConfig.IncludeSymbol( PSZ_UNATTENDED, L"NO" )) { break; } } } if (_dwError = siConfig.Run( FALSE )) { break; } _dwError = InfCompleted( siConfig.QueryReturnValue(), NCFG_INSTALL ); if (_fRefill) { // clear the lists _bindery.Reset() ; } } while ( FALSE ) ; return ((_dwError == 0) || _fRefill); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- BOOL NCP :: RunRemove( HWND hwndParent, HWND hwndNotify, PCWSTR pchInfs, PCWSTR pchOptions, PCWSTR pchText, PCWSTR pchRegBases) { SetupInterpreter siConfig; do { _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndNotify )) { break; } if (!siConfig.SetNetShellModes( SIM_DEINSTALL, SIO_INSTALL )) { break; } if (!siConfig.SetNetInf( PSZ_NETREMOVESECTION )) { break; } // add our specific parameters if (!siConfig.IncludeSymbol( PSZ_NETOPTIONS, pchOptions )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETINFS, pchInfs )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETTEXT, pchText )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETREGBASES, pchRegBases )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETNOTIFYHWND, (DWORD)hwndNotify, TRUE )) { break; } if (_dwError = siConfig.Run( FALSE )) { break; } _dwError = InfCompleted( siConfig.QueryReturnValue(), NCFG_REMOVE ); if (_fRefill) { // clear the lists _bindery.Reset() ; } } while ( FALSE ) ; return ((_dwError == 0) || _fRefill); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- // // build an INF list of network types to request the buffer for // void BuildNetTypeInfList( PWSTR pszType, DWORD fNetType ) { BOOL fFirst = TRUE; lstrcpy( pszType, PSZ_BEGINBRACE ); if (fNetType & QIFT_ADAPTERS) { //addParameter( &nlsInfParam, PSZ_NETTYPE, PSZ_NETADAPTER ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_NETADAPTER ); lstrcat( pszType, L"\"" ); fFirst = FALSE; } if (fNetType & QIFT_SERVICES) { if (!fFirst) { lstrcat( pszType, PSZ_COMMA ); } // addParameter( &nlsInfParam, PSZ_NETTYPE, PSZ_NETSERVICE ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_NETSERVICE ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_COMMA ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_NETWORK ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_COMMA ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_NETPROVIDER ); lstrcat( pszType, L"\"" ); fFirst = FALSE; } if (fNetType & QIFT_PROTOCOLS) { if (!fFirst) { lstrcat( pszType, PSZ_COMMA ); } // addParameter(&nlsInfParam, PSZ_NETTYPE, PSZ_NETPROTOCOL ); lstrcat( pszType, L"\"" ); lstrcat( pszType, PSZ_NETPROTOCOL ); lstrcat( pszType, L"\"" ); fFirst = FALSE; } lstrcat( pszType, PSZ_ENDBRACE ); } /******************************************************************* NAME: NCP::RunUpdateRegOemInfs SYNOPSIS: ENTRY: EXIT: RETURNS: NOTES: HISTORY: ********************************************************************/ /* const DWORD QIFT_ADAPTERS = 0x0001; const DWORD QIFT_PROTOCOLS = 0x0002; const DWORD QIFT_SERVICES = 0x0004; */ BOOL NCP :: RunUpdateRegOemInfs( HWND hwndParent, DWORD fNetType ) { SetupInterpreter siConfig; WCHAR pszType[MAX_PATH]; BOOL fDisableParent = TRUE; _dwError = 0; do { BuildNetTypeInfList( pszType, fNetType ); _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndParent )) { break; } if (!siConfig.SetNetInf( PSZ_NETQUERYCOMPINFSSECTION )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETTYPE, pszType )) { break; } // deinstall will skip starting detection if (!siConfig.SetNetShellModes( SIM_DEINSTALL, SIO_INSTALL )) { break; } // during main install, we don't want to disable the desktop // if (NULL == hwndParent) { fDisableParent = FALSE; } if (_dwError = siConfig.Run( fDisableParent )) { break; } _dwError = siConfig.QueryReturnValue(); } while ( FALSE ) ; return (_dwError == 0); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- BOOL NCP :: RunConfigureOnInf ( HWND hwndParent, PCWSTR pszInfName, PCWSTR pszInfOption, PCWSTR pszTitle, PCWSTR pszRegBase ) { SetupInterpreter siConfig; do { _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndParent )) { break; } if (!siConfig.SetNetShellModes( SIM_CONFIGURE, SIO_INSTALL )) { break; } if (_dwError = siConfig.SetNetComponent( pszInfOption, pszInfName, pszRegBase )) { break; } if (_dwError = siConfig.Run()) { break; } _dwError = InfCompleted( siConfig.QueryReturnValue(), NCFG_CONFIGURE ); } while ( FALSE ) ; return ((_dwError == 0) || _fRefill); } //------------------------------------------------------------------- // // // // //------------------------------------------------------------------- BOOL NCP::HaveDisk(HWND hwndParent, DWORD fNetType) { SetupInterpreter siConfig; WCHAR pszType[MAX_PATH]; _dwError = 0; do { BuildNetTypeInfList( pszType, fNetType ); _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndParent )) { break; } if (!siConfig.SetNetInf( PSZ_NETHAVEDISKSECTION )) { break; } if (!siConfig.IncludeSymbol( PSZ_NETTYPE, pszType )) { break; } if (!siConfig.SetNetShellModes( SIM_INSTALL, SIO_INSTALL )) { break; } if (_dwError = siConfig.Run()) { break; } _dwError = siConfig.QueryReturnValue(); } while ( FALSE ) ; return (_dwError == 0); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- static const WCHAR PSZ_INFSETUPKEY[] = L"SOFTWARE\\Microsoft\\Ncpa\\InfOptions"; static const WCHAR PSZ_INFOPTIONVALUE[] = L"OptionList"; static const WCHAR PSZ_INFOPTIONTEXTVALUE[] = L"OptionTextList"; static int RegQueryList( HKEY hkey, PCWSTR pszValue, PWSTR* ppszBuff ) { //DWORD dwType = REG_MULTI_SZ; DWORD cbBuff = 0; PWCHAR pchBuff = NULL; LONG lrt; // get size of list lrt = RegQueryValueEx( hkey, pszValue, NULL, NULL, NULL, &cbBuff ); if (ERROR_SUCCESS == lrt) { // new a temp buffer for it pchBuff = new WCHAR[cbBuff / sizeof(WCHAR)]; // get the list lrt = RegQueryValueEx( hkey, pszValue, NULL, NULL, (PBYTE)pchBuff, &cbBuff ); if (ERROR_SUCCESS != lrt) { delete [] pchBuff; pchBuff = NULL; } } *ppszBuff = pchBuff; return( cbBuff / sizeof(WCHAR) ); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- static INT CountEntries( PWSTR pszList ) { PWCHAR pch = pszList; INT cstr = 0; while (L'\0' != *pch) { while (L'\0' != *pch) { pch++; } pch++; cstr++; } return( cstr ); } //------------------------------------------------------------------- // // //------------------------------------------------------------------- static int AppendOptionsToBuff( PWSTR* ppszBuff, int cchBuff, PWSTR pszName, PWSTR pszType, HKEY hkeyInf ) { HKEY hkey; PWCHAR pszOptionList; PWCHAR pszOptionTextList; int cchNew; int cchNewBuff; int cstrBuffs; int i; PWCHAR pszNewBuff; if (ERROR_SUCCESS == RegOpenKeyEx( hkeyInf, pszType, 0, KEY_READ, &hkey )) { // retrieve option and option text lists from registry // cchNew = RegQueryList( hkey, PSZ_INFOPTIONVALUE, &pszOptionList ); cchNew += RegQueryList( hkey, PSZ_INFOPTIONTEXTVALUE, &pszOptionTextList ); cchNew -= 2; // the sizes returned include double null at end, remove // the number of entries we need to duplicate the inf file name cstrBuffs = CountEntries( pszOptionList ); cchNew += cstrBuffs * (lstrlen(pszName) + 1); assert( cstrBuffs == CountEntries( pszOptionTextList ) ); // calc new buff size if (cchBuff == 0) { cchNewBuff = cchNew + 1; } else { cchNewBuff = cchBuff + cchNew; } pszNewBuff = new WCHAR[cchNewBuff]; PWCHAR pchDest = pszNewBuff; // duplicate old buffer // if (*ppszBuff != NULL ) { PWCHAR pchSrc = *ppszBuff; // old buff size includes double null, don't copy it cchBuff--; // copy old buffer for (i=0; iLock()) { break; } _pscm->Unlock(); } break ; case NCFG_BIND: simMode = SIM_BIND ; break; /* case NCFG_INSTALL: simMode = SIM_INSTALL; break; */ default: UIASSERT( !"Invalid mode passed to NCP::RunConfigurator()" ) ; _dwError = ERROR_INVALID_PARAMETER ; break ; } do { if (_dwError) { break; } _dwError = ERROR_NOT_ENOUGH_MEMORY ; if (!siConfig.Initialize( hwndParent )) { break; } if (!siConfig.SetNetShellModes( simMode )) { break; } if (_dwError = siConfig.SetNetComponent( *prnComponent )) { break; } if ( simMode == SIM_DEINSTALL ) { // Product removal: drain the listboxes, discard old binding data. // This closes all open REG_KEYs, so that product and service // deletion will work. // Drain() ; _bindery.Reset() ; _fRefill = TRUE; } if (_dwError = siConfig.Run()) { break; } _dwError = InfCompleted( siConfig.QueryReturnValue(), ecfgFunc ); } while ( FALSE ) ; return _dwError == 0 ; } //------------------------------------------------------------------- // // // // //------------------------------------------------------------------- DWORD NCP :: InfCompleted( DWORD dwExit, NCPA_CFG_FUNC ecfgFunc ) { NCPA_CFG_EXIT_CODE errExit = (NCPA_CFG_EXIT_CODE)dwExit; if ( errExit >= NCFG_EC_MAX ) { // Invalid result: force it to "success" errExit = NCFG_EC_SUCCESS ; } // Get the action control mask from the table NCPA_ACTION_CTL nac = nacResultControl[ ecfgFunc ] [ errExit ] ; // Set for rebooting if necessary. This allows any review INF to // indicate that a reboot is necessary and "OR" it into the result // so far. if ( nac & NCAC_Reboot ) { MustReboot() ; } if ( nac & NCAC_Rebind ) { _bindery.SetBindState( BND_OUT_OF_DATE_NO_REBOOT ) ; } _fRefill = (nac & NCAC_Refill) > 0 ; return( errResultControl[ errExit ] ); } // End of NCPDINST.CXX