|
|
// ----------------------------------------------------------------------
//
// Microsoft Windows NT
// Copyright (C) Microsoft Corporation, 1997.
//
// File: N E T R E G . C P P
//
// Contents: Windows NT4.0 & 3.51 Network Registry Info Dumper
//
// Notes:
//
// Author: kumarp 22-December-97
//
// ----------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include <ntsecapi.h>
#include "afilestr.h"
#include "conflict.h"
#include "infmap.h"
#include "kkcwinf.h"
#include "kkenet.h"
#include "kkreg.h"
#include "kkstl.h"
#include "kkutils.h"
#include "ncipaddr.h"
#include "ncmisc.h"
#include "ncreg.h"
#include "ncsetup.h"
#include "netreg.h"
#include "netupgrd.h"
#include "nustrs.h"
#include "nuutils.h"
#include "oemupg.h"
#include "resource.h"
#include "ipafval.h"
#include "winsock2.h"
#include "ws2spi.h"
#include "dhcpupg.h"
// for WLBS stuff
#include "wlbsparm.h"
// ----------------------------------------------------------------------
// external string constants
extern const WCHAR c_szAfWins[]; extern const WCHAR c_szAfForceStrongEncryption[]; extern const WCHAR c_szDrives[]; extern const WCHAR c_szInfId_MS_AppleTalk[]; extern const WCHAR c_szInfId_MS_Isotpsys[]; extern const WCHAR c_szInfId_MS_MSClient[]; extern const WCHAR c_szInfId_MS_NWIPX[]; extern const WCHAR c_szInfId_MS_NWNB[]; extern const WCHAR c_szInfId_MS_NWSPX[]; extern const WCHAR c_szInfId_MS_NetBIOS[]; extern const WCHAR c_szInfId_MS_NetBT[]; extern const WCHAR c_szInfId_MS_NwSapAgent[]; extern const WCHAR c_szInfId_MS_RasCli[]; extern const WCHAR c_szInfId_MS_RasSrv[]; extern const WCHAR c_szInfId_MS_Streams[]; extern const WCHAR c_szInfId_MS_TCPIP[]; extern const WCHAR c_szInfId_MS_WLBS[]; extern const WCHAR c_szNdisWan[]; extern const WCHAR c_szNo[]; extern const WCHAR c_szParameters[]; extern const WCHAR c_szRegKeyComponentClasses[]; extern const WCHAR c_szRegKeyServices[]; extern const WCHAR c_szRegValDependOnGroup[]; extern const WCHAR c_szRegValDependOnService[]; extern const WCHAR c_szRegValServiceName[]; extern const WCHAR c_szRegValStart[]; extern const WCHAR c_szShares[]; extern const WCHAR c_szSvcBrowser[]; extern const WCHAR c_szSvcDhcpRelayAgent[]; extern const WCHAR c_szSvcDhcpServer[]; extern const WCHAR c_szSvcLmServer[]; extern const WCHAR c_szSvcNWCWorkstation[]; extern const WCHAR c_szSvcNetBIOS[]; extern const WCHAR c_szSvcNetLogon[]; extern const WCHAR c_szSvcRasAuto[]; extern const WCHAR c_szSvcRipForIp[]; extern const WCHAR c_szSvcRipForIpx[]; extern const WCHAR c_szSvcRouter[]; extern const WCHAR c_szSvcSapAgent[]; extern const WCHAR c_szSvcWorkstation[]; extern const WCHAR c_szYes[];
// ----------------------------------------------------------------------
// string constants
const WCHAR c_szRAS[] = L"RAS"; const WCHAR c_szRasMan[] = L"RasMan"; const WCHAR c_szRouter[] = L"Router"; const WCHAR c_szServer[] = L"Server"; const WCHAR sz_DLC[] = L"DLC"; const WCHAR sz_MS_DLC[] = L"MS_DLC";
// WLBS:
const WCHAR c_szWLBS[] = L"WLBS"; const WCHAR c_szConvoy[] = L"Convoy"; const WCHAR c_szMSWLBS[] = L"MS_WLBS"; const WCHAR c_szMSTCPIP[] = L"MS_TCPIP"; // end WLBS:
// ----------------------------------------------------------------------
// variables
//Global
// Novell Client32 upgrades
BOOL g_fForceNovellDirCopy = FALSE;
//File scope
static TStringList *g_pslNetCard, *g_pslNetCardInstance, *g_pslNetCardAFileName; static PCWInfSection g_pwisBindings;
// WLBS:
static WCHAR pszWlbsClusterAdapterName[16], pszWlbsVirtualAdapterName[16]; // end WLBS:
// static PCWInfSection g_pwisMSNetClient;
// static PCWInfSection g_pwisNetClients;
// used by WriteRASParams
static BOOL g_fAtLeastOneDialIn=FALSE; static BOOL g_fAtLeastOneDialOut=FALSE; static BOOL g_fAtLeastOneDialInUsingNdisWan=FALSE; static BOOL g_fAtLeastOneDialOutUsingNdisWan=FALSE;
static PCWSTR g_pszServerOptimization[] = { c_szAfUnknown, c_szAfMinmemoryused, c_szAfBalance, c_szAfMaxthroughputforfilesharing, c_szAfMaxthrouputfornetworkapps };
static PCWSTR g_szNetComponentSectionName[] = { c_szAfUnknown, c_szAfSectionNetAdapters, c_szAfSectionNetProtocols, c_szAfSectionNetServices, c_szAfSectionNetClients };
// ----------------------------------------------------------------------
// Forward Declarations
BOOL WriteIdentificationInfo(IN CWInfFile *pwifAnswerFile);
BOOL WriteNetAdaptersInfo(IN CWInfFile *pwifAnswerFile);
HRESULT HrWriteNetComponentsInfo(IN CWInfFile* pwifAnswerFile);
//Protocols
BOOL WriteTCPIPParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisTCPIPGlobalParams, OUT TStringList& slAdditionalParamsSections); BOOL WriteTCPIPAdapterParams(PCWInfFile pwifAnswerFile, PCWSTR pszAdapterDriver, OUT TStringList& slAdditionalParamsSections, BOOL fDisabledToDhcpServer, BOOL fDisableNetbios);
BOOL WriteIPXParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisIPXGlobalParams, OUT TStringList& slAdditionalParamsSections);
BOOL WriteAppleTalkParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisGlobalParams, OUT TStringList& slAdditionalParamsSections);
BOOL WritePPTPParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams);
//Services
BOOL WriteRASParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisNetServices, PCWInfSection pwisRASParams); HRESULT HrWritePreSP3ComponentsToSteelHeadUpgradeParams( IN CWInfFile* pwifAnswerFile);
BOOL WriteNWCWorkstationParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteDhcpServerParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteTp4Params(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteWLBSParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteConvoyParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams);
// the following four actually write into [params.MS_NetClient] section
BOOL WriteNetBIOSParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteBrowserParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteLanmanServerParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteLanmanWorkstationParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams); BOOL WriteRPCLocatorParams(PCWInfFile pwifAnswerFile, PCWInfSection pwisParams);
//Bindings
BOOL WriteBindings(IN PCWSTR pszComponentName);
//Helper Functions
inline WORD SwapHiLoBytes(WORD w) { return ((w & 0xff) << 8) | (w >> 8); }
BOOL FIsDontExposeLowerComponent ( IN PCWSTR pszInfId) { return ((0 == lstrcmpiW(pszInfId, c_szInfId_MS_NWIPX) || (0 == lstrcmpiW(pszInfId, c_szInfId_MS_NWNB) || (0 == lstrcmpiW(pszInfId, c_szInfId_MS_NWSPX))))); }
BOOL WriteRegValueToAFile( IN PCWInfSection pwisSection, IN HKEY hKey, IN PCWSTR pszSubKey, IN PCWSTR pszValueName, IN WORD wValueType = REG_SZ, IN PCWSTR pszValueNewName = NULL, IN BOOL fDefaultProvided = FALSE, IN ...);
BOOL WriteRegValueToAFile( IN DWORD dwReserved, // added this to fix BUG 577502.
IN PCWInfSection pwisSection, IN HKEY hKey, IN PCWSTR pszSubKey, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, IN va_list arglist);
BOOL WriteRegValueToAFile( IN PCWInfSection pwisSection, IN CORegKey& rk, IN PCWSTR pszValueName, IN WORD wValueType = REG_SZ, IN PCWSTR pszValueNewName = NULL, IN BOOL fDefaultProvided = FALSE, ...);
BOOL WriteRegValueToAFile( IN DWORD dwReserved, // added this to fix bug 577502
IN PCWInfSection pwisSection, IN CORegKey& rk, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, IN va_list arglist);
BOOL WriteServiceRegValueToAFile( IN PCWInfSection pwisSection, IN PCWSTR pszServiceKey, IN PCWSTR pszValueName, IN WORD wValueType = REG_SZ, IN PCWSTR pszValueNewName = NULL, IN BOOL fDefaultProvided = FALSE, ...);
//PCWSTR GetBusTypeName(DWORD dwBusType);
PCWSTR GetBusTypeName(INTERFACE_TYPE eBusType); void AddToNetCardDB(IN PCWSTR pszAdapterName, IN PCWSTR pszProductName, IN PCWSTR pszAdapterDriver); BOOL IsNetCardProductName(IN PCWSTR pszName); BOOL IsNetCardInstance(IN PCWSTR pszName); PCWSTR MapNetCardInstanceToAFileName(IN PCWSTR pszNetCardInstance); void MapNetCardInstanceToAFileName(IN PCWSTR pszNetCardInstance, OUT tstring& strMappedName);
OUT BOOL IsNetworkComponent(IN CORegKey *prkSoftwareMicrosoft, IN const tstring strComponentName); BOOL GetServiceKey(IN PCWSTR pszServiceName, OUT PCORegKey &prkService); BOOL GetServiceParamsKey(IN PCWSTR pszServiceName, OUT PCORegKey &prkServiceParams); BOOL GetServiceSubkey(IN PCWSTR pszServiceName, IN PCWSTR pszSubKeyName, OUT PCORegKey &prkServiceSubkey); BOOL GetServiceSubkey(IN const PCORegKey prkService, IN PCWSTR pszSubKeyName, OUT PCORegKey &prkServiceSubkey); void ConvertRouteToStringList (PCWSTR pszRoute, TStringList &slRoute ); BOOL StringListsIntersect(const TStringList& sl1, const TStringList& sl2);
QWORD ConvertToQWord(TByteArray ab); VOID ConvertToByteList(TByteArray ab, tstring& str); void ReplaceCharsInString(IN OUT PWSTR szString, IN PCWSTR szFindChars, IN WCHAR chReplaceWith); HRESULT HrNetRegSaveKey(IN HKEY hkeyBase, IN PCWSTR szSubKey, IN PCWSTR szComponent, OUT tstring* pstrFileName); HRESULT HrNetRegSaveKeyAndAddToSection(IN HKEY hkeyBase, IN PCWSTR szSubKey, IN PCWSTR szComponent, IN PCWSTR szKeyName, IN CWInfSection* pwisSection); HRESULT HrNetRegSaveServiceSubKeyAndAddToSection(IN PCWSTR szServiceName, IN PCWSTR szServiceSubKeyName, IN PCWSTR szKeyName, IN CWInfSection* pwisSection);
HRESULT HrProcessOemComponentAndUpdateAfSection( IN CNetMapInfo* pnmi, IN HWND hParentWindow, IN HKEY hkeyParams, IN PCWSTR szPreNT5InfId, IN PCWSTR szPreNT5Instance, IN PCWSTR szNT5InfId, IN PCWSTR szDescription, IN CWInfSection* pwisParams);
HRESULT HrGetNumPhysicalNetAdapters(OUT UINT* puNumAdapters); HRESULT HrHandleMiscSpecialCases(IN CWInfFile* pwifAnswerFile); VOID WriteWinsockOrder(IN CWInfFile* pwifAnswerFile);
// ----------------------------------------------------------------------
static const WCHAR c_szCleanMainSection[] = L"Clean"; static const WCHAR c_szCleanAddRegSection[] = L"Clean.AddReg"; static const WCHAR c_szCleanDelRegSection[] = L"Clean.DelReg"; static const WCHAR c_szCleanServicesSection[] = L"Clean.Services"; static const WCHAR c_szAddReg[] = L"AddReg"; static const WCHAR c_szDelReg[] = L"DelReg"; static const WCHAR c_szDelService[] = L"DelService"; static const WCHAR c_szDelRegFromSoftwareKey[] = L"HKLM, \"Software\\Microsoft\\"; static const WCHAR c_szDelRegFromServicesKey[] = L"HKLM, \"SYSTEM\\CurrentControlSet\\Services\\"; static const WCHAR c_szTextModeFlags[] = L"TextModeFlags"; static const WCHAR c_szDelRegNCPA[] = L"HKLM, \"Software\\Microsoft\\NCPA\"";
//
// List of software key names that are optional components. These are either
// new names OR old names of optional components.
//
static const PCWSTR c_aszOptComp[] = { L"SNMP", L"WINS", L"SFM", L"DNS", L"SimpTcp", L"LPDSVC", L"DHCPServer", L"ILS", L"TCPUTIL", L"NETMONTOOLS", L"DSMIGRAT", L"MacPrint", L"MacSrv", L"NETCM", L"NETCMAK", L"NETCPS" };
static const WCHAR c_szBloodHound[] = L"Bh"; static const WCHAR c_szInfOption[] = L"InfOption"; static const WCHAR c_szNetMonTools[] = L"NETMONTOOLS";
static const WCHAR c_szIas[] = L"IAS"; static const WCHAR c_szIasVersion[] = L"Version";
// ----------------------------------------------------------------------
//
// Function: HrInitNetUpgrade
//
// Purpose: Initialize netupgrd data structures.
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 02-December-97
//
HRESULT HrInitNetUpgrade() { DefineFunctionName("HrInitNetUpgrade");
HRESULT hr; DWORD dwErrorMessageCode = IDS_E_SetupCannotContinue;
hr = HrInitNetMapInfo(); if (S_OK != hr) { dwErrorMessageCode = IDS_E_NetMapInfError; }
//
// Detect presence of Novell client to trigger special-case upgrade actions
//
if (S_OK == hr) { if (g_NetUpgradeInfo.From.dwBuildNumber > wWinNT4BuildNumber) { // now see if client32 is installed.
static const WCHAR c_szNovell[] = L"NetWareWorkstation";
HKEY hkeyServices, hkeyNovell;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServices, KEY_READ, &hkeyServices); if (S_OK == hr) { // CONSIDER: is it better to check to see if some service is running?
// see if Services\NetwareWorkstation key exists
if (S_OK == HrRegOpenKeyEx(hkeyServices, c_szNovell, KEY_READ, &hkeyNovell)) { RegCloseKey(hkeyNovell); g_fForceNovellDirCopy = TRUE; } RegCloseKey(hkeyServices); } else { hr = S_OK; // no NetWare.
} } }
if (S_OK == hr) { UINT cNumConflicts;
hr = HrGenerateConflictList(&cNumConflicts);
if (S_OK == hr) { if ((cNumConflicts > 0) || g_fForceNovellDirCopy) { hr = HrInitAndProcessOemDirs(); if (FAILED(hr)) { dwErrorMessageCode = IDS_E_InitAndProcessOemDirs; } } } else { dwErrorMessageCode = IDS_E_GenUpgradeConflictList; } }
if( S_OK == hr ) { //
// Handle special-cased DHCP upgrade code to convert from
// old format databases to current ESE format.
//
dwErrorMessageCode = DhcpUpgConvertDhcpDbToTemp(); hr = HRESULT_FROM_WIN32(dwErrorMessageCode); TraceError( "DhcpUpgConvertDhcpDbToTemp", hr );
if( FAILED(hr) ) { dwErrorMessageCode = IDS_E_DhcpServerUpgradeError; } } if (FAILED(hr)) { AbortUpgradeId(DwWin32ErrorFromHr(hr), dwErrorMessageCode); }
TraceError(__FUNCNAME__, hr); return hr; }
// ----------------------------------------------------------------------
//
// Function: MapNetComponentNameForBinding
//
// Purpose: Map component name to proper answerfile token so that it can
// be used in a binding path
// (e.g. IEEPRO3 --> Adapter02)
//
// Arguments:
// pszComponentName [in] constTString object name of name of
// strMappedName [out] name of name of
//
// Returns: None
//
// Author: kumarp 17-December-97
//
VOID MapNetComponentNameForBinding ( IN PCWSTR pszComponentName, OUT tstring &strMappedName) { if (IsNetCardInstance(pszComponentName)) { MapNetCardInstanceToAFileName(pszComponentName, strMappedName); } else { HRESULT hr;
hr = HrMapPreNT5NetComponentServiceNameToNT5InfId( pszComponentName, &strMappedName); if (S_OK != hr) { strMappedName = c_szAfUnknown; } } }
// ----------------------------------------------------------------------
//
// Function: FIsOptionalComponent
//
// Purpose: Determine if a component is an optional component
//
// Arguments:
// pszName [in] name of component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 02-December-97
//
BOOL FIsOptionalComponent( PCWSTR pszName) { BOOL fIsOc;
fIsOc = FIsInStringArray(c_aszOptComp, celems(c_aszOptComp), pszName); if (!fIsOc) { // BUG #148890 (danielwe) 13 Mar 1998: Special case check for NetMon
// (bloodhound). If component name is "Bh", open its NetRules key (if
// it exists) and see if it was installed as NETMONTOOLS which means
// it was the NetMon tools optional component
if (!lstrcmpiW (pszName, c_szBloodHound)) { tstring strNetRules; HKEY hkeyBh;
strNetRules = L"Software\\Microsoft\\"; strNetRules += pszName; strNetRules += L"\\CurrentVersion\\NetRules";
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strNetRules.c_str(), KEY_READ, &hkeyBh))) { tstring strOption;
if (SUCCEEDED(HrRegQueryString(hkeyBh, c_szInfOption, &strOption))) { if (!lstrcmpiW(strOption.c_str(), c_szNetMonTools)) { fIsOc = TRUE; } }
RegCloseKey(hkeyBh); } } }
return fIsOc; }
static const WCHAR c_szRegKeyOc[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OptionalComponents"; static const WCHAR c_szInstalled[] = L"Installed"; static const WCHAR c_szOcIsInstalled[] = L"1"; extern const WCHAR c_szOcMainSection[];
static const WCHAR c_szSfm[] = L"SFM"; static const WCHAR c_szMacSrv[] = L"MacSrv"; static const WCHAR c_szMacPrint[] = L"MacPrint"; static const WCHAR c_szRegKeyOcmSubComp[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents"; static const WCHAR c_szRegKeyCmak[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\CMAK.EXE"; static const WCHAR c_szRegValueCpsSrv[] = L"CPSSRV"; static const WCHAR c_szRegValueCpsAd[] = L"CPSAD"; static const WCHAR c_szNetCm[] = L"NETCM"; static const WCHAR c_szNetCmak[] = L"NETCMAK"; static const WCHAR c_szNetCps[] = L"NETCPS";
static const TCHAR c_szRegKeyIAS[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\AuthSrv\\Parameters");
//+---------------------------------------------------------------------------
//
// Function: WriteNt5OptionalComponentList
//
// Purpose: Writes the list of optional components that were installed
// prior to upgrading from an NT5 build.
//
// Arguments:
// pwifAnswerFile [in] Answer file object
//
// Returns: TRUE if success, FALSE if not.
//
// Author: danielwe 8 Jan 1998
//
// Notes:
//
BOOL WriteNt5OptionalComponentList(IN CWInfFile *pwifAnswerFile) { HRESULT hr = S_OK; PCWInfSection pwisMain;
// Add section "[OldOptionalComponents]"
pwisMain = pwifAnswerFile->AddSectionIfNotPresent(c_szOcMainSection); if (!pwisMain) { hr = E_FAIL; }
if (SUCCEEDED(hr)) { CORegKey rkOc(HKEY_LOCAL_MACHINE, c_szRegKeyOc, KEY_READ); CORegKeyIter rkOcIter(rkOc); tstring strOcName;
// loop over each subkey in the OptionalComponents tree
while (!rkOcIter.Next(&strOcName)) { if (!FIsOptionalComponent(strOcName.c_str())) { continue; }
HKEY hkeyOc; hr = HrRegOpenKeyEx(rkOc.HKey(), strOcName.c_str(), KEY_READ, &hkeyOc); if (SUCCEEDED(hr)) { ULONG fInstalled;
hr = HrRegQueryStringAsUlong(hkeyOc, c_szInstalled, 10, &fInstalled); if (SUCCEEDED(hr) || HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK;
if (fInstalled) { if (!lstrcmpiW(strOcName.c_str(), c_szSfm)) { // Special case the SFM component because
// it got split into 2
pwisMain->AddKey(c_szMacSrv, c_szOcIsInstalled); pwisMain->AddKey(c_szMacPrint, c_szOcIsInstalled); } else if (!lstrcmpiW(strOcName.c_str(), c_szNetCm)) { // Special case the NetCM component because
// it got split into NetCMAK and NetCPS
pwisMain->AddKey(c_szNetCmak, c_szOcIsInstalled); pwisMain->AddKey(c_szNetCps, c_szOcIsInstalled); } else { pwisMain->AddKey(strOcName.c_str(), c_szOcIsInstalled); } } }
RegCloseKey(hkeyOc); } } }
TraceError("WriteNt5OptionalComponentList", hr); return SUCCEEDED(hr); }
//+---------------------------------------------------------------------------
//
// Function: HandlePostConnectionsSfmOcUpgrade
//
// Purpose: Handles the upgrade of the SFM optional component which was
// split into 2 different components. This only applies to
// post connections builds (1740+).
//
// Arguments:
// pwifAnswerFile [in] Answer file object
//
// Returns: TRUE
//
// Author: danielwe 3 Feb 1998
//
// Notes: If SFM was previously installed, write out MacSrv and MacPrint
// to the answer file in its place.
//
BOOL HandlePostConnectionsSfmOcUpgrade(IN CWInfFile *pwifAnswerFile) { HKEY hkeyOc;
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyOcmSubComp, KEY_READ, &hkeyOc))) { DWORD dwSfm;
if (SUCCEEDED(HrRegQueryDword(hkeyOc, c_szSfm, &dwSfm))) { if (dwSfm == 1) { PCWInfSection pwisMain;
pwisMain = pwifAnswerFile->AddSectionIfNotPresent(c_szOcMainSection); if (pwisMain) { pwisMain->AddKey(c_szMacSrv, c_szOcIsInstalled); pwisMain->AddKey(c_szMacPrint, c_szOcIsInstalled); } } }
RegCloseKey(hkeyOc); }
return TRUE; }
//+---------------------------------------------------------------------------
//
// Function: HandleCMComponentSplitOcUpgrade
//
// Purpose: Handles the upgrade of the CM optional component which was
// split into 2 different components (NetCMAK and NetCPS).
// This was done for RC1 of .Net server.
//
// Arguments:
// pwifAnswerFile [in] Answer file object
//
// Returns: TRUE
//
// Author: quintinb 5 Apr 2001
//
// Notes: If NetCm was previously installed, write out NetCmak and NetCPS
// to the answer file in its place.
//
BOOL HandleCMComponentSplitOcUpgrade(IN CWInfFile *pwifAnswerFile) { HKEY hkeyOc;
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyOcmSubComp, KEY_READ, &hkeyOc))) { DWORD dwInstalled;
if (SUCCEEDED(HrRegQueryDword(hkeyOc, c_szNetCm, &dwInstalled))) { if (dwInstalled == 1) { PCWInfSection pwisMain;
pwisMain = pwifAnswerFile->AddSectionIfNotPresent(c_szOcMainSection); if (pwisMain) { pwisMain->AddKey(c_szNetCmak, c_szOcIsInstalled); pwisMain->AddKey(c_szNetCps, c_szOcIsInstalled); } } }
RegCloseKey(hkeyOc); }
return TRUE; }
//+---------------------------------------------------------------------------
//
// Function: HrWriteConfigManagerOptionalComponents
//
// Purpose: Special case for writing config manager components to the
// answer file.
//
// Arguments:
// pwifAnswerFile [in] Answer file object
//
// Returns: S_OK if success, otherwise an error code
//
// Author: danielwe 1 May 1998
//
// Notes:
//
HRESULT HrWriteConfigManagerOptionalComponents(CWInfFile *pwifAnswerFile) { HKEY hkeyCmak; HKEY hkeyOcm; PCWInfSection pwisMain;
pwisMain = pwifAnswerFile->FindSection(c_szOcMainSection);
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyCmak, KEY_READ, &hkeyCmak))) { // Okay, we found CMAK let's add an answer file entry to upgrade it.
//
RegCloseKey(hkeyCmak); pwisMain->AddKey(c_szNetCmak, c_szOcIsInstalled); }
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyOcmSubComp, KEY_READ, &hkeyOcm))) { DWORD dwValue;
if (SUCCEEDED(HrRegQueryDword(hkeyOcm, c_szRegValueCpsSrv, &dwValue))) { if (dwValue) { // Okay, we found CPS let's add an answer file entry to upgrade it.
//
pwisMain->AddKey(c_szNetCps, c_szOcIsInstalled); } }
RegCloseKey(hkeyOcm); }
return S_OK; // currently always returns SUCCESS
}
//+---------------------------------------------------------------------------
//
// Function: HrWriteIASOptionalComponents
//
// Purpose: Special case for writing IAS component to the
// answer file.
//
// Arguments:
// pwifAnswerFile [in] Answer file object
//
// Returns: S_OK if success, otherwise an error code
//
// Author: tperraut (T.P. comments) Feb 22 1999
//
// Notes: 03/31/2000 tperraut: do not check the content of the Version
// string anymore: all NT4 IAS should get upgraded
//
HRESULT HrWriteIASOptionalComponents(CWInfFile *pwifAnswerFile) { HRESULT hr; HKEY hkeyIAS;
PCWInfSection pwisMain = pwifAnswerFile->FindSection(c_szOcMainSection);
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyIAS, KEY_READ, &hkeyIAS))) { tstring strVersion; hr = HrRegQueryString(hkeyIAS, c_szIasVersion, &strVersion);
if (S_OK == hr) { pwisMain->AddKey(c_szIas, c_szOcIsInstalled); }
RegCloseKey(hkeyIAS); } else { hr = E_FAIL; }
TraceError("HrWriteIASOptionalComponents", hr); return hr; }
// ----------------------------------------------------------------------
//
// Function: HrWriteNt4OptionalComponentList
//
// Purpose: Writes the list of optional components that were installed
// if upgrading from NT4.
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
// slNetOcList [in] list of optional components
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 02-December-97
//
HRESULT HrWriteNt4OptionalComponentList ( IN CWInfFile *pwifAnswerFile, IN const TStringList &slNetOcList) { HRESULT hr = S_OK; PCWInfSection pwisMain;
pwisMain = pwifAnswerFile->AddSectionIfNotPresent(c_szOcMainSection); if (!pwisMain) { hr = E_FAIL; } if (SUCCEEDED(hr)) { TStringListIter iter; tstring strTemp;
for (iter = slNetOcList.begin(); iter != slNetOcList.end(); iter++) { strTemp = **iter; if (!lstrcmpiW(strTemp.c_str(), c_szSfm)) { // Special case the SFM component because it got split into 2
pwisMain->AddKey(c_szMacSrv, c_szOcIsInstalled); } else if (!lstrcmpiW(strTemp.c_str(), c_szBloodHound)) { // Special case NetMon. If tools were installed via the "Bh"
// component of NT4, write this out as NETMONTOOLS=1 in the
// answer file.
pwisMain->AddKey(c_szNetMonTools, c_szOcIsInstalled); } else { pwisMain->AddKey(strTemp.c_str(), c_szOcIsInstalled); } } // tperraut
hr = HrWriteIASOptionalComponents(pwifAnswerFile);
hr = HrWriteConfigManagerOptionalComponents(pwifAnswerFile); }
TraceError("HrWriteNt4OptionalComponentList", hr); return hr; }
// ----------------------------------------------------------------------
//
// Function: HrWriteMainCleanSection
//
// Purpose: Write [Clean] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 02-December-97
//
// Notes: The [Clean] section holds data that controls what is deleted
// at the start of GUI mode setup
//
HRESULT HrWriteMainCleanSection ( IN CWInfFile *pwifAnswerFile) { HRESULT hr = S_OK; PCWInfSection pwisMain;
// Add section "[Clean]"
pwisMain = pwifAnswerFile->AddSection(c_szCleanMainSection); if (!pwisMain) { hr = E_FAIL; }
if (SUCCEEDED(hr)) { pwisMain->AddKey(c_szDelReg, c_szCleanDelRegSection); }
TraceError("HrWriteMainCleanSection", hr); return hr; }
// ----------------------------------------------------------------------
//
// Function: HrGetListOfServicesNotToBeDeleted
//
// Purpose: Generate list of services that should not be deleted
// during upgrade.
//
// Arguments:
// pmszServices [out] pointer to multisz list of services
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 02-December-97
//
// Notes: This info is read from netupg.inf file
//
HRESULT HrGetListOfServicesNotToBeDeleted ( OUT PWSTR* pmszServices) { AssertValidWritePtr(pmszServices);
HRESULT hr; HINF hinf;
*pmszServices = NULL;
hr = HrOpenNetUpgInfFile(&hinf); if (S_OK == hr) { INFCONTEXT ic;
hr = HrSetupFindFirstLine( hinf, L"UpgradeData", L"ServicesNotToBeDeletedDuringUpgrade", &ic);
if (S_OK == hr) { hr = HrSetupGetMultiSzFieldWithAlloc(ic, 1, pmszServices); }
SetupCloseInfFile(hinf); }
return hr; }
// ----------------------------------------------------------------------
//
// Function: GetNetworkServicesList
//
// Purpose: Generate list of net services
//
// Arguments:
// slNetServices [out] list of net services
// slNetOptionalComponents [out] list of optional components found
//
// Returns: None
//
// Author: kumarp 02-December-97
//
void GetNetworkServicesList ( OUT TStringList& slNetServices, OUT TStringList& slNetOptionalComponents) { DefineFunctionName("GetNetworkServicesList");
HRESULT hr=S_OK;
tstring strNetComponentName; tstring strServiceName;
Assert (g_NetUpgradeInfo.From.dwBuildNumber); if (g_NetUpgradeInfo.From.dwBuildNumber <= wWinNT4BuildNumber) { // found Pre-NT5 networking, collect list by enumerating over
// the registry
CORegKey rkSoftwareMicrosoft(HKEY_LOCAL_MACHINE, c_szRegKeySoftwareMicrosoft, KEY_READ); if (!rkSoftwareMicrosoft.HKey()) { TraceTag(ttidError, "%s: Error reading HKLM\\%S", __FUNCNAME__, c_szRegKeySoftwareMicrosoft); hr = E_FAIL; goto return_from_function; }
CORegKeyIter* prkiNetComponents = new CORegKeyIter(rkSoftwareMicrosoft);
if(prkiNetComponents) { // mbend - this is not great, but it should get Prefix to shutup
while (!prkiNetComponents->Next(&strNetComponentName)) { if (FIsOptionalComponent(strNetComponentName.c_str())) { AddAtEndOfStringList(slNetOptionalComponents, strNetComponentName); }
// any software that has a NetRules key under the CurrentVersion
// key is a network component
if (!IsNetworkComponent(&rkSoftwareMicrosoft, strNetComponentName)) { continue; }
CORegKey rkNetComponent(rkSoftwareMicrosoft, (strNetComponentName + L"\\CurrentVersion").c_str()); if (!((HKEY) rkNetComponent)) { continue; }
strServiceName.erase(); rkNetComponent.QueryValue(c_szRegValServiceName, strServiceName);
if (!strServiceName.empty()) { AddAtEndOfStringList(slNetServices, strServiceName); } } } hr = S_OK; }
// with the above algorithm we do not catch all networking components
// because there are certain networking servies such as NetBIOSInformation
// that have entry under service but not under software\microsoft
// for such components, we use the following rule
// if a serice under CurrentControlSet\Sevices has a Linkage sub key
// then it is considered as a networking service
//
HKEY hkeyServices; hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServices, KEY_READ, &hkeyServices); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize; DWORD dwRegIndex; HKEY hkeyService; HKEY hkeyLinkage; BOOL fHasLinkageKey;
for (dwRegIndex = 0, dwSize = celems(szBuf); S_OK == HrRegEnumKeyEx(hkeyServices, dwRegIndex, szBuf, &dwSize, NULL, NULL, &time); dwRegIndex++, dwSize = celems(szBuf)) { Assert(*szBuf);
hr = HrRegOpenKeyEx(hkeyServices, szBuf, KEY_READ, &hkeyService); if (hr == S_OK) { //
// 399641: instead of using Linkage, we use Linkage\Disabled.
//
hr = HrRegOpenKeyEx(hkeyService, c_szLinkageDisabled, KEY_READ, &hkeyLinkage); fHasLinkageKey = (S_OK == hr); RegSafeCloseKey(hkeyLinkage);
if (fHasLinkageKey && !FIsInStringList(slNetServices, szBuf)) { slNetServices.push_back(new tstring(szBuf)); }
RegCloseKey (hkeyService); } }
RegCloseKey(hkeyServices); }
return_from_function: TraceError(__FUNCNAME__, hr); }
// REVIEW$ (shaunco)
// This is a list of drivers/services that were disabled (via TextModeFlags)
// but not deleted. Thus, the purpose was just to prevent these from
// starting during GUI mode. That is now handled automatically by the
// service controller, so the only things from this list which we might have
// an issue with are those that are system-start.
//
static const PCWSTR c_aszServicesToDisable[] = { L"Afd", L"CiFilter", L"ClipSrv", L"DHCP", L"DigiFEP5", L"IpFilterDriver" L"LicenseService", L"NdisTapi", L"NetDDE", L"NetDDEdsdm", L"Pcimac", L"RasAcd", L"RasArp", L"Telnet", L"ftpsvc", L"gophersvc", L"msftpsvc", L"ntcx", L"ntepc", L"ntxall", L"ntxem", L"raspptpf", L"w3svc", L"wuser32", };
HRESULT HrPrepareServiceForUpgrade ( IN PCWSTR pszServiceName, IN PCWSTR pmszServicesNotToBeDeleted, IN CWInfSection* pwisDelReg, IN CWInfSection* pwisDelService, IN CWInfSection* pwisStartTypes) { Assert (pszServiceName); Assert (pmszServicesNotToBeDeleted); Assert (pwisDelReg); Assert (pwisDelService); Assert (pwisStartTypes);
HRESULT hr; HKEY hkey; DWORD dwValue; WCHAR szBuf [_MAX_PATH]; BOOL fDelete;
fDelete = !FIsSzInMultiSzSafe (pszServiceName, pmszServicesNotToBeDeleted) && FCanDeleteOemService (pszServiceName);
if (fDelete) { // Remove from the software hive if present.
//
wcscpy (szBuf, c_szDelRegFromSoftwareKey); wcscat (szBuf, pszServiceName); wcscat (szBuf, L"\""); pwisDelReg->AddRawLine (szBuf); }
hr = HrRegOpenServiceKey (pszServiceName, KEY_READ_WRITE, &hkey); if (S_OK == hr) { // Save the start type so that we can restore it after we reinstall
// the service for Windows 2000.
//
hr = HrRegQueryDword (hkey, c_szRegValStart, &dwValue); if (S_OK == hr) { pwisStartTypes->AddKey (pszServiceName, dwValue); }
if (fDelete) { hr = HrRegQueryDword (hkey, c_szType, &dwValue); if (S_OK == hr) { if (dwValue & SERVICE_ADAPTER) { // Pseudo service on NT4. We have to delete this with
// a DelReg, not a DelService.
//
wcscpy (szBuf, c_szDelRegFromServicesKey); wcscat (szBuf, pszServiceName); wcscat (szBuf, L"\""); pwisDelReg->AddRawLine (szBuf); } else { pwisDelService->AddKey(c_szDelService, pszServiceName); }
// Since we will be deleting it during GUI mode, we need to
// ensure that it gets set to disabled during text mode so
// that (in the event it is a SYSTEM_START driver) it does
// not get started during GUI mode before we can delete it.
//
(VOID) HrRegSetDword (hkey, c_szTextModeFlags, 0x4); } }
RegCloseKey (hkey); } else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { // Not a service. We'll remove from the software key.
//
hr = S_OK; }
TraceHr (ttidError, FAL, hr, FALSE, "HrPrepareServiceForUpgrade"); return hr; }
// ----------------------------------------------------------------------
//
// Function: WriteDisableServicesList
//
// Purpose: Determine which services need to be disabled during ugprade and
// write proper info to the answerfile to make that happen.
// The set of such services consists of
// - network component services AND
// - services that depend of atleast one net-service
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteDisableServicesList ( IN CWInfFile *pwifAnswerFile) { HRESULT hr = S_OK; TStringList slNetServices; TStringList slNetOcList; TStringListIter iter; tstring* pstrServiceName; CWInfSection* pwisDelReg; CWInfSection* pwisDelService; CWInfSection* pwisStartTypes; PWSTR pmszServicesNotToBeDeleted;
// We should only be here if we are upgrading from from NT4 or earlier.
//
Assert (g_NetUpgradeInfo.From.dwBuildNumber); Assert (g_NetUpgradeInfo.From.dwBuildNumber <= wWinNT4BuildNumber)
// First, collect all network services and optional components.
//
GetNetworkServicesList(slNetServices, slNetOcList);
hr = HrWriteNt4OptionalComponentList(pwifAnswerFile, slNetOcList); if (FAILED(hr)) { goto finished; }
pwisDelReg = pwifAnswerFile->AddSectionIfNotPresent(c_szCleanDelRegSection); pwisDelService = pwifAnswerFile->AddSectionIfNotPresent(c_szCleanServicesSection); pwisStartTypes = pwifAnswerFile->AddSectionIfNotPresent(c_szAfServiceStartTypes);
if (!pwisDelReg || !pwisDelService || !pwisStartTypes) { hr = E_OUTOFMEMORY; goto finished; }
hr = HrGetListOfServicesNotToBeDeleted(&pmszServicesNotToBeDeleted);
if (S_OK == hr) { pwisDelReg->AddRawLine(c_szDelRegNCPA);
for (iter = slNetServices.begin(); iter != slNetServices.end(); iter++) { pstrServiceName = *iter; Assert (pstrServiceName);
hr = HrPrepareServiceForUpgrade ( pstrServiceName->c_str(), pmszServicesNotToBeDeleted, pwisDelReg, pwisDelService, pwisStartTypes);
if (S_OK != hr) { break; } }
MemFree (pmszServicesNotToBeDeleted); }
finished: EraseAndDeleteAll(&slNetOcList); EraseAndDeleteAll(&slNetServices);
TraceError("WriteDisableServicesList", hr); return SUCCEEDED(hr); }
extern const DECLSPEC_SELECTANY WCHAR c_szRegNetKeys[] = L"System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"; extern const DECLSPEC_SELECTANY WCHAR c_szRegKeyConFmt[] = L"System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection"; extern const DECLSPEC_SELECTANY WCHAR c_szafNICsWithIcons[] = L"NetworkAdaptersWithIcons"; static const WCHAR c_szShowIcon[] = L"ShowIcon";
// ----------------------------------------------------------------------
//
// Function: WritePerAdapterInfoForNT5
//
// Purpose: Determine which services need to be disabled during ugprade from
// Windows 2000 and write proper info to the answerfile to make that happen.
// The set of such services consists of
// - network component services
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: deonb 10-July-2000
//
BOOL WritePerAdapterInfoForNT5 ( IN CWInfFile *pwifAnswerFile) { HRESULT hr = S_OK; HKEY hkey; // Check for the existence of the connection sub-key
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegNetKeys, KEY_READ, &hkey); if (SUCCEEDED(hr)) { DWORD dwIndex(0); TCHAR szName[MAX_PATH+1]; DWORD dwSize(MAX_PATH); FILETIME ftLastWriteTime; DWORD dwRetVal(0);
do { dwRetVal = RegEnumKeyEx(hkey, dwIndex, szName, &dwSize, NULL, NULL, NULL, &ftLastWriteTime); if ( ERROR_SUCCESS == dwRetVal ) { TCHAR szRegKey[MAX_PATH+1]; swprintf(szRegKey, c_szRegKeyConFmt, szName);
HKEY hkeyConnection; hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, KEY_READ, &hkeyConnection); if (SUCCEEDED(hr)) { DWORD dwValue; HRESULT hr = HrRegQueryDword(hkeyConnection, c_szShowIcon, &dwValue); if (SUCCEEDED(hr) && dwValue) { CWInfSection* pwisStartTypes; pwisStartTypes = pwifAnswerFile->AddSectionIfNotPresent(c_szafNICsWithIcons); if (!pwisStartTypes) { hr = E_OUTOFMEMORY; } else { pwisStartTypes->AddKey (szName, 1); } } RegSafeCloseKey(hkeyConnection); } } } while ( (ERROR_SUCCESS == dwRetVal) && (SUCCEEDED(hr)) );
RegSafeCloseKey(hkey); }
TraceError("WritePerAdapterInfoForNT5", hr); return SUCCEEDED(hr); }
// ----------------------------------------------------------------------
//
// Function: WriteDisableServicesListForNT5
//
// Purpose: Determine which services need to be disabled during ugprade from
// Windows 2000 and write proper info to the answerfile to make that happen.
// The set of such services consists of
// - network component services
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: deonb 10-July-2000
//
BOOL WriteDisableServicesListForNT5 ( IN CWInfFile *pwifAnswerFile) { static PCWSTR c_aszNT5UpgrdCheckComponents[] = { L"Browser", L"LanmanServer", c_szSvcDhcpServer };
HRESULT hr = S_OK;
PCWSTR pstrServiceName; CWInfSection* pwisStartTypes; PWSTR pmszServicesNotToBeDeleted;
// We should only be here if we are upgrading from NT5 or later.
//
Assert (g_NetUpgradeInfo.From.dwBuildNumber); Assert (g_NetUpgradeInfo.From.dwBuildNumber > wWinNT4BuildNumber)
// First, collect all network services and optional components.
//
pwisStartTypes = pwifAnswerFile->AddSectionIfNotPresent(c_szAfServiceStartTypes); if (!pwisStartTypes) { hr = E_OUTOFMEMORY; goto finished; }
if (S_OK == hr) { DWORD x; for (x = 0, pstrServiceName = c_aszNT5UpgrdCheckComponents[0]; x < sizeof(c_aszNT5UpgrdCheckComponents)/sizeof(c_aszNT5UpgrdCheckComponents[0]); x++, pstrServiceName = c_aszNT5UpgrdCheckComponents[x]) { Assert (pstrServiceName);
HKEY hkey; hr = HrRegOpenServiceKey (pstrServiceName, KEY_READ, &hkey); if (S_OK == hr) { // Save the start type (only if disabled) so that we can restore it after we install
// the service for Windows 2000.
DWORD dwValue; hr = HrRegQueryDword (hkey, c_szRegValStart, &dwValue); if ( (S_OK == hr) && (SERVICE_DISABLED == dwValue) ) { pwisStartTypes->AddKey (pstrServiceName, dwValue); } RegCloseKey (hkey); } } }
finished: TraceError("WriteDisableServicesListNT5", hr); return SUCCEEDED(hr); }
// ----------------------------------------------------------------------
//
// Function: GetProductTypeStr
//
// Purpose: Get string representation of PRODUCTTYPE
//
// Arguments:
// pt [in] Product type
//
// Returns: pointer to string representation of PRODUCTTYPE
//
// Author: kumarp 03-December-97
//
PCWSTR GetProductTypeStr ( IN PRODUCTTYPE pt) { PCWSTR szProductType;
switch(pt) { case NT_WORKSTATION: szProductType = c_szAfNtWorkstation; break;
case NT_SERVER: szProductType = c_szAfNtServer; break;
default: szProductType = NULL; break; }
return szProductType; }
// ----------------------------------------------------------------------
//
// Function: WriteNetComponentsToRemove
//
// Purpose: Write the network components in the answerfile
// that will be removed.
//
// Arguments:
// pwisNetworking [in] pointer to [Networking] section
//
// Returns: none
//
// Author: asinha 29-March-2001
//
void WriteNetComponentsToRemove (IN CWInfSection* pwisNetworking) {
DefineFunctionName("WriteNetComponentsToRemove"); TraceFunctionEntry(ttidNetUpgrade);
TraceTag(ttidNetUpgrade, "netupgrd.dll: WriteNetComponentsToRemove");
if ( ShouldRemoveDLC(NULL, NULL) ) { PCWInfKey pwisKey; TStringList slNetComponentsToRemove;
pwisKey = pwisNetworking->FindKey(c_szAfNetComponentsToRemove, ISM_FromBeginning);
if ( pwisKey ) { // Read the old value of NetComponentsToRemove
pwisKey->GetStringListValue(slNetComponentsToRemove); } else { pwisKey = pwisNetworking->AddKey(c_szAfNetComponentsToRemove); }
// Make sure to write the new infId/PnpId.
AddAtEndOfStringList(slNetComponentsToRemove, sz_MS_DLC);
pwisKey->SetValue( slNetComponentsToRemove ); }
return; }
// ----------------------------------------------------------------------
//
// Function: WriteProductTypeInfo
//
// Purpose: Write product-type info to the answerfile
//
// Arguments:
// pwisNetworking [in] pointer to [Networking] section
//
// Returns: none
//
// Author: kumarp 03-December-97
//
void WriteProductTypeInfo ( IN CWInfSection* pwisNetworking) { PCWSTR pszProduct;
pszProduct = GetProductTypeStr(g_NetUpgradeInfo.From.ProductType);
Assert(pszProduct);
//UpgradeFromProduct
pwisNetworking->AddKey(c_szAfUpgradeFromProduct, pszProduct);
//BuildNumber
Assert (g_NetUpgradeInfo.From.dwBuildNumber); pwisNetworking->AddKey(c_szAfBuildNumber, g_NetUpgradeInfo.From.dwBuildNumber); }
// ----------------------------------------------------------------------
//
// Function: WriteNetworkInfoToAnswerFile
//
// Purpose: Write information about current network components
// to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteNetworkInfoToAnswerFile ( IN CWInfFile *pwifAnswerFile) { DefineFunctionName("WriteNetworkInfoToAnswerFile");
BOOL status=FALSE;
g_pslNetCard = new TStringList; g_pslNetCardInstance = new TStringList; g_pslNetCardAFileName = new TStringList;
Assert (g_NetUpgradeInfo.From.dwBuildNumber); if ((g_NetUpgradeInfo.From.dwBuildNumber <= wWinNT4BuildNumber) && !FIsPreNT5NetworkingInstalled()) { // this is NT4 or earlier and networking is not installed
// dont need to dump answerfile
TraceTag(ttidNetUpgrade, "%s: Networking is not installed, " "answerfile will not be dumped", __FUNCNAME__);
goto return_from_function; }
CWInfSection* pwisNetworking;
pwisNetworking = pwifAnswerFile->AddSectionIfNotPresent(c_szAfSectionNetworking);
//The order in which these functions are called is important
//DO NOT change it
WriteProductTypeInfo(pwisNetworking); status = WriteNt5OptionalComponentList(pwifAnswerFile); status = HandlePostConnectionsSfmOcUpgrade(pwifAnswerFile); status = HandleCMComponentSplitOcUpgrade(pwifAnswerFile);
WriteNetComponentsToRemove(pwisNetworking);
if (g_NetUpgradeInfo.From.dwBuildNumber > wWinNT4BuildNumber) { status = WriteDisableServicesListForNT5(pwifAnswerFile); status = WritePerAdapterInfoForNT5(pwifAnswerFile);
// we dont want netsetup to process other sections
//
pwisNetworking->AddBoolKey(c_szAfProcessPageSections, FALSE);
//for NT5 to NT5 upgrade, no need to dump other info
//
goto return_from_function; }
// we want netsetup to process other sections
//
pwisNetworking->AddBoolKey(c_szAfProcessPageSections, TRUE);
(void) HrWriteMainCleanSection(pwifAnswerFile);
status = WriteIdentificationInfo(pwifAnswerFile); status = WriteNetAdaptersInfo(pwifAnswerFile);
pwifAnswerFile->GotoEnd();
g_pwisBindings = pwifAnswerFile->AddSection(c_szAfSectionNetBindings); g_pwisBindings->AddComment(L"Only the disabled bindings are listed");
HrWriteNetComponentsInfo(pwifAnswerFile);
status = WriteDisableServicesList(pwifAnswerFile);
(void) HrHandleMiscSpecialCases(pwifAnswerFile);
WriteWinsockOrder(pwifAnswerFile);
return_from_function: EraseAndDeleteAll(g_pslNetCard); EraseAndDeleteAll(g_pslNetCardInstance); EraseAndDeleteAll(g_pslNetCardAFileName);
DeleteIfNotNull(g_pslNetCard); DeleteIfNotNull(g_pslNetCardInstance); DeleteIfNotNull(g_pslNetCardAFileName);
return status; }
//+---------------------------------------------------------------------------
//
// Function: WriteWinsockOrder
//
// Purpose: Records the order of winsock providers in NT4 so that they
// can be restored after upgrade.
//
// Arguments:
// pwifAnswerFile [in] Answer file structure
//
// Returns: Nothing
//
// Author: danielwe 1 Jun 1999
//
// Notes:
//
VOID WriteWinsockOrder ( IN CWInfFile* pwifAnswerFile) { AssertValidReadPtr(pwifAnswerFile); DefineFunctionName("WriteWinsockOrder");
CWInfSection* pwisWinsock;
pwisWinsock = pwifAnswerFile->AddSection(c_szAfSectionWinsock); if (pwisWinsock) { tstring strWinsockOrder; INT nErr; ULONG ulRes; DWORD cbInfo = 0; WSAPROTOCOL_INFO* pwpi = NULL; WSAPROTOCOL_INFO* pwpiInfo = NULL; LPWSCENUMPROTOCOLS pfnWSCEnumProtocols = NULL; HMODULE hmod;
if (SUCCEEDED(HrLoadLibAndGetProc(L"ws2_32.dll", "WSCEnumProtocols", &hmod, reinterpret_cast<FARPROC *>(&pfnWSCEnumProtocols)))) { // First get the size needed
//
ulRes = pfnWSCEnumProtocols(NULL, NULL, &cbInfo, &nErr); if ((SOCKET_ERROR == ulRes) && (WSAENOBUFS == nErr)) { pwpi = reinterpret_cast<WSAPROTOCOL_INFO*>(new BYTE[cbInfo]); if (pwpi) { // Find out all the protocols on the system
//
ulRes = pfnWSCEnumProtocols(NULL, pwpi, &cbInfo, &nErr);
if (SOCKET_ERROR != ulRes) { ULONG cProt; WCHAR szCatId[64];
for (pwpiInfo = pwpi, cProt = ulRes; cProt; cProt--, pwpiInfo++) { wsprintfW(szCatId, L"%lu", pwpiInfo->dwCatalogEntryId); if (cProt < ulRes) { // prepend a semicolon if not first time through
// we can't use a comma because setup will munge
// this string into separate strings and we don't
// want that
//
strWinsockOrder.append(L"."); } strWinsockOrder.append(szCatId); } }
delete pwpi; } }
pwisWinsock->AddKey(c_szAfKeyWinsockOrder, strWinsockOrder.c_str());
FreeLibrary(hmod); } } }
//+---------------------------------------------------------------------------
//
// Function: HrHandleMiscSpecialCases
//
// Purpose: Handle misc. special cases for upgrade
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 28-January-99
//
HRESULT HrHandleMiscSpecialCases ( IN CWInfFile* pwifAnswerFile) { AssertValidReadPtr(pwifAnswerFile); DefineFunctionName("HrHandleMiscSpecialCases");
HRESULT hr=S_OK;
CWInfSection* pwisMiscUpgradeData; pwisMiscUpgradeData = pwifAnswerFile->AddSection(c_szAfMiscUpgradeData);
// -------------------------------------------------------
// Tapi server upgrade
//
static const WCHAR c_szRegKeyTapiServer[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Server"; static const WCHAR c_szDisableSharing[] = L"DisableSharing"; HKEY hkeyTapiServer; DWORD dwDisableSharing;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyTapiServer, KEY_READ, &hkeyTapiServer); if (S_OK == hr) { hr = HrRegQueryDword(hkeyTapiServer, c_szDisableSharing, &dwDisableSharing); if ((S_OK == hr) && !dwDisableSharing) { pwisMiscUpgradeData->AddBoolKey(c_szAfTapiSrvRunInSeparateInstance, TRUE); }
RegCloseKey(hkeyTapiServer); } // -------------------------------------------------------
TraceErrorOptional(__FUNCNAME__, hr, (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)));
return hr; }
// ----------------------------------------------------------------------
// Computer Identification Page
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// Function: GetDomainMembershipInfo
//
// Purpose: Determine domain membership status
//
// Arguments:
// fDomainMember [out] pointer to
// strName [out] name of name of
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
// Notes: Information on the APIs used in this function is in the file:
// public\spec\se\lsa\lsaapi.doc
//
BOOL GetDomainMembershipInfo ( OUT BOOL* fDomainMember, OUT tstring& strName) { BOOL status=FALSE; LSA_HANDLE h=0; POLICY_PRIMARY_DOMAIN_INFO* ppdi;
LSA_OBJECT_ATTRIBUTES loa; ZeroMemory (&loa, sizeof(loa)); loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
NTSTATUS ntstatus; ntstatus = LsaOpenPolicy(NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &h); if (FALSE == LSA_SUCCESS(ntstatus)) return FALSE;
ntstatus = LsaQueryInformationPolicy(h, PolicyPrimaryDomainInformation, (VOID **) &ppdi); if (LSA_SUCCESS(ntstatus)) { *fDomainMember = ppdi->Sid > 0; strName = ppdi->Name.Buffer; status = TRUE; }
LsaClose(h);
return status; }
// ----------------------------------------------------------------------
//
// Function: WriteIdentificationInfo
//
// Purpose: Write computer identification info to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteIdentificationInfo ( IN CWInfFile *pwifAnswerFile) { DefineFunctionName("WriteIdentificationInfo");
TraceFunctionEntry(ttidNetUpgrade);
BOOL fStatus=FALSE;
PCWInfSection pwisIdentification = pwifAnswerFile->AddSectionIfNotPresent(c_szAfSectionIdentification); CORegKey *prkComputerName = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegValComputerName);
tstring strValue, strComment;
if(!prkComputerName) { goto error_cleanup; }
//ComputerName
prkComputerName->QueryValue(c_szComputerName, strValue); strComment = L"Computer '" + strValue + L"' is a member of the ";
BOOL fDomainMember; fStatus = GetDomainMembershipInfo(&fDomainMember, strValue); if (!fStatus) goto error_cleanup;
strComment = strComment + L"'" + strValue + L"' ";
if (fDomainMember) { strComment = strComment + L"domain "; } else { strComment = strComment + L"workgroup "; }
pwisIdentification->AddComment(strComment.c_str());
fStatus=TRUE; goto cleanup;
error_cleanup: fStatus = FALSE;
cleanup: DeleteIfNotNull(prkComputerName);
return fStatus; }
// ----------------------------------------------------------------------
// Net Cards Page
// ----------------------------------------------------------------------
//$ REVIEW kumarp 10-September-97
// this is a temporary fix only
//
// we want to avoid queryin the mac addr for these drivers because
// the drivers are faulty. the query never returns and it hangs netupgrd.dll
//
static const PCWSTR c_aszDriversToIgnoreWhenGettingMacAddr[] = { L"Diehl_ISDNSDI", };
static const PCWSTR c_aszIrq[] = { L"IRQ", L"INTERRUPT", L"InterruptNumber", L"IRQLevel" };
static const PCWSTR c_aszIoAddr[] = { L"IOADDRESS", L"IoBaseAddress", L"BaseAddr" };
static const PCWSTR c_aszMem[] = { L"Mem", L"MemoryMappedBaseAddress" };
static const PCWSTR c_aszDma[] = { L"DMA", L"DMALevel" };
static const PCWSTR c_aszAdapterParamsToIgnore[] = { L"BusType" };
// ----------------------------------------------------------------------
//
// Function: WriteNetAdaptersInfo
//
// Purpose: Write information about installed net-adapters to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteNetAdaptersInfo ( IN CWInfFile *pwifAnswerFile) { DefineFunctionName("WriteNetAdaptersInfo");
TraceFunctionEntry(ttidNetUpgrade);
HRESULT hr=E_FAIL; BOOL fStatus=FALSE; UINT cNumPhysicalAdapters=0;
// ignore the errror, it is a non-error if we cannot find
// the cNumPhysicalAdapters
(void) HrGetNumPhysicalNetAdapters(&cNumPhysicalAdapters);
CORegKey *prkNetworkCards = NULL; tstring strNetAdapterInstance; tstring strUnsupportedMessage; CORegKeyIter *prkiNetAdapters = NULL; CORegKey *prkNetAdapterInstance=NULL, *prkNetRules=NULL;
CWInfSection *pwisNetAdapters; CWInfSection *pwisNetAdapterParams=NULL; CWInfSection *pwisNetAdapterAdditionalParams=NULL;
tstring strNT5InfId; tstring strAdapterType;
// WLBS: find out which netcard WLBS is bound to
pszWlbsClusterAdapterName[0] = pszWlbsVirtualAdapterName[0] = 0;
tstring strWlbsClusterAdapterDriver, strWlbsVirtualAdapterDriver;
TStringList slWlbsLinkage;
CORegKey *prkWlbsLinkage = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegWlbsLinkage, KEY_READ);
if(!prkWlbsLinkage) { return false; }
CORegKey *prkConvoyLinkage = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegConvoyLinkage, KEY_READ);
if(!prkConvoyLinkage) { delete prkWlbsLinkage; return false; }
if ((prkWlbsLinkage->HKey() != NULL && prkWlbsLinkage->QueryValue(c_szRegValBind, slWlbsLinkage) == ERROR_SUCCESS) || (prkConvoyLinkage->HKey() != NULL && prkConvoyLinkage->QueryValue(c_szRegValBind, slWlbsLinkage) == ERROR_SUCCESS)) { TraceTag(ttidNetUpgrade, "%s: WLBS found - iterating", __FUNCNAME__);
TStringListIter iter; tstring strTmp; DWORD i;
// proper WLBS configuration will have only two bindings - one to the
// wlbs virtual NIC, the other to the cluster NIC
for (i = 0, iter = slWlbsLinkage.begin(); i < 2 && iter != slWlbsLinkage.end(); i++, iter++) { strTmp = **iter;
TraceTag(ttidNetUpgrade, "%s: WLBS bound to %S", __FUNCNAME__, strTmp.c_str());
strTmp.erase(0, 8);
TraceTag(ttidNetUpgrade, "%s: WLBS now bound to %S", __FUNCNAME__, strTmp.c_str());
if (strTmp.find(c_szWLBS) != tstring::npos || strTmp.find(c_szConvoy) != tstring::npos) { strWlbsVirtualAdapterDriver = strTmp; } else { strWlbsClusterAdapterDriver = strTmp; } }
if (iter != slWlbsLinkage.end()) { TraceTag(ttidNetUpgrade, "%s: WLBS bound to more than one NIC!", __FUNCNAME__); }
TraceTag(ttidNetUpgrade, "%s: WLBS is bound to %S and %S", __FUNCNAME__, strWlbsVirtualAdapterDriver.c_str(), strWlbsClusterAdapterDriver.c_str()); }
delete prkWlbsLinkage; delete prkConvoyLinkage;
// end WLBS:
pwisNetAdapters = pwifAnswerFile->AddSection(c_szAfSectionNetAdapters);
prkNetworkCards = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegKeyAdapterHome, KEY_READ);
if(prkNetworkCards) { prkiNetAdapters = new CORegKeyIter(*prkNetworkCards); prkiNetAdapters->Reset(); } WORD wNumAdapters = 0; CORegKey *prkAdapterDriverParams=NULL; BOOL fAbortFunction=FALSE;
// This determines if we will write the line under NetAdapters to
// reference the params section for this adapter.
//
BOOL fWriteNetAdaptersReference;
while (!fAbortFunction && prkiNetAdapters && !prkiNetAdapters->Next(&strNetAdapterInstance)) { DWORD dwHidden=0, err=0; WCHAR pszAdapterName[16], pszAdapterSectionName[256]; WCHAR pszAdapterAdditionalParamsSectionName[256];
tstring strPreNT5InfId, strAdapterDescription, strAdapterDescComment;
fWriteNetAdaptersReference = FALSE;
prkNetAdapterInstance = new CORegKey(*prkNetworkCards, strNetAdapterInstance.c_str());
// for REAL netcards, "Hidden" is absent or if present the value is 0
BOOL fRealNetCard; err = prkNetAdapterInstance->QueryValue(L"Hidden", dwHidden); fRealNetCard = (err != ERROR_SUCCESS) || (dwHidden == 0);
prkNetAdapterInstance->QueryValue(c_szRegValDescription, strAdapterDescription); swprintf(pszAdapterName, L"Adapter%02d", ++wNumAdapters);
TraceTag(ttidNetUpgrade, "%s: writing info for adapter %S (%S)", __FUNCNAME__, pszAdapterName, strNetAdapterInstance.c_str());
// Now, create adapter parameters sections
swprintf(pszAdapterSectionName, L"%s%s", c_szAfParams, pszAdapterName); //pwisNetAdapters->AddKey(pszAdapterName, pszAdapterSectionName);
swprintf(pszAdapterAdditionalParamsSectionName, L"%s%s.Additional", c_szAfParams, pszAdapterName);
if (NULL != pwisNetAdapterParams) pwifAnswerFile->GotoEndOfSection(pwisNetAdapterParams);
pwisNetAdapterParams = pwifAnswerFile->AddSection(pszAdapterSectionName); pwisNetAdapterAdditionalParams = pwifAnswerFile->AddSection(pszAdapterAdditionalParamsSectionName);
// moved up here from below so that for WLBS adapter we can set
// fRealNetCard to FALSE
tstring strAdapterDriver;
prkNetAdapterInstance->QueryValue(c_szRegValServiceName, strAdapterDriver);
// WLBS: based on pre-upgrade instance, find out virtual and cluster
// NIC adapter instances
if (_wcsicmp (strAdapterDriver.c_str(), strWlbsVirtualAdapterDriver.c_str()) == 0) { TraceTag(ttidNetUpgrade, "%s: WLBS virtual adapter is %S", __FUNCNAME__, pszAdapterName);
wcscpy(pszWlbsVirtualAdapterName, pszAdapterName); fRealNetCard = FALSE; } else if (_wcsicmp (strAdapterDriver.c_str(), strWlbsClusterAdapterDriver.c_str()) == 0) { TraceTag(ttidNetUpgrade, "%s: WLBS cluster adapter is %S", __FUNCNAME__, pszAdapterName);
wcscpy(pszWlbsClusterAdapterName, pszAdapterName); }
// end WLBS:
prkNetRules = new CORegKey(*prkNetAdapterInstance, c_szRegKeyNetRules); prkNetRules->QueryValue(c_szRegValInfOption, strPreNT5InfId);
if (fRealNetCard) { strAdapterDescComment = tstring(L"Net Card: ") + strPreNT5InfId + tstring(L" (") + strAdapterDescription + tstring(L")"); } else { strAdapterDescComment = tstring(L"Pseudo Adapter: ") + strAdapterDescription; } ReplaceCharsInString((PWSTR) strAdapterDescComment.c_str(), L"\n\r", L' ');
pwisNetAdapterParams->AddComment(strAdapterDescComment.c_str()); pwisNetAdapterParams->AddKey(c_szAfAdditionalParams, pszAdapterAdditionalParamsSectionName); pwisNetAdapterParams->AddBoolKey(c_szAfPseudoAdapter, !fRealNetCard);
pwisNetAdapterParams->AddKey(c_szAfPreUpgradeInstance, strAdapterDriver.c_str());
tstring strProductName; prkNetAdapterInstance->QueryValue(L"ProductName", strProductName); AddToNetCardDB(pszAdapterName, strProductName.c_str(), strAdapterDriver.c_str());
// We need to look at the ndiswan instances (if any) to decide
// which RAS components we need to install.
// the algorithm is like this
//
// - for each <instance> in
// software\microsoft\windows nt\currentversion\networkcards\<instance>
// - if atleast one <intance>\ProductName
// - begins with "ndiswan" AND
// - has string "in" in it --> install ms_rassrv
// - has string "out" in it --> install ms_rascli
//
PCWSTR pszProductName; pszProductName = strProductName.c_str(); if (FIsPrefix(c_szNdisWan, pszProductName)) { static const WCHAR c_szIn[] = L"in"; static const WCHAR c_szOut[] = L"out";
if (wcsstr(pszProductName, c_szIn)) { TraceTag(ttidNetUpgrade, "%s: g_fAtLeastOneDialInUsingNdisWan set to TRUE because of %S", __FUNCNAME__, pszProductName); g_fAtLeastOneDialInUsingNdisWan = TRUE; } if (wcsstr(pszProductName, c_szOut)) { TraceTag(ttidNetUpgrade, "%s: g_fAtLeastOneDialOutUsingNdisWan set to TRUE because of %S", __FUNCNAME__, pszProductName); g_fAtLeastOneDialOutUsingNdisWan = TRUE; } }
if (!fRealNetCard) { pwisNetAdapterParams->AddKey(c_szAfInfid, strPreNT5InfId.c_str());
//The rest of the keys are for real net cards only
goto cleanup_for_this_iteration; }
//EthernetAddress
if (!FIsInStringArray(c_aszDriversToIgnoreWhenGettingMacAddr, celems(c_aszDriversToIgnoreWhenGettingMacAddr), strProductName.c_str())) { QWORD qwEthernetAddress;
// ignore the error if we cannot get the netcard address
// this error is non-fatal
// Based on what build we are on, we call a different API to
// get netcard address. Currently, this code path isn't executed
// on any NT5 to NT5 upgrade, but if it changes, we want to use
// the newer api.
//
if (g_NetUpgradeInfo.From.dwBuildNumber < 2031) // Pre-Beta3
{ (VOID) HrGetNetCardAddrOld(strAdapterDriver.c_str(), &qwEthernetAddress); } else { (VOID) HrGetNetCardAddr(strAdapterDriver.c_str(), &qwEthernetAddress); } pwisNetAdapterParams->AddQwordKey(c_szAfNetCardAddr, qwEthernetAddress);
fWriteNetAdaptersReference = (0 != qwEthernetAddress); } else { TraceTag(ttidNetUpgrade, "%s: did not query %S for mac address", __FUNCNAME__, strProductName.c_str()); }
GetServiceParamsKey(strAdapterDriver.c_str(), prkAdapterDriverParams);
//write INFID key
HKEY hkeyAdapterDriverParams; if (prkAdapterDriverParams) { hkeyAdapterDriverParams = prkAdapterDriverParams->HKey(); } else { hkeyAdapterDriverParams = NULL; }
BOOL fIsOemAdapter; CNetMapInfo* pnmi;
fIsOemAdapter = FALSE; pnmi = NULL;
hr = HrMapPreNT5NetCardInfIdToNT5InfId(hkeyAdapterDriverParams, strPreNT5InfId.c_str(), &strNT5InfId, &strAdapterType, &fIsOemAdapter, &pnmi);
if (S_OK == hr) { if (!lstrcmpiW(strAdapterType.c_str(), c_szAsyncAdapters) || !lstrcmpiW(strAdapterType.c_str(), c_szOemAsyncAdapters)) { CWInfSection* pwisAsyncCards; pwisAsyncCards = pwifAnswerFile->AddSectionIfNotPresent(c_szAsyncAdapters); if (pwisAsyncCards) { pwisAsyncCards->AddKey(pszAdapterName, pszAdapterSectionName); } } else { fWriteNetAdaptersReference = TRUE; } } else { GetUnsupportedMessage(c_szNetCard, strAdapterDescription.c_str(), strPreNT5InfId.c_str(), &strUnsupportedMessage); pwisNetAdapterParams->AddComment(strUnsupportedMessage.c_str()); strNT5InfId = c_szAfUnknown; TraceTag(ttidNetUpgrade, "WriteNetAdaptersInfo: %S", strUnsupportedMessage.c_str()); }
if (fWriteNetAdaptersReference) { // We have enough information to determine which adapter goes
// with this section so write out the reference.
//
pwisNetAdapters->AddKey(pszAdapterName, pszAdapterSectionName); }
if (1 == cNumPhysicalAdapters) { TraceTag(ttidNetUpgrade, "%s: dumped '*' as InfID for %S", __FUNCNAME__, strNT5InfId.c_str()); pwisNetAdapterParams->AddKey(c_szAfInfid, L"*"); pwisNetAdapterParams->AddKey(c_szAfInfidReal, strNT5InfId.c_str()); } else { pwisNetAdapterParams->AddKey(c_szAfInfid, strNT5InfId.c_str()); }
if (!prkAdapterDriverParams) { // since we could not open the driver params key
// we cant dump parameters. just skip this card and continue
goto cleanup_for_this_iteration; }
// -----------------------------------------------------------------
// OEM upgrade code
//
if (fIsOemAdapter) { hr = HrProcessOemComponentAndUpdateAfSection( pnmi, NULL, prkAdapterDriverParams->HKey(), strPreNT5InfId.c_str(), strAdapterDriver.c_str(), strNT5InfId.c_str(), strAdapterDescription.c_str(), pwisNetAdapterParams);
// OEM upgrade may be aborted because of a fatal error or
// if an OEM DLL requests it. in both cases we need to stop
// our current answerfile generation
//
if (FIsUpgradeAborted()) { fAbortFunction = TRUE; goto cleanup_for_this_iteration; } } // -----------------------------------------------------------------
//BusType
DWORD dwBusType; INTERFACE_TYPE eBusType; prkAdapterDriverParams->QueryValue(L"BusType", dwBusType); eBusType = (INTERFACE_TYPE) dwBusType; pwisNetAdapterParams->AddKey(c_szAfBusType, GetBusTypeName(eBusType));
// for certain ISA cards the driver parameters store EISA as the bus type
// when these cards are installed in EISA slots. Thus we have to dump parameters
// when BusType is Eisa.
//
BOOL fDumpResources; fDumpResources = ((eBusType == Isa) || (eBusType == Eisa));
// kumarp 14-July-97
// this fix has been requested by billbe.
// we do not dump hardware resources for the ISAPNP cards
//
if (!lstrcmpiW(strPreNT5InfId.c_str(), L"IEEPRO") || !lstrcmpiW(strPreNT5InfId.c_str(), L"ELNK3ISA509")) { fDumpResources = FALSE; }
DWORD dwIndex; dwIndex = 0; DWORD dwValueNameLen, dwValueType;
WCHAR szValueName[REGSTR_MAX_VALUE_LENGTH+1]; PCWSTR pszResourceName; DWORD dwValueDumpFormat; do { dwValueNameLen = REGSTR_MAX_VALUE_LENGTH; hr = HrRegEnumValue(prkAdapterDriverParams->HKey(), dwIndex, szValueName, &dwValueNameLen, &dwValueType, NULL, NULL);
if (hr == S_OK) { pszResourceName = NULL; dwValueDumpFormat = REG_HEX;
dwIndex++; if (FIsInStringArray(c_aszIrq, celems(c_aszIrq), szValueName)) { pszResourceName = c_szAfIrq; dwValueDumpFormat = REG_DWORD; } else if (FIsInStringArray(c_aszIoAddr, celems(c_aszIoAddr), szValueName)) { pszResourceName = c_szAfIoAddr; } else if (FIsInStringArray(c_aszMem, celems(c_aszMem), szValueName)) { pszResourceName = c_szAfMem; } else if (FIsInStringArray(c_aszDma, celems(c_aszDma), szValueName)) { pszResourceName = c_szAfDma; }
if (pszResourceName) { if (fDumpResources) { WriteRegValueToAFile(pwisNetAdapterParams, *prkAdapterDriverParams, szValueName, (WORD)dwValueDumpFormat, pszResourceName); } } else if (!FIsInStringArray(c_aszAdapterParamsToIgnore, celems(c_aszAdapterParamsToIgnore), szValueName)) { WriteRegValueToAFile(pwisNetAdapterAdditionalParams, *prkAdapterDriverParams, szValueName, (WORD)dwValueType); } } } while (hr == S_OK);
cleanup_for_this_iteration: DeleteIfNotNull(prkNetAdapterInstance); DeleteIfNotNull(prkNetRules); DeleteIfNotNull(prkAdapterDriverParams); }
// WLBS: if either cluster or virtual adapter were not matched - blow off
// WLBS-specific upgrade code
if (pszWlbsClusterAdapterName[0] == 0 || pszWlbsVirtualAdapterName[0] ==0) { pszWlbsClusterAdapterName[0] = pszWlbsVirtualAdapterName[0] = 0; }
// end WLBS:
fStatus=TRUE; goto cleanup;
fStatus=FALSE;
cleanup: DeleteIfNotNull(prkNetworkCards); DeleteIfNotNull(prkiNetAdapters);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: HrGetNumPhysicalNetAdapters
//
// Purpose: Count and return number of physical adapters installed
//
// Arguments:
// puNumAdapters [out] pointer to num adapters
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 29-May-98
//
HRESULT HrGetNumPhysicalNetAdapters ( OUT UINT* puNumAdapters) { AssertValidWritePtr(puNumAdapters); DefineFunctionName("HrGetNumPhysicalNetAdapters");
HRESULT hr; HKEY hkeyAdapters; HKEY hkeyAdapter; DWORD dwHidden; BOOL fRealNetCard = FALSE;
*puNumAdapters = 0;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyAdapterHome, KEY_READ, &hkeyAdapters); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize; DWORD dwRegIndex;
for (dwRegIndex = 0, dwSize = celems(szBuf); S_OK == HrRegEnumKeyEx(hkeyAdapters, dwRegIndex, szBuf, &dwSize, NULL, NULL, &time); dwRegIndex++, dwSize = celems(szBuf)) { Assert(*szBuf);
hr = HrRegOpenKeyEx(hkeyAdapters, szBuf, KEY_READ, &hkeyAdapter); if (hr == S_OK) { hr = HrRegQueryDword(hkeyAdapter, c_szHidden, &dwHidden);
// for REAL netcards, "Hidden" is absent or if present the value is 0
if (S_OK == hr) { fRealNetCard = (0 == dwHidden); } else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { fRealNetCard = TRUE; hr = S_OK; }
if ((S_OK == hr) && fRealNetCard) { (*puNumAdapters)++; } RegCloseKey(hkeyAdapter); } }
RegCloseKey(hkeyAdapters); }
TraceTag(ttidNetUpgrade, "%s: Found %d physical net adapters", __FUNCNAME__, *puNumAdapters);
TraceError(__FUNCNAME__, hr); return hr; }
// ----------------------------------------------------------------------
//
// Function: IsNetworkComponent
//
// Purpose: Determine if a component is a net-component
//
// Arguments:
// prkSoftwareMicrosoft [in] pointer to CORegKey object
// strComponentName [in] constTString object name of
//
// Returns:
//
// Author: kumarp 03-December-97
//
// Notes: any software that has a NetRules key under the CurrentVersion
// key is considered a network component
//
BOOL IsNetworkComponent ( IN CORegKey *prkSoftwareMicrosoft, IN const tstring strComponentName) { tstring strNetRules = strComponentName + L"\\CurrentVersion\\NetRules"; CORegKey rkNetRules((HKEY) *prkSoftwareMicrosoft, strNetRules.c_str()); return (((HKEY) rkNetRules) != NULL); }
// ----------------------------------------------------------------------
// Network components (protocols, services)
// ----------------------------------------------------------------------
typedef BOOL (*WriteNetComponentParamsFn)( IN CWInfFile* pwifAnswerFile, IN CWInfSection* pwisGlobalParams);
static PCWSTR c_aszNetComponents[] = { L"RASPPTP", L"Browser", c_szSvcWorkstation, L"RpcLocator", L"LanmanServer", c_szSvcNetBIOS, c_szSvcNWCWorkstation, c_szSvcDhcpServer, L"ISOTP", c_szWLBS, c_szConvoy };
static WriteNetComponentParamsFn c_afpWriteParamsFns[] = { WritePPTPParams, WriteBrowserParams, WriteLanmanWorkstationParams, WriteRPCLocatorParams, WriteLanmanServerParams, WriteNetBIOSParams, WriteNWCWorkstationParams, WriteDhcpServerParams, WriteTp4Params, WriteWLBSParams, WriteConvoyParams };
typedef BOOL (*WriteNetComponentParamsAndAdapterSectionsFn)( IN CWInfFile* pwifAnswerFile, IN CWInfSection* pwisGlobalParams, OUT TStringList& slAdditionalParamsSections);
static const PCWSTR c_aszNetComponentsWithAdapterSpecificParams[] = { L"Tcpip", L"NwlnkIpx", L"AppleTalk" };
static WriteNetComponentParamsAndAdapterSectionsFn c_afpWriteParamsAndAdapterSectionsFns[] = { WriteTCPIPParams, WriteIPXParams, WriteAppleTalkParams };
// ----------------------------------------------------------------------
//
// Function: HrWriteNetComponentInfo
//
// Purpose: Write info of the specified component to the answerfile
//
// Arguments:
// szNetComponent [in] net component
// pwifAnswerFile [in] pointer to CWInfFile object (answerfile)
// hkeyCurrentVersion [in] handle of CurrentVersion regkey
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 13-May-98
//
HRESULT HrWriteNetComponentInfo ( IN PCWSTR szNetComponent, IN CWInfFile* pwifAnswerFile, IN HKEY hkeyCurrentVersion) { DefineFunctionName("HrWriteNetComponentInfo");
HRESULT hr=S_OK;
tstring strPreNT5InfId; tstring strNT5InfId; tstring strProductCurrentVersion; tstring strDescription; tstring strSoftwareType; tstring strParamsSectionName;
TStringList slAdditionalParamsSections; BOOL fIsOemComponent; UINT uIndex;
CWInfSection* pwisNetComponents; CWInfSection* pwisNetComponentParams; ENetComponentType nct=NCT_Unknown; PCWSTR szNetComponentsSection; CNetMapInfo* pnmi; static BOOL fRasParamsDumped=FALSE;
hr = HrGetPreNT5InfIdAndDesc(hkeyCurrentVersion, &strPreNT5InfId, &strDescription, NULL);
if (S_OK == hr) { TraceTag(ttidNetUpgrade, "%s: processing '[%S] %S'", __FUNCNAME__, strPreNT5InfId.c_str(), strDescription.c_str());
hr = HrMapPreNT5NetComponentInfIDToNT5InfID( strPreNT5InfId.c_str(), &strNT5InfId, &fIsOemComponent, &nct, &pnmi);
if (S_OK == hr) { Assert((nct >= NCT_Adapter) && (nct <= NCT_Client));
// add the top level section [Net*] if not present
szNetComponentsSection = g_szNetComponentSectionName[nct]; pwisNetComponents = pwifAnswerFile->AddSectionIfNotPresent( szNetComponentsSection);
strParamsSectionName = c_szAfParams + strNT5InfId;
if (!pwisNetComponents->FindKey(strNT5InfId.c_str(), ISM_FromBeginning)) { pwisNetComponentParams = pwifAnswerFile->AddSection(strParamsSectionName.c_str());
// RAS is a special case.
if (0 != _wcsicmp(strNT5InfId.c_str(), c_szRAS)) { pwisNetComponents->AddKey(strNT5InfId.c_str(), strParamsSectionName.c_str()); }
} else { pwisNetComponentParams = pwifAnswerFile->FindSection(strParamsSectionName.c_str()); }
AssertSz(pwisNetComponentParams, "HrWriteNetComponentInfo: Need a section to add key to!");
if (FIsInStringArray(c_aszNetComponents, celems(c_aszNetComponents), szNetComponent, &uIndex)) { c_afpWriteParamsFns[uIndex](pwifAnswerFile, pwisNetComponentParams); } else if (FIsInStringArray( c_aszNetComponentsWithAdapterSpecificParams, celems(c_aszNetComponentsWithAdapterSpecificParams), szNetComponent, &uIndex)) { EraseAndDeleteAll(slAdditionalParamsSections); c_afpWriteParamsAndAdapterSectionsFns[uIndex] (pwifAnswerFile, pwisNetComponentParams, slAdditionalParamsSections); if (!slAdditionalParamsSections.empty()) { pwisNetComponentParams->AddKey(c_szAfAdapterSections, slAdditionalParamsSections); } } else if (!lstrcmpiW(strNT5InfId.c_str(), c_szRAS) && !fRasParamsDumped) { fRasParamsDumped = TRUE; WriteRASParams(pwifAnswerFile, pwisNetComponents, pwisNetComponentParams); } else if (fIsOemComponent) { HKEY hkeyServiceParams=NULL; tstring strServiceName; hr = HrRegQueryString(hkeyCurrentVersion, c_szRegValServiceName, &strServiceName); if (S_OK == hr) { AssertSz(!strServiceName.empty(), "Service name is empty for OEM component!!"); hr = HrRegOpenServiceSubKey(strServiceName.c_str(), c_szParameters, KEY_READ, &hkeyServiceParams); if (S_OK == hr) { hr = HrProcessOemComponentAndUpdateAfSection( pnmi, NULL, hkeyServiceParams, // Parameters reg key
strPreNT5InfId.c_str(), strServiceName.c_str(), strNT5InfId.c_str(), strDescription.c_str(), pwisNetComponentParams);
// OEM upgrade may be aborted because of a fatal error or
// if an OEM DLL requests it. in both cases we need to
// stop our current answerfile generation
if (FIsUpgradeAborted()) { TraceTag(ttidNetUpgrade, "%s: upgrade aborted by %S", __FUNCNAME__, strNT5InfId.c_str()); } } else { TraceTag(ttidNetUpgrade, "%s: could not open Parameters key for '%S'", __FUNCNAME__, strServiceName.c_str()); } } } else { TraceTag(ttidNetUpgrade, "%s: '%S' Unknown component!!", __FUNCNAME__, strPreNT5InfId.c_str()); } } else if (S_FALSE == hr) { CWInfSection* pwisNetworking; pwisNetworking = pwifAnswerFile->FindSection(c_szAfSectionNetworking); if (pwisNetworking) { tstring strUnsupportedMessage;
GetUnsupportedMessage(NULL, strDescription.c_str(), strPreNT5InfId.c_str(), &strUnsupportedMessage); pwisNetworking->AddComment(strUnsupportedMessage.c_str()); } } else if (FAILED(hr)) { TraceTag(ttidNetUpgrade, "%s: mapping failed, skipped '%S'", __FUNCNAME__, szNetComponent); hr = S_OK; } } else { TraceTag(ttidNetUpgrade, "%s: HrGetPreNT5InfIdAndDesc failed, " "skipped '%S'", __FUNCNAME__, szNetComponent); hr = S_OK; }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: WriteNetComponentInfoForProvider
//
// Purpose: Write info on installed net components (except net cards)
// of the specified provider to the answerfile
//
// Arguments:
// pszSoftwareProvider [in] name of provider
// pwifAnswerFile [in] pointer to CWInfFile object (answerfile)
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 13-May-98
//
VOID WriteNetComponentInfoForProvider( IN HKEY hkeyProvider, IN PCWSTR pszSoftwareProvider, IN CWInfFile* pwifAnswerFile) { AssertValidReadPtr(pszSoftwareProvider); AssertValidReadPtr(pwifAnswerFile);
HRESULT hr; HKEY hkeyProductCurrentVersion;
tstring strProductCurrentVersion; tstring strSoftwareType;
WCHAR szNetComponent[MAX_PATH]; FILETIME time; DWORD dwSize; DWORD dwRegIndex;
for (dwRegIndex = 0, dwSize = celems(szNetComponent); !FIsUpgradeAborted() && (S_OK == HrRegEnumKeyEx(hkeyProvider, dwRegIndex, szNetComponent, &dwSize, NULL, NULL, &time)); dwRegIndex++, dwSize = celems(szNetComponent)) { Assert(*szNetComponent);
strProductCurrentVersion = szNetComponent; AppendToPath(&strProductCurrentVersion, c_szRegKeyCurrentVersion);
hr = HrRegOpenKeyEx(hkeyProvider, strProductCurrentVersion.c_str(), KEY_READ, &hkeyProductCurrentVersion); if (S_OK == hr) { hr = HrRegQueryString(hkeyProductCurrentVersion, c_szRegValSoftwareType, &strSoftwareType);
// ignore components of type "driver"
if ((S_OK == hr) && (0 != lstrcmpiW(strSoftwareType.c_str(), c_szSoftwareTypeDriver))) { // Don't write disabled bindings of NdisWan and NetBT.
// They should always be enabled on upgrade.
//
if ((0 != lstrcmpiW(szNetComponent, L"NdisWan")) && (0 != lstrcmpiW(szNetComponent, L"NetBT"))) { WriteBindings(szNetComponent); }
if (!ShouldIgnoreComponent(szNetComponent)) { (VOID) HrWriteNetComponentInfo( szNetComponent, pwifAnswerFile, hkeyProductCurrentVersion); } }
RegCloseKey(hkeyProductCurrentVersion); } } }
// ----------------------------------------------------------------------
//
// Function: HrWriteNetComponentsInfo
//
// Purpose: Write info on installed net components (except net cards)
// of all providers to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object (answerfile)
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 13-May-98
//
HRESULT HrWriteNetComponentsInfo( IN CWInfFile* pwifAnswerFile) { AssertValidReadPtr(pwifAnswerFile);
HRESULT hr; HKEY hkeySoftware;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeySoftware, KEY_READ, &hkeySoftware); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize; DWORD dwRegIndex;
for (dwRegIndex = 0, dwSize = celems(szBuf); S_OK == HrRegEnumKeyEx(hkeySoftware, dwRegIndex, szBuf, &dwSize, NULL, NULL, &time); dwRegIndex++, dwSize = celems(szBuf)) { Assert(*szBuf);
HKEY hkeyProvider;
hr = HrRegOpenKeyEx(hkeySoftware, szBuf, KEY_READ, &hkeyProvider);
if (S_OK == hr) { // We want to continue even if there is any error dumping info
// of one provider
//
WriteNetComponentInfoForProvider( hkeyProvider, szBuf, pwifAnswerFile);
if (0 == _wcsicmp(szBuf, L"Microsoft")) { (VOID) HrWritePreSP3ComponentsToSteelHeadUpgradeParams( pwifAnswerFile); }
RegCloseKey(hkeyProvider); }
}
RegCloseKey(hkeySoftware); }
return hr; }
// ----------------------------------------------------------------------
// TCPIP related
// ----------------------------------------------------------------------
static const WCHAR c_szTcpipParams[] = L"Tcpip\\Parameters";
VOID WriteRegValueToAFile( IN PCWInfSection pwisSection, IN CORegKey& rk, IN const ValueTypePair* prgVtp, IN ULONG crg) { for (ULONG idx = 0; idx < crg; idx++) { if (REG_FILE == prgVtp[idx].dwType) { //This is just for "PersistentRoute" which we handle specifically
continue; }
WriteRegValueToAFile(pwisSection, rk, prgVtp[idx].pszValueName, (WORD)prgVtp[idx].dwType); } }
// ----------------------------------------------------------------------
//
// Function: WriteTCPIPParams
//
// Purpose: Write parameters of TCPIP to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
// pwisTCPIPGlobalParams [in] pointer to TCPIP global params section
// slAdditionalParamsSections [out] list of adapter sections
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteTCPIPParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisTCPIPGlobalParams, OUT TStringList& slAdditionalParamsSections) { DefineFunctionName("WriteTCPIPParams");
TraceFunctionEntry(ttidNetUpgrade);
HRESULT hr; TStringList slList; PCORegKey prkRouter=NULL; PCORegKey prkTCPIP=NULL; PCORegKey prkTcpipParams=NULL; PCORegKey prkTCPIPLinkage=NULL; PCORegKey prkNetBT=NULL; DWORD dwEnableDNS=0; BOOL fEnableDNS=FALSE;
GetServiceKey(c_szSvcTcpip, prkTCPIP); prkTcpipParams = new CORegKey(*prkTCPIP, c_szParameters);
tstring strValue; DWORD dwValue;
//first write the global parameters
// UseDomainNameDevolution
WriteServiceRegValueToAFile(pwisTCPIPGlobalParams, L"DnsCache\\Parameters", L"UseDomainNameDevolution", REG_BOOL, NULL, // dont change value name
TRUE, // use default
(BOOL) TRUE); // default value
// EnableSecurity
dwValue = 0; if (0 == prkTcpipParams->QueryValue(L"EnableSecurityFilters", dwValue)) pwisTCPIPGlobalParams->AddBoolKey(c_szAfEnableSecurity, dwValue);
// DNS
GetServiceParamsKey(c_szSvcNetBT, prkNetBT); if (prkNetBT) { if (0 == prkNetBT->QueryValue(L"EnableDNS", dwEnableDNS)) { fEnableDNS = dwEnableDNS; }
// EnableLMHosts
WriteRegValueToAFile(pwisTCPIPGlobalParams, *prkNetBT, NULL, c_szAfEnableLmhosts, REG_BOOL, NULL, TRUE, (BOOL)FALSE);
// Write any present optional parameters to the answerfile
//
WriteRegValueToAFile(pwisTCPIPGlobalParams, *prkNetBT, rgVtpNetBt, celems(rgVtpNetBt)); }
pwisTCPIPGlobalParams->AddBoolKey(c_szAfDns, fEnableDNS);
// DNSDomain
// Fix bug 349343, if the Domain value is empty, don't upgrade it
strValue.erase(); prkTcpipParams->QueryValue(c_szDomain, strValue); if (!strValue.empty()) { pwisTCPIPGlobalParams->AddKey(c_szAfDnsDomain, strValue.c_str()); }
// HostName
// 391590: save the hostname so we can maintain the capitalization
strValue.erase(); prkTcpipParams->QueryValue(c_szHostname, strValue); if (!strValue.empty()) { pwisTCPIPGlobalParams->AddKey(c_szAfDnsHostname, strValue.c_str()); }
// --------------------------------------------------
//$ ISSUE: kumarp 12-December-97
//
// this should be removed for Connections
// (they have been moved to adapter specific sections
//
//DNSServerSearchOrder
strValue.erase(); prkTcpipParams->QueryValue(c_szNameServer, strValue); ConvertDelimitedListToStringList(strValue, ' ', slList); pwisTCPIPGlobalParams->AddKey(c_szAfDnsServerSearchOrder, slList); // --------------------------------------------------
// DNSSuffixSearchOrder
strValue.erase(); prkTcpipParams->QueryValue(L"SearchList", strValue); ConvertDelimitedListToStringList(strValue, ' ', slList); pwisTCPIPGlobalParams->AddKey(c_szAfDnsSuffixSearchOrder, slList);
// ImportLMHostsFile
// REVIEW: how to migrate the user-modified-lmhosts file ?
// Per AmritanR, drop the upgrade support of IpEnableRouter (EnableIPForwarding in the answer file) to fix bug 345700
// EnableIPForwarding (i.e. IpEnableRouter)
// If Steelhead is installed then write the following otherwise do nothing
//
if (TRUE == GetServiceKey(c_szRouter, prkRouter)) { pwisTCPIPGlobalParams->AddBoolKey(c_szAfEnableICMPRedirect, FALSE); pwisTCPIPGlobalParams->AddBoolKey(c_szAfDeadGWDetectDefault, FALSE); pwisTCPIPGlobalParams->AddBoolKey(c_szAfDontAddDefaultGatewayDefault, TRUE); }
// DatabasePath (REG_EXPAND_SZ)
strValue.erase(); prkTcpipParams->QueryValue(c_szDatabasePath, strValue); if (!strValue.empty()) { pwisTCPIPGlobalParams->AddKey(c_szDatabasePath, strValue.c_str()); }
// Write any present optional parameters to the answerfile
//
WriteRegValueToAFile(pwisTCPIPGlobalParams, *prkTcpipParams, rgVtpIp, celems(rgVtpIp));
//PersistentRoutes
(void) HrNetRegSaveKeyAndAddToSection(prkTcpipParams->HKey(), c_szPersistentRoutes, c_szAfTcpip, c_szPersistentRoutes, pwisTCPIPGlobalParams);
//Write Adapter specific parameters
prkTCPIPLinkage = new CORegKey(*prkTCPIP, c_szLinkage); prkTCPIPLinkage->QueryValue(L"Bind", slList);
TraceStringList(ttidNetUpgrade, L"TCPIP: enabled adapters", slList); CORegKey* prkTCPIPLinkageDisabled; TStringList slDisabled;
prkTCPIPLinkageDisabled = new CORegKey(*prkTCPIP, c_szLinkageDisabled); prkTCPIPLinkageDisabled->QueryValue(L"Bind", slDisabled); TraceStringList(ttidNetUpgrade, L"TCPIP: disabled adapters", slDisabled); slList.splice(slList.end(), slDisabled); delete prkTCPIPLinkageDisabled;
// $REVIEW(tongl 2/18/99): Added for bug #192576
// Get the list of disabled adapters to DHCP server, if it is installed
HKEY hkey; ListStrings lstDisabledToDhcp; ListStrings lstDisabledNetbt;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szDhcpServerLinkageDisabled, KEY_READ, &hkey);
if (S_OK == hr) { hr = HrRegQueryColString(hkey, L"Bind", &lstDisabledToDhcp);
RegCloseKey (hkey); }
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Netbt\\Linkage\\Disabled", KEY_READ, &hkey);
if (S_OK == hr) { hr = HrRegQueryColString(hkey, L"Bind", &lstDisabledNetbt);
RegCloseKey (hkey); }
TStringListIter iter;
for (iter = slList.begin(); iter != slList.end(); iter++) { static WCHAR szAdapterDriver[256];
if (swscanf((*iter)->c_str(), L"\\Device\\%s", szAdapterDriver) == 1) { // $REVIEW(tongl 2/18/99): Added for bug #192576
// If this adapter was on the disabled list to DHCP server,
// set this to FALSE, otherwise, don't do anything
BOOL fDisabledToDhcpServer = FALSE; BOOL fDisableNetbios = FALSE;
if (lstDisabledToDhcp.size()) { TraceTag(ttidNetUpgrade, "szAdapterDriver: %S", szAdapterDriver);
TStringListIter iterD; for (iterD = lstDisabledToDhcp.begin(); iterD != lstDisabledToDhcp.end(); iterD++) { TraceTag(ttidNetUpgrade, "binding string: %S", (*iterD)->c_str());
if (FIsSubstr(szAdapterDriver, (*iterD)->c_str())) { TraceTag(ttidNetUpgrade, "Adapter %S is disabled to Dhcp Server", szAdapterDriver); fDisabledToDhcpServer = TRUE; break; } } }
if (lstDisabledNetbt.size()) { TraceTag(ttidNetUpgrade, "szAdapterDriver: %S", szAdapterDriver);
TStringListIter iterD; for (iterD = lstDisabledNetbt.begin(); iterD != lstDisabledNetbt.end(); iterD++) { TraceTag(ttidNetUpgrade, "binding string: %S", (*iterD)->c_str());
if (FIsSubstr(szAdapterDriver, (*iterD)->c_str())) { TraceTag(ttidNetUpgrade, "Adapter %S is disabled for NetBIOS over TCP/IP", szAdapterDriver); fDisableNetbios = TRUE; break; } } }
WriteTCPIPAdapterParams( pwifAnswerFile, szAdapterDriver, slAdditionalParamsSections, fDisabledToDhcpServer, fDisableNetbios); } }
DeleteIfNotNull(prkTCPIP); DeleteIfNotNull(prkTcpipParams); DeleteIfNotNull(prkNetBT); DeleteIfNotNull(prkTCPIPLinkage); DeleteIfNotNull(prkRouter);
EraseAndDeleteAll(slList);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteTCPIPAdapterParams
//
// Purpose: Write adapter-specific parameters of TCPIP to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pszAdapterDriver [in] instance name of the adapter driver
// (e.g. ieepro2)
// slAdditionalParamsSections [out] list of adapter sections
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 03-December-97
//
BOOL WriteTCPIPAdapterParams ( IN PCWInfFile pwifAnswerFile, IN PCWSTR pszAdapterDriver, OUT TStringList& slAdditionalParamsSections, BOOL fDisabledToDhcpServer, BOOL fDisableNetbios) { DefineFunctionName("WriteTCPIPAdapterParams");
TraceFunctionEntry(ttidNetUpgrade);
BOOL fStatus=FALSE; PCORegKey prkNetBTParams=NULL; tstring strValue; TStringList slList; tstring strAdapterParamsSectionName; PCWInfSection pwisParams; tstring strParamsKeyName; PCORegKey prkParams = NULL;
PCWSTR pszAdapter = MapNetCardInstanceToAFileName(pszAdapterDriver);
if (!pszAdapter) { // this is most likely due to corrupt or inconsistent registry
//
TraceTag(ttidNetUpgrade, "%s: skipped writing adapter specific ", "parameters for %S", __FUNCNAME__, pszAdapterDriver); goto error_cleanup; }
// WLBS: write WLBS TCP/IP parameters under the name of the cluster adapter,
// and skip cluster adapter TCP/IP parameters alltogether.
if (pszWlbsClusterAdapterName[0] != 0) { if (_wcsicmp(pszAdapter, pszWlbsClusterAdapterName) == 0) { TraceTag(ttidNetUpgrade, "%s: skipping %S section", __FUNCNAME__, pszAdapter);
goto error_cleanup; } else if (_wcsicmp(pszAdapter, pszWlbsVirtualAdapterName) == 0) { TraceTag(ttidNetUpgrade, "%s: replacing %S section with %S", __FUNCNAME__, pszAdapter, pszWlbsClusterAdapterName);
pszAdapter = pszWlbsClusterAdapterName; } }
// end WLBS:
strAdapterParamsSectionName = tstring(c_szAfParams) + c_szInfId_MS_TCPIP + L"." + pszAdapter; AddAtEndOfStringList(slAdditionalParamsSections, strAdapterParamsSectionName);
pwisParams = pwifAnswerFile->AddSection(strAdapterParamsSectionName.c_str()); pwisParams->AddKey(c_szAfSpecificTo, pszAdapter);
// TCPIP parameters for <adapter> are found at
// Services\<adapter-driver>\Parameters\Tcpip
strParamsKeyName = tstring(c_szRegKeyServices) + L"\\" + pszAdapterDriver + L"\\Parameters\\Tcpip";
prkParams = new CORegKey(HKEY_LOCAL_MACHINE, strParamsKeyName.c_str()); if (!prkParams) goto error_cleanup;
//DNSServerSearchOrder
//
HRESULT hr; HKEY hkeyTcpipParams;
hr = HrRegOpenServiceKey(c_szTcpipParams, KEY_READ, &hkeyTcpipParams); if (S_OK == hr) { tstring strDnsServerSearchOrder;
hr = HrRegQueryString(hkeyTcpipParams, c_szNameServer, &strDnsServerSearchOrder); if (S_OK == hr) { TStringList slDnsServerSearchOrder;
ConvertDelimitedListToStringList(strDnsServerSearchOrder, ' ', slDnsServerSearchOrder); pwisParams->AddKey(c_szAfDnsServerSearchOrder, slDnsServerSearchOrder); } }
//DNSDomain
WriteServiceRegValueToAFile(pwisParams, c_szTcpipParams, c_szDomain, REG_SZ, c_szAfDnsDomain);
DWORD dwValue; prkParams->QueryValue(L"EnableDHCP", dwValue); pwisParams->AddBoolKey(c_szAfDhcp, dwValue); if (!dwValue) { //IPAddress
WriteRegValueToAFile(pwisParams, *prkParams, c_szAfIpaddress, REG_MULTI_SZ);
//SubnetMask
WriteRegValueToAFile(pwisParams, *prkParams, c_szAfSubnetmask, REG_MULTI_SZ); }
//Gateway
WriteRegValueToAFile(pwisParams, *prkParams, c_szAfDefaultGateway, REG_MULTI_SZ);
// TcpAllowedPorts
WriteRegValueToAFile(pwisParams, *prkParams, L"TcpAllowedPorts", REG_MULTI_SZ, c_szAfTcpAllowedPorts);
// UdpAllowedPorts
WriteRegValueToAFile(pwisParams, *prkParams, L"UdpAllowedPorts", REG_MULTI_SZ, c_szAfUdpAllowedPorts);
// IpAllowedProtocols
WriteRegValueToAFile(pwisParams, *prkParams, L"RawIPAllowedProtocols", REG_MULTI_SZ, c_szAfIpAllowedProtocols);
// Write any present optional parameters to the answerfile
//
WriteRegValueToAFile(pwisParams, *prkParams, rgVtpIpAdapter, celems(rgVtpIpAdapter));
strValue = L"Adapters\\"; strValue += pszAdapterDriver;
GetServiceSubkey(c_szSvcNetBT, strValue.c_str(), prkNetBTParams); if (!prkNetBTParams) goto error_cleanup;
strValue.erase(); prkNetBTParams->QueryValue(c_szNameServer, strValue); if (strValue.empty()) { //WINS=No
pwisParams->AddKey(c_szAfWins, c_szNo); } else { //WINS=Yes
pwisParams->AddKey(c_szAfWins, c_szYes);
tstring strWinsServerList; strWinsServerList = strValue;
prkNetBTParams->QueryValue(L"NameServerBackup", strValue); if (!strValue.empty()) { strWinsServerList += L","; strWinsServerList += strValue; } pwisParams->AddKey(c_szAfWinsServerList, strWinsServerList.c_str()); }
// BindToDhcpServer
// $REVIEW(tongl 2/18/99): Added for bug #192576
// If this adapter was on the disabled list to DHCP server, set this to FALSE
// otherwise, don't do anything
if (fDisabledToDhcpServer) { pwisParams->AddBoolKey(c_szAfBindToDhcpServer, !fDisabledToDhcpServer); }
if (fDisableNetbios) { // Value of 2 means disable netbios over tcpip for this interface.
pwisParams->AddKey(c_szAfNetBIOSOptions, 2); }
fStatus=TRUE; goto cleanup;
error_cleanup: fStatus = FALSE;
cleanup: DeleteIfNotNull(prkParams); DeleteIfNotNull(prkNetBTParams);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: WriteAppleTalkParams
//
// Purpose: Write parameters of AppleTalk protocol
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisGlobalParams [in] pointer to global params section
// slAdditionalParamsSections [out] list of adapter params sections
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 11-December-97
//
BOOL WriteAppleTalkParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisGlobalParams, OUT TStringList& slAdditionalParamsSections) { DefineFunctionName("WriteAppleTalkParams");
TraceFunctionEntry(ttidNetUpgrade);
BOOL fStatus=FALSE;
tstring strTemp; CORegKeyIter *prkiAdapters=NULL; tstring strAdapterInstance; PCORegKey prkAdapters=NULL; tstring strDefaultPort;
PCORegKey prkParams=NULL; GetServiceSubkey(L"AppleTalk", L"Parameters", prkParams); if (!prkParams) goto error_cleanup;
//Write Global Parameters
// DefaultPort
prkParams->QueryValue(L"DefaultPort", strDefaultPort); WCHAR szTemp[256]; PCWSTR pszNetCardAFileName; if ((swscanf(strDefaultPort.c_str(), L"\\Device\\%s", szTemp) == 1) && ((pszNetCardAFileName = MapNetCardInstanceToAFileName(szTemp)) != NULL)) { pwisGlobalParams->AddKey(L"DefaultPort", pszNetCardAFileName); }
// DesiredZone
WriteRegValueToAFile(pwisGlobalParams, *prkParams, L"DesiredZone");
// EnableRouter
WriteRegValueToAFile(pwisGlobalParams, *prkParams, L"EnableRouter", REG_BOOL, NULL, // dont change value name
TRUE, // use default
(BOOL) FALSE); // default value
//Write Adapter specific parameters
GetServiceSubkey(L"AppleTalk", L"Adapters", prkAdapters); DoErrorCleanupIf(!prkAdapters);
prkiAdapters = new CORegKeyIter(*prkAdapters); prkiAdapters->Reset();
strTemp = tstring(c_szAfParams) + c_szInfId_MS_AppleTalk + L"."; while (!prkiAdapters->Next(&strAdapterInstance)) { ContinueIf(strAdapterInstance.empty());
CORegKey rkAdapterInstance(*prkAdapters, strAdapterInstance.c_str());
PCWSTR pszNetCardAFileName = MapNetCardInstanceToAFileName(strAdapterInstance.c_str()); ContinueIf(!pszNetCardAFileName);
tstring strAdapterParamsSection = strTemp + pszNetCardAFileName; AddAtEndOfStringList(slAdditionalParamsSections, strAdapterParamsSection);
PCWInfSection pwisAdapterParams; pwisAdapterParams = pwifAnswerFile->AddSection(strAdapterParamsSection.c_str());
//SpecificTo
pwisAdapterParams->AddKey(c_szAfSpecificTo, pszNetCardAFileName);
// DefaultZone
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"DefaultZone");
// NetworkRangeLowerEnd
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"NetworkRangeLowerEnd", REG_DWORD);
// NetworkRangeUpperEnd
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"NetworkRangeUpperEnd", REG_DWORD);
// PortName
//
//$ REVIEW kumarp 24-May-97
// the value is of the form ieepro2@kumarp1
// this may need to be changed to Adapter03@kumarp1
//
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"PortName");
// SeedingNetwork
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"SeedingNetwork", REG_DWORD, NULL, // dont change value name
TRUE, // use default
(DWORD) 0); // default value
// ZoneList
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"ZoneList", REG_MULTI_SZ);
}
fStatus = TRUE; goto cleanup;
error_cleanup: fStatus = FALSE;
cleanup: DeleteIfNotNull(prkParams); DeleteIfNotNull(prkAdapters); DeleteIfNotNull(prkiAdapters);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: WritePPTPParams
//
// Purpose: Write parameters of PPTP protocol
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] pointer to global params section
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 11-December-97
//
BOOL WritePPTPParams ( PCWInfFile pwifAnswerFile, PCWInfSection pwisParams) { DefineFunctionName("WritePPTPParams");
TraceFunctionEntry(ttidNetUpgrade);
//NumberLineDevices
WriteServiceRegValueToAFile(pwisParams, L"RASPPTPE\\Parameters\\Configuration", L"NumberLineDevices", REG_DWORD);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteIPXParams
//
// Purpose: Write parameters of IPX protocol
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisIPXGlobalParams [in] pointer to global params section
// slAdditionalParamsSections [out] list of adapter params sections
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 11-December-97
//
BOOL WriteIPXParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisIPXGlobalParams, OUT TStringList& slAdditionalParamsSections) { DefineFunctionName("WriteIPXParams");
TraceFunctionEntry(ttidNetUpgrade);
BOOL fStatus=FALSE;
tstring strTemp; CORegKeyIter *prkiNetConfig=NULL;
//InternalNetworkNumber
WriteServiceRegValueToAFile(pwisIPXGlobalParams, L"NwlnkIpx\\Parameters", L"VirtualNetworkNumber", REG_HEX, c_szAfInternalNetworkNumber);
// DedicatedRouter
WriteServiceRegValueToAFile(pwisIPXGlobalParams, L"NwlnkIpx\\Parameters", L"DedicatedRouter", REG_BOOL, NULL, // dont change value name
TRUE, // use default
(BOOL) FALSE); // default value
// EnableWANRouter
WriteServiceRegValueToAFile(pwisIPXGlobalParams, L"NwlnkIpx\\Parameters", L"EnableWANRouter", REG_BOOL, NULL, // dont change value name
TRUE, // use default
TRUE); // default value
// RipRoute
WriteServiceRegValueToAFile(pwisIPXGlobalParams, L"NwlnkIpx\\Parameters", L"RipRoute", REG_DWORD);
// ------------------------------------------------------------------------------
//Write Adapter specific parameters
tstring strAdapterInstance; PCORegKey prkNetConfig=NULL; GetServiceSubkey(L"NwlnkIpx", L"NetConfig", prkNetConfig); if (!prkNetConfig) goto error_cleanup;
prkiNetConfig = new CORegKeyIter(*prkNetConfig); prkiNetConfig->Reset();
strTemp = tstring(c_szAfParams) + c_szInfId_MS_NWIPX + L"."; while (!prkiNetConfig->Next(&strAdapterInstance)) { ContinueIf(strAdapterInstance.empty());
CORegKey rkAdapterInstance(*prkNetConfig, strAdapterInstance.c_str());
PCWSTR pszNetCardAFileName = MapNetCardInstanceToAFileName(strAdapterInstance.c_str()); ContinueIf(!pszNetCardAFileName);
tstring strAdapterParamsSection = strTemp + pszNetCardAFileName; AddAtEndOfStringList(slAdditionalParamsSections, strAdapterParamsSection);
PCWInfSection pwisAdapterParams; pwisAdapterParams = pwifAnswerFile->AddSection(strAdapterParamsSection.c_str());
//SpecificTo
pwisAdapterParams->AddKey(c_szAfSpecificTo, pszNetCardAFileName);
// PktType
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"PktType", REG_MULTI_SZ);
// MaxPktSize
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"MaxPktSize", REG_DWORD, NULL, // dont change value name
TRUE, // use default
(DWORD) 0); // default value
// NetworkNumber
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"NetworkNumber", REG_MULTI_SZ);
// BindSap
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"BindSap", REG_HEX, NULL, // dont change value name
TRUE, // use default
(DWORD) 0x8137); // default value
// EnableFuncAddr
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"EnableFuncaddr", REG_BOOL, NULL, // dont change value name
TRUE, // use default
TRUE); // default value
// SourceRouteDef
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"SourceRouteDef", REG_DWORD, NULL, // dont change value name
TRUE, // use default
(DWORD) 0); // default value
// SourceRouteMcast
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"SourceRouteMcast", REG_BOOL, NULL, // dont change value name
TRUE, // use default
(BOOL) FALSE); // default value
// SourceRouting
WriteRegValueToAFile(pwisAdapterParams, rkAdapterInstance, L"SourceRouting", REG_BOOL, NULL, // dont change value name
TRUE, // use default
(BOOL) FALSE); // default value
strAdapterInstance.erase(); }
fStatus=TRUE; goto cleanup;
error_cleanup: fStatus=FALSE;
cleanup: // DeleteIfNotNull(prkParams);
DeleteIfNotNull(prkNetConfig); DeleteIfNotNull(prkiNetConfig);
return fStatus; }
static const WCHAR c_szRegKeyRas[] = L"Software\\Microsoft\\RAS"; static const WCHAR c_szRegKeyRasMan[] = L"System\\CurrentControlSet\\Services\\Rasman\\PPP"; static const WCHAR c_szRegKeyRasManSH[] = L"System\\CurrentControlSet\\Services\\Rasman\\PPP\\COMPCP"; static const WCHAR c_szRegKeyUnimodem[] = L"TAPI DEVICES\\Unimodem"; static const WCHAR c_szAddress[] = L"Address"; static const WCHAR c_szUsage[] = L"Usage";
// ----------------------------------------------------------------------
//
// Function: HrGetRasPortsInfo
//
// Purpose: Find out ports' usage info from registry.
// If the registry does not have this info (in case of NT3.51)
// then try to get it from serial.ini file
//
// Arguments:
// pslPorts [out] list of ports
// pslUsage [out] usage of ports in the above list
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
HRESULT HrGetRasPortsInfo ( OUT TStringList* pslPorts, OUT TStringList* pslUsage) { DefineFunctionName("HrGetRasPortsInfo");
HRESULT hr=S_OK;
HKEY hkeyUnimodem; tstring strUnimodem; strUnimodem = c_szRegKeyRas; strUnimodem += '\\'; strUnimodem += c_szRegKeyUnimodem;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, strUnimodem.c_str(), KEY_READ, &hkeyUnimodem); if (S_OK == hr) { hr = HrRegQueryColString(hkeyUnimodem, c_szAddress, pslPorts); if (S_OK == hr) { hr = HrRegQueryColString(hkeyUnimodem, c_szUsage, pslUsage); } }
if (pslPorts->empty()) { TraceTag(ttidNetUpgrade, "%s: there are no entries found under %S", __FUNCNAME__, strUnimodem.c_str()); TraceTag(ttidNetUpgrade, "%s: trying to get port usage info from serial.ini file", __FUNCNAME__);
HINF hinf; tstring strSerialIni; hr = HrGetWindowsDir(&strSerialIni); if (S_OK == hr) { static const WCHAR c_szSystem32SerialIni[] = L"\\system32\\ras\\serial.ini"; strSerialIni += c_szSystem32SerialIni;
hr = HrSetupOpenInfFile(strSerialIni.c_str(), NULL, INF_STYLE_OLDNT, NULL, &hinf); if (S_OK == hr) { tstring strUsage; WCHAR szPortName[16]; INFCONTEXT ic;
for (int i=1; i<=255; i++) { swprintf(szPortName, L"COM%d", i);
hr = HrSetupFindFirstLine(hinf, szPortName, c_szUsage, &ic); if (S_OK == hr) { hr = HrSetupGetStringField(ic, 1, &strUsage); if (S_OK == hr) { TraceTag(ttidNetUpgrade, "%s: as per serial.ini file: %S --> %S", __FUNCNAME__, szPortName, strUsage.c_str()); pslPorts->push_back(new tstring(szPortName)); pslUsage->push_back(new tstring(strUsage.c_str())); } } }
hr = S_OK; SetupCloseInfFile(hinf); } } }
TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: ConvertIpAddrRangeToAddrAndMask
//
// Purpose: Convert a range of IP addr specified using Start/End to
// equivalent Start+Mask combination
//
// Arguments:
// pszIpBegin [in] Start addr
// pszIpEnd [in] End addr
// pstrIpAddr [out] pointer to Start addr
// pstrIpMask [out] pointer to Mask
//
// Returns: None
//
// Author: kumarp 27-April-98
//
void ConvertIpAddrRangeToAddrAndMask( IN PCWSTR pszIpBegin, IN PCWSTR pszIpEnd, OUT tstring* pstrIpAddr, OUT tstring* pstrIpMask) { WCHAR szBuf[16];
DWORD dwIpBegin = IpPszToHostAddr(pszIpBegin); DWORD dwIpEnd = IpPszToHostAddr(pszIpEnd);
// dwTemp will have a bit set for each common bit between
// dwIpBegin and dwIpEnd.
//
DWORD dwTemp = ~(dwIpBegin ^ dwIpEnd);
// Compute the subnet mask as the longest run of 1s from
// the highest order down.
//
DWORD dwIpMask = 0; while (dwTemp & 0x80000000) { dwTemp <<= 1; // Eventually shifts a zero to the high bit
// so the loop will stop.
// Form the mask by shifting 1 right from the high bit.
dwIpMask = 0x80000000 | (dwIpMask >> 1); }
// Reset the begin address (if needed) to the base of the subnet mask.
//
dwIpBegin &= dwIpMask;
IpHostAddrToPsz(dwIpBegin, szBuf); *pstrIpAddr = szBuf;
IpHostAddrToPsz(dwIpMask, szBuf); *pstrIpMask = szBuf; }
// ----------------------------------------------------------------------
//
// Function: ConvertAddrAndMaskToIpAddrRange
//
// Purpose: Convert a IP address Start + Mask combination into the
// equivalent IP address range
//
// Arguments:
// pszIpAddr [in] Start
// pszIpMask [in] Mask
// pstrIpBegin [out] pointer to Start addr
// pstrIpEnd [out] pointer to End addr
//
// Returns: None
//
// Author: SumitC 28-Jul-99
//
void ConvertAddrAndMaskToIpAddrRange( IN PCWSTR pszIpAddr, IN PCWSTR pszIpMask, OUT tstring* pstrIpBegin, OUT tstring* pstrIpEnd) { WCHAR szBuf[16];
DWORD dwIpBegin = IpPszToHostAddr(pszIpAddr);
// dwEnd is generated by inverting the mask and adding to IpBegin
//
DWORD dwIpEnd = dwIpBegin + (~ IpPszToHostAddr(pszIpMask));
*pstrIpBegin = pszIpAddr;
IpHostAddrToPsz(dwIpEnd, szBuf); *pstrIpEnd = szBuf; }
//+---------------------------------------------------------------------------
//
// Function: RasGetDialInUsage
//
// Purpose: Find out if at least one RAS port is configured for dialin.
//
// Returns: TRUE if at least one port configured for dial in.
//
// Author: kumarp 28-January-99
//
BOOL RasGetDialInUsage (VOID) { static const WCHAR c_szTapiDevices[] = L"Software\\Microsoft\\RAS\\TAPI DEVICES"; HRESULT hr=S_OK; HKEY hkeyTapiDevices; HKEY hkeyTapiDevice;
BOOL fAtLeastOneDialin = FALSE;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szTapiDevices, KEY_READ, &hkeyTapiDevices); if (S_OK == hr) { WCHAR szBuf[MAX_PATH]; FILETIME time; DWORD dwSize; DWORD dwRegIndex;
for (dwRegIndex = 0, dwSize = celems(szBuf); !fAtLeastOneDialin && (S_OK == HrRegEnumKeyEx(hkeyTapiDevices, dwRegIndex, szBuf, &dwSize, NULL, NULL, &time)); dwRegIndex++, dwSize = celems(szBuf)) { Assert(*szBuf);
hr = HrRegOpenKeyEx(hkeyTapiDevices, szBuf, KEY_READ, &hkeyTapiDevice); if (S_OK == hr) { PWSTR pmszUsage;
hr = HrRegQueryMultiSzWithAlloc(hkeyTapiDevice, c_szUsage, &pmszUsage); if ((S_OK == hr) && pmszUsage) { PCWSTR pszScan;
for (pszScan = pmszUsage; *pszScan; pszScan += wcslen(pszScan) + 1) { if (FIsSubstr(c_szServer, pszScan) || FIsSubstr(c_szRouter, pszScan)) { fAtLeastOneDialin = TRUE; break; } }
MemFree(pmszUsage); }
RegCloseKey(hkeyTapiDevice); } }
RegCloseKey(hkeyTapiDevices); }
return fAtLeastOneDialin; }
//+---------------------------------------------------------------------------
//
// Function: WriteRouterUpgradeInfo
//
// Purpose: Write info required for upgrading Router to answerfile.
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: None
//
// Author: kumarp 16-June-98
//
void WriteRouterUpgradeInfo ( IN CWInfFile* pwifAnswerFile) { DefineFunctionName("HrWriteRouterUpgradeInfo");
TraceTag(ttidNetUpgrade, "-----> entering %s", __FUNCNAME__);
tstring strParamsSectionName; CWInfSection* pwisNetServices; CWInfSection* pwisRouter;
strParamsSectionName = c_szAfParams; strParamsSectionName = strParamsSectionName + L"ms_rasrtr";
pwisNetServices = pwifAnswerFile->FindSection(c_szAfSectionNetServices);
AssertSz(pwisNetServices, "No [NetServices] section ??");
pwisNetServices->AddKey(L"ms_rasrtr", strParamsSectionName.c_str()); pwisRouter = pwifAnswerFile->AddSection(strParamsSectionName.c_str()); pwisRouter->AddKey(c_szAfInfid, L"ms_rasrtr"); pwisRouter->AddKey(c_szAfParamsSection, strParamsSectionName.c_str());
(void) HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcRouter, NULL, c_szAfPreUpgradeRouter, pwisRouter);
(void) HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcSapAgent, c_szParameters, c_szAfNwSapAgentParams, pwisRouter);
(void) HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcRipForIp, c_szParameters, c_szAfIpRipParameters, pwisRouter);
(void) HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcDhcpRelayAgent, c_szParameters, c_szAfDhcpRelayAgentParameters, pwisRouter);
(void) HrNetRegSaveKeyAndAddToSection(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Ras\\Radius", L"Radius", c_szAfRadiusParameters, pwisRouter); }
// ----------------------------------------------------------------------
//
// Function: WriteRASParams
//
// Purpose: Write RAS parameters to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisNetServices [in] pointer to NetServices section
// pwisParams [in] pointer to global params section
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 11-December-97
//
BOOL WriteRASParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisNetServices, IN PCWInfSection pwisParams) { DefineFunctionName("WriteRASParams");
TraceFunctionEntry(ttidNetUpgrade);
PCORegKey prkRAS = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegKeyRas); PCORegKey prkProtocols = new CORegKey(*prkRAS, L"Protocols");
if(!prkRAS || !prkProtocols) { return false; }
WriteRegValueToAFile(pwisParams, *prkProtocols, c_szAfRouterType, REG_DWORD);
TStringList slPorts, slUsage, slTemp; tstring strPorts, strValue, strTemp, strPortSections; tstring strIpAddrStart; tstring strIpAddrEnd; DWORD dwValue=0; BOOL fSteelHeadInstalled=FALSE; HRESULT hr=S_OK; LONG err;
// find out if SteelHead is installed.
// if the service "Router" is found --> SteelHead is installed
fSteelHeadInstalled = FIsServiceKeyPresent(c_szSvcRouter);
PCWInfSection pwisPort;
(void) HrGetRasPortsInfo(&slPorts, &slUsage);
TStringListIter pos1 = slPorts.begin(); TStringListIter pos2 = slUsage.begin(); //Write parameters for each port
while ((pos1 != slPorts.end()) && (pos2 != slUsage.end())) { strValue = **pos1++; strTemp = c_szAfParams; strTemp += strValue; if (!strPortSections.empty()) strPortSections += c_szAfListDelimiter; strPortSections += strTemp;
pwisPort = pwifAnswerFile->AddSection(strTemp.c_str());
//PortName
pwisPort->AddKey(c_szAfPortname, strValue.c_str());
//PortUsage
strValue = **pos2++; //MapPortUsageRegValueToAFileValue(strValue, strValue);
pwisPort->AddKey(c_szAfPortUsage, strValue.c_str());
//this decides what we need to install
// i.e a combination of MS_RasCli / MS_RasSrv
//
if (wcsstr(strValue.c_str(), L"Client")) { TraceTag(ttidNetUpgrade, "%s: g_fAtLeastOneDialOut set to TRUE because of PortUsage %S", __FUNCNAME__, strValue.c_str()); g_fAtLeastOneDialOut = TRUE; }
if (wcsstr(strValue.c_str(), c_szServer)) { TraceTag(ttidNetUpgrade, "%s: g_fAtLeastOneDialIn set to TRUE because of PortUsage %S", __FUNCNAME__, strValue.c_str()); g_fAtLeastOneDialIn = TRUE; }
}
// if the Port usage cannot be determined using the ports list
// then we need to use the values found using ndiswan ProductName
//
if (slPorts.size() == 0) { TraceTag(ttidNetUpgrade, "%s: Since PortUsage is not defined, using flags generated by inspecting ndiswan ProductName", __FUNCNAME__); g_fAtLeastOneDialIn = g_fAtLeastOneDialInUsingNdisWan; g_fAtLeastOneDialOut = g_fAtLeastOneDialOutUsingNdisWan; }
//Now write RAS Global parameters
ValueTypePair rgVtpRasParams[] = { {L"ForceEncryptedPassword", REG_DWORD}, {L"ForceEncryptedData",REG_BOOL}, {L"Multilink", REG_BOOL}};
WriteRegValueToAFile(pwisParams, *prkProtocols, rgVtpRasParams, celems(rgVtpRasParams));
//PortSections
pwisParams->AddKey(c_szAfPortSections, strPortSections.c_str());
//DialoutProtocols
err = prkProtocols->QueryValue(L"fIpxSelected", dwValue); if ((0 == err) && dwValue) { AddAtEndOfStringList(slTemp, c_szAfIpx); } err = prkProtocols->QueryValue(L"fNetbeuiSelected", dwValue); if ((0 == err) && dwValue) { AddAtEndOfStringList(slTemp, c_szAfNetbeui); } err = prkProtocols->QueryValue(L"fTcpIpSelected", dwValue); if ((0 == err) && dwValue) { AddAtEndOfStringList(slTemp, c_szAfTcpip); } if (!slTemp.empty()) pwisParams->AddKey(L"DialoutProtocols", slTemp);
//DialinProtocols
DWORD dwIpxAllowed, dwNetBEUIAllowed, dwTcpIpAllowed;
EraseAndDeleteAll(slTemp); err = prkProtocols->QueryValue(L"fIpxAllowed", dwIpxAllowed); if ((0 == err) && dwIpxAllowed) { AddAtEndOfStringList(slTemp, c_szAfIpx); } err = prkProtocols->QueryValue(L"fNetbeuiAllowed", dwNetBEUIAllowed); if ((0 == err) && dwNetBEUIAllowed) { AddAtEndOfStringList(slTemp, c_szAfNetbeui); } err = prkProtocols->QueryValue(L"fTcpIpAllowed", dwTcpIpAllowed); if ((0 == err) && dwTcpIpAllowed) { AddAtEndOfStringList(slTemp, c_szAfTcpip); } if (!slTemp.empty()) pwisParams->AddKey(L"DialinProtocols", slTemp);
if (dwNetBEUIAllowed) { //NetBEUIClientAccess
PCORegKey prkNetBEUI = new CORegKey(*prkProtocols, L"NBF"); err = prkNetBEUI->QueryValue(L"NetbiosGatewayEnabled", dwValue); if (0 == err) { if (dwValue) { pwisParams->AddKey(c_szAfNetbeuiClientAccess, c_szAfNetwork); } else { pwisParams->AddKey(c_szAfNetbeuiClientAccess, c_szAfThisComputer); } } DeleteIfNotNull(prkNetBEUI); }
if (dwTcpIpAllowed) { //TcpIpClientAccess
PCORegKey prkTcpIp = new CORegKey(*prkProtocols, L"IP"); err = prkTcpIp->QueryValue(L"AllowNetworkAccess", dwValue); if (0 == err) { if (dwValue) { pwisParams->AddKey(c_szAfTcpipClientAccess, c_szAfNetwork); } else { pwisParams->AddKey(c_szAfTcpipClientAccess, c_szAfThisComputer); } }
//UseDHCP
err = prkTcpIp->QueryValue(L"UseDHCPAddressing", dwValue); if (0 == err) { pwisParams->AddBoolKey(c_szAfUseDhcp, dwValue); if (!dwValue) { // registry values for NT4
static const WCHAR c_szIpAddressStart[] = L"IpAddressStart"; static const WCHAR c_szIpAddressEnd[] = L"IpAddressEnd";
err = prkTcpIp->QueryValue(c_szIpAddressStart, strIpAddrStart); if (0 == err) { err = prkTcpIp->QueryValue(c_szIpAddressEnd, strIpAddrEnd); if (0 == err) { pwisParams->AddKey(c_szAfIpAddressStart, strIpAddrStart.c_str()); pwisParams->AddKey(c_szAfIpAddressEnd, strIpAddrEnd.c_str()); } } else if (ERROR_FILE_NOT_FOUND == err) { // IpAddressStart value not found, try for IpAddress/Mask
static const WCHAR c_szIpAddress[] = L"IpAddress"; static const WCHAR c_szIpMask[] = L"IpMask"; tstring strIpAddr; tstring strIpMask;
err = prkTcpIp->QueryValue(c_szIpAddress, strIpAddr); if (0 == err) { err = prkTcpIp->QueryValue(c_szIpMask, strIpMask); if (0 == err) { ConvertAddrAndMaskToIpAddrRange(strIpAddr.c_str(), strIpMask.c_str(), &strIpAddrStart, &strIpAddrEnd); pwisParams->AddKey(c_szAfIpAddressStart, strIpAddrStart.c_str()); pwisParams->AddKey(c_szAfIpAddressEnd, strIpAddrEnd.c_str()); } } } } }
//ClientCanRequestIPAddress
if (0 == prkTcpIp->QueryValue(L"AllowClientIPAddresses", dwValue)) { pwisParams->AddBoolKey(c_szAfClientCanReqIpaddr, dwValue); }
DeleteIfNotNull(prkTcpIp); }
if (dwIpxAllowed) { //IpxClientAccess
PCORegKey prkIpx = new CORegKey(*prkProtocols, L"IPX"); err = prkIpx->QueryValue(L"AllowNetworkAccess", dwValue); if (0 == err) { if (dwValue) { pwisParams->AddKey(c_szAfIpxClientAccess, c_szAfNetwork); } else { pwisParams->AddKey(c_szAfIpxClientAccess, c_szAfThisComputer); } }
//AutomaticNetworkNumbers
err = prkIpx->QueryValue(L"AutoWanNetAllocation", dwValue); if (0 == err) { pwisParams->AddBoolKey(c_szAfAutoNetworkNumbers, dwValue); }
//NetworkNumberFrom
err = prkIpx->QueryValue(L"FirstWanNet", dwValue); if (0 == err) { pwisParams->AddKey(c_szAfNetNumberFrom, dwValue); }
// WanNetPoolSize
err = prkIpx->QueryValue(L"WanNetPoolSize", dwValue); if (0 == err) { pwisParams->AddKey(c_szAfWanNetPoolSize, dwValue); }
//AssignSameNetworkNumber
err = prkIpx->QueryValue(L"GlobalWanNet", dwValue); if (0 == err) { pwisParams->AddBoolKey(c_szAfSameNetworkNumber, dwValue); }
//ClientsCanRequestIpxNodeNumber
err = prkIpx->QueryValue(L"AcceptRemoteNodeNumber", dwValue); if (0 == err) { pwisParams->AddBoolKey(c_szAfClientReqNodeNumber, dwValue); }
DeleteIfNotNull(prkIpx); }
{ //SecureVPN
PCORegKey prkRasman = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegKeyRasMan);
err = prkRasman->QueryValue(L"SecureVPN", dwValue); if (0 == err) { pwisParams->AddKey(c_szAfSecureVPN, dwValue); }
//ForceStrongEncryption
// 398632: write this value, for both regular RAS case & steelhead case
dwValue = 0; // to avoid fall-thru problem (writing 0 to the answerfile is ok)
if (fSteelHeadInstalled) { err = prkRasman->QueryValue(L"ForceStrongEncryption", dwValue); } else { PCORegKey prkComPCP = new CORegKey(HKEY_LOCAL_MACHINE, c_szRegKeyRasManSH); err = prkComPCP->QueryValue(L"ForceStrongEncryption", dwValue); DeleteIfNotNull(prkComPCP); }
if (0 == err) { pwisParams->AddBoolKey(c_szAfForceStrongEncryption, dwValue); }
DeleteIfNotNull(prkRasman); }
pwifAnswerFile->GotoEnd(); tstring strParamsSectionName; PCWInfSection pwisRasComponent;
if (g_fAtLeastOneDialOut) { strParamsSectionName = c_szAfParams; strParamsSectionName = strParamsSectionName + c_szInfId_MS_RasCli; pwisNetServices->AddKey(c_szInfId_MS_RasCli, strParamsSectionName.c_str()); pwisRasComponent = pwifAnswerFile->AddSection(strParamsSectionName.c_str()); pwisRasComponent->AddKey(c_szAfInfid, c_szInfId_MS_RasCli); pwisRasComponent->AddKey(c_szAfParamsSection, pwisParams->Name()); }
if (g_fAtLeastOneDialIn) { strParamsSectionName = c_szAfParams; strParamsSectionName = strParamsSectionName + c_szInfId_MS_RasSrv; pwisNetServices->AddKey(c_szInfId_MS_RasSrv, strParamsSectionName.c_str()); pwisRasComponent = pwifAnswerFile->AddSection(strParamsSectionName.c_str()); pwisRasComponent->AddKey(c_szAfInfid, c_szInfId_MS_RasSrv); pwisRasComponent->AddKey(c_szAfParamsSection, pwisParams->Name()); }
// SetDialInUsage
BOOL fSetDialInUsage = TRUE;
if (g_NetUpgradeInfo.To.ProductType != NT_SERVER) { fSetDialInUsage = RasGetDialInUsage (); } pwisParams->AddKey(c_szAfSetDialinUsage, (UINT) fSetDialInUsage);
if (fSteelHeadInstalled) { WriteRouterUpgradeInfo(pwifAnswerFile); } else { TraceTag(ttidNetUpgrade, "%s: Router is not installed", __FUNCNAME__); }
DeleteIfNotNull(prkRAS); DeleteIfNotNull(prkProtocols);
EraseAndDeleteAll(slTemp); EraseAndDeleteAll(slPorts); EraseAndDeleteAll(slUsage);
return TRUE; } // ----------------------------------------------------------------------
//
// Function: HrWritePreSP3ComponentsToSteelHeadUpgradeParams
//
// Purpose: Write parameters of pre-SP3 steelhead components to answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 11-December-97
//
// Notes: DHCPRelayAgent, Rip for Ip(x), SapAgent --> Steelhead upgrade
//
HRESULT HrWritePreSP3ComponentsToSteelHeadUpgradeParams( IN CWInfFile* pwifAnswerFile) { DefineFunctionName("HrWritePreSP3ComponentsToSteelHeadUpgradeParams");
TraceFunctionEntry(ttidNetUpgrade);
HRESULT hr=S_OK; CWInfSection* pwisServices; pwisServices = pwifAnswerFile->FindSection(c_szAfSectionNetServices); if (!pwisServices) { hr = E_FAIL; goto return_from_function; }
if (FIsServiceKeyPresent(c_szSvcRouter)) { hr = S_OK; TraceTag(ttidNetUpgrade, "%s: SteelHead is found to be installed, individual components will not be upgraded", __FUNCNAME__); goto return_from_function; }
BOOL fSrv2SrvUpgrade; fSrv2SrvUpgrade = FALSE;
if (g_NetUpgradeInfo.From.ProductType == NT_SERVER) { if (g_NetUpgradeInfo.To.ProductType == NT_WORKSTATION) { AssertSz(FALSE, "Cannot upgrade from srv to wks!!"); } else if (g_NetUpgradeInfo.To.ProductType == NT_SERVER) { fSrv2SrvUpgrade = TRUE; } }
BOOL fInstallSteelHead; BOOL fInstallSapAgent;
fInstallSteelHead = FALSE; fInstallSapAgent = FALSE;
BOOL fSapAgentInstalled; BOOL fRipForIpInstalled; BOOL fRipForIpxInstalled; BOOL fDhcpRelayAgentInstalled;
fSapAgentInstalled = FALSE; fRipForIpInstalled = FALSE; fRipForIpxInstalled = FALSE; fDhcpRelayAgentInstalled = FALSE;
// first find out which components are installed.
//
fSapAgentInstalled = FIsServiceKeyPresent(c_szSvcSapAgent); fRipForIpInstalled = FIsServiceKeyPresent(c_szSvcRipForIp); fRipForIpxInstalled = FIsServiceKeyPresent(c_szSvcRipForIpx); fDhcpRelayAgentInstalled = FIsServiceKeyPresent(c_szSvcDhcpRelayAgent);
#ifdef ENABLETRACE
if (fSapAgentInstalled) { TraceTag(ttidNetUpgrade, "%s: %S is installed", __FUNCNAME__, c_szSvcSapAgent); }
if (fRipForIpInstalled) { TraceTag(ttidNetUpgrade, "%s: %S is installed", __FUNCNAME__, c_szSvcRipForIp); }
if (fRipForIpxInstalled) { TraceTag(ttidNetUpgrade, "%s: %S is installed", __FUNCNAME__, c_szSvcRipForIpx); }
if (fDhcpRelayAgentInstalled) { TraceTag(ttidNetUpgrade, "%s: %S is installed", __FUNCNAME__, c_szSvcDhcpRelayAgent); } #endif
// now separate out cases to consider
//
if (fSapAgentInstalled && !(fRipForIpxInstalled || fRipForIpInstalled || fDhcpRelayAgentInstalled)) { fInstallSapAgent = TRUE; } else if (fRipForIpInstalled && !(fRipForIpxInstalled || fSapAgentInstalled || fDhcpRelayAgentInstalled)) { if (fSrv2SrvUpgrade) { fInstallSteelHead = TRUE; } } else if ((fRipForIpInstalled && fSapAgentInstalled) && !(fRipForIpxInstalled || fDhcpRelayAgentInstalled)) { if (fSrv2SrvUpgrade) { fInstallSteelHead = TRUE; } else { fInstallSapAgent = TRUE; } } else if (fRipForIpxInstalled || fDhcpRelayAgentInstalled) { fInstallSteelHead = TRUE; } else { TraceTag(ttidNetUpgrade, "%s: no pre-SP3 steelhead components found", __FUNCNAME__); }
AssertSz(!(fInstallSapAgent && fInstallSteelHead), "Both fInstallSteelHead && fInstallSapAgent cannot be TRUE");
// now go ahead and output the right information for the right case
// in the answerfile
//
if (fInstallSteelHead) { TraceTag(ttidNetUpgrade, "%s: The component(s) found will be upgraded to SteelHead", __FUNCNAME__);
WriteRouterUpgradeInfo(pwifAnswerFile); } else if (fInstallSapAgent) { TraceTag(ttidNetUpgrade, "%s: dumping data to upgrade SAP agent", __FUNCNAME__);
CWInfSection* pwisServices; pwisServices = pwifAnswerFile->FindSection(c_szAfSectionNetServices); AssertSz(pwisServices, "[NetServices] section missing!!");
if (pwisServices) { tstring strSapSection; strSapSection = c_szAfParams; strSapSection += c_szInfId_MS_NwSapAgent;
CWInfSection* pwisSap; pwisSap = pwifAnswerFile->AddSection(strSapSection.c_str()); if (pwisSap) { pwisServices->AddKey(c_szInfId_MS_NwSapAgent, strSapSection.c_str()); (void) HrNetRegSaveServiceSubKeyAndAddToSection( c_szSvcSapAgent, c_szParameters, c_szAfNwSapAgentParams, pwisSap); } } }
return_from_function: TraceError(__FUNCNAME__, hr);
return hr; }
// ----------------------------------------------------------------------
//
// Function: WriteNetBIOSParams
//
// Purpose: Write parameters of NetBIOS to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write this info
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteNetBIOSParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteNetBIOSParams");
TraceFunctionEntry(ttidNetUpgrade);
PCORegKey prkLinkage;
// The netbios section will be used to apply lana config but since
// MSClient installs NetBIOS we don't want to install it
// via the answerfilein GUI mode.
//
pwisParams->AddBoolKey(c_szAfSkipInstall, TRUE);
GetServiceSubkey(c_szSvcNetBIOS, c_szLinkage, prkLinkage); if (!prkLinkage) return FALSE;
TStringList slRoutes, slRoute, slLanaPath; tstring strRoute, strLanaPath, strTemp; TStringListIter iter; TByteArray baLanaMap;
prkLinkage->QueryValue(L"LanaMap", baLanaMap);
BYTE* pbData=NULL;
if (baLanaMap.size() > 0) { GetDataFromByteArray(baLanaMap, pbData);
WORD* pwLanaCodes; WORD wLanaNumber; WORD wRouteNum;
pwLanaCodes = (WORD *) pbData;
prkLinkage->QueryValue(c_szRegValRoute, slRoutes);
iter = slRoutes.begin(); wRouteNum=0;
while (iter != slRoutes.end()) { strRoute = **iter++; TraceTag(ttidNetUpgrade, "%s: processing: %S", __FUNCNAME__, strRoute.c_str());
EraseAndDeleteAll(slLanaPath); ConvertRouteToStringList(strRoute.c_str(), slRoute); TStringListIter pos2 = slRoute.begin(); while (pos2 != slRoute.end()) { strTemp = **pos2++; TraceTag(ttidNetUpgrade, "%s: route component: %S", __FUNCNAME__, strTemp.c_str()); if (IsNetCardProductName(strTemp.c_str())) continue; MapNetComponentNameForBinding(strTemp.c_str(), strTemp); AddAtEndOfStringList(slLanaPath, strTemp.c_str());
// Stop adding components if the last one soesn't
// expose its lower components.
if (FIsDontExposeLowerComponent (strTemp.c_str())) { break; } }
// Note: The following must be written out exactly!!! The
// consumer of this information expects each LanaPath key to be
// followed by the corresponding LanaNumber key.
//
TraceStringList(ttidNetUpgrade, L"LanaPath: ", slLanaPath); pwisParams->AddKey(L"LanaPath", slLanaPath);
wLanaNumber = HIBYTE (pwLanaCodes[wRouteNum]);
TraceTag(ttidNetUpgrade, "%s: LanaNumber: 0x%x", __FUNCNAME__, wLanaNumber); pwisParams->AddHexKey(L"LanaNumber", wLanaNumber);
wRouteNum++; } pwisParams->AddKey (L"NumberOfPaths", wRouteNum); } else { TraceTag(ttidNetUpgrade, "%s: LanaMap has no entries!!, skipped LanaMap dump", __FUNCNAME__); }
DeleteIfNotNull(prkLinkage);
EraseAndDeleteAll(slRoute); EraseAndDeleteAll(slRoutes); EraseAndDeleteAll(slLanaPath);
delete pbData;
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteDhcpServerParams
//
// Purpose: Write parameters of DHCPServer to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteDhcpServerParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteDhcpServerParams");
TraceFunctionEntry(ttidNetUpgrade);
static const WCHAR c_szConfiguration[] = L"Configuration";
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcDhcpServer, c_szParameters, c_szAfDhcpServerParameters, pwisParams);
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcDhcpServer, c_szConfiguration, c_szAfDhcpServerConfiguration, pwisParams);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteTp4Params
//
// Purpose: Write parameters of Tp4 to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 01-October-98
//
BOOL WriteTp4Params ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { static const WCHAR c_szCLNP[] = L"IsoTp\\Parameters\\CLNP"; static const WCHAR c_szLocalMachineName[] = L"LocalMachineName"; static const WCHAR c_szLocalMachineNSAP[] = L"LocalMachineNSAP";
WriteServiceRegValueToAFile(pwisParams, c_szCLNP, c_szLocalMachineName); WriteServiceRegValueToAFile(pwisParams, c_szCLNP, c_szLocalMachineNSAP);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function:WriteWLBSParams
//
// Purpose: Write parameters of WLBS (windows load balancing service)
// to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: SumitC 04-Mar-99 created
//
BOOL WriteWLBSParams( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteWLBSParams");
TraceFunctionEntry(ttidNetUpgrade);
/* We should get here only for upgrades from NT4 or earlier */ Assert (g_NetUpgradeInfo.From.dwBuildNumber); Assert (g_NetUpgradeInfo.From.dwBuildNumber <= wWinNT4BuildNumber);
HRESULT hr = S_OK;
static const struct { PCWSTR szName; WORD wType; } aParams[] = { { CVY_NAME_VERSION, CVY_TYPE_VERSION }, { CVY_NAME_DED_IP_ADDR, CVY_TYPE_DED_IP_ADDR }, { CVY_NAME_DED_NET_MASK, CVY_TYPE_DED_NET_MASK }, { CVY_NAME_HOST_PRIORITY, CVY_TYPE_HOST_PRIORITY }, { CVY_NAME_NETWORK_ADDR, CVY_TYPE_NETWORK_ADDR }, { CVY_NAME_CL_IP_ADDR, CVY_TYPE_CL_IP_ADDR }, { CVY_NAME_CL_NET_MASK, CVY_TYPE_CL_NET_MASK }, { CVY_NAME_CLUSTER_MODE, CVY_TYPE_CLUSTER_MODE }, { CVY_NAME_ALIVE_PERIOD, CVY_TYPE_ALIVE_PERIOD }, { CVY_NAME_ALIVE_TOLER, CVY_TYPE_ALIVE_TOLER }, { CVY_NAME_NUM_ACTIONS, CVY_TYPE_NUM_ACTIONS }, { CVY_NAME_NUM_PACKETS, CVY_TYPE_NUM_PACKETS }, { CVY_NAME_NUM_SEND_MSGS, CVY_TYPE_NUM_SEND_MSGS }, { CVY_NAME_DOMAIN_NAME, CVY_TYPE_DOMAIN_NAME }, { CVY_NAME_LICENSE_KEY, CVY_TYPE_LICENSE_KEY }, { CVY_NAME_RMT_PASSWORD, CVY_TYPE_RMT_PASSWORD }, { CVY_NAME_RCT_PASSWORD, CVY_TYPE_RCT_PASSWORD }, { CVY_NAME_RCT_PORT, CVY_TYPE_RCT_PORT }, { CVY_NAME_RCT_ENABLED, CVY_TYPE_RCT_ENABLED }, { CVY_NAME_NUM_RULES, CVY_TYPE_NUM_RULES }, { CVY_NAME_CUR_VERSION, CVY_TYPE_CUR_VERSION }, { CVY_NAME_PORT_RULES, CVY_TYPE_PORT_RULES }, { CVY_NAME_DSCR_PER_ALLOC, CVY_TYPE_DSCR_PER_ALLOC }, { CVY_NAME_MAX_DSCR_ALLOCS,CVY_TYPE_MAX_DSCR_ALLOCS }, { CVY_NAME_SCALE_CLIENT, CVY_TYPE_SCALE_CLIENT }, { CVY_NAME_CLEANUP_DELAY, CVY_TYPE_CLEANUP_DELAY }, { CVY_NAME_NBT_SUPPORT, CVY_TYPE_NBT_SUPPORT }, { CVY_NAME_MCAST_SUPPORT, CVY_TYPE_MCAST_SUPPORT }, { CVY_NAME_MCAST_SPOOF, CVY_TYPE_MCAST_SPOOF }, { CVY_NAME_MASK_SRC_MAC, CVY_TYPE_MASK_SRC_MAC }, { CVY_NAME_CONVERT_MAC, CVY_TYPE_CONVERT_MAC }, };
// Verify that we have the name of the adapter to which NLB should be bound
if (0 == pszWlbsClusterAdapterName[0]) { hr = E_UNEXPECTED; }
if (SUCCEEDED(hr)) { static const WCHAR c_szWLBSParams[] = L"WLBS\\Parameters"; tstring szSectionName = pwisParams->Name(); // Adapter01 is hardcoded is for an NT4 to Whistler upgrade, we will always only have one WLBS adapter
szSectionName += L".Adapter01"; pwisParams->AddKey(c_szAfAdapterSections, szSectionName.c_str()); PCWInfSection pWlbsAdapterSection = pwifAnswerFile->AddSection(szSectionName.c_str()); if (!pWlbsAdapterSection) { hr = E_FAIL; }
if (SUCCEEDED(hr)) { pWlbsAdapterSection->AddKey(c_szAfSpecificTo, pszWlbsClusterAdapterName);
for (UINT i = 0 ; i < celems(aParams); ++i) { WriteServiceRegValueToAFile(pWlbsAdapterSection, c_szWLBSParams, aParams[i].szName, aParams[i].wType); } } } if (FAILED(hr)) { TraceError("WriteWLBSParams", hr ); }
return SUCCEEDED(hr);
}
// ----------------------------------------------------------------------
//
// Function:WriteConvoyParams
//
// Purpose: Write parameters of Convoy (windows load balancing service)
// to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: SumitC 04-Mar-99 created
//
BOOL WriteConvoyParams( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteConvoyParams");
TraceFunctionEntry(ttidNetUpgrade);
HRESULT hr = S_OK;
static const struct { PCWSTR szName; WORD wType; } aParams[] = { { CVY_NAME_VERSION, CVY_TYPE_VERSION }, { CVY_NAME_DED_IP_ADDR, CVY_TYPE_DED_IP_ADDR }, { CVY_NAME_DED_NET_MASK, CVY_TYPE_DED_NET_MASK }, { CVY_NAME_HOST_PRIORITY, CVY_TYPE_HOST_PRIORITY }, { CVY_NAME_NETWORK_ADDR, CVY_TYPE_NETWORK_ADDR }, { CVY_NAME_CL_IP_ADDR, CVY_TYPE_CL_IP_ADDR }, { CVY_NAME_CL_NET_MASK, CVY_TYPE_CL_NET_MASK }, { CVY_NAME_CLUSTER_MODE, CVY_TYPE_CLUSTER_MODE }, { CVY_NAME_ALIVE_PERIOD, CVY_TYPE_ALIVE_PERIOD }, { CVY_NAME_ALIVE_TOLER, CVY_TYPE_ALIVE_TOLER }, { CVY_NAME_NUM_ACTIONS, CVY_TYPE_NUM_ACTIONS }, { CVY_NAME_NUM_PACKETS, CVY_TYPE_NUM_PACKETS }, { CVY_NAME_NUM_SEND_MSGS, CVY_TYPE_NUM_SEND_MSGS }, { CVY_NAME_DOMAIN_NAME, CVY_TYPE_DOMAIN_NAME }, { CVY_NAME_LICENSE_KEY, CVY_TYPE_LICENSE_KEY }, { CVY_NAME_RMT_PASSWORD, CVY_TYPE_RMT_PASSWORD }, { CVY_NAME_RCT_PASSWORD, CVY_TYPE_RCT_PASSWORD }, { CVY_NAME_RCT_PORT, CVY_TYPE_RCT_PORT }, { CVY_NAME_RCT_ENABLED, CVY_TYPE_RCT_ENABLED }, { CVY_NAME_NUM_RULES, CVY_TYPE_NUM_RULES }, { CVY_NAME_CUR_VERSION, CVY_TYPE_CUR_VERSION }, { CVY_NAME_PORT_RULES, CVY_TYPE_PORT_RULES }, { CVY_NAME_DSCR_PER_ALLOC, CVY_TYPE_DSCR_PER_ALLOC }, { CVY_NAME_MAX_DSCR_ALLOCS,CVY_TYPE_MAX_DSCR_ALLOCS }, { CVY_NAME_SCALE_CLIENT, CVY_TYPE_SCALE_CLIENT }, { CVY_NAME_CLEANUP_DELAY, CVY_TYPE_CLEANUP_DELAY }, { CVY_NAME_NBT_SUPPORT, CVY_TYPE_NBT_SUPPORT }, { CVY_NAME_MCAST_SUPPORT, CVY_TYPE_MCAST_SUPPORT }, { CVY_NAME_MCAST_SPOOF, CVY_TYPE_MCAST_SPOOF }, { CVY_NAME_MASK_SRC_MAC, CVY_TYPE_MASK_SRC_MAC }, { CVY_NAME_CONVERT_MAC, CVY_TYPE_CONVERT_MAC }, }; static const WCHAR c_szConvoyParams[] = L"Convoy\\Parameters";
for (UINT i = 0 ; i < celems(aParams); ++i) { WriteServiceRegValueToAFile(pwisParams, c_szConvoyParams, aParams[i].szName, aParams[i].wType); }
return SUCCEEDED(hr);
}
// ----------------------------------------------------------------------
//
// Function: WriteNWCWorkstationParams
//
// Purpose: Write parameters of Netware Client to the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteNWCWorkstationParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteNWCWorkstationParams");
TraceFunctionEntry(ttidNetUpgrade);
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcNWCWorkstation, c_szParameters, c_szAfNWCWorkstationParameters, pwisParams);
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcNWCWorkstation, c_szShares, c_szAfNWCWorkstationShares, pwisParams); HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcNWCWorkstation, c_szDrives, c_szAfNWCWorkstationDrives, pwisParams);
return TRUE;
// we want to retain this code till jeffspr makes up his mind
//
/* PCORegKey prkParams;
PCWInfSection pwisLogonInfo; tstring strId;
GetServiceParamsKey(c_szSvcNWCWorkstation, prkParams); if (!prkParams) return FALSE;
CORegKey rkLogon(*prkParams, L"Logon"); CORegKey rkOption(*prkParams, L"Option"); //CORegKeyIter rkiLogon(rkLogon);
CORegKeyIter rkiOption(rkOption);
while (!rkiOption.Next(&strId)) { CORegKey rkId(rkLogon, strId.c_str()); ContinueIf(!rkId.HKey());
TByteArray abLogonID; rkId.QueryValue(L"LogonID", abLogonID); QWORD qwLogonID = ConvertToQWord(abLogonID);
pwisParams->AddKey(L"LogonInfo", strId.c_str()); pwisLogonInfo = pwifAnswerFile->AddSection(strId.c_str()); ContinueIf(!pwisParams);
CORegKey rkOptionLogonId(rkOption, strId.c_str()); if (!rkOption.HKey()) { continue; }
// LogonId
pwisLogonInfo->AddQwordKey(L"LogonID", qwLogonID);
// LogonScript
WriteRegValueToAFile(pwisLogonInfo, rkOptionLogonId, L"LogonScript", REG_DWORD, NULL, TRUE, (DWORD) 0);
// PreferredServer
WriteRegValueToAFile(pwisLogonInfo, rkOptionLogonId, L"PreferredServer");
// PrintOption
WriteRegValueToAFile(pwisLogonInfo, rkOptionLogonId, L"PrintOption", REG_DWORD); }
return TRUE; */ }
// ----------------------------------------------------------------------
//
// Function: WriteBrowserParams
//
// Purpose: Write parameters of Browser to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteBrowserParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteBrowserParams");
TraceFunctionEntry(ttidNetUpgrade);
PCORegKey prkParams; //Browser stores its parameters under the LanmanWorkstation key!
GetServiceParamsKey(c_szSvcWorkstation, prkParams);
TStringList slDomains;
prkParams->QueryValue(L"OtherDomains", slDomains); pwisParams->AddKey(c_szAfBrowseDomains, slDomains);
DeleteIfNotNull(prkParams);
// now write reg-dump keys
tstring strFileName; tstring strServices = c_szRegKeyServices; strServices += L"\\";
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcBrowser, c_szParameters, c_szAfBrowserParameters, pwisParams);
HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcNetLogon, c_szParameters, c_szAfNetLogonParameters, pwisParams);
EraseAndDeleteAll(slDomains);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteLanmanServerParams
//
// Purpose: Write parameters of LanmanServer to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteLanmanServerParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteLanmanServerParams");
TraceFunctionEntry(ttidNetUpgrade);
PCORegKey prkParams; static const WCHAR c_szShares[] = L"Shares"; static const WCHAR c_szAutotunedParameters[] = L"AutotunedParameters"; static const WCHAR c_szMemoryManagement[] = L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management"; static const WCHAR c_szLargeSystemCache[] = L"LargeSystemCache";
GetServiceParamsKey(c_szSvcLmServer, prkParams);
DWORD dwValue=3; HRESULT hr=S_OK;
//Optimization
prkParams->QueryValue(L"Size", dwValue); if ((dwValue >= 1) && (dwValue <= 3)) { if (dwValue == 3) { HKEY hkey; // need to inspect one more key
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szMemoryManagement, KEY_READ, &hkey); if (S_OK == hr) { DWORD dw;
hr = HrRegQueryDword(hkey, c_szLargeSystemCache, &dw); if (S_OK == hr) { if (dw == 0) { dwValue = 4; } } RegCloseKey(hkey); } } pwisParams->AddKey(c_szAfLmServerOptimization, g_pszServerOptimization[dwValue]); }
//BroadcastsToLanman2Clients
dwValue=0; prkParams->QueryValue(L"Lmannounce", dwValue); pwisParams->AddBoolKey(c_szAfBroadcastToClients, dwValue);
// now write reg-dump keys
tstring strFileName; tstring strServices = c_szRegKeyServices; strServices += L"\\";
// ignore the error codes so that we can dump whatever is available/present
//
hr = HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcLmServer, c_szParameters, c_szAfLmServerParameters, pwisParams);
hr = HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcLmServer, c_szShares, c_szAfLmServerShares, pwisParams);
hr = HrNetRegSaveServiceSubKeyAndAddToSection(c_szSvcLmServer, c_szAutotunedParameters, c_szAfLmServerAutotunedParameters, pwisParams);
DeleteIfNotNull(prkParams);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteLanmanWorkstationParams
//
// Purpose: Write parameters of LanmanWorkstation to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteLanmanWorkstationParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteLanmanWorkstationParams");
TraceFunctionEntry(ttidNetUpgrade);
// pwisParams->AddComment(c_szNoParamsRequired);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: WriteRPCLocatorParams
//
// Purpose: Write parameters of RPCLOCATOR to the specified section
//
// Arguments:
// pwifAnswerFile [in] pointer to answerfile
// pwisParams [in] section where to write the parameters
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteRPCLocatorParams ( IN PCWInfFile pwifAnswerFile, IN PCWInfSection pwisParams) { DefineFunctionName("WriteRPCLocatorParams");
TraceFunctionEntry(ttidNetUpgrade);
//DefaultSecurityProvider
WriteRegValueToAFile(pwisParams, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Rpc\\SecurityService", L"DefaultProvider", REG_SZ, c_szAfDefaultProvider);
//NameServiceNetworkAddress
WriteRegValueToAFile(pwisParams, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Rpc\\NameService", L"NetworkAddress", REG_SZ, c_szAfNameServiceAddr);
//NameServiceProtocol
WriteRegValueToAFile(pwisParams, HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Rpc\\NameService", L"Protocol", REG_SZ, c_szAfNameServiceProtocol);
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: IsNetComponentBindable
//
// Purpose: Determine if a component is bindable
// (it has Bind value under the Linkage key)
//
// Arguments:
// prkNetComponentLinkage [in] Linkage key of the component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL IsNetComponentBindable ( IN const PCORegKey prkNetComponentLinkage) { BOOL status; TStringList slTemp;
status = prkNetComponentLinkage->QueryValue(c_szRegValBind, slTemp) == ERROR_SUCCESS;
EraseAndDeleteAll(slTemp);
return status; }
// ----------------------------------------------------------------------
//
// Function: ConvertRouteToStringList
//
// Purpose: Convert Linkage\Route value to a tstring list
//
// Arguments:
// pszRoute [in] route
// slRoute [out] list of route elements
//
// Returns: None
//
// Author: kumarp 17-December-97
//
void ConvertRouteToStringList ( IN PCWSTR pszRoute, OUT TStringList &slRoute ) { EraseAndDeleteAll(slRoute); const WCHAR CHQUOTE = '"'; tstring str;
INT cQuote;
for ( cQuote = 0 ; *pszRoute ; pszRoute++ ) { if ( *pszRoute == CHQUOTE ) { if ( cQuote++ & 1 ) // If it's a closing quote...
{ if ( str.size() ) { if (FIsDontExposeLowerComponent(str.c_str())) { break; }
AddAtEndOfStringList(slRoute, str.c_str());
// If the route contains NetBT, then add in TCPIP
// because TCPIP is in the bind string in Windows 2000.
// e.g. a binding of NetBT->Adapter will become
// NetBT->TCPIP->Adapter.
//
if (0 == _wcsicmp (str.c_str(), L"NetBT")) { AddAtEndOfStringList(slRoute, L"TCPIP"); } } } str.erase(); } else { str += *pszRoute; } } }
// ----------------------------------------------------------------------
//
// Function: IsMSNetClientComponent
//
// Purpose: Determine if the specified component is a subcomponent
// of MS_MSClient
//
// Arguments:
// pszComponentName [in] name of component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL IsMSNetClientComponent ( IN PCWSTR pszComponentName) { Assert (pszComponentName && *pszComponentName);
return ((!_wcsicmp(pszComponentName, c_szSvcBrowser)) || (!_wcsicmp(pszComponentName, c_szSvcWorkstation)) || (!_wcsicmp(pszComponentName, L"RpcLocator"))); }
// ----------------------------------------------------------------------
//
// Function: WriteBindings
//
// Purpose: Write disabled bindings of a component to [NetBindings] section
//
// Arguments:
// pszComponentName [in] name of component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteBindings ( IN PCWSTR pszComponentName) { Assert (pszComponentName && *pszComponentName);
DefineFunctionName("WriteBindings");
BOOL fStatus=TRUE; TStringList slBindings, slRoute; tstring strRoute, strBindings, strTemp; TStringListIter iter;
// we want to write bindings only for LanmanWorkstation among the
// MSClient components
//
if (IsMSNetClientComponent(pszComponentName) && (lstrcmpiW(pszComponentName, c_szSvcWorkstation))) { return TRUE; }
TraceTag(ttidNetUpgrade, "%s: writing bindings of '%S'...", __FUNCNAME__, pszComponentName);
PCORegKey prkNetComponentLinkage=NULL, prkNetComponentLinkageDisabled=NULL; GetServiceSubkey(pszComponentName, c_szLinkage, prkNetComponentLinkage);
if (!prkNetComponentLinkage || !IsNetComponentBindable(prkNetComponentLinkage)) goto error_cleanup;
GetServiceSubkey(pszComponentName, c_szLinkageDisabled, prkNetComponentLinkageDisabled); if (!prkNetComponentLinkageDisabled) goto error_cleanup;
//We write only those bindings that are disabled, others by default are enabled
// prkNetComponentLinkage->QueryValue(c_szRegValRoute, slBindings);
prkNetComponentLinkageDisabled->QueryValue(c_szRegValRoute, slBindings);
for (iter = slBindings.begin(); iter != slBindings.end(); iter++) { strRoute = **iter;
MapNetComponentNameForBinding(pszComponentName, strBindings); if (!lstrcmpiW(strBindings.c_str(), c_szInfId_MS_NetBT)) { strBindings += L","; strBindings += c_szInfId_MS_TCPIP; } ConvertRouteToStringList(strRoute.c_str(), slRoute); TStringListIter iterComponentsInRoute;
for (iterComponentsInRoute = slRoute.begin(); iterComponentsInRoute != slRoute.end(); iterComponentsInRoute++) { strTemp = **iterComponentsInRoute;
if (IsNetCardProductName(strTemp.c_str())) continue; MapNetComponentNameForBinding(strTemp.c_str(), strTemp);
// pre-NT5 code stores bindings such that MS_NetBT appears to
// bind directly to a netcard. in NT5 MS_NetBT binds to MS_TCPIP
// which then binds to a netcard.
// thus for any binding path having MS_NetBT in it, we need to
// convert this to MS_NetBT,MS_TCPIP
//
// NTRAID9:210426@20001130#deonb.
// This is redundant. ConvertRouteToStringList already add MS_TCPIP after encountering NETBT,
// Adding it again will result in a bindpath of MS_NetBT,ms_tcpip,MS_TCPIP which will not be matched
// by GUI setup. Removing this check.
// if (!lstrcmpiW(strTemp.c_str(), c_szInfId_MS_NetBT))
// {
// strTemp += L",";
// strTemp += c_szInfId_MS_TCPIP;
// }
// 306866: pre-NT5 code stores ISO/TP4 bindings in the form
// isotp4->streams->adapter. In NT5, each of these binds
// directly to the adapter. So if we find an isotp Route for
// which the first component is Streams, we skip it.
//
if (!lstrcmpiW(strBindings.c_str(), c_szInfId_MS_Isotpsys) && !lstrcmpiW(strTemp.c_str(), c_szInfId_MS_Streams)) { continue; }
strBindings += L"," + strTemp;
// 243906: if the component is DONT_EXPOSE_LOWER, terminate the bindpath
if (!lstrcmpiW(strTemp.c_str(), c_szInfId_MS_NWIPX) || !lstrcmpiW(strTemp.c_str(), c_szInfId_MS_NWNB) || !lstrcmpiW(strTemp.c_str(), c_szInfId_MS_NWSPX)) { break; } } EraseAndDeleteAll(slRoute);
// WLBS: don't write Disable bindings that contain MS_TCPIP and WLBS
// cluster adapter.
if (pszWlbsClusterAdapterName[0] != 0 && (strBindings.find(c_szInfId_MS_TCPIP) != tstring::npos || strBindings.find(c_szMSTCPIP) != tstring::npos) && strBindings.find(pszWlbsClusterAdapterName) != tstring::npos) { TraceTag(ttidNetUpgrade, "%s: skipping Disable=%S", __FUNCNAME__, strBindings.c_str());
continue; }
// end WLBS:
g_pwisBindings->AddKey(c_szAfDisable, strBindings.c_str()); TraceTag(ttidNetUpgrade, "%s: Disable=%S", __FUNCNAME__, strBindings.c_str()); }
// WLBS: if WLBS is bound to a NIC, then write explicit Enable binding to it.
// by default, WLBS notifier object will disable all bindings on install.
if ((_wcsicmp(pszComponentName, c_szWLBS) == 0 || _wcsicmp(pszComponentName, c_szConvoy) == 0) && pszWlbsClusterAdapterName[0] != 0) { strBindings = c_szMSWLBS; strBindings += L","; strBindings += pszWlbsClusterAdapterName; g_pwisBindings->AddKey(c_szAfEnable, strBindings.c_str());
TraceTag(ttidNetUpgrade, "%s: Enable=%S", __FUNCNAME__, strBindings.c_str()); }
// end WLBS:
fStatus=TRUE; goto cleanup;
error_cleanup: fStatus = FALSE;
cleanup: DeleteIfNotNull(prkNetComponentLinkage); DeleteIfNotNull(prkNetComponentLinkageDisabled);
EraseAndDeleteAll(slBindings);
return fStatus; }
// ----------------------------------------------------------------------
// Misc. Helper Functions
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// Function: WriteServiceRegValueToAFile
//
// Purpose: Write specified value in registry to the specified section
// in the answerfile, renaming if required
//
// Arguments:
// pwisSection [in] section to which the value is written
// pszServiceKey [in] name of service
// pszValueName [in] name of value under Parameters subkey
// wValueType [in] type of value
// pszValueNewName [in] change name to this
// fDefaultProvided [in] is a default value provided ?
// ... [in] use this default value if the specified value is
// not found in the registry
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteServiceRegValueToAFile( IN PCWInfSection pwisSection, IN PCWSTR pszServiceKey, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, ...) { AssertValidReadPtr(pwisSection); AssertValidReadPtr(pszValueName);
tstring strKeyFullPath; strKeyFullPath = tstring(L"System\\CurrentControlSet\\Services\\") + pszServiceKey;
va_list arglist;
va_start (arglist, fDefaultProvided); BOOL fStatus = WriteRegValueToAFile(0, pwisSection, HKEY_LOCAL_MACHINE, strKeyFullPath.c_str(), pszValueName, wValueType, pszValueNewName, fDefaultProvided, arglist); va_end(arglist);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: WriteServiceRegValueToAFile
//
// Purpose: Write specified value in registry to the specified section
// in the answerfile, renaming if required
//
// Arguments:
// pwisSection [in] section to which the value is written
// hkey [in] handle to a regkey
// pszSubKey [in] name of subkey
// pszValueName [in] name of value
// wValueType [in] type of value
// pszValueNewName [in] change name to this
// fDefaultProvided [in] is a default value provided ?
// ... [in] use this default value if the specified value is
// not found in the registry
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteRegValueToAFile( IN PCWInfSection pwisSection, IN HKEY hKey, IN PCWSTR pszSubKey, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, ...) { BOOL fStatus; va_list arglist;
va_start (arglist, fDefaultProvided); fStatus = WriteRegValueToAFile(0, pwisSection, hKey, pszSubKey, pszValueName, wValueType, pszValueNewName, fDefaultProvided, arglist); va_end(arglist);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: WriteServiceRegValueToAFile
//
// Purpose: Write specified value in registry to the specified section
// in the answerfile, renaming if required
//
// Arguments:
// pwisSection [in] section to which the value is written
// hkey [in] handle to a regkey
// pszSubKey [in] name of subkey
// pszValueName [in] name of value
// wValueType [in] type of value
// pszValueNewName [in] change name to this
// fDefaultProvided [in] is a default value provided ?
// arglist [in] use this default value if the specified value is
// not found in the registry
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteRegValueToAFile( IN DWORD dwReserved, IN PCWInfSection pwisSection, IN HKEY hKey, IN PCWSTR pszSubKey, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, va_list arglist) { Assert( !dwReserved );
CORegKey rk(hKey, pszSubKey); BOOL fKeyNotFound = (((HKEY) rk) == NULL);
if (fKeyNotFound && !fDefaultProvided) { return FALSE; } else { //even if key is not found, we need to write the default value
return WriteRegValueToAFile(0, pwisSection, rk, pszValueName, wValueType, pszValueNewName, fDefaultProvided, arglist); } }
// ----------------------------------------------------------------------
//
// Function: WriteServiceRegValueToAFile
//
// Purpose: Write specified value in registry to the specified section
// in the answerfile, renaming if required
//
// Arguments:
// pwisSection [in] section to which the value is written
// rk [in] regkey
// pszValueName [in] name of value
// wValueType [in] type of value
// pszValueNewName [in] change name to this
// fDefaultProvided [in] is a default value provided ?
// ... [in] use this default value if the specified value is
// not found in the registry
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteRegValueToAFile( IN PCWInfSection pwisSection, IN CORegKey& rk, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, ...) { BOOL fStatus; va_list arglist;
va_start (arglist, fDefaultProvided); fStatus = WriteRegValueToAFile(0, pwisSection, rk, pszValueName, wValueType, pszValueNewName, fDefaultProvided, arglist); va_end(arglist);
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: WriteServiceRegValueToAFile
//
// Purpose: Write specified value in registry to the specified section
// in the answerfile, renaming if required
//
// Arguments:
// pwisSection [in] section to which the value is written
// rk [in] regkey
// pszValueName [in] name of value
// wValueType [in] type of value
// pszValueNewName [in] change name to this
// fDefaultProvided [in] is a default value provided ?
// arglist [in] use this default value if the specified value is
// not found in the registry
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL WriteRegValueToAFile( IN DWORD dwReserved, IN PCWInfSection pwisSection, IN CORegKey& rk, IN PCWSTR pszValueName, IN WORD wValueType, IN PCWSTR pszValueNewName, IN BOOL fDefaultProvided, IN va_list arglist) { Assert( !dwReserved );
if (!pwisSection) { return FALSE; }
BOOL fValue, fDefault=FALSE; DWORD dwValue, dwDefault=0; PCWSTR pszValue, pszDefault=NULL; TStringList slValue; tstring strValue;
if (pszValueNewName == NULL) { pszValueNewName = pszValueName; }
if (fDefaultProvided) { switch (wValueType) { default: AssertSz(FALSE, "WriteRegValueToAFile: Invalid wValueType"); break;
case REG_SZ: pszDefault = va_arg(arglist, PCWSTR); break;
case REG_HEX: case REG_DWORD: dwDefault = va_arg(arglist, DWORD); break;
case REG_BOOL: fDefault = va_arg(arglist, BOOL); break;
} }
LONG err; BOOL fStatus=FALSE;
switch(wValueType) { default: AssertSz(FALSE, "WriteRegValueToAFile: Invalid wValueType"); break;
case REG_SZ: err = rk.QueryValue(pszValueName, strValue); if (err) { if (fDefaultProvided) { pszValue = pszDefault; } else { return FALSE; } } else { pszValue = strValue.c_str(); } pwisSection->AddKey(pszValueNewName, pszValue); fStatus = TRUE; break;
case REG_HEX: case REG_DWORD: err = rk.QueryValue(pszValueName, dwValue); if (err) { if (fDefaultProvided) { dwValue = dwDefault; } else { return FALSE; } } if (wValueType == REG_HEX) { pwisSection->AddHexKey(pszValueNewName, dwValue); } else { pwisSection->AddKey(pszValueNewName, dwValue); } fStatus = TRUE; break;
case REG_BOOL: err = rk.QueryValue(pszValueName, dwValue); if (err) { if (fDefaultProvided) { dwValue = fDefault; } else { return FALSE; } } fValue = dwValue != 0; pwisSection->AddBoolKey(pszValueNewName, fValue); fStatus = TRUE; break;
case REG_MULTI_SZ: err = rk.QueryValue(pszValueName, slValue); if (err) { // cant specify default for REG_MULTI_SZ, just return FALSE
return FALSE; } pwisSection->AddKey(pszValueNewName, slValue); EraseAndDeleteAll(slValue); fStatus = TRUE; break;
case REG_BINARY: { TByteArray ab;
err = rk.QueryValue(pszValueName, ab); if (err) { // cant specify default for REG_BINARY, just return FALSE
return FALSE; }
ConvertToByteList(ab, strValue);
pszValue = strValue.c_str(); pwisSection->AddKey(pszValueNewName, pszValue);
break; } }
return fStatus; }
// ----------------------------------------------------------------------
//
// Function: GetBusTypeName
//
// Purpose: Get name string for the specify bus-type
//
// Arguments:
// eBusType [in] bus type
//
// Returns: name string for the bus-type
//
// Author: kumarp 17-December-97
//
PCWSTR GetBusTypeName ( IN INTERFACE_TYPE eBusType) { switch (eBusType) { case Internal: return c_szAfBusInternal;
case Isa: return c_szAfBusIsa;
case Eisa: return c_szAfBusEisa;
case MicroChannel: return c_szAfBusMicrochannel;
case TurboChannel: return c_szAfBusTurbochannel;
case PCIBus: return c_szAfBusPci;
case VMEBus: return c_szAfBusVme;
case NuBus: return c_szAfBusNu;
case PCMCIABus: return c_szAfBusPcmcia;
case CBus: return c_szAfBusC;
case MPIBus: return c_szAfBusMpi;
case MPSABus: return c_szAfBusMpsa;
case ProcessorInternal: return c_szAfBusProcessorinternal;
case InternalPowerBus: return c_szAfBusInternalpower;
case PNPISABus: return c_szAfBusPnpisa;
default: return c_szAfUnknown; } };
// ----------------------------------------------------------------------
//
// Function: AddToNetCardDB
//
// Purpose: Add the given adapter token to a list. This list is later
// used to map token <--> drivername
//
// Arguments:
// pszAdapterName [in] adapter token (e.g. Adapter01)
// pszProductName [in] adapter ID (e.g. IEEPRO)
// pszAdapterDriver [in] instance ID (e.g. IEEPRO3)
//
// Returns: None
//
// Author: kumarp 17-December-97
//
void AddToNetCardDB ( IN PCWSTR pszAdapterName, IN PCWSTR pszProductName, IN PCWSTR pszAdapterDriver) { Assert(pszAdapterName && *pszAdapterName); Assert(pszProductName && *pszProductName); Assert(pszAdapterDriver && *pszAdapterDriver);
AddAtEndOfStringList(*g_pslNetCardAFileName, pszAdapterName); AddAtEndOfStringList(*g_pslNetCard, pszProductName); AddAtEndOfStringList(*g_pslNetCardInstance, pszAdapterDriver); }
// ----------------------------------------------------------------------
//
// Function: IsNetCardProductName
//
// Purpose: Determine if the specified name represents an adapter
//
// Arguments:
// pszName [in] name of a component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL IsNetCardProductName ( IN PCWSTR pszName) { AssertValidReadPtr(pszName);
return FIsInStringList(*g_pslNetCard, pszName); }
// ----------------------------------------------------------------------
//
// Function: IsNetCardInstance
//
// Purpose: Determine if the specified instance represents an adapter
//
// Arguments:
// pszName [in] instance name of a component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL IsNetCardInstance( IN PCWSTR pszName) { AssertValidReadPtr(pszName);
return FIsInStringList(*g_pslNetCardInstance, pszName); }
// ----------------------------------------------------------------------
//
// Function: MapNetCardInstanceToAFileName
//
// Purpose: Map netcard instance name to its answerfile token
//
// Arguments:
// pszNetCardInstance [in] net card instance
// strNetCardAFileName [out] answerfile token for that net card
//
// Returns: None
//
// Author: kumarp 17-December-97
//
VOID MapNetCardInstanceToAFileName ( IN PCWSTR pszNetCardInstance, OUT tstring& strNetCardAFileName) { strNetCardAFileName = MapNetCardInstanceToAFileName(pszNetCardInstance); }
// ----------------------------------------------------------------------
//
// Function: MapNetCardInstanceToAFileName
//
// Purpose: Map netcard instance name to its answerfile token
//
// Arguments:
// pszNetCardInstance [in] net card instance
//
// Returns: answerfile token for that net card
//
// Author: kumarp 17-December-97
//
PCWSTR MapNetCardInstanceToAFileName ( IN PCWSTR pszNetCardInstance) { DefineFunctionName("MapNetCardInstanceToAFileName");
Assert(pszNetCardInstance && *pszNetCardInstance);
tstring strTemp; TStringListIter iter = g_pslNetCardInstance->begin(); TStringListIter pos2; DWORD index=0; PCWSTR pszNetCardAFileName=NULL;
while (iter != g_pslNetCardInstance->end()) { strTemp = **iter++; if (0 == _wcsicmp(strTemp.c_str(), pszNetCardInstance)) { pszNetCardAFileName = GetNthItem(*g_pslNetCardAFileName, index)->c_str(); break; } index++; }
if (!pszNetCardAFileName) { TraceTag(ttidError, "%s: Couldnt locate %S in g_pslNetCardAFileName", __FUNCNAME__, pszNetCardInstance); }
return pszNetCardAFileName; }
// ----------------------------------------------------------------------
//
// Function: GetServiceKey
//
// Purpose: Get regkey object for the specified service
//
// Arguments:
// pszServiceName [in] name of service
// prkService [out] pointer to CORegKey object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL GetServiceKey ( IN PCWSTR pszServiceName, OUT PCORegKey &prkService) { DefineFunctionName("GetServiceKey");
tstring strServiceFullName = tstring(c_szRegKeyServices) + L"\\" + pszServiceName; prkService = new CORegKey(HKEY_LOCAL_MACHINE, strServiceFullName.c_str());
if(!prkService) { return false; }
if (!prkService->HKey()) { delete prkService; prkService = NULL; TraceHr (ttidError, FAL, HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST), FALSE, "GetServiceKey for service %S", pszServiceName); return FALSE; }
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: GetServiceParamsKey
//
// Purpose: Get regkey object for the Parameters subkey of the specified service
//
// Arguments:
// pszServiceName [in] name of a service
// prkServiceParams [out] pointer to CORegKey object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL GetServiceParamsKey ( IN PCWSTR pszServiceName, OUT PCORegKey &prkServiceParams) { return GetServiceSubkey(pszServiceName, c_szParameters, prkServiceParams); }
// ----------------------------------------------------------------------
//
// Function: GetServiceSubkey
//
// Purpose: Get subkey of a service
//
// Arguments:
// pszServiceName [in] name of service
// pszSubKeyName [in] name of subkey
// prkServiceSubkey [out] pointer to CORegKey object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL GetServiceSubkey ( IN PCWSTR pszServiceName, IN PCWSTR pszSubKeyName, OUT PCORegKey &prkServiceSubkey) { DefineFunctionName("GetServiceSubkey(PCWSTR pszServiceName, )");
tstring strServiceSubkeyFullName = tstring(c_szRegKeyServices) + L"\\" + pszServiceName + L"\\" + pszSubKeyName;
prkServiceSubkey = new CORegKey(HKEY_LOCAL_MACHINE, strServiceSubkeyFullName.c_str());
if(!prkServiceSubkey) { return false; }
if (!prkServiceSubkey->HKey()) { delete prkServiceSubkey; prkServiceSubkey = NULL; TraceTag(ttidError, "%s: error opening service sub key for %S -- %S", __FUNCNAME__, pszServiceName, pszServiceName); return FALSE; }
return TRUE; }
// ----------------------------------------------------------------------
//
// Function: GetServiceSubkey
//
// Purpose: Get subkey of a service
//
// Arguments:
// prkService [in] service regkey
// pszSubKeyName [in] name of subkey
// prkServiceSubkey [out] pointer to CORegKey object
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL GetServiceSubkey ( IN const PCORegKey prkService, IN PCWSTR pszSubKeyName, OUT PCORegKey &prkServiceSubkey) { DefineFunctionName("GetServiceSubkey(PCORegKey prkService, )");
prkServiceSubkey = new CORegKey(*prkService, pszSubKeyName);
if(!prkServiceSubkey) { return false; }
if (!prkServiceSubkey->HKey()) { delete prkServiceSubkey; prkServiceSubkey = NULL; TraceWin32FunctionError(ERROR_SERVICE_DOES_NOT_EXIST); return FALSE; }
return TRUE; }
#pragma BEGIN_CONST_SECTION
static const PCWSTR c_aszComponentsToIgnore[] = { // These are installed automatically when TCPIP is installed
// and has no user settable parameters of its own
//
L"NetBT", L"TcpipCU", L"Wins",
// This is installed automatically when RAS is installed
// and has no user settable parameters of its own
//
L"NdisWan",
// Parameters of RAS are under Software\Microsoft\RAS
// and not under the service key as with other net components
//
L"RASPPTPE", L"RASPPTPM", L"RasAuto", L"RemoteAccess", L"Router",
// These are installed automatically when MS_IPX is installed
// and has no user settable parameters of its own
//
L"NwlnkNb", L"NwlnkSpx",
// This is installed automatically when MS_MSClient is installed
// and has no user settable parameters of its own
//
L"RpcBanyan",
// we dont install this using answer-file
//
L"Inetsrv", L"DFS",
// this will be cleaned up by the IIS setup guys.
// contact "Linan Tong" if you have any questions:
//
L"FTPD",
// these are installed when SFM is installed
//
L"MacPrint", L"MacFile",
// pre-sp3 SteelHead components
//
L"NwSapAgent", L"IPRIP", L"NWLNKRIP", L"RelayAgent", }; #pragma END_CONST_SECTION
// ----------------------------------------------------------------------
//
// Function: ShouldIgnoreComponent
//
// Purpose: Determine if a components should be ignored when
// writing parameters to answerfile
//
// Arguments:
// pszComponentName [in] name of component
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL ShouldIgnoreComponent ( IN PCWSTR pszComponentName) { BOOL fRet=TRUE;
DefineFunctionName("ShouldIgnoreComponent"); TraceFunctionEntry(ttidNetUpgrade);
TraceTag(ttidNetUpgrade, "%s: Checking if %S should be ignored.", __FUNCNAME__, pszComponentName);
fRet = !FIsInStringArray(c_aszComponentsToIgnore, celems(c_aszComponentsToIgnore), pszComponentName) && (!FIsOptionalComponent(pszComponentName) || // even though DHCPServer is an optional component,
// we need to treat it differently and thus must write its
// parameters
!lstrcmpiW(pszComponentName, c_szSvcDhcpServer));
// If none of the above net components then, check if it is DLC.
if ( fRet == TRUE ) { if ( lstrcmpiW(pszComponentName, sz_DLC) == 0 ) { return ShouldRemoveDLC( NULL, NULL ); } }
return !fRet; }
// ----------------------------------------------------------------------
//
// Function: StringListsIntersect
//
// Purpose: Determine if at least one item of sl1 matches with
// at least one item of sl2
//
// Arguments:
// sl1 [in] list 1
// sl2 [in] list 2
//
// Returns: TRUE on success, FALSE otherwise
//
// Author: kumarp 17-December-97
//
BOOL StringListsIntersect ( IN const TStringList& sl1, IN const TStringList& sl2) { if ((sl1.size() == 0) || (sl2.size() == 0)) return FALSE;
tstring s1, s2; TStringListIter pos1, pos2;
pos1 = sl1.begin(); while (pos1 != sl1.end()) { s1 = **pos1++; pos2 = sl2.begin(); while (pos2 != sl2.end()) { s2 = **pos2++; if (s1 == s2) { return TRUE; } } }
return FALSE; }
// ----------------------------------------------------------------------
//
// Function: ConvertToQWord
//
// Purpose: Convert a size 8 byte array to a qword
//
// Arguments:
// ab [in] byte array
//
// Returns:
//
// Author: kumarp 17-December-97
//
QWORD ConvertToQWord ( IN TByteArray ab) { Assert(ab.size() == 8);
QWORD qwRet = 0; WORD wShiftBy=0; for (int i=0; i<8; i++) { qwRet |= ((QWORD) ab[i]) << wShiftBy; wShiftBy += 8; }
return qwRet; }
// ----------------------------------------------------------------------
//
// Function: ConvertToByteList
//
// Purpose: Convert TByteArray to comma-separated byte list
//
// Arguments:
// ab [in] byte array
//
// Returns:
//
// Author: kyrilf 2-April-99
//
VOID ConvertToByteList ( IN TByteArray ab, OUT tstring& str) { WCHAR byte [3]; DWORD size = ab.size();
for (DWORD i=0; i < size; i++) { swprintf(byte, L"%0.2X", ab[i]);
str += byte;
if (i == size - 1) break; else str += ','; } }
// ----------------------------------------------------------------------
//
// Function: ReplaceCharsInString
//
// Purpose: Replace all occurrances of chFindChar in the specified string
// by chReplaceWith charater
//
// Arguments:
// pszString [in] string
// pszFindChars [in] set of chars to find
// chReplaceWith [in] char to replace with
//
// Returns: None
//
// Author: kumarp 17-December-97
//
void ReplaceCharsInString ( IN OUT PWSTR pszString, IN PCWSTR pszFindChars, IN WCHAR chReplaceWith) { UINT uLen = wcslen(pszString); UINT uPos;
while ((uPos = wcscspn(pszString, pszFindChars)) < uLen) { pszString[uPos] = chReplaceWith; pszString += uPos + 1; uLen -= uPos + 1; } }
// ----------------------------------------------------------------------
//
// Function: HrNetRegSaveKey
//
// Purpose: Save the entire specified registry tree to a file
//
// Arguments:
// hkeyBase [in] handle of base key
// pszSubKey [in] name of subkey
// pszComponent [in] file name prefix to use
// pstrFileName [out] name of file written
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
HRESULT HrNetRegSaveKey ( IN HKEY hkeyBase, IN PCWSTR pszSubKey, IN PCWSTR pszComponent, OUT tstring* pstrFileName) { DefineFunctionName("HrNetRegSaveKey");
Assert(hkeyBase); AssertValidReadPtr(pszComponent); AssertValidWritePtr(pstrFileName);
HRESULT hr; HKEY hkey;
hr = HrRegOpenKeyEx(hkeyBase, pszSubKey, KEY_READ, &hkey);
if (S_OK == hr) { tstring strFileName; strFileName = pszComponent; if (pszSubKey) { AssertValidReadPtr(pszSubKey);
strFileName += L"-"; strFileName += pszSubKey; ReplaceCharsInString((PWSTR) strFileName.c_str(), L"\\/", '-'); } strFileName += L".reg";
tstring strFullPath;
hr = HrGetNetUpgradeTempDir(&strFullPath); if (S_OK == hr) { strFullPath += strFileName;
TraceTag(ttidNetUpgrade, "%s: dumping key %S to file %S", __FUNCNAME__, pszSubKey ? pszSubKey : L"", strFullPath.c_str());
DeleteFile(strFullPath.c_str());
extern LONG EnableAllPrivileges ( VOID ); EnableAllPrivileges();
DWORD err = ::RegSaveKey(hkey, strFullPath.c_str(), NULL); if (err == ERROR_SUCCESS) { *pstrFileName = strFullPath; hr = S_OK; } else { hr = HrFromLastWin32Error(); } }
RegCloseKey(hkey); }
TraceErrorOptional(__FUNCNAME__, hr, (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)));
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrNetRegSaveKeyAndAddToSection
//
// Purpose: Save the entire specified registry tree to a file and
// add a key in the specified section to indicate where
// this file is located
//
// Arguments:
// hkeyBase [in] handle of base key
// pszSubKey [in] name of subkey
// pszComponent [in] file name prefix to use
// pszKeyName [in] name of key to write
// pwisSection [in] section to write to
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
HRESULT HrNetRegSaveKeyAndAddToSection ( IN HKEY hkeyBase, IN PCWSTR pszSubKey, IN PCWSTR pszComponent, IN PCWSTR pszKeyName, IN CWInfSection* pwisSection) { DefineFunctionName("HrNetRegSaveKeyAndAddToSection");
Assert(hkeyBase); AssertValidReadPtr(pszComponent); AssertValidReadPtr(pszKeyName); AssertValidReadPtr(pwisSection);
HRESULT hr; tstring strFileName;
hr = HrNetRegSaveKey(hkeyBase, pszSubKey, pszComponent, &strFileName); if (SUCCEEDED(hr)) { pwisSection->AddKey(pszKeyName, strFileName.c_str()); }
if (S_OK != hr) { TraceTag(ttidNetUpgrade, "%s: failed for %S in [%S] -- %S: hr: 0x%08X", __FUNCNAME__, pszKeyName, pwisSection->Name(), pszSubKey, hr); }
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrNetRegSaveKeyAndAddToSection
//
// Purpose: Save the entire specified registry tree to a file and
// add a key in the specified section to indicate where
// this file is located
//
// Arguments:
// pszServiceName [in] name of service
// pszSubKey [in] name of subkey
// pszKeyName [in] name of key to write
// pwisSection [in] section to write to
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 17-December-97
//
HRESULT HrNetRegSaveServiceSubKeyAndAddToSection ( IN PCWSTR pszServiceName, IN PCWSTR pszServiceSubKeyName, IN PCWSTR pszKeyName, IN CWInfSection* pwisSection) { AssertValidReadPtr(pszServiceName); AssertValidReadPtr(pszKeyName); AssertValidWritePtr(pwisSection);
HRESULT hr; tstring strServiceSubKey = c_szRegKeyServices;
strServiceSubKey += L"\\"; strServiceSubKey += pszServiceName; if (pszServiceSubKeyName) { strServiceSubKey += L"\\"; strServiceSubKey += pszServiceSubKeyName; }
// we ignore the return code
hr = HrNetRegSaveKeyAndAddToSection(HKEY_LOCAL_MACHINE, strServiceSubKey.c_str(), pszServiceName, pszKeyName, pwisSection);
return hr; }
// ----------------------------------------------------------------------
//
// Function: HrProcessOemComponentAndUpdateAfSection
//
// Purpose: Process the specified OEM component in the following steps:
// - Load an OEM DLL
// - call PreUpgradeInitialize once
// - call DoPreUpgradeProcessing
// - if the above steps are successful,
// add the right sections in the answerfile
//
// Arguments:
// pnmi [in] pointer to CNetMapInfo object
// hParentWindow [in] handle of parent window
// hkeyParams [in] handle of Parameters registry key
// pszPreNT5InfId [in] pre-NT5 InfID of a component (e.g. IEEPRO)
// pszPreNT5Instance [in] pre-NT5 instance of a component (e.g. IEEPRO2)
// pszNT5InfId [in] NT5 InfID of the component
// pszDescription [in] description of the component
// pwisParams [in] pointer to params section of this component
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 13-May-98
//
HRESULT HrProcessOemComponentAndUpdateAfSection( IN CNetMapInfo* pnmi, IN HWND hParentWindow, IN HKEY hkeyParams, IN PCWSTR pszPreNT5InfId, IN PCWSTR pszPreNT5Instance, IN PCWSTR pszNT5InfId, IN PCWSTR pszDescription, IN CWInfSection* pwisParams) { AssertValidReadPtr(pnmi); //Assert(hParentWindow);
Assert(hkeyParams); AssertValidReadPtr(pszPreNT5InfId); AssertValidReadPtr(pszPreNT5Instance); AssertValidReadPtr(pszNT5InfId); AssertValidReadPtr(pszDescription); AssertValidReadPtr(pwisParams);
DefineFunctionName("HrProcessOemComponentAndUpdateAfSection");
HRESULT hr; tstring strOemSectionName; DWORD dwFlags = 0; PCWSTR pszOemSection;
TraceTag(ttidNetUpgrade, "%s: Component %S (%S) is an OEM component", __FUNCNAME__, pszDescription, pszPreNT5Instance);
strOemSectionName = pwisParams->Name(); strOemSectionName += L"."; strOemSectionName += c_szAfOemSection; pszOemSection = strOemSectionName.c_str();
hr = HrProcessOemComponent(pnmi, &g_NetUpgradeInfo, hParentWindow, hkeyParams, pszPreNT5InfId, pszPreNT5Instance, pszNT5InfId, pszDescription, pszOemSection, &dwFlags);
if (S_OK == hr) { tstring strOemInf;
pwisParams->AddKey(c_szAfOemSection, pszOemSection);
AssertSz(!pnmi->m_strOemDir.empty(), "Did not get OemDir!!");
pwisParams->AddKey(c_szAfOemDir, pnmi->m_strOemDir.c_str());
hr = pnmi->HrGetOemInfName(pszNT5InfId, &strOemInf); if (S_OK == hr) { pwisParams->AddKey(c_szAfOemInf, strOemInf.c_str()); }
if (dwFlags & NUA_LOAD_POST_UPGRADE) { pwisParams->AddKey(c_szAfOemDllToLoad, pnmi->m_strOemDllName.c_str()); }
// currently the SkipInstall feature is used only by
// SNA and MS_NetBios for their peculiar upgrade requirements.
// This may or may not become a documented feature.
//
if (dwFlags & NUA_SKIP_INSTALL_IN_GUI_MODE) { pwisParams->AddBoolKey(c_szAfSkipInstall, TRUE); } }
TraceError(__FUNCNAME__, hr);
return hr; }
/*******************************************************************
NAME: EnableAllPrivileges
SYNOPSIS: Enxable all privileges on the current process token. This is used just prior to attempting to shut down the system.
ENTRY: Nothing
EXIT: Nothing
RETURNS: LONG error code
NOTES:
HISTORY:
********************************************************************/
LONG EnableAllPrivileges ( VOID ) { HANDLE Token = NULL ; ULONG ReturnLength = 4096, Index ; PTOKEN_PRIVILEGES NewState = NULL ; BOOL Result = FALSE ; LONG Error = 0 ;
do { Result = OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, & Token ) ; if (! Result) { Error = GetLastError() ; break; }
Result = (NewState = (PTOKEN_PRIVILEGES) MemAlloc( ReturnLength )) != NULL ;
if (! Result) { Error = ERROR_NOT_ENOUGH_MEMORY ; break; }
Result = GetTokenInformation( Token, // TokenHandle
TokenPrivileges, // TokenInformationClass
NewState, // TokenInformation
ReturnLength, // TokenInformationLength
&ReturnLength // ReturnLength
); if (! Result) { Error = GetLastError() ; break; }
//
// Set the state settings so that all privileges are enabled...
//
if ( NewState->PrivilegeCount > 0 ) { for (Index = 0; Index < NewState->PrivilegeCount; Index++ ) { NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED ; } }
Result = AdjustTokenPrivileges( Token, // TokenHandle
FALSE, // DisableAllPrivileges
NewState, // NewState (OPTIONAL)
ReturnLength, // BufferLength
NULL, // PreviousState (OPTIONAL)
&ReturnLength // ReturnLength
);
if (! Result) { Error = GetLastError() ; break; } } while ( FALSE ) ;
if ( Token != NULL ) CloseHandle( Token );
MemFree( NewState ) ;
return Result ? Error : 0 ; }
|