Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

7262 lines
215 KiB

// ----------------------------------------------------------------------
//
// 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 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 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"
};
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 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
{
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: 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)
{
HRESULT hr = S_OK;
HKEY hkeyCmak;
HKEY hkeyOcm;
PCWInfSection pwisMain;
BOOL fFoundCmComponent = FALSE;
pwisMain = pwifAnswerFile->FindSection(c_szOcMainSection);
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyCmak, KEY_READ,
&hkeyCmak)))
{
fFoundCmComponent = TRUE;
RegCloseKey(hkeyCmak);
}
if (SUCCEEDED(HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyOcmSubComp,
KEY_READ, &hkeyOcm)))
{
DWORD dwValue;
if (SUCCEEDED(HrRegQueryDword(hkeyOcm, c_szRegValueCpsSrv, &dwValue)))
{
if (dwValue)
{
fFoundCmComponent = TRUE;
}
}
if (SUCCEEDED(HrRegQueryDword(hkeyOcm, c_szRegValueCpsAd, &dwValue)))
{
if (dwValue)
{
fFoundCmComponent = TRUE;
}
}
RegCloseKey(hkeyOcm);
}
// If we found any one of the three CM components, then we want to install the suite of
// all three components.
//
if (fFoundCmComponent)
{
pwisMain->AddKey(c_szNetCm, c_szOcIsInstalled);
}
TraceError("HrWriteConfigManagerOptionalComponents", hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// 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);
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, dwValueDumpFormat,
pszResourceName);
}
}
else if (!FIsInStringArray(c_aszAdapterParamsToIgnore,
celems(c_aszAdapterParamsToIgnore),
szValueName))
{
WriteRegValueToAFile(pwisNetAdapterAdditionalParams,
*prkAdapterDriverParams,
szValueName, 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,
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(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(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 PCWInfSection pwisSection,
IN HKEY hKey,
IN PCWSTR pszSubKey,
IN PCWSTR pszValueName,
IN WORD wValueType,
IN PCWSTR pszValueNewName,
IN BOOL fDefaultProvided,
va_list arglist)
{
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(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(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 PCWInfSection pwisSection,
IN CORegKey& rk,
IN PCWSTR pszValueName,
IN WORD wValueType,
IN PCWSTR pszValueNewName,
IN BOOL fDefaultProvided,
IN va_list arglist)
{
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 ;
}