Leaked source code of windows server 2003
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.
 
 
 
 
 
 

5473 lines
153 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: A F I L E I N T . C P P
//
// Contents: Functions that operate on the answer file.
//
// Notes:
//
// Author: kumarp 25-November-97
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "afileint.h"
#include "afilestr.h"
#include "afilexp.h"
#include "errorlog.h"
#include "kkenet.h"
#include "kkreg.h"
#include "kkutils.h"
#include "ncerror.h"
#include "ncnetcfg.h"
#include "netcfgn.h"
#include "netcfgp.h"
#include "nsbase.h"
#include "resource.h"
#include "upgrade.h"
#include "ncreg.h"
#include "ncmisc.h"
#include "oemupgrd.h"
#include "ncsetup.h"
#include "nsexports.h"
#include "nslog.h"
#include "netshell.h"
#include "ncnetcon.h"
#include "lancmn.h"
#include "compid.h"
#include "nceh.h"
// ----------------------------------------------------------------------
// String constants
// ----------------------------------------------------------------------
extern const WCHAR c_szYes[];
extern const WCHAR c_szNo[];
extern const WCHAR c_szDevice[];
extern const WCHAR c_szInfId_MS_GPC[];
extern const WCHAR c_szInfId_MS_MSClient[];
extern const WCHAR c_szInfId_MS_RasCli[];
extern const WCHAR c_szInfId_MS_RasSrv[];
extern const WCHAR c_szInfId_MS_Server[];
extern const WCHAR c_szInfId_MS_TCPIP[];
const WCHAR sz_DLC[] = L"MS_DLC";
const WCHAR sz_DLC_NT40_Inf[] = L"system32\\oemnxpdl.inf";
const WCHAR sz_DLC_Win2k_Inf[] = L"inf\\netdlc.inf";
const WCHAR sz_DLC_Win2k_Pnf[] = L"inf\\netdlc.pnf";
const WCHAR sz_DLC_Sys[] = L"system32\\drivers\\dlc.sys";
const WCHAR sz_DLC_Dll[] = L"system32\\dlcapi.dll";
// ----------------------------------------------------------------------
// Forward declarations
// ----------------------------------------------------------------------
//Misc. helper functions
PCWSTR GetDisplayModeStr(IN EPageDisplayMode pdmDisplay);
EPageDisplayMode MapToDisplayMode(IN PCWSTR pszDisplayMode);
DWORD MapToUpgradeFlag(IN PCWSTR pszUpgradeFromProduct);
HRESULT HrGetProductInfo (LPDWORD pdwUpgradeFrom,
LPDWORD pdwBuildNo);
INTERFACE_TYPE GetBusTypeFromName(IN PCWSTR pszBusType);
void AddAnswerFileError(IN DWORD dwErrorId);
void AddAnswerFileError(IN PCWSTR pszSectionName, IN DWORD dwErrorId);
void AddAnswerFileError(IN PCWSTR pszSectionName,
IN PCWSTR pszKeyName,
IN DWORD dwErrorId);
CNetComponent* FindComponentInList(IN CNetComponentList* pnclComponents,
IN PCWSTR szInfID);
HRESULT HrRemoveNetComponents(IN INetCfg* pnc,
IN TStringList* pslComponents);
HRESULT HrSetLanConnectionName(IN GUID* pguidAdapter,
IN PCWSTR szConnectionName);
VOID RemoveFiles (IN PCWSTR szInfID);
// ----------------------------------------------------------------------
CErrorLog* g_elAnswerFileErrors;
// ======================================================================
// class CNetInstallInfo
// ======================================================================
CNetInstallInfo::CNetInstallInfo()
{
TraceFileFunc(ttidGuiModeSetup);
m_pwifAnswerFile = NULL;
m_pnaiAdaptersPage = NULL;
m_pnpiProtocolsPage = NULL;
m_pnsiServicesPage = NULL;
m_pnciClientsPage = NULL;
m_pnbiBindingsPage = NULL;
m_dwUpgradeFlag = 0;
m_dwBuildNumber = 0;
m_fProcessPageSections = TRUE;
m_fUpgrade = FALSE;
m_fInstallDefaultComponents = FALSE;
ZeroMemory(&m_nui, sizeof(m_nui));
m_hinfAnswerFile = NULL;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::CNetInstallInfo
//
// Purpose: constructor for class CNetInstallInfo
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
// static
HRESULT
CNetInstallInfo::HrCreateInstance (
IN PCWSTR pszAnswerFileName,
OUT CNetInstallInfo** ppObj)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr;
CNetInstallInfo* pObj;
Assert(ppObj);
*ppObj = NULL;
hr = E_OUTOFMEMORY;
pObj = new CNetInstallInfo ();
if (pObj)
{
g_elAnswerFileErrors = new CErrorLog;
pObj->m_pnaiAdaptersPage = new CNetAdaptersPage(pObj);
pObj->m_pnpiProtocolsPage = new CNetProtocolsPage(pObj);
pObj->m_pnsiServicesPage = new CNetServicesPage(pObj);
pObj->m_pnciClientsPage = new CNetClientsPage(pObj);
pObj->m_pnbiBindingsPage = new CNetBindingsPage(pObj);
if (g_elAnswerFileErrors &&
pObj->m_pnaiAdaptersPage &&
pObj->m_pnpiProtocolsPage &&
pObj->m_pnsiServicesPage &&
pObj->m_pnciClientsPage &&
pObj->m_pnbiBindingsPage)
{
if ( pszAnswerFileName )
{
hr = pObj->HrInitFromAnswerFile (pszAnswerFileName);
}
else
{
hr = pObj->InitRepairMode();
}
if (S_OK == hr)
{
CBindingAction::m_pnii = pObj;
*ppObj = pObj;
}
}
if (S_OK != hr)
{
delete pObj;
}
}
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::~CNetInstallInfo
//
// Purpose: destructor for class CNetInstallInfo
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetInstallInfo::~CNetInstallInfo()
{
TraceFileFunc(ttidGuiModeSetup);
if (IsValidHandle(m_hinfAnswerFile))
{
SetupCloseInfFile (m_hinfAnswerFile);
}
delete m_pnaiAdaptersPage;
delete m_pnpiProtocolsPage;
delete m_pnsiServicesPage;
delete m_pnciClientsPage;
delete m_pnbiBindingsPage;
if ( m_pwifAnswerFile )
{
delete m_pwifAnswerFile;
}
delete g_elAnswerFileErrors;
g_elAnswerFileErrors = NULL;
}
HRESULT CNetInstallInfo::InitRepairMode (VOID)
{
m_fProcessPageSections = FALSE;
m_fInstallDefaultComponents = FALSE;
m_fUpgrade = TRUE;
HrGetProductInfo( &m_dwUpgradeFlag, &m_dwBuildNumber );
m_nui.From.ProductType = m_nui.To.ProductType = MapProductFlagToProductType( m_dwUpgradeFlag );
m_nui.From.dwBuildNumber = m_nui.To.dwBuildNumber = m_dwBuildNumber;
m_dwUpgradeFlag |= NSF_PRIMARYINSTALL;
return S_OK;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::HrInitFromAnswerFile
//
// Purpose: Initialize internal data by reading answer-file
//
// Arguments:
// pwifAnswerFile [in] pointer to answer-file
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetInstallInfo::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetInstallInfo::HrInitFromAnswerFile(CWInfFile*)");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr, hrReturn=S_OK;
tstring strUpgradeFromProduct;
DWORD dwUpgradeFromProduct = 0;
m_pwifAnswerFile = pwifAnswerFile;
//Find upgrade info:
CWInfSection* pwisNetworking;
pwisNetworking = pwifAnswerFile->FindSection(c_szAfSectionNetworking);
if (!pwisNetworking)
{
ShowProgressMessage(L"[%s] section is missing",
c_szAfSectionNetworking);
hrReturn = NETSETUP_E_NO_ANSWERFILE;
goto return_from_function;
}
// ProcessPageSections
m_fProcessPageSections =
pwisNetworking->GetBoolValue(c_szAfProcessPageSections, TRUE);
//UpgradeFromProduct
strUpgradeFromProduct =
pwisNetworking->GetStringValue(c_szAfUpgradeFromProduct, c_szEmpty);
if (strUpgradeFromProduct.empty())
{
// UpgradeFromProduct is missing, implies not an upgrade
m_fUpgrade = FALSE;
m_fInstallDefaultComponents = TRUE;
// pwisNetworking->GetBoolValue(c_szAfInstallDefaultComponents, FALSE);
}
else
{
dwUpgradeFromProduct = MapToUpgradeFlag(strUpgradeFromProduct.c_str());
m_dwUpgradeFlag |= dwUpgradeFromProduct;
if (!dwUpgradeFromProduct)
{
AddAnswerFileError(c_szAfSectionNetworking,
c_szAfUpgradeFromProduct,
IDS_E_AF_InvalidValueForThisKey);
hrReturn = NETSETUP_E_ANS_FILE_ERROR;
goto return_from_function;
}
else
{
m_fUpgrade = TRUE;
}
}
// installing using an answerfile is ALWAYS a primary-install
//
m_dwUpgradeFlag |= NSF_PRIMARYINSTALL;
//BuildNumber
DWORD dwDummy;
dwDummy = 0;
m_dwBuildNumber = pwisNetworking->GetIntValue(c_szAfBuildNumber, dwDummy);
if (m_fUpgrade && !m_dwBuildNumber)
{
AddAnswerFileError(c_szAfSectionNetworking,
c_szAfBuildNumber,
IDS_E_AF_InvalidValueForThisKey);
hrReturn = NETSETUP_E_ANS_FILE_ERROR;
}
m_nui.From.ProductType = MapProductFlagToProductType(dwUpgradeFromProduct);
m_nui.From.dwBuildNumber = m_dwBuildNumber;
m_nui.To = GetCurrentProductInfo();
// the following two keys are currently unsupported
//
pwisNetworking->GetStringListValue(c_szAfNetComponentsToRemove,
m_slNetComponentsToRemove);
if (!m_fProcessPageSections)
{
// we are upgrading from NT5
// no other sections need to be parsed
TraceTag(ttidNetSetup, "%s: %S is FALSE, did not process page sections",
__FUNCNAME__, c_szAfProcessPageSections);
return hrReturn;
}
hr = m_pnaiAdaptersPage->HrInitFromAnswerFile(pwifAnswerFile);
if (FAILED(hr))
{
hrReturn = hr;
}
// HrInitFromAnswerFile returns FALSE if [NetProtocols] is missing
hr = m_pnpiProtocolsPage->HrInitFromAnswerFile(pwifAnswerFile);
if ((S_FALSE == hr) && m_fInstallDefaultComponents)
{
// the section is missing, initialize so that
// default components will be installed
ShowProgressMessage(L"Since InstallDefaultComponents is specified "
L" and the section [%s] is missing, default "
L"components for this section will be installed",
c_szAfSectionNetProtocols);
hr = m_pnpiProtocolsPage->HrInitForDefaultComponents();
}
if (FAILED(hr))
{
hrReturn = hr;
}
// HrInitFromAnswerFile returns FALSE if [NetServices] is missing
hr = m_pnsiServicesPage->HrInitFromAnswerFile(pwifAnswerFile);
if ((S_FALSE == hr) && m_fInstallDefaultComponents)
{
// the section is missing, initialize so that
// default components will be installed
ShowProgressMessage(L"Since InstallDefaultComponents is specified "
L" and the section [%s] is missing, default "
L"components for this section will be installed",
c_szAfSectionNetServices);
hr = m_pnsiServicesPage->HrInitForDefaultComponents();
}
if (FAILED(hr))
{
hrReturn = hr;
}
// HrInitFromAnswerFile returns FALSE if [NetClients] is missing
hr = m_pnciClientsPage->HrInitFromAnswerFile(pwifAnswerFile);
if ((S_FALSE == hr) && m_fInstallDefaultComponents)
{
// the section is missing, initialize so that
// default components will be installed
ShowProgressMessage(L"Since InstallDefaultComponents is specified "
L" and the section [%s] is missing, default "
L"components for this section will be installed",
c_szAfSectionNetClients);
hr = m_pnciClientsPage->HrInitForDefaultComponents();
}
if (FAILED(hr))
{
hrReturn = hr;
}
hr = m_pnbiBindingsPage->HrInitFromAnswerFile(pwifAnswerFile);
if (FAILED(hr))
{
hrReturn = hr;
}
return_from_function:
TraceErrorOptional(__FUNCNAME__, hrReturn,
((hrReturn == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
(hrReturn == NETSETUP_E_NO_ANSWERFILE)));
// ERROR_FILE_NOT_FOUND and NETSETUP_E_NO_ANSWERFILE are not treated
// as error by the caller of this function since they have a defined
// meaning in the context of initializing from answerfile.
// However, if logged unchanged, they will be treated as errors
// by the loggin code which will cause GUI setup to halt and display
// setuperr.log. To avoid this, change hr to S_OK if hrReturn is
// set to one of the above error codes.
//
hr = hrReturn;
if ((HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) ||
(NETSETUP_E_NO_ANSWERFILE == hr))
{
hr = S_OK;
}
NetSetupLogHrStatusV(hr, SzLoadIds(IDS_INIT_FROM_ANSWERFILE), hr);
return hrReturn;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::HrInitFromAnswerFile
//
// Purpose: Initialize internal data by reading answer-file
//
// Arguments:
// pwifAnswerFile [in] name of answer-file
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetInstallInfo::HrInitFromAnswerFile(IN PCWSTR pszAnswerFileName)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetInstallInfo::HrInitFromAnswerFile(PCWSTR)");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(pszAnswerFileName);
HRESULT hr;
hr = E_OUTOFMEMORY;
m_pwifAnswerFile = new CWInfFile();
// initialize answer file class
if ((m_pwifAnswerFile == NULL) ||
(m_pwifAnswerFile->Init() == FALSE))
{
AssertSz(FALSE,"CNetInstallInfo::HrInitFromAnswerFile - Failed to initialize CWInfFile");
return(E_OUTOFMEMORY);
}
if (m_pwifAnswerFile)
{
BOOL fStatus = m_pwifAnswerFile->Open(pszAnswerFileName);
if (fStatus)
{
hr = HrInitFromAnswerFile(m_pwifAnswerFile);
if (S_OK == hr)
{
hr = HrSetupOpenInfFile(
pszAnswerFileName, NULL,
INF_STYLE_OLDNT | INF_STYLE_WIN4,
NULL, &m_hinfAnswerFile);
}
}
else
{
hr = NETSETUP_E_NO_ANSWERFILE;
}
}
TraceErrorOptional(__FUNCNAME__, hr,
(hr == NETSETUP_E_NO_ANSWERFILE));
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::AnswerFileName
//
// Purpose:
//
// Arguments: None
//
// Returns: Name of answer-file or NULL if not yet initialized
//
// Author: kumarp 25-November-97
//
// Notes:
//
PCWSTR CNetInstallInfo::AnswerFileName()
{
TraceFileFunc(ttidGuiModeSetup);
if (!m_pwifAnswerFile)
{
return NULL;
}
else
{
return m_pwifAnswerFile->FileName();
}
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::HrGetInstanceGuidOfPreNT5NetCardInstance
//
// Purpose: Find and return instance guid of a net-card whose
// pre-nt5 instance is known
//
// Arguments:
// szPreNT5NetCardInstance [in] pre-nt5 instance of a net-card
// pguid [out] pointer to
//
// Returns: S_OK if found, S_FALSE if not
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetInstallInfo::HrGetInstanceGuidOfPreNT5NetCardInstance (
IN PCWSTR szPreNT5NetCardInstance,
OUT LPGUID pguid)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr = S_FALSE;
CNetAdapter* pna;
pna = m_pnaiAdaptersPage->FindAdapterFromPreUpgradeInstance(
szPreNT5NetCardInstance);
if (pna)
{
pna->GetInstanceGuid(pguid);
hr = S_OK;
}
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::Find
//
// Purpose: Find a component using its name in answerfile
//
// Arguments:
// pszComponentName [in] name in answerfile, e.g. Adapter01 | MS_TCPIP
//
// Returns: pointer to CNetComponent object found, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetInstallInfo::Find(IN PCWSTR pszComponentName) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszComponentName);
CNetComponent* pnc;
(pnc = m_pnaiAdaptersPage->Find(pszComponentName)) ||
(pnc = m_pnpiProtocolsPage->Find(pszComponentName)) ||
(pnc = m_pnsiServicesPage->Find(pszComponentName)) ||
(pnc = m_pnciClientsPage->Find(pszComponentName));
return pnc;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::FindFromInfID
//
// Purpose: Find a component using its InfID in answerfile
//
// Arguments:
// szInfID [in] InfID of component
//
// Returns: pointer to CNetComponent object found, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetInstallInfo::FindFromInfID(IN PCWSTR szInfID) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(szInfID);
CNetComponent* pnc;
(pnc = m_pnaiAdaptersPage->FindFromInfID(szInfID)) ||
(pnc = m_pnpiProtocolsPage->FindFromInfID(szInfID)) ||
(pnc = m_pnsiServicesPage->FindFromInfID(szInfID)) ||
(pnc = m_pnciClientsPage->FindFromInfID(szInfID));
return pnc;
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::FindAdapter
//
// Purpose: Find adapter with a given net-card-address in anwerfile
//
// Arguments:
// qwNetCardAddress [in] net card address
//
// Returns: pointer to CNetAdapter object found, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetInstallInfo::FindAdapter (
IN QWORD qwNetCardAddress,
CNetAdapter** ppNetAdapter) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(m_pnaiAdaptersPage);
return m_pnaiAdaptersPage->FindAdapter(qwNetCardAddress, ppNetAdapter);
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::FindAdapter
//
// Purpose: Find adapter with a given net-card-address in anwerfile
//
// Arguments:
// qwNetCardAddress [in] net card address
//
// Returns: pointer to CNetAdapter object found, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetInstallInfo::FindAdapter (
IN DWORD BusNumber,
IN DWORD Address,
CNetAdapter** ppNetAdapter) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(m_pnaiAdaptersPage);
return m_pnaiAdaptersPage->FindAdapter(BusNumber, Address, ppNetAdapter);
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::FindAdapter
//
// Purpose: Find adapter with given InfID in answerfile
//
// Arguments:
// pszInfId [in] InfID of an adapter
//
// Returns: pointer to CNetAdapter object found, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdapter* CNetInstallInfo::FindAdapter(IN PCWSTR pszInfId) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(m_pnaiAdaptersPage);
return m_pnaiAdaptersPage->FindAdapter(pszInfId);
}
// ----------------------------------------------------------------------
//
// Function: CNetInstallInfo::HrDoUnattended
//
// Purpose: Run answerfile section corresponding to idPage and
// install components specified in that section
//
// Arguments:
// hwndParent [in] handle of parent window
// punk [in] pointer to an interface
// idPage [in] indicates which section to run
// ppdm [out] pointer to
// pfAllowChanges [out] pointer to
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetInstallInfo::HrDoUnattended(
IN HWND hwndParent,
IN IUnknown* punk,
IN EUnattendWorkType uawType,
OUT EPageDisplayMode* ppdm,
OUT BOOL* pfAllowChanges)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetInstallInfo::HrDoUnattended");
TraceFunctionEntry(ttidNetSetup);
AssertValidWritePtr(ppdm);
AssertValidWritePtr(pfAllowChanges);
// set the defaults in case they are not specified in the answer-file
*ppdm = PDM_ONLY_ON_ERROR;
*pfAllowChanges = FALSE;
HRESULT hr=S_OK;
INetCfg * pnc = reinterpret_cast<INetCfg *>(punk);
switch(uawType)
{
case UAW_NetAdapters:
(void) m_pnaiAdaptersPage->HrDoOemPostUpgradeProcessing(pnc, hwndParent);
(void) m_pnaiAdaptersPage->HrSetConnectionNames();
break;
case UAW_NetProtocols:
m_pnpiProtocolsPage->GetDisplaySettings(ppdm, pfAllowChanges);
if (m_fProcessPageSections)
{
hr = m_pnpiProtocolsPage->HrDoNetworkInstall(hwndParent, pnc);
}
else if (m_fUpgrade)
{
hr = m_pnpiProtocolsPage->HrDoOsUpgrade(pnc);
}
break;
case UAW_NetClients:
m_pnciClientsPage->GetDisplaySettings(ppdm, pfAllowChanges);
if (m_fProcessPageSections)
{
hr = m_pnciClientsPage->HrDoNetworkInstall(hwndParent, pnc);
}
else if (m_fUpgrade)
{
hr = m_pnciClientsPage->HrDoOsUpgrade(pnc);
}
break;
case UAW_NetServices:
m_pnsiServicesPage->GetDisplaySettings(ppdm, pfAllowChanges);
if (m_fProcessPageSections)
{
// we ignore the error code since we want to do other
// things even if HrDoNetworkInstall fails
//
hr = m_pnsiServicesPage->HrDoNetworkInstall(hwndParent, pnc);
// if we installed Router during upgrade, we need to call the
// router upgrade dll to munge the registry at this point
//
if (m_fUpgrade)
{
hr = HrUpgradeRouterIfPresent(pnc, this);
if (FAILED(hr))
{
TraceError(__FUNCNAME__, hr);
TraceTag(ttidError, "%s: router upgrade failed, but the failure was ignored", __FUNCNAME__);
hr = S_OK;
}
hr = HrUpgradeTapiServer(m_hinfAnswerFile);
if (S_OK != hr)
{
TraceTag(ttidError, "%s: TAPI server upgrade failed, but the failure was ignored. error code: 0x%x", __FUNCNAME__, hr);
hr = S_OK;
}
if ( m_pwifAnswerFile )
{
(void) HrRestoreServiceStartValuesToPreUpgradeSetting(m_pwifAnswerFile);
}
// RAID 332622 (jeffspr)
//
(void) HrRemoveEvilIntelWinsockSPs();
// hr = HrRestoreWinsockProviderOrder(m_pwifAnswerFile);
}
}
else if (m_fUpgrade)
{
hr = m_pnsiServicesPage->HrDoOsUpgrade(pnc);
// RAID:NTBUG9:25950 - We need to even do this for NT5 services.
if ( m_pwifAnswerFile )
{
(void) HrRestoreServiceStartValuesToPreUpgradeSetting(m_pwifAnswerFile);
}
}
break;
case UAW_NetBindings:
if (m_fProcessPageSections)
{
m_pnbiBindingsPage->GetDisplaySettings(ppdm, pfAllowChanges);
hr = m_pnbiBindingsPage->HrDoUnattended(pnc);
}
break;
case UAW_RemoveNetComponents:
hr = HrRemoveNetComponents(pnc, &m_slNetComponentsToRemove);
break;
default:
AssertSz(FALSE, "HrDoUnattended: Invalid Page ID passed");
}
// normalize result
//
if (S_FALSE == hr)
{
hr = S_OK;
}
TraceError(__FUNCNAME__, hr);
return hr;
}
// ======================================================================
// class CPageDisplayCommonInfo: public functions
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CPageDisplayCommonInfo::CPageDisplayCommonInfo
//
// Purpose: constructor for class CPageDisplayCommonInfo
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CPageDisplayCommonInfo::CPageDisplayCommonInfo()
{
TraceFileFunc(ttidGuiModeSetup);
// InitDefaults();
m_pdmDisplay = PDM_ONLY_ON_ERROR;
m_fAllowChanges = TRUE;
}
// ----------------------------------------------------------------------
//
// Function: CPageDisplayCommonInfo::HrInitFromAnswerFile
//
// Purpose: Initialize display related keys from anwerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CPageDisplayCommonInfo::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CPageDisplayCommonInfo::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr=S_OK;
//Defaults for AnswerFile mode
m_pdmDisplay = PDM_ONLY_ON_ERROR;
m_fAllowChanges = TRUE;
//Display
PCWSTR pszDisplayMode;
pszDisplayMode = GetDisplayModeStr(m_pdmDisplay);
pszDisplayMode = pwifAnswerFile->GetStringValue(c_szAfDisplay, pszDisplayMode);
m_pdmDisplay = MapToDisplayMode(pszDisplayMode);
if (m_pdmDisplay == PDM_UNKNOWN)
{
AddAnswerFileError(pwifAnswerFile->CurrentReadSection()->Name(),
c_szAfDisplay,
IDS_E_AF_InvalidValueForThisKey);
hr = NETSETUP_E_ANS_FILE_ERROR;
}
//AllowChanges
m_fAllowChanges = pwifAnswerFile->GetBoolValue(c_szAfAllowChanges,
m_fAllowChanges);
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CNetComponentsPageBase
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::CNetComponentsPageBase
//
// Purpose: constructor for class CNetComponentsPageBase
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponentsPageBase::CNetComponentsPageBase(
IN CNetInstallInfo* pnii,
IN const GUID* lpguidDevClass) : CPageDisplayCommonInfo()
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pnii);
AssertValidReadPtr(lpguidDevClass);
//InitDefaults();
if (lpguidDevClass == &GUID_DEVCLASS_NET)
{
m_pszClassName = L"Network Cards";
m_eType = NCT_Adapter;
}
else if (lpguidDevClass == &GUID_DEVCLASS_NETTRANS)
{
m_pszClassName = L"Network Protocols";
m_eType = NCT_Protocol;
}
else if (lpguidDevClass == &GUID_DEVCLASS_NETSERVICE)
{
m_pszClassName = L"Network Services";
m_eType = NCT_Service;
}
else if (lpguidDevClass == &GUID_DEVCLASS_NETCLIENT)
{
m_pszClassName = L"Network Clients";
m_eType = NCT_Client;
}
else
{
m_pszClassName = L"unknown";
m_eType = NCT_Unknown;
}
m_pnii = pnii;
m_lpguidDevClass = lpguidDevClass;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::~CNetComponentsPageBase
//
// Purpose: destructor for class CNetComponentsPageBase
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponentsPageBase::~CNetComponentsPageBase()
{
TraceFileFunc(ttidGuiModeSetup);
EraseAndDeleteAll(m_pnclComponents);
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::HrInitFromAnswerFile
//
// Purpose: Initialize from the specified section in answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
// pszSectionName [in] section to initialize from
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetComponentsPageBase::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
IN PCWSTR pszSectionName)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetComponentsPageBase::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
AssertValidReadPtr(pszSectionName);
HRESULT hr=S_OK, hrReturn=S_OK;
PCWInfSection pwisComponents=NULL;
pwisComponents = pwifAnswerFile->FindSection(pszSectionName);
if (!pwisComponents)
{
// not an error if the entire section is missing
// AddAnswerFileError(pszSectionName, IDS_E_AF_Missing);
TraceTag(ttidNetSetup, "%s: the section [%S] is missing",
__FUNCNAME__, pszSectionName);
return S_FALSE;
}
PCWInfKey pwikComponent=NULL;
CWInfContext cwicTemp;
tstring strParamsSections;
EraseAndDeleteAll(m_pnclComponents);
do
{
pwikComponent = pwisComponents->NextKey();
ContinueIf(!pwikComponent);
strParamsSections = pwikComponent->GetStringValue(c_szEmpty);
if (strParamsSections.empty())
{
AddAnswerFileError(pszSectionName, pwikComponent->Name(),
IDS_E_AF_InvalidValueForThisKey);
hrReturn = NETSETUP_E_ANS_FILE_ERROR;
continue;
}
CNetComponent *pnc = GetNewComponent(pwikComponent->Name());
ReturnErrorIf(!pnc, E_OUTOFMEMORY);
// pnc->HrInitFromAnswerFile() destroys our context, need to save it
cwicTemp = pwifAnswerFile->CurrentReadContext();
hr = pnc->HrInitFromAnswerFile(pwifAnswerFile, strParamsSections.c_str());
// now, restore the read context
pwifAnswerFile->SetReadContext(cwicTemp);
if (FAILED(hr))
{
ShowProgressMessage(L"component %s has answerfile errors, "
L"it will not be installed/updated",
pwikComponent->Name());
delete pnc;
hrReturn = hr;
continue;
}
m_pnclComponents.insert(m_pnclComponents.end(), pnc);
}
while (pwikComponent);
if (E_OUTOFMEMORY != hrReturn)
{
// we do not want to break upgrade if a single component has answerfile errors
// only in case E_OUTOFMEMORY we want the upgrade to fail
hrReturn = S_OK;
}
TraceErrorOptional(__FUNCNAME__, hrReturn, (S_FALSE == hr));
return hrReturn;
}
// type of PFN_EDC_CALLBACK
VOID
CALLBACK
DefaultComponentCallback (
IN EDC_CALLBACK_MESSAGE Message,
IN ULONG_PTR MessageData,
IN PVOID pvCallerData OPTIONAL)
{
TraceFileFunc(ttidGuiModeSetup);
CNetComponentsPageBase* pCallbackData;
pCallbackData = (CNetComponentsPageBase*)pvCallerData;
Assert (pCallbackData);
if (EDC_INDICATE_COUNT == Message)
{
}
else if (EDC_INDICATE_ENTRY == Message)
{
const EDC_ENTRY* pEntry = (const EDC_ENTRY*)MessageData;
if (*pEntry->pguidDevClass == *pCallbackData->m_lpguidDevClass)
{
CNetComponent* pnc;
pnc = pCallbackData->GetNewComponent(pEntry->pszInfId);
if (pnc)
{
ShowProgressMessage(L"adding default component: %s",
pEntry->pszInfId);
pnc->m_strParamsSections = c_szAfNone;
pCallbackData->m_pnclComponents.push_back(pnc);
}
}
}
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::HrInitForComponents
//
// Purpose: Initialize data as if the components passed in the specified
// array were really present in the answerfile.
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes: This function is used when a top level component section
// is missing. e.g. if [NetProtocols] section is missing, this
// function initializes the internal data such that
// MS_TCPIP (the default protocol) gets installed.
//
HRESULT CNetComponentsPageBase::HrInitForDefaultComponents()
{
TraceFileFunc(ttidGuiModeSetup);
EnumDefaultComponents (
EDC_DEFAULT,
DefaultComponentCallback,
this);
return S_OK;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::Find
//
// Purpose: Find the component with the specified name
//
// Arguments:
// pszComponentName [in] name of component to find
//
// Returns: pointer to CNetComponent object found or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetComponentsPageBase::Find(IN PCWSTR pszComponentName) const
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszComponentName);
CNetComponent *pnc = NULL;
TPtrListIter pos;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pnc = (CNetComponent*) *pos++;
if (!lstrcmpiW(pnc->Name().c_str(), pszComponentName))
{
return pnc;
}
}
return NULL;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::FindFromInfID
//
// Purpose: Find the component with the specified InfID
//
// Arguments:
// szInfID [in]
//
// Returns: pointer to CNetComponent object or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetComponentsPageBase::FindFromInfID(IN PCWSTR szInfID) const
{
TraceFileFunc(ttidGuiModeSetup);
return FindComponentInList(
const_cast<CNetComponentList*>(&m_pnclComponents),
szInfID);
}
// ----------------------------------------------------------------------
//
// Function: ForceDeleteFile
//
// Purpose: Delete file whether it is readonly or not
//
// Arguments:
// lpFileName [in]
//
// Returns: TRUE for success, FALSE for failure
//
// Notes:
//
BOOL
ForceDeleteFile(IN LPCWSTR lpFileName)
{
TraceFileFunc(ttidGuiModeSetup);
Assert(lpFileName);
BOOL lRet = DeleteFile(lpFileName);
if (!lRet && (ERROR_ACCESS_DENIED == GetLastError()))
{
// kill the readonly bit, and try again
//
DWORD dwAttr = GetFileAttributes(lpFileName);
SetFileAttributes(lpFileName, (dwAttr & ~FILE_ATTRIBUTE_READONLY));
lRet = DeleteFile(lpFileName);
}
return lRet;
}
#if 0
// ----------------------------------------------------------------------
//
// Function: HrCopyNovellInf
//
// Purpose: Copies the Novell Client32's INF (iwclient.inf) so that setup will
// find it in the INF directory when we try to upgrade the client.
// Currently there is no other way to upgrade non-netclass OEM components
// on NT5->NT5 upgrades.
//
// Returns: S_OK on success, otherwise an error code
//
// Notes: Special case code that should be folded into a more generic solution
// as other users for this are found.
//
HRESULT
HrCopyNovellInf(INetCfgComponent* pINetCfgComponent)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr = S_OK;
tstring strTemp;
tstring strNewNovellInfName;
DefineFunctionName("HrCopyNovellInf");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(pINetCfgComponent);
// get the windir location
//
WCHAR szWindowsDir[MAX_PATH+1];
TraceTag(ttidNetSetup, "%s: about to get windows dir", __FUNCNAME__);
if (GetWindowsDirectory(szWindowsDir, MAX_PATH))
{
tstring strTemp;
//
// old Novell INFs used to copy themselves as part of their install.
// This is unnecessary, and will confuse setup when it grouts around
// for INFs. Delete this file.
//
strTemp = szWindowsDir;
strTemp += L"\\inf\\iwclient.inf";
TraceTag(ttidNetSetup, "%s: deleting old Novell INF file (%S)",
__FUNCNAME__, strTemp.c_str());
if (!ForceDeleteFile (strTemp.c_str()))
{
TraceTag(ttidNetSetup, "%s: old iwclient.inf not found", __FUNCNAME__);
}
else
{
TraceTag(ttidNetSetup, "%s: old iwclient.inf found and deleted", __FUNCNAME__);
}
strTemp = szWindowsDir;
strTemp += L"\\inf\\iwclient.Pnf";
ForceDeleteFile(strTemp.c_str());
//
// copy in the new INF file, and remember the destination name.
//
if (S_OK == hr)
{
static const WCHAR c_szNovellSubDir[] = L"\\netsetup\\novell";
static const WCHAR c_szNovellInfFile[] = L"\\iwclient.inf";
tstring strDir = szWindowsDir;
strDir += c_szNovellSubDir;
strTemp = szWindowsDir;
strTemp += c_szNovellSubDir;
strTemp += c_szNovellInfFile;
TraceTag(ttidNetSetup, "%s: Copying new Novell INF", __FUNCNAME__, strTemp.c_str());
hr = HrSetupCopyOemInf(strTemp, strDir, SPOST_PATH, 0, NULL, &strNewNovellInfName);
if (S_OK == hr)
{
TraceTag(ttidNetSetup, "%s: New Novell INF copied", __FUNCNAME__);
}
}
//
// There may be duplicate INF(s) for nw_nwfs remaining in the INF dir.
// Find and delete them all, making sure we *don't* delete the one we just copied.
//
TStringList lstrNovellInfs;
HINF hinf;
INFCONTEXT ic;
HANDLE hfile;
WIN32_FIND_DATA FindData;
WCHAR szTemplate[MAX_PATH+1];
wcscpy(szTemplate, szWindowsDir);
wcscat(szTemplate, L"\\inf\\oem*.inf");
hfile = FindFirstFile(szTemplate, &FindData);
while (INVALID_HANDLE_VALUE != hfile)
{
// if it's the file we just copied, skip it.
if (0 == lstrcmpiW(FindData.cFileName, strNewNovellInfName.c_str()))
goto loopcleanup;
// try it
hr = HrSetupOpenInfFile(FindData.cFileName, NULL, INF_STYLE_WIN4,
NULL, &hinf);
if (S_OK == hr)
{
// look in a section titled [Novell]...
//
hr = HrSetupFindFirstLine(hinf, L"Novell", NULL, &ic);
if (S_OK == hr)
{
WCHAR szBuf[LINE_LEN]; // LINE_LEN defined in setupapi.h as 256
do
{
// ... for a line that looks like "... = ... , nw_nwfs".
//
hr = HrSetupGetStringField(ic, 2, szBuf,
celems(szBuf), NULL);
if ((S_OK == hr) && !lstrcmpiW(szBuf, L"nw_nwfs"))
{
// another old INF file for Novell Client32!
TraceTag(ttidNetSetup, "%s: found dup INF for nw_nwfs (%S)",
__FUNCNAME__, FindData.cFileName);
// add to list for later deletion
NC_TRY
{
lstrNovellInfs.push_back(new tstring(FindData.cFileName));
}
NC_CATCH_BAD_ALLOC
{
hr = E_OUTOFMEMORY;
break;
}
// generate the PNF name and add that too.
//
if (S_OK == hr)
{
WCHAR szPNF[MAX_PATH+1];
wcscpy(szPNF, FindData.cFileName);
szPNF[wcslen(szPNF) - 3] = L'p';
NC_TRY
{
lstrNovellInfs.push_back(new tstring(szPNF));
}
NC_CATCH_BAD_ALLOC
{
hr = E_OUTOFMEMORY;
break;
}
}
}
}
while (S_OK == (hr = HrSetupFindNextLine(ic, &ic)));
}
SetupCloseInfFile(hinf);
if (SUCCEEDED(hr) || (HRESULT_FROM_WIN32(SPAPI_E_LINE_NOT_FOUND) == hr))
{
// S_FALSE is returned when HrSetupFindNextLine can find no more lines.
// line_not_found indicates HrSetupFindFirstLine didn't find a Novell section.
hr = S_OK;
}
}
if (S_OK != hr)
{
break;
}
loopcleanup:
if (!FindNextFile(hfile, &FindData))
{
if (ERROR_NO_MORE_FILES != GetLastError())
{
hr = HrFromLastWin32Error();
}
// either way, end the loop
break;
}
}
if (INVALID_HANDLE_VALUE != hfile)
{
FindClose(hfile);
}
//
// and finally, delete the old INF and PNF.
//
if (S_OK == hr)
{
TStringListIter iterlstr;
for (iterlstr = lstrNovellInfs.begin();
iterlstr != lstrNovellInfs.end();
iterlstr++)
{
tstring strInfName = szWindowsDir;
strInfName += L"\\inf\\";
strInfName += (*iterlstr)->c_str();
TraceTag(ttidNetSetup, "%s: deleting %S", __FUNCNAME__, strInfName.c_str());
if (!ForceDeleteFile (strInfName.c_str()))
{
TraceTag(ttidNetSetup, "%s: strange - we just found this file,",
" now it is deleted...", __FUNCNAME__);
}
else
{
TraceTag(ttidNetSetup, "%s: Old Novell INF or PNF deleted (%S)",
__FUNCNAME__, strInfName.c_str());
}
// no errors returned for delete failures...
}
}
EraseAndDeleteAll(&lstrNovellInfs);
}
else
{
hr = HrFromLastWin32Error();
}
return hr;
}
#endif
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::HrDoOsUpgrade
//
// Purpose: call Upgrade function of each component in order to
// upgrade it from earlier build of NT5.
//
// Arguments:
// pnc [in] pointer to INetCfg object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
HRESULT CNetComponentsPageBase::HrDoOsUpgrade(IN INetCfg* pnc)
{
TraceFileFunc(ttidGuiModeSetup);
HRESULT hr;
DefineFunctionName("CNetComponentsPageBase::HrDoOsUpgrade");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(m_pnii);
TraceTag(ttidNetSetup, "%s: upgrading components of class: %S",
__FUNCNAME__, m_pszClassName);
INetCfgInternalSetup* pInternalSetup;
hr = pnc->QueryInterface (
IID_INetCfgInternalSetup,
(VOID**)&pInternalSetup);
if (S_OK == hr)
{
INetCfgComponent* pINetCfgComponent;
CIterNetCfgComponent nccIter(pnc, m_lpguidDevClass);
while (S_OK == nccIter.HrNext(&pINetCfgComponent))
{
PWSTR pszInfId;
if (FAILED(pINetCfgComponent->GetId(&pszInfId)))
{
ReleaseObj(pINetCfgComponent);
continue;
}
TraceTag(ttidNetSetup,
"%s: Calling INetCfgInstaller::Update for: %S",
__FUNCNAME__, pszInfId);
#if 0
// NOVELL Client32 special casing
//
if (!lstrcmpiW(pszInfId, L"nw_nwfs"))
{
hr = HrCopyNovellInf(pINetCfgComponent);
if (FAILED(hr))
{
TraceTag(ttidError, "%s: Novell Client32 INF copy failed, upgrade will likely fail : hr = %08lx",
__FUNCNAME__, hr);
}
}
// end special case
#endif
hr = pInternalSetup->UpdateNonEnumeratedComponent (
pINetCfgComponent,
m_pnii->UpgradeFlag(),
m_pnii->BuildNumber());
if (FAILED(hr))
{
TraceTag(ttidError, "%s: error upgrading %S: hr = %08lx",
__FUNCNAME__, pszInfId, hr);
}
NetSetupLogComponentStatus(pszInfId, SzLoadIds (IDS_UPDATING), hr);
// we dont want to quit upgrade just because 1 component
// failed OsUpgrade, therefore reset hr to S_OK
hr = S_OK;
CoTaskMemFree(pszInfId);
ReleaseObj(pINetCfgComponent);
}
}
ReleaseObj(pInternalSetup);
TraceError(__FUNCNAME__, hr);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::HrDoNetworkInstall
//
// Purpose: call Install function of each component
// in the answerfile in order to install it.
//
// Arguments:
// hwndParent [in] handle of parent window
// pnc [in] pointer to INetCfg object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetComponentsPageBase::HrDoNetworkInstall (
IN HWND hwndParent,
IN INetCfg* pnc)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetComponentsPageBase::HrDoNetworkInstall");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(pnc);
if (m_pnclComponents.size() > 0)
{
ShowProgressMessage(L"Installing components of class: %s",
m_pszClassName);
}
else
{
ShowProgressMessage(L"No components to install/update for class: %s",
m_pszClassName);
}
HRESULT hr;
INetCfgClassSetup* pINetCfgClassSetup;
hr = pnc->QueryNetCfgClass(m_lpguidDevClass, IID_INetCfgClassSetup,
reinterpret_cast<void**>(&pINetCfgClassSetup));
if (S_OK == hr)
{
INetCfgComponent* pINetCfgComponent;
CNetComponentList::iterator pos;
CNetComponent* pncTemp;
OBO_TOKEN OboToken;
ZeroMemory (&OboToken, sizeof(OboToken));
OboToken.Type = OBO_USER;
for (pos = m_pnclComponents.begin();
pos != m_pnclComponents.end();
pos++)
{
pncTemp = (CNetComponent*)*pos;
Assert(pncTemp);
PCWSTR pszInfId;
PCWSTR pszParamsSections;
pszInfId = pncTemp->InfID().c_str();
pszParamsSections = pncTemp->ParamsSections().c_str();
// cant install a component whose InfID is "Unknown"
// the down-level upgrade DLL, dumps correct InfID
// for only the supported components,
// all others are dumped as "Unknown"
//
if (!_wcsicmp(pszInfId, c_szAfUnknown))
{
continue;
}
hr = pnc->FindComponent(pszInfId, &pINetCfgComponent);
if (FAILED(hr))
{
continue;
}
else if (S_FALSE == hr)
{
// currently the SkipInstall feature is used only by
// SNA for its peculiar upgrade requirements. This may or may
// not become a documented feature.
//
if (pncTemp->m_fSkipInstall)
{
TraceTag(ttidNetSetup,
"%s: SkipInstall is TRUE for %S --> "
"skipped its install",
__FUNCNAME__, pszInfId);
pINetCfgComponent = NULL;
hr = S_OK;
}
else
{
// component is not installed. need to install it first
//
ShowProgressMessage(
L"Installing '%s' and applying "
L"properties in section [%s] to it... ",
pszInfId, pszParamsSections);
TraceTag(ttidNetSetup,
"%s: UpgradeFlag: 0x%x, BuildNumber: %d",
__FUNCNAME__,
m_pnii->UpgradeFlag(),
m_pnii->BuildNumber());
Assert (!pINetCfgComponent);
hr = pINetCfgClassSetup->Install(
pszInfId,
&OboToken,
m_pnii->UpgradeFlag(),
m_pnii->BuildNumber(),
m_pnii->AnswerFileName(),
pszParamsSections,
&pINetCfgComponent);
if (SUCCEEDED(hr))
{
ShowProgressMessage(L"...successfully installed %s",
pszInfId);
GUID guid;
pINetCfgComponent->GetInstanceGuid(&guid);
pncTemp->SetInstanceGuid(&guid);
}
else
{
ShowProgressMessage(L"...error installing: %s, "
L"errcode: %08lx", pszInfId, hr);
// Answerfile specified a non-existent INF.
if (SPAPI_E_NO_DRIVER_SELECTED == hr)
{
hr = S_OK;
continue;
}
}
NetSetupLogComponentStatus(pszInfId,
SzLoadIds (IDS_INSTALLING), hr);
}
}
else // S_FALSE != hr IOW ( (SUCCEEDED(hr)) && (S_FALSE != hr) )
{
Assert (pINetCfgComponent);
// Component is already installed, just call ReadAnswerFile
// Need to query for the private component interface which
// gives us access to the notify object.
//
INetCfgComponentPrivate* pComponentPrivate;
hr = pINetCfgComponent->QueryInterface(
IID_INetCfgComponentPrivate,
reinterpret_cast<void**>(&pComponentPrivate));
if (S_OK == hr)
{
INetCfgComponentSetup* pINetCfgComponentSetup;
// Query the notify object for its setup interface.
// If it doesn't support it, that's okay, we can continue.
//
hr = pComponentPrivate->QueryNotifyObject(
IID_INetCfgComponentSetup,
(void**) &pINetCfgComponentSetup);
if (S_OK == hr)
{
ShowProgressMessage(L"Applying properties in section [%s] to component: %s",
pszParamsSections,
pszInfId);
hr = pINetCfgComponentSetup->ReadAnswerFile(
m_pnii->AnswerFileName(),
pszParamsSections);
ReleaseObj(pINetCfgComponentSetup);
if (SUCCEEDED(hr))
{
if (S_OK == hr)
{
hr = pComponentPrivate->SetDirty();
}
ShowProgressMessage(L"...successfully applied properties to %s",
pszInfId);
}
else
{
ShowProgressMessage(L"...error applying properties to: %s, "
L"errcode: %08lx",
pszInfId, hr);
}
NetSetupLogComponentStatus(pszInfId,
SzLoadIds (IDS_CONFIGURING), hr);
}
else if (E_NOINTERFACE == hr)
{
hr = S_OK;
}
ReleaseObj (pComponentPrivate);
}
}
if (S_OK == hr)
{
// If required, run OEM INF against the Params key
// of the component that we just installed
//
if (pncTemp->m_fIsOemComponent)
{
HKEY hkeyParams;
// currently the SkipInstall feature is used only by
// SNA for its peculiar upgrade requirements. This may or may
// not become a documented feature.
//
if (pncTemp->m_fSkipInstall)
{
hkeyParams = NULL;
}
else
{
hr = pINetCfgComponent->OpenParamKey(&hkeyParams);
}
// if specified, run OEM INF section to patch
// the component Params key
//
if ((S_OK == hr) &&
!pncTemp->m_strInfToRunAfterInstall.empty())
{
TraceTag(ttidNetSetup,
"%s: running InfToRunAfterInstall for %S, "
"INF: %S, section: %S",
__FUNCNAME__, pszInfId,
pncTemp->m_strInfToRunAfterInstall.c_str(),
pncTemp->m_strSectionToRunAfterInstall.c_str());
hr = HrInstallFromInfSectionInFile(
hwndParent,
pncTemp->m_strInfToRunAfterInstall.c_str(),
pncTemp->m_strSectionToRunAfterInstall.c_str(),
hkeyParams, TRUE);
if (S_OK != hr)
{
TraceTag(ttidNetSetup, "%s: error applying OEM INF for %S, "
"INF: %S, section: %S",
__FUNCNAME__, pszInfId,
pncTemp->m_strInfToRunAfterInstall.c_str(),
pncTemp->m_strSectionToRunAfterInstall.c_str());
}
NetSetupLogComponentStatus(pszInfId,
SzLoadIds (IDS_APPLY_INFTORUN), hr);
}
// If specified, load OEM DLL and call migration function
//
if ((S_OK == hr) &&
!pncTemp->m_strOemDll.empty())
{
hr = HrProcessOemComponent(
hwndParent,
pncTemp->m_strOemDir.c_str(),
pncTemp->m_strOemDll.c_str(),
&m_pnii->m_nui,
hkeyParams,
pncTemp->m_strInfID.c_str(),
pncTemp->m_strInfID.c_str(),
m_pnii->m_hinfAnswerFile,
pncTemp->m_strParamsSections.c_str());
NetSetupLogComponentStatus(pszInfId,
SzLoadIds (IDS_PROCESSING_OEM), hr);
}
RegSafeCloseKey(hkeyParams);
}
}
ReleaseObj(pINetCfgComponent);
}
ReleaseObj(pINetCfgClassSetup);
pnc->Apply();
}
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponentsPageBase::HrValidate
//
// Purpose: Validate data read from the answerfile
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetComponentsPageBase::HrValidate() const
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetComponentsPageBase::HrValidate");
HRESULT hr = E_FAIL;
TPtrListIter pos;
CNetComponent* pnc;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pnc = (CNetComponent *) *pos++;
hr = pnc->HrValidate();
ReturnHrIfFailed(hr);
}
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CNetAdaptersPage
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::CNetAdaptersPage
//
// Purpose: constructor for class CNetAdaptersPage
//
// Arguments:
// pnii [in] pointer to CNetInstallInfo object
//
// Returns:
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdaptersPage::CNetAdaptersPage(IN CNetInstallInfo* pnii)
: CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NET)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::HrInitFromAnswerFile
//
// Purpose: Initialize from [NetAdapters] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetAdaptersPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdaptersPage::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr;
hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
c_szAfSectionNetAdapters);
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::FindAdapter
//
// Purpose: Find adapter with a given net-card-address in anwerfile
//
// Arguments:
// qwNetCardAddress [in] net card address
//
// Returns: pointer to CNetAdapter object
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetAdaptersPage::FindAdapter(
IN QWORD qwNetCardAddress,
OUT CNetAdapter** ppNetAdapter) const
{
TraceFileFunc(ttidGuiModeSetup);
CNetAdapter* pna;
HRESULT hr;
TPtrListIter pos;
Assert(ppNetAdapter);
hr = NETSETUP_E_NO_EXACT_MATCH;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pna = (CNetAdapter*) *pos++;
if (pna->NetCardAddr() == qwNetCardAddress)
{
*ppNetAdapter = pna;
hr = S_OK;
break;
}
else if (0 == pna->NetCardAddr())
{
hr = NETSETUP_E_AMBIGUOUS_MATCH;
}
}
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::FindAdapter
//
// Purpose: Find adapter with a given net-card-address in anwerfile
//
// Arguments:
// qwNetCardAddress [in] net card address
//
// Returns: pointer to CNetAdapter object
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetAdaptersPage::FindAdapter(
IN DWORD BusNumber,
IN DWORD Address,
OUT CNetAdapter** ppNetAdapter) const
{
TraceFileFunc(ttidGuiModeSetup);
CNetAdapter* pna;
HRESULT hr;
TPtrListIter pos;
Assert(ppNetAdapter);
hr = NETSETUP_E_NO_EXACT_MATCH;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pna = (CNetAdapter*) *pos++;
// Only check sections that did not specify a MAC address and
// did specify PCI location info.
//
if ((0 == pna->NetCardAddr()) && pna->FPciInfoSpecified())
{
if ((pna->PciBusNumber() == BusNumber) &&
(pna->PciAddress() == Address))
{
*ppNetAdapter = pna;
hr = S_OK;
break;
}
}
else
{
hr = NETSETUP_E_AMBIGUOUS_MATCH;
}
}
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::FindAdapter
//
// Purpose: Find adapter with the given InfID
//
// Arguments:
// szInfID [in] InfID of the adapter to be located
//
// Returns: pointer to CNetAdapter object, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdapter* CNetAdaptersPage::FindAdapter(IN PCWSTR szInfID) const
{
TraceFileFunc(ttidGuiModeSetup);
return (CNetAdapter*) FindComponentInList(
const_cast<CNetComponentList*>(&m_pnclComponents),
szInfID);
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::FindAdapterFromPreUpgradeInstance
//
// Purpose: Find adapter with the given pre-upgrade instance
//
// Arguments:
// szPreUpgradeInstance [in]
//
// Returns: pointer to CNetAdapter object
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdapter* CNetAdaptersPage::FindAdapterFromPreUpgradeInstance(IN PCWSTR szPreUpgradeInstance)
{
CNetAdapter* pna;
TPtrListIter pos;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pna = (CNetAdapter*) *pos++;
if (!lstrcmpiW(pna->PreUpgradeInstance(), szPreUpgradeInstance))
{
return pna;
}
}
return NULL;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::GetNumCompatibleAdapters
//
// Purpose: Find the total number of adapters in the answerfile that
// are compatible with the given list of adapters
//
// Arguments:
// mszInfID [in] list of adapters as a multi-sz
//
// Returns: number of such adapters found
//
// Author: kumarp 25-November-97
//
// Notes:
//
DWORD CNetAdaptersPage::GetNumCompatibleAdapters(IN PCWSTR mszInfID) const
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdaptersPage::GetNumCompatibleAdapters");
if ((NULL == mszInfID) || (0 == *mszInfID))
{
return 0;
}
CNetAdapter* pna;
TPtrListIter pos;
pos = m_pnclComponents.begin();
DWORD dwNumAdapters=0;
PCWSTR szInfId;
while (pos != m_pnclComponents.end())
{
pna = (CNetAdapter*) *pos++;
if ((0 == pna->NetCardAddr()) && !pna->FPciInfoSpecified())
{
szInfId = pna->InfID().c_str();
if (0 == lstrcmpiW(szInfId, c_szAfInfIdWildCard))
{
TraceTag(ttidNetSetup, "%s: InfID=%S matches %S",
__FUNCNAME__, c_szAfInfIdWildCard, mszInfID);
dwNumAdapters++;
}
else if (FIsSzInMultiSzSafe(szInfId, mszInfID))
{
dwNumAdapters++;
}
}
}
return dwNumAdapters;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::FindCompatibleAdapter
//
// Purpose: Find an adapter in the answerfile that
// is compatible with the given list of adapters
//
// Arguments:
// mszInfIDs [in] list of adapters as a multi-sz
//
// Returns: pointer to CNetAdapter object, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdapter* CNetAdaptersPage::FindCompatibleAdapter(IN PCWSTR mszInfIDs) const
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdaptersPage::FindCompatibleAdapter");
CNetAdapter* pna;
TPtrListIter pos;
pos = m_pnclComponents.begin();
PCWSTR szInfId;
while (pos != m_pnclComponents.end())
{
pna = (CNetAdapter*) *pos++;
// Only compare with those sections that did not specify an ethernet
// address or PCI location info.
//
if ((0 == pna->NetCardAddr()) && !pna->FPciInfoSpecified())
{
szInfId = pna->InfID().c_str();
if (0 == lstrcmpiW(szInfId, c_szAfInfIdWildCard))
{
TraceTag(ttidNetSetup, "%s: InfID=%S matched to %S",
__FUNCNAME__, c_szAfInfIdWildCard, mszInfIDs);
return pna;
}
else if (FIsSzInMultiSzSafe(szInfId, mszInfIDs))
{
return pna;
}
}
}
return NULL;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::HrResolveNetAdapters
//
// Purpose: Enumerate over installed adapters and determine which
// installed adapter corresponds to which adapter specified in
// the answerfile.
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-December-97
//
// Notes:
//
HRESULT CNetAdaptersPage::HrResolveNetAdapters(IN INetCfg* pnc)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdaptersPage::HrResolveNetAdapters");
HRESULT hr=S_OK;
AssertValidReadPtr(m_pnii);
AssertValidReadPtr(m_pnii->AnswerFile());
CWInfSection* pwisNetAdapters;
pwisNetAdapters =
m_pnii->AnswerFile()->FindSection(c_szAfSectionNetAdapters);
if (!pwisNetAdapters)
{
TraceTag(ttidNetSetup, "%s: not resolving adapters, since section [%S]"
" is missing",
__FUNCNAME__, c_szAfSectionNetAdapters);
return S_OK;
}
INetCfgComponent* pINetCfgComponent;
GUID guid;
PWSTR pszInfId;
PWSTR pmszInfIDs = NULL;
CNetAdapter* pna;
WORD cNumAdapters;
WCHAR szServiceInstance[_MAX_PATH];
DWORD dwcc; // component characteristics
ShowProgressMessage(L"Matching installed adapters to the ones "
L"specified in the answerfile...");
CIterNetCfgComponent nccIter(pnc, m_lpguidDevClass);
while ((S_OK == hr) && (S_OK == (hr = nccIter.HrNext(&pINetCfgComponent))))
{
hr = pINetCfgComponent->GetId(&pszInfId);
if (S_OK == hr)
{
hr = pINetCfgComponent->GetCharacteristics(&dwcc);
if (S_OK == hr)
{
if (dwcc & NCF_PHYSICAL)
{
ShowProgressMessage(L"Trying to resolve adapter '%s'...", pszInfId);
// the defs of HIDWORD and LODWORD are wrong in byteorder.hxx
# define LODWORD(a) (DWORD)( (a) & ( (DWORD)~0 ))
# define HIDWORD(a) (DWORD)( (a) >> (sizeof(DWORD)*8) )
// since we have more than one adapters of the same type
// we need to compare their netcard address in order to find a match
QWORD qwNetCardAddr=0;
PWSTR pszBindName;
hr = pINetCfgComponent->GetBindName (&pszBindName);
if (S_OK == hr)
{
wcscpy (szServiceInstance, c_szDevice);
wcscat (szServiceInstance, pszBindName);
hr = HrGetNetCardAddr(szServiceInstance,
&qwNetCardAddr);
if (S_OK == hr)
{
// there is a bug in wvsprintfA (used in trace.cpp)
// because of which it does not handle %I64x
// therefore we need to show the QWORD addr as follows
//
ShowProgressMessage(
L"\t... net card address of %s is 0x%x%x",
szServiceInstance, HIDWORD(qwNetCardAddr),
LODWORD(qwNetCardAddr));
hr = FindAdapter(qwNetCardAddr, &pna);
if (NETSETUP_E_NO_EXACT_MATCH == hr)
{
ShowProgressMessage(
L"\t... there is no card with this "
L"netcard address in the answerfile");
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
}
else
{
ShowProgressMessage(
L"\t... unable to find netcard addr of %s",
pszInfId);
}
CoTaskMemFree (pszBindName);
}
hr = HrGetCompatibleIdsOfNetComponent(pINetCfgComponent,
&pmszInfIDs);
if (FAILED(hr))
{
hr = E_OUTOFMEMORY;
// make this single InfID into a msz
//
UINT cchInfId = wcslen (pszInfId);
pmszInfIDs = (PWSTR)MemAlloc ((cchInfId + 2) *
sizeof (WCHAR));
if (pmszInfIDs)
{
hr = S_OK;
wcscpy (pmszInfIDs, pszInfId);
pmszInfIDs[cchInfId + 1] = '\0';
}
}
if (S_OK == hr)
{
cNumAdapters=0;
pna = NULL;
cNumAdapters = (WORD)GetNumCompatibleAdapters(pmszInfIDs);
if (cNumAdapters == 1)
{
// no need to match the netcard address
pna = (CNetAdapter*) FindCompatibleAdapter(pmszInfIDs);
AssertValidReadPtr(pna);
}
else
{
// no matching adapters found
ShowProgressMessage(L"... answerfile does not have the "
L"installed card %s", pszInfId);
}
if (!pna)
{
hr = NETSETUP_E_NO_EXACT_MATCH;
}
MemFree (pmszInfIDs);
}
if (S_OK == hr)
{
hr = pINetCfgComponent->GetInstanceGuid(&guid);
if (S_OK == hr)
{
pna->SetInstanceGuid(&guid);
WCHAR szGuid[c_cchGuidWithTerm];
StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
ShowProgressMessage(L"%s == %s (%s)",
pna->Name().c_str(),
pszInfId, szGuid);
}
}
}
else
{
TraceTag(ttidNetSetup,
"%s: skipped non-physical adapter %S",
__FUNCNAME__, pszInfId);
}
}
CoTaskMemFree(pszInfId);
}
ReleaseObj(pINetCfgComponent);
}
if (S_FALSE == hr)
{
hr = S_OK;
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrFindByInstanceGuid
//
// Purpose: Get INetCfgComponent* from the instance GUID
//
// Arguments:
// pnc [in] pointer to INetCfg object
// pguidDevClass [in] pointer to class GUID
// pguid [in] pointer to instance GUID
// ppncc [out] pointer to INetCfgComponent* to return
//
// Returns: S_OK on success, S_FALSE if not found,
// otherwise an error code
//
// Author: kumarp 10-September-98
//
// Notes:
//
HRESULT HrFindByInstanceGuid(IN INetCfg* pnc,
IN const GUID* pguidDevClass,
IN LPGUID pguid,
OUT INetCfgComponent** ppncc)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrFindByInstanceGuid");
HRESULT hr=S_FALSE;
CIterNetCfgComponent nccIter(pnc, pguidDevClass);
GUID guid;
INetCfgComponent* pINetCfgComponent;
int cAdapter=0;
*ppncc = NULL;
while (S_OK == (hr = nccIter.HrNext(&pINetCfgComponent)))
{
hr = pINetCfgComponent->GetInstanceGuid(&guid);
if (S_OK == hr)
{
#ifdef ENABLETRACE
WCHAR szGuid[c_cchGuidWithTerm];
StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
TraceTag(ttidNetSetup, "%s: ...%d] %S",
__FUNCNAME__, ++cAdapter, szGuid);
#endif
if (*pguid == guid)
{
hr = S_OK;
*ppncc = pINetCfgComponent;
break;
}
}
ReleaseObj(pINetCfgComponent);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: CNetAdaptersPage::HrDoOemPostUpgradeProcessing
//
// Purpose: Call the post-upgrade functions from OEM DLL
//
// Arguments:
// pnc [in] pointer to INetCfg object
// hwndParent [in] handle of parent window
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 10-September-98
//
// Notes:
//
HRESULT CNetAdaptersPage::HrDoOemPostUpgradeProcessing(IN INetCfg* pnc,
IN HWND hwndParent)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdaptersPage::HrDoOemPostUpgradeProcessing");
TPtrListIter pos;
CNetComponent* pncTemp;
HRESULT hr=S_OK;
PCWSTR szInfID;
HKEY hkeyParams;
GUID guid;
INetCfgComponent* pncc=NULL;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pncTemp = (CNetComponent*) *pos++;
AssertSz(pncTemp,
"HrDoOemPostUpgradeProcessing: pncTemp cannot be null!");
szInfID = pncTemp->InfID().c_str();
// cant process a component whose InfID is "Unknown"
//
if (!_wcsicmp(szInfID, c_szAfUnknown))
{
continue;
}
// we process only those components that specify OemDll
//
if (pncTemp->OemDll().empty())
{
continue;
}
Assert(!pncTemp->OemDir().empty());
TraceTag(ttidNetSetup, "%s: processing %S (%S)...",
__FUNCNAME__, pncTemp->Name().c_str(), szInfID);
pncTemp->GetInstanceGuid(&guid);
#ifdef ENABLETRACE
WCHAR szGuid[c_cchGuidWithTerm];
StringFromGUID2(guid, szGuid, c_cchGuidWithTerm);
TraceTag(ttidNetSetup, "%s: ...%S == %S",
__FUNCNAME__, pncTemp->Name().c_str(), szGuid);
#endif
hr = HrFindByInstanceGuid(pnc, m_lpguidDevClass,
&guid, &pncc);
if (S_OK == hr)
{
hr = pncc->OpenParamKey(&hkeyParams);
if (S_OK == hr)
{
hr = HrProcessOemComponent(
hwndParent,
pncTemp->OemDir().c_str(),
pncTemp->OemDll().c_str(),
&m_pnii->m_nui,
hkeyParams,
szInfID,
szInfID,
m_pnii->m_hinfAnswerFile,
pncTemp->m_strParamsSections.c_str());
NetSetupLogComponentStatus(szInfID,
SzLoadIds (IDS_PROCESSING_OEM), hr);
RegSafeCloseKey(hkeyParams);
}
ReleaseObj(pncc);
}
#ifdef ENABLETRACE
else
{
TraceTag(ttidNetSetup, "%s: ...could not locate %S",
__FUNCNAME__, pncTemp->Name().c_str());
}
#endif
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: CNetAdaptersPage::HrSetConnectionNames
//
// Purpose: Enumerate over each adapter specified in the answerfile
// and rename the corresponding connection if
// ConnectionName is specified for that adapter.
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 23-September-98
//
// Notes:
//
HRESULT CNetAdaptersPage::HrSetConnectionNames()
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrSetConnectionNames");
HRESULT hr=S_OK;
TPtrListIter pos;
CNetAdapter* pncTemp;
GUID guid;
PCWSTR szConnectionName;
PCWSTR szAdapterName;
pos = m_pnclComponents.begin();
while (pos != m_pnclComponents.end())
{
pncTemp = (CNetAdapter*) *pos++;
AssertSz(pncTemp,
"HrSetConnectionNames: pncTemp cannot be null!");
pncTemp->GetInstanceGuid(&guid);
if (GUID_NULL != guid)
{
szAdapterName = pncTemp->Name().c_str();
szConnectionName = pncTemp->ConnectionName();
if (wcslen(szConnectionName) > 0)
{
hr = HrSetLanConnectionName(&guid, szConnectionName);
if (S_OK == hr)
{
ShowProgressMessage(L"Name of the connection represented by '%s' set to '%s'", szAdapterName, szConnectionName);
}
else
{
ShowProgressMessage(L"Could not set name of the connection represented by '%s' to '%s'. Error code: 0x%lx", szAdapterName, szConnectionName, hr);
}
}
}
#ifdef ENABLETRACE
else
{
TraceTag (ttidNetSetup, "An exact owner could not be found for section %S", pncTemp->m_strParamsSections.c_str());
}
#endif
}
TraceError(__FUNCNAME__, hr);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdaptersPage::GetNewComponent
//
// Purpose: Create and return a new component suitabe for this class
//
// Arguments:
// pszName [in] name of component to create
//
// Returns: pointer to CNetComponent object created
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetAdaptersPage::GetNewComponent(IN PCWSTR pszName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszName);
return new CNetAdapter(pszName);
}
// ======================================================================
// class CNetProtocolsPage
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetProtocolsPage::CNetProtocolsPage
//
// Purpose: constructor for class CNetProtocolsPage
//
// Arguments:
// pnii [in] pointer to CNetInstallInfo object
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetProtocolsPage::CNetProtocolsPage(IN CNetInstallInfo* pnii)
: CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETTRANS)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ----------------------------------------------------------------------
//
// Function: CNetProtocolsPage::HrInitFromAnswerFile
//
// Purpose: Initialize from the [NetProtocols] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetProtocolsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetProtocolsPage::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr;
hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
c_szAfSectionNetProtocols);
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetProtocolsPage::GetNewComponent
//
// Purpose: Create and return a new component suitabe for this class
//
// Arguments:
// pszName [in] name of
//
// Returns: pointer to CNetComponent object
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetProtocolsPage::GetNewComponent(IN PCWSTR pszName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszName);
return new CNetProtocol(pszName);
}
// ======================================================================
// class CNetServicesPage
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetServicesPage::CNetServicesPage
//
// Purpose: constructor for class CNetServicesPage
//
// Arguments:
// pnii [in] pointer to CNetInstallInfo object
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetServicesPage::CNetServicesPage(IN CNetInstallInfo* pnii)
: CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETSERVICE)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ----------------------------------------------------------------------
//
// Function: CNetServicesPage::HrInitFromAnswerFile
//
// Purpose: Initialize from the [NetServices] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetServicesPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetServicesPage::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr;
hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
c_szAfSectionNetServices);
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetServicesPage::GetNewComponent
//
// Purpose: Create and return a new component suitabe for this class
//
// Arguments:
// pszName [in] name of component to be created
//
// Returns: pointer to CNetComponent object
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetServicesPage::GetNewComponent(IN PCWSTR pszName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszName);
return new CNetService(pszName);
}
// ======================================================================
// class CNetClientsPage
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetClientsPage::CNetClientsPage
//
// Purpose: constructor for class CNetClientsPage
//
// Arguments:
// pnii [in] pointer to CNetInstallInfo object
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetClientsPage::CNetClientsPage(IN CNetInstallInfo* pnii)
: CNetComponentsPageBase(pnii, &GUID_DEVCLASS_NETCLIENT)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ----------------------------------------------------------------------
//
// Function: CNetClientsPage::HrInitFromAnswerFile
//
// Purpose: Initialize from the [NetClients] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetClientsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetClientsPage::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr;
hr = CNetComponentsPageBase::HrInitFromAnswerFile(pwifAnswerFile,
c_szAfSectionNetClients);
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetClientsPage::GetNewComponent
//
// Purpose: Create and return a new component suitabe for this class
//
// Arguments:
// pszName [in] name of
//
// Returns: pointer to CNetComponent object
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* CNetClientsPage::GetNewComponent(IN PCWSTR pszName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszName);
return new CNetClient(pszName);
}
// ======================================================================
// class CNetBindingsPage
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetBindingsPage::CNetBindingsPage
//
// Purpose: constructor for class CNetBindingsPage
//
// Arguments:
// pnii [in] pointer to CNetInstallInfo object
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetBindingsPage::CNetBindingsPage(IN CNetInstallInfo* pnii)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pnii);
m_pnii = pnii;
}
// ----------------------------------------------------------------------
//
// Function: CNetBindingsPage::HrInitFromAnswerFile
//
// Purpose: Initialize from the [NetBindings] section in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetBindingsPage::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetBindingsPage::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
HRESULT hr;
PCWInfSection pwisBindings;
pwisBindings = pwifAnswerFile->FindSection(c_szAfSectionNetBindings);
if (!pwisBindings)
{
//it is not an error if the Bindings section is missing
return S_OK;
}
EraseAndDeleteAll(m_plBindingActions);
hr = E_OUTOFMEMORY;
CBindingAction* pba = new CBindingAction();
if (pba)
{
hr = S_OK;
PCWInfKey pwikKey;
for (pwikKey = pwisBindings->FirstKey();
pwikKey;
pwikKey = pwisBindings->NextKey())
{
HRESULT hrT = pba->HrInitFromAnswerFile(pwikKey);
if (S_OK == hrT)
{
AddAtEndOfPtrList(m_plBindingActions, pba);
pba = new CBindingAction();
if (!pba)
{
hr = E_OUTOFMEMORY;
break;
}
}
}
delete pba;
}
TraceFunctionError(hr);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetBindingsPage::HrDoUnattended
//
// Purpose: Perform instrunctions specified in the [NetBindings] section
// in the answerfile
//
// Arguments:
// hwndParent [in] handle of parent window
// pnc [in] pointer to INetCfg object
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT
CNetBindingsPage::HrDoUnattended (
IN INetCfg* pnc)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetBindingsPage::HrDoUnattended");
HRESULT hr;
if (m_plBindingActions.size() > 0)
{
ShowProgressMessage(L"Applying bindings...");
}
else
{
ShowProgressMessage(L"No binding actions to apply");
}
TPtrListIter pos = m_plBindingActions.begin();
CBindingAction* pba;
while (pos != m_plBindingActions.end())
{
pba = (CBindingAction*) *pos++;
// ignore the return code so that we can try to perform
// remaining actions
hr = pba->HrPerformAction(pnc);
}
hr = pnc->Apply();
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CBindingAction
// ======================================================================
CNetInstallInfo* CBindingAction::m_pnii = NULL;
//+---------------------------------------------------------------------------
//
// Function: CBindingAction::CBindingAction
//
// Purpose: constructor
//
// Arguments: (none)
//
//
// Returns: none
//
// Author: kumarp 05-July-97
//
// Notes:
//
CBindingAction::CBindingAction()
{
TraceFileFunc(ttidGuiModeSetup);
m_eBindingAction = BND_Unknown;
}
//+---------------------------------------------------------------------------
//
// Function: CBindingAction::~CBindingAction
//
// Purpose: destructor
//
// Arguments: (none)
//
// Returns: none
//
// Author: kumarp 05-July-97
//
// Notes:
//
CBindingAction::~CBindingAction()
{
}
//+---------------------------------------------------------------------------
//
// Function: MapBindingActionName
//
// Purpose: maps the answerfile token to appropriate binding action
//
// Arguments:
// pszActionName [in] answer-file token, e.g. "Disable"
//
// Returns: enum for binding action, or BND_Unknown if incorrect token passed
//
// Author: kumarp 05-July-97
//
// Notes:
//
EBindingAction MapBindingActionName(IN PCWSTR pszActionName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszActionName);
if (!_wcsicmp(c_szAfEnable, pszActionName))
return BND_Enable;
else if (!_wcsicmp(c_szAfDisable, pszActionName))
return BND_Disable;
else if (!_wcsicmp(c_szAfPromote, pszActionName))
return BND_Promote;
else if (!_wcsicmp(c_szAfDemote, pszActionName))
return BND_Demote;
else
return BND_Unknown;
}
//+---------------------------------------------------------------------------
//
// Function: CBindingAction::HrInitFromAnswerFile
//
// Purpose: Reads value of a single key passed as argument and initializes
// internal data
//
// Arguments:
// pwikKey [in] pointer to CWInfKey
//
// Returns: S_OK if success or NETSETUP_E_ANS_FILE_ERROR on failure
//
// Author: kumarp 05-July-97
//
// Notes:
//
HRESULT CBindingAction::HrInitFromAnswerFile(IN const CWInfKey* pwikKey)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CBindingAction::HrInitFromAnswerFile");
AssertValidReadPtr(pwikKey);
HRESULT hr=E_FAIL;
tstring strComponent;
TStringListIter pos;
m_eBindingAction = MapBindingActionName(pwikKey->Name());
if (m_eBindingAction == BND_Unknown)
{
AddAnswerFileError(c_szAfSectionNetBindings,
pwikKey->Name(),
IDS_E_AF_InvalidBindingAction);
hr = NETSETUP_E_ANS_FILE_ERROR;
}
else
{
BOOL fStatus;
TStringList slComponents;
#if DBG
m_strBindingPath = pwikKey->GetStringValue(c_szAfUnknown);
#endif
fStatus = pwikKey->GetStringListValue(m_slBindingPath);
DWORD cComponentsInBindingPath = m_slBindingPath.size();
// we need binding path to have atleast 2 items
// e.g. Disable=service1,proto1,adapter1
// we do not process binding actions like
// Disable=proto1,adapter1 or Disable=adapter1
//
if (!fStatus || (cComponentsInBindingPath < 2))
{
AddAnswerFileError(c_szAfSectionNetBindings,
pwikKey->Name(),
IDS_E_AF_InvalidValueForThisKey);
hr = NETSETUP_E_ANS_FILE_ERROR;
#if DBG
if (cComponentsInBindingPath < 2)
{
ShowProgressMessage(L"ignored binding path %s of length %d",
m_strBindingPath.c_str(),
cComponentsInBindingPath);
}
#endif
}
else
{
hr = S_OK;
}
}
TraceFunctionError(hr);
return hr;
}
// =================================================================
// Add to common
//+---------------------------------------------------------------------------
//
// Function: ReleaseINetCfgComponentsAndEraseList
//
// Purpose: releases INetCfgComponent pointers in the passed list
// and then erases the list
//
// Arguments:
// pplComponents [in] list of INetCfgComponent pointers
//
// Returns: none
//
// Author: kumarp 05-July-97
//
// Notes: Does NOT free the passed list
//
void ReleaseINetCfgComponentsAndEraseList(TPtrList* pplComponents)
{
TraceFileFunc(ttidGuiModeSetup);
INetCfgComponent* pncc;
TPtrListIter pos;
pos = pplComponents->begin();
while (pos != pplComponents->end())
{
pncc = (INetCfgComponent*) *pos++;
ReleaseObj(pncc);
}
EraseAll(pplComponents);
}
//+---------------------------------------------------------------------------
//
// Function: HrGetBindingPathStr
//
// Purpose: Gets a string representation of a given binding-path
//
// Arguments:
// pncbp [in] binding path
// pstrBindingPath [out] string representation of the binding path
//
// Returns: S_OK if success, error code returned by respective COM
// interfaces otherwise
//
// Author: kumarp 05-July-97
//
// Notes:
//
HRESULT HrGetBindingPathStr(INetCfgBindingPath *pncbp, tstring* pstrBindingPath)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetBindingPathStr");
AssertValidReadPtr(pncbp);
AssertValidWritePtr(pstrBindingPath);
HRESULT hr=S_OK;
CIterNetCfgBindingInterface ncbiIter(pncbp);
INetCfgBindingInterface * pncbi;
INetCfgComponent * pncc = NULL;
BOOL fFirstInterface=TRUE;
PWSTR szInfId;
while (SUCCEEDED(hr) && (S_OK == (hr = ncbiIter.HrNext(&pncbi))))
{
if (fFirstInterface)
{
fFirstInterface = FALSE;
hr = pncbi->GetUpperComponent(&pncc);
if (SUCCEEDED(hr))
{
hr = pncc->GetId(&szInfId);
ReleaseObj(pncc);
if (SUCCEEDED(hr))
{
*pstrBindingPath = szInfId;
CoTaskMemFree(szInfId);
}
}
}
if (SUCCEEDED(hr))
{
hr = pncbi->GetLowerComponent(&pncc);
if (SUCCEEDED(hr))
{
hr = pncc->GetId(&szInfId);
if (SUCCEEDED(hr))
{
AssertSz(!fFirstInterface, "fFirstInterface should be FALSE");
if (!pstrBindingPath->empty())
{
*pstrBindingPath += L" -> ";
}
*pstrBindingPath += szInfId;
CoTaskMemFree(szInfId);
}
ReleaseObj(pncc);
}
}
ReleaseObj(pncbi);
}
if (hr == S_FALSE)
{
hr = S_OK;
}
TraceError(__FUNCNAME__, hr);
return hr;
}
#if DBG
//+---------------------------------------------------------------------------
//
// Function: TraceBindPath
//
// Purpose: Traces string representation of a given binding-path using
// the given trace id
//
// Arguments:
// pncbp [in] binding path
// ttid [out] trace tag id as defined in tracetag.cpp
//
// Returns: none
//
// Author: kumarp 05-July-97
//
// Notes:
//
void TraceBindPath(INetCfgBindingPath *pncbp, TraceTagId ttid)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pncbp);
tstring strBindingPath;
HRESULT hr;
hr = HrGetBindingPathStr(pncbp, &strBindingPath);
if (SUCCEEDED(hr))
{
TraceTag(ttid, "Binding path = %S", strBindingPath.c_str());
}
else
{
TraceTag(ttid, "Error dumping binding path.");
}
}
#endif
// =================================================================
//+---------------------------------------------------------------------------
//
// Function: HrGetINetCfgComponentOfComponentsInBindingPath
//
// Purpose: Finds the INetCfgComponent interface of all components in a
// binding path.
//
// Arguments:
// pncbp [in] binding path
// pplComponents [out] list of INetCfgComponent
//
// Returns: S_OK if found all, or an error code if not.
//
// Author: kumarp 05-July-97
//
// Notes:
// Makes error handling easier since this returns either all components
// or none.
// The caller must release the INetCfgComponent interfaces thus obtained.
//
HRESULT HrGetINetCfgComponentOfComponentsInBindingPath(IN INetCfgBindingPath* pncbp,
OUT TPtrList* pplComponents)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetINetCfgComponentOfComponentsInBindingPath");
AssertValidReadPtr(pncbp);
AssertValidWritePtr(pplComponents);
HRESULT hr=S_OK;
CIterNetCfgBindingInterface ncbiIter(pncbp);
INetCfgBindingInterface * pncbi;
INetCfgComponent * pncc = NULL;
BOOL fFirstInterface = TRUE;
while (SUCCEEDED(hr) && (S_OK == (hr = ncbiIter.HrNext(&pncbi))))
{
if (fFirstInterface)
{
fFirstInterface = FALSE;
hr = pncbi->GetUpperComponent(&pncc);
if (SUCCEEDED(hr))
{
pplComponents->push_back(pncc);
}
}
if (SUCCEEDED(hr))
{
hr = pncbi->GetLowerComponent(&pncc);
if (SUCCEEDED(hr))
{
AssertSz(!fFirstInterface, "fFirstInterface shouldn't be TRUE");
pplComponents->push_back(pncc);
}
}
ReleaseObj(pncbi);
if (SUCCEEDED(hr))
{
DWORD dwcc=0;
hr = pncc->GetCharacteristics(&dwcc);
if (S_OK == hr)
{
if (dwcc & NCF_DONTEXPOSELOWER)
{
// if this component does not want to expose components
// below it, set hr to end the while loop
//
hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
#ifdef ENABLETRACE
PWSTR szInfId;
BOOL fFree = TRUE;
if (FAILED(pncc->GetId(&szInfId)))
{
szInfId = L"<GetId failed!>";
fFree = FALSE;
}
TraceTag(ttidNetSetup,
"%s: Component '%S' has NCF_DONTEXPOSELOWER "
"set. Further components will not be added to "
"the list of INetCfgComponent in this binding path",
__FUNCNAME__, szInfId);
if (fFree)
{
CoTaskMemFree(szInfId);
}
#endif
}
}
}
}
if ((hr == S_FALSE) ||
(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)))
{
hr = S_OK;
}
else if (FAILED(hr))
{
// need to release all INetCfgComponent found so far
ReleaseINetCfgComponentsAndEraseList(pplComponents);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetInstanceGuidOfComponents
//
// Purpose: Finds the instance guid of all INetCfgComponents in a list
//
// Arguments:
// pplINetCfgComponent [in] list of INetCfgComponent interfaces
// pplInstanceGuids [out] list of instance guids
//
// Returns: S_OK if found all, or an error code if not.
//
// Author: kumarp 05-July-97
//
// Notes:
// Makes error handling easier since this returns either all instance guids
// or none.
// The caller must free each instance guid and the list elements.
//
HRESULT HrGetInstanceGuidOfComponents(IN TPtrList* pplINetCfgComponent,
OUT TPtrList* pplInstanceGuids)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetInstanceGuidOfComponents");
HRESULT hr = S_OK;
TPtrListIter iter;
INetCfgComponent* pncc;
GUID guidComponentInstance;
for (iter = pplINetCfgComponent->begin();
(iter != pplINetCfgComponent->end()) && (S_OK == hr);
iter++)
{
pncc = (INetCfgComponent*) *iter;
Assert (pncc);
hr = pncc->GetInstanceGuid(&guidComponentInstance);
if (S_OK == hr)
{
GUID* pguidTemp = new GUID;
if (pguidTemp)
{
*pguidTemp = guidComponentInstance;
pplInstanceGuids->push_back(pguidTemp);
}
else
{
hr = E_OUTOFMEMORY;
}
}
}
if (S_OK != hr)
{
// need to free all instace guids found so far
EraseAndDeleteAll(pplInstanceGuids);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetInstanceGuidOfComponentsInBindingPath
//
// Purpose: Finds the instance guid of all components in a binding path.
//
// Arguments:
// pncbp [in] binding path
// pplComponentGuids [out] list of instance guids
//
// Returns: S_OK if found all, or an error code if not.
//
// Author: kumarp 05-July-97
//
// Notes:
// Makes error handling easier since this returns either all components
// or none.
// The caller must free each instance guid and the list elements.
//
HRESULT HrGetInstanceGuidOfComponentsInBindingPath(IN INetCfgBindingPath* pncbp,
OUT TPtrList* pplComponentGuids)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetInstanceGuidOfComponentsInBindingPath");
HRESULT hr=E_FAIL;
TPtrList plINetCfgComponent;
hr = HrGetINetCfgComponentOfComponentsInBindingPath(pncbp, &plINetCfgComponent);
if (SUCCEEDED(hr))
{
hr = HrGetInstanceGuidOfComponents(&plINetCfgComponent,
pplComponentGuids);
ReleaseINetCfgComponentsAndEraseList(&plINetCfgComponent);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetInstanceGuidOfComponentInAnswerFile
//
// Purpose: Finds the instance guid of a component specified in the answerfile
// or an already installed component
//
// Arguments:
// pszComponentName [in] component id to find.
// pguid [out] instance guid of the component
//
// Returns: S_OK if found, S_FALSE if not, or an error code.
//
// Author: kumarp 05-July-97
//
// Notes: Caller must free the instance guid
//
HRESULT
HrGetInstanceGuidOfComponentInAnswerFile (
IN INetCfg* pnc,
IN PCWSTR pszComponentName,
OUT LPGUID pguid)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetInstanceGuidOfComponentInAnswerFile");
TraceFunctionEntry(ttidNetSetup);
AssertValidReadPtr(pnc);
AssertValidReadPtr(pszComponentName);
AssertValidWritePtr(pguid);
AssertValidReadPtr(g_pnii);
#if DBG
tstring strGuid;
#endif
HRESULT hr=E_FAIL;
if (!g_pnii->AnswerFileInitialized())
{
hr = E_FAIL;
goto return_from_function;
}
INetCfgComponent* pncc;
hr = pnc->FindComponent(pszComponentName, &pncc);
if (hr == S_OK)
{
hr = pncc->GetInstanceGuid(pguid);
ReleaseObj(pncc);
}
else if (S_FALSE == hr)
{
TraceTag(ttidNetSetup, "%s: '%S' is not installed on system, "
"let's see if is in the answerfile",
__FUNCNAME__, pszComponentName);
// couldnt find as an installed component, try to see if it is
// in the answer-file-map
//
CNetComponent* pnc;
pnc = g_pnii->Find(pszComponentName);
if (!pnc)
{
hr = S_FALSE;
}
else
{
pnc->GetInstanceGuid(pguid);
hr = S_OK;
}
}
#if DBG
if (S_OK == hr)
{
WCHAR szGuid[c_cchGuidWithTerm];
StringFromGUID2(*pguid, szGuid, c_cchGuidWithTerm);
strGuid = szGuid;
}
else
{
strGuid = c_szAfUnknown;
}
TraceTag(ttidNetSetup, "%s: %S = %S",
__FUNCNAME__, pszComponentName, strGuid.c_str());
#endif
NetSetupLogComponentStatus(pszComponentName,
SzLoadIds (IDS_GETTING_INSTANCE_GUID), hr);
return_from_function:
TraceFunctionError((S_FALSE == hr) ? S_OK : hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetInstanceGuidOfComponentsInAnswerFile
//
// Purpose: Finds the instance guid of a component specified in the answerfile
// or an already installed component
//
// Arguments:
// pslComponents [in] list of component ids to find.
// pguid [out] list of instance guids
//
// Returns: S_OK if found all, or an error code.
//
// Author: kumarp 05-July-97
//
// Notes: Caller must free the instance guids and the list items.
//
HRESULT HrGetInstanceGuidOfComponentsInAnswerFile(
IN INetCfg* pnc,
IN TStringList* pslComponents,
OUT TPtrList* pplComponentGuids)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetInstanceGuidOfComponentsInAnswerFile");
AssertValidReadPtr(pnc);
AssertValidReadPtr(pslComponents);
AssertValidWritePtr(pplComponentGuids);
HRESULT hr = S_OK;
TStringListIter iter;
tstring* pstr;
GUID guidComponentInstance;
for (iter = pslComponents->begin();
(iter != pslComponents->end()) && (S_OK == hr);
iter++)
{
pstr = *iter;
hr = HrGetInstanceGuidOfComponentInAnswerFile(
pnc, pstr->c_str(), &guidComponentInstance);
if (hr == S_OK)
{
GUID* pguidTemp = new GUID;
if (pguidTemp)
{
*pguidTemp = guidComponentInstance;
pplComponentGuids->push_back(pguidTemp);
}
else
{
hr = E_OUTOFMEMORY;
}
}
}
if (S_OK != hr)
{
// need to free all instace guids found so far
EraseAndDeleteAll(pplComponentGuids);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: FAreBindingPathsEqual
//
// Purpose: Compares two representations of binding paths to find
// if they represent the same binding path
//
// Arguments:
// pncbp [in] binding path 1
// pplBindingPathComponentGuids2 [in] list of instance guids representing
// binding path 2
//
// Returns: TRUE if paths are equal, FALSE otherwise
//
// Author: kumarp 05-July-97
//
// Notes:
//
BOOL FAreBindingPathsEqual(INetCfgBindingPath* pncbp,
TPtrList* pplBindingPathComponentGuids2)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("FAreBindingPathsEqual");
BOOL fEqual = FALSE;
HRESULT hr=E_FAIL;
TPtrList plBindingPathComponentGuids1;
hr = HrGetInstanceGuidOfComponentsInBindingPath(pncbp, &plBindingPathComponentGuids1);
if (SUCCEEDED(hr))
{
// now compare the two lists to see if they are equal
if (plBindingPathComponentGuids1.size() ==
pplBindingPathComponentGuids2->size())
{
fEqual = TRUE;
TPtrListIter pos1, pos2;
GUID guid1, guid2;
pos1 = plBindingPathComponentGuids1.begin();
pos2 = pplBindingPathComponentGuids2->begin();
while (fEqual && (pos1 != plBindingPathComponentGuids1.end()))
{
AssertSz(pos2 != pplBindingPathComponentGuids2->end(),
"reached end of other list ??");
guid1 = *((LPGUID) *pos1++);
guid2 = *((LPGUID) *pos2++);
fEqual = (guid1 == guid2);
}
}
EraseAndDeleteAll(plBindingPathComponentGuids1);
}
TraceError(__FUNCNAME__, hr);
return fEqual;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetBindingPathFromStringList
//
// Purpose: Finds the binding path represented by a list of string tokens.
// Each token in the list may either be InfID of a networking
// component or a component specified in the answerfile.
//
// Arguments:
// pnc [in] INetCfg interface
// pslBindingPath [in] list of component ids to find.
// ppncbp [out] INetCfgBindingPath
//
// Returns: S_OK if found, S_FALSE if not found or an error code.
//
// Author: kumarp 05-July-97
//
// Notes: Caller must release the binding path
//
HRESULT HrGetBindingPathFromStringList(IN INetCfg* pnc,
IN TStringList* pslBindingPath,
OUT INetCfgBindingPath** ppncbp)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("GetBindingPathFromStringList");
HRESULT hr=S_FALSE;
//initialize out param
*ppncbp = NULL;
#if DBG
tstring strBindingPath;
ConvertStringListToCommaList(*pslBindingPath, strBindingPath);
TraceTag(ttidNetSetup, "%s: trying to find binding path: %S", __FUNCNAME__,
strBindingPath.c_str());
#endif
TPtrList plComponentGuids;
TStringListIter pos;
pos = pslBindingPath->begin();
tstring strTopComponent;
strTopComponent = **pos++;
INetCfgComponent* pnccTop;
BOOL fFound=FALSE;
hr = pnc->FindComponent(strTopComponent.c_str(), &pnccTop);
if (hr == S_OK)
{
hr = HrGetInstanceGuidOfComponentsInAnswerFile(pnc,
pslBindingPath,
&plComponentGuids);
if (hr == S_OK)
{
CIterNetCfgBindingPath ncbpIter(pnccTop);
INetCfgBindingPath* pncbp;
while (!fFound && (S_OK == (hr = ncbpIter.HrNext(&pncbp))))
{
#if DBG
TraceBindPath(pncbp, ttidNetSetup);
#endif
if (FAreBindingPathsEqual(pncbp, &plComponentGuids))
{
*ppncbp = pncbp;
fFound = TRUE;
}
else
{
ReleaseObj(pncbp);
}
}
EraseAndDeleteAll(plComponentGuids);
if (!fFound && (SUCCEEDED(hr)))
{
hr = S_FALSE;
}
}
ReleaseObj(pnccTop);
}
#if DBG
if (hr != S_OK)
{
TraceTag(ttidNetSetup, "%s: could not find binding path: %S", __FUNCNAME__,
strBindingPath.c_str());
}
#endif
TraceError(__FUNCNAME__, (S_FALSE == hr) ? S_OK : hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: CBindingAction::HrPerformAction
//
// Purpose: Performs the binding action specified in the answerfile
//
// Arguments: none
//
// Returns: S_OK if success, or an error code.
//
// Author: kumarp 05-July-97
//
// Notes:
//
HRESULT CBindingAction::HrPerformAction(IN INetCfg* pnc)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CBindingAction::HrPerformAction");
HRESULT hr=S_OK;
INetCfgBindingPath* pINetCfgBindingPath;
AssertValidReadPtr(m_pnii);
#if DBG
switch (m_eBindingAction)
{
case BND_Enable:
TraceTag(ttidNetSetup, "%s: Enabling: %S",
__FUNCNAME__, m_strBindingPath.c_str());
break;
case BND_Disable:
TraceTag(ttidNetSetup, "%s: Disabling: %S",
__FUNCNAME__, m_strBindingPath.c_str());
break;
case BND_Promote:
TraceTag(ttidNetSetup, "%s: Promoting: %S",
__FUNCNAME__, m_strBindingPath.c_str());
break;
case BND_Demote:
TraceTag(ttidNetSetup, "%s: Demoting: %S",
__FUNCNAME__, m_strBindingPath.c_str());
break;
default:
TraceTag(ttidNetSetup, "%s: Cannot perform invalid binding action",
__FUNCNAME__);
hr = E_FAIL;
goto return_from_function;
break;
}
#endif
hr = HrGetBindingPathFromStringList(pnc,
&m_slBindingPath,
&pINetCfgBindingPath);
if (hr == S_OK)
{
#if DBG
TraceTag(ttidNetSetup, "%s: bindpath matches %S",
__FUNCNAME__, m_strBindingPath.c_str());
#endif
switch (m_eBindingAction)
{
default:
hr = S_FALSE;
TraceTag(ttidNetSetup, "%s: ignored unknown binding action",
__FUNCNAME__);
break;
case BND_Enable:
hr = pINetCfgBindingPath->Enable(TRUE);
break;
case BND_Disable:
hr = pINetCfgBindingPath->Enable(FALSE);
break;
case BND_Promote:
case BND_Demote:
AssertValidReadPtr(m_pnii);
AssertValidReadPtr(pnc);
INetCfgComponentBindings* pncb;
INetCfgComponent* pncc;
tstring strTopComponent;
strTopComponent = **(m_slBindingPath.begin());
hr = pnc->FindComponent(strTopComponent.c_str(), &pncc);
if (hr == S_OK)
{
hr = pncc->QueryInterface(IID_INetCfgComponentBindings,
(void**) &pncb);
if (SUCCEEDED(hr))
{
AssertValidReadPtr(pncb);
if (m_eBindingAction == BND_Promote)
{
hr = pncb->MoveBefore(pINetCfgBindingPath, NULL);
}
else
{
hr = pncb->MoveAfter(pINetCfgBindingPath, NULL);
}
ReleaseObj(pncb);
}
ReleaseObj(pncc);
}
break;
}
#if DBG
if (S_OK == hr)
{
TraceTag(ttidNetSetup, "%s: ...successfully performed binding action",
__FUNCNAME__);
}
#endif
ReleaseObj(pINetCfgBindingPath);
}
#if DBG
return_from_function:
#endif
if (S_FALSE == hr)
{
hr = S_OK;
}
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CNetComponent
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetComponent::CNetComponent
//
// Purpose: constructor for class CNetComponent
//
// Arguments:
// pszName [in] name of the component
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent::CNetComponent(IN PCWSTR pszName)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszName);
m_strName = pszName;
// for all components except adapters, name is same as InfID
m_strInfID = pszName;
m_fIsOemComponent = FALSE;
// currently the SkipInstall feature is used only by
// SNA for its peculiar upgrade requirements. This may or may
// not become a documented feature.
//
m_fSkipInstall = FALSE;
m_guidInstance = GUID_NULL;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponent::GetInstanceGuid
//
// Purpose: Get instance guid of this component
//
// Arguments:
// pguid [out] pointer to guid to be returned
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
VOID
CNetComponent::GetInstanceGuid (
OUT LPGUID pguid) const
{
TraceFileFunc(ttidGuiModeSetup);
Assert (pguid);
if (IsInitializedFromAnswerFile() && (m_guidInstance == GUID_NULL))
{
// the Instance GUID is not in memory, need to get it from
// the registry location where it has been saved by an earlier
// instance of netsetup.dll
//
HrLoadInstanceGuid(Name().c_str(), (LPGUID) &m_guidInstance);
}
*pguid = m_guidInstance;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponent::SetInstanceGuid
//
// Purpose: Set instance guid of this component
//
// Arguments:
// pguid [in] pointer to the guid to set to
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
VOID
CNetComponent::SetInstanceGuid (
IN const GUID* pguid)
{
TraceFileFunc(ttidGuiModeSetup);
m_guidInstance = *pguid;
if (IsInitializedFromAnswerFile())
{
HrSaveInstanceGuid(Name().c_str(), pguid);
}
}
// ----------------------------------------------------------------------
//
// Function: CNetComponent::HrInitFromAnswerFile
//
// Purpose: Initialize initialize basic information from the section of
// this component in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
// pszParamsSections [in] parameters section name
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetComponent::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
IN PCWSTR pszParamsSections)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetComponent::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
AssertValidReadPtr(pszParamsSections);
HRESULT hr=S_OK;
m_strParamsSections = pszParamsSections;
TStringList slParamsSections;
ConvertCommaDelimitedListToStringList(m_strParamsSections, slParamsSections);
tstring strSection;
CWInfSection *pwisSection;
tstring strInfID;
tstring strInfIDReal;
//if there are multiple sections, InfID could be in any one of them
//we need to search all.
TStringListIter pos = slParamsSections.begin();
while (pos != slParamsSections.end())
{
strSection = **pos++;
pwisSection = pwifAnswerFile->FindSection(strSection.c_str());
if (!pwisSection)
{
TraceTag(ttidNetSetup, "%s: warning: section %S is missing",
__FUNCNAME__, strSection.c_str());
continue;
}
// it is really an error to specify different InfIDs in different
// sections. We just take the last one found and overwrite earlier one.
if (pwisSection->GetStringValue(c_szAfInfid, strInfID))
{
//InfId
m_strInfID = strInfID;
}
if (pwisSection->GetStringValue(c_szAfInfidReal, strInfIDReal))
{
//InfIdReal
m_strInfIDReal = strInfIDReal;
}
// 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.
//
m_fSkipInstall = pwisSection->GetBoolValue(c_szAfSkipInstall, FALSE);
if (m_strOemSection.empty())
{
m_strOemSection =
pwisSection->GetStringValue(c_szAfOemSection, c_szEmpty);
m_strOemDir =
pwisSection->GetStringValue(c_szAfOemDir, c_szEmpty);
m_strOemDll =
pwisSection->GetStringValue(c_szAfOemDllToLoad, c_szEmpty);
if (!m_strOemSection.empty() &&
!m_strOemDir.empty())
{
m_fIsOemComponent = TRUE;
CWInfSection* pwisOemSection;
pwisOemSection =
pwifAnswerFile->FindSection(m_strOemSection.c_str());
if (pwisOemSection)
{
TStringArray saTemp;
if (pwisOemSection->GetStringArrayValue(c_szInfToRunBeforeInstall,
saTemp))
{
m_strInfToRunBeforeInstall = *saTemp[0];
m_strSectionToRunBeforeInstall = *saTemp[1];
TraceTag(ttidNetSetup, "%s: '%S' specified %S: %S, %S",
__FUNCNAME__, InfID().c_str(),
c_szInfToRunBeforeInstall,
m_strInfToRunBeforeInstall.c_str(),
m_strSectionToRunBeforeInstall.c_str());
}
if (pwisOemSection->GetStringArrayValue(c_szInfToRunAfterInstall,
saTemp))
{
m_strInfToRunAfterInstall = *saTemp[0];
m_strSectionToRunAfterInstall = *saTemp[1];
if (m_strInfToRunAfterInstall.empty())
{
m_strInfToRunAfterInstall = pwifAnswerFile->FileName();
}
TraceTag(ttidNetSetup, "%s: '%S' specified %S: %S, %S",
__FUNCNAME__, InfID().c_str(),
c_szInfToRunAfterInstall,
m_strInfToRunAfterInstall.c_str(),
m_strSectionToRunAfterInstall.c_str());
}
EraseAndDeleteAll(&saTemp);
}
}
}
}
// cleanup:
EraseAndDeleteAll(slParamsSections);
TraceFunctionError(hr);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: CNetComponent::HrValidate
//
// Purpose: Validate keys specified in the parameters section
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetComponent::HrValidate() const
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetComponent::HrValidate");
HRESULT hr=S_OK;
// BOOL fStatus = !(m_strInfID.empty() || m_strParamsSections.empty());
// HRESULT hr = fStatus ? S_OK : NETSETUP_E_ANS_FILE_ERROR;
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CNetAdapter
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetAdapter::CNetAdapter
//
// Purpose: constructor for class CNetAdapter
//
// Arguments:
// pszName [in] name of the adapter
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetAdapter::CNetAdapter(IN PCWSTR pszName)
: CNetComponent(pszName)
{
TraceFileFunc(ttidGuiModeSetup);
m_fDetect = FALSE;
m_fPseudoAdapter = FALSE;
m_itBus = Isa;
m_wIOAddr = 0;
m_wIRQ = 0;
m_wDMA = 0;
m_dwMem = 0;
m_qwNetCardAddress = 0;
m_PciBusNumber = 0xFFFF;
m_PciDeviceNumber = 0xFFFF;
m_PciFunctionNumber = 0xFFFF;
m_fPciLocationInfoSpecified = FALSE;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdapter::HrInitFromAnswerFile
//
// Purpose: Initialize from the parameters section of this adapter
// in the answerfile
//
// Arguments:
// pwifAnswerFile [in] pointer to CWInfFile object
// pszParamsSections [in] name of the parameters section
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT CNetAdapter::HrInitFromAnswerFile(IN CWInfFile* pwifAnswerFile,
IN PCWSTR pszParamsSections)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdapter::HrInitFromAnswerFile");
AssertValidReadPtr(pwifAnswerFile);
AssertValidReadPtr(pszParamsSections);
HRESULT hr, hrReturn=S_OK;
hrReturn = CNetComponent::HrInitFromAnswerFile(pwifAnswerFile,
pszParamsSections);
PCWInfSection pwisParams;
pwisParams = pwifAnswerFile->FindSection(pszParamsSections);
if (!pwisParams)
{
AddAnswerFileError(pszParamsSections, IDS_E_AF_Missing);
return NETSETUP_E_ANS_FILE_ERROR;
}
PCWSTR pszTemp;
DWORD dwDefault = 0;
//Detect
m_fDetect = pwisParams->GetBoolValue(c_szAfDetect, TRUE);
if (!m_fDetect && m_strInfID.empty())
{
AddAnswerFileError(pszParamsSections,
IDS_E_AF_SpecifyInfIdWhenNotDetecting);
hrReturn = NETSETUP_E_ANS_FILE_ERROR;
}
//PreUpgradeInstance
m_strPreUpgradeInstance = pwisParams->GetStringValue(c_szAfPreUpgradeInstance,
c_szEmpty);
//PseudoAdapter
m_fPseudoAdapter = pwisParams->GetBoolValue(c_szAfPseudoAdapter, FALSE);
//if it is a PseudoAdapter, no need to get values of other parameters
if (m_fPseudoAdapter)
{
TraceFunctionError(hrReturn);
return hrReturn;
}
// ConnectionName
m_strConnectionName = pwisParams->GetStringValue(c_szAfConnectionName,
c_szEmpty);
//BusType
pszTemp = pwisParams->GetStringValue(c_szAfBusType, c_szEmpty);
m_itBus = GetBusTypeFromName(pszTemp);
//IOAddr
m_wIOAddr = (WORD)pwisParams->GetIntValue(c_szAfIoAddr, dwDefault);
//IRQ
m_wIRQ = (WORD)pwisParams->GetIntValue(c_szAfIrq, dwDefault);
//DMA
m_wDMA = (WORD)pwisParams->GetIntValue(c_szAfDma, dwDefault);
//MEM
m_dwMem = pwisParams->GetIntValue(c_szAfMem, dwDefault);
//NetCardAddr
pwisParams->GetQwordValue(c_szAfNetCardAddr, &m_qwNetCardAddress);
// BusNumber
m_PciBusNumber = (WORD)pwisParams->GetIntValue (L"PciBusNumber", 0xFFFF);
if (0xFFFF != m_PciBusNumber)
{
// DeviceNumber
m_PciDeviceNumber = (WORD)pwisParams->GetIntValue (L"PciDeviceNumber", 0xFFFF);
if (0xFFFF != m_PciDeviceNumber)
{
// FunctionNumber
m_PciFunctionNumber = (WORD)pwisParams->GetIntValue (L"PciFunctionNumber",
0xFFFF);
if (0xFFFF != m_PciFunctionNumber)
{
m_fPciLocationInfoSpecified = TRUE;
}
}
}
TraceFunctionError(hrReturn);
return hrReturn;
}
// ----------------------------------------------------------------------
//
// Function: CNetAdapter::HrValidate
//
// Purpose: Validate netcard parameters
//
// Arguments: None
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 23-December-97
//
// Notes:
//
HRESULT CNetAdapter::HrValidate()
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("CNetAdapter::HrValidate");
HRESULT hr;
hr = CNetComponent::HrValidate();
ReturnHrIfFailed(hr);
//$ REVIEW kumarp 21-April-97
// no additinal checking for now
TraceFunctionError(hr);
return hr;
}
// ======================================================================
// class CNetProtocol
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetProtocol::CNetProtocol
//
// Purpose: constructor for class CNetProtocol
//
// Arguments:
// pszName [in] name of the protocol
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetProtocol::CNetProtocol(IN PCWSTR pszName)
: CNetComponent(pszName)
{
}
// ======================================================================
// class CNetService
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetService::CNetService
//
// Purpose: constructor for class CNetService
//
// Arguments:
// pszName [in] name of the service
//
// Returns:
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetService::CNetService(IN PCWSTR pszName)
: CNetComponent(pszName)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ======================================================================
// class CNetClient
// ======================================================================
// ----------------------------------------------------------------------
//
// Function: CNetClient::CNetClient
//
// Purpose: constructor for class CNetClient
//
// Arguments:
// pszName [in] name of the client
//
// Returns:
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetClient::CNetClient(IN PCWSTR pszName)
: CNetComponent(pszName)
{
TraceFileFunc(ttidGuiModeSetup);
}
// ----------------------------------------------------------------------
// Misc. Helper Functions
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
//
// Function: FindComponentInList
//
// Purpose: Find component in the given list
//
// Arguments:
// pnclComponents [in] pointer to list of components
// szInfID [in] component to find
//
// Returns: pointer to CNetComponent object, or NULL if not found
//
// Author: kumarp 25-November-97
//
// Notes:
//
CNetComponent* FindComponentInList(
IN CNetComponentList* pnclComponents,
IN PCWSTR szInfID)
{
TraceFileFunc(ttidGuiModeSetup);
CNetComponent* pna;
TPtrListIter pos;
pos = pnclComponents->begin();
while (pos != pnclComponents->end())
{
pna = (CNetComponent*) *pos++;
if (0 == lstrcmpiW(pna->InfID().c_str(), szInfID))
{
return pna;
}
}
return NULL;
}
// ----------------------------------------------------------------------
//
// Function: GetDisplayModeStr
//
// Purpose: Get string representation of DisplayMode
//
// Arguments:
// pdmDisplay [in] display mode
//
// Returns:
//
// Author: kumarp 23-December-97
//
// Notes:
//
PCWSTR GetDisplayModeStr(EPageDisplayMode pdmDisplay)
{
TraceFileFunc(ttidGuiModeSetup);
switch (pdmDisplay)
{
case PDM_YES:
return c_szYes;
case PDM_NO:
return c_szNo;
case PDM_ONLY_ON_ERROR:
default:
return c_szAfOnlyOnError;
}
}
// ----------------------------------------------------------------------
//
// Function: MapToDisplayMode
//
// Purpose: Map display mode string to proper enum value
//
// Arguments:
// pszDisplayMode [in] display mode string
//
// Returns: enum corresponding to the string
//
// Author: kumarp 25-November-97
//
// Notes:
//
EPageDisplayMode MapToDisplayMode(IN PCWSTR pszDisplayMode)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszDisplayMode);
if (!lstrcmpiW(pszDisplayMode, c_szYes))
return PDM_YES;
else if (!lstrcmpiW(pszDisplayMode, c_szNo))
return PDM_NO;
else if (!lstrcmpiW(pszDisplayMode, c_szAfOnlyOnError))
return PDM_ONLY_ON_ERROR;
else
return PDM_UNKNOWN;
}
// ----------------------------------------------------------------------
//
// Function: MapToUpgradeFlag
//
// Purpose: Map string to proper upgrade flag value
//
// Arguments:
// pszUpgradeFromProduct [in] string describing product
//
// Returns: flag corresponding to the string
//
// Author: kumarp 25-November-97
//
// Notes:
//
DWORD MapToUpgradeFlag(IN PCWSTR pszUpgradeFromProduct)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszUpgradeFromProduct);
if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtServer))
return NSF_WINNT_SVR_UPGRADE;
else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtSbServer))
return NSF_WINNT_SBS_UPGRADE;
else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfNtWorkstation))
return NSF_WINNT_WKS_UPGRADE;
else if (!lstrcmpiW(pszUpgradeFromProduct, c_szAfWin95))
return NSF_WIN95_UPGRADE;
else
return 0;
}
HRESULT HrGetProductInfo (LPDWORD pdwUpgradeFrom,
LPDWORD pdwBuildNo)
{
OSVERSIONINFOEX osvi;
HRESULT hr;
*pdwUpgradeFrom = 0;
*pdwBuildNo = 0;
ZeroMemory( &osvi,
sizeof(OSVERSIONINFOEX) );
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if ( GetVersionEx((LPOSVERSIONINFO)&osvi) )
{
*pdwBuildNo = osvi.dwBuildNumber;
if ( osvi.wSuiteMask & (VER_SUITE_SMALLBUSINESS | VER_SUITE_SMALLBUSINESS_RESTRICTED) )
{
*pdwUpgradeFrom = NSF_WINNT_SBS_UPGRADE;
}
else if ( osvi.wProductType == VER_NT_WORKSTATION )
{
*pdwUpgradeFrom = NSF_WINNT_WKS_UPGRADE;
}
else
{
*pdwUpgradeFrom = NSF_WINNT_SVR_UPGRADE;
}
hr = S_OK;
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
return hr;
}
// ----------------------------------------------------------------------
//
// Function: GetBusTypeFromName
//
// Purpose: Map bus-type enum from string
//
// Arguments:
// pszBusType [in] name of the bus
//
// Returns: enum INTERFACE_TYPE corresponding to the string
//
// Author: kumarp 25-November-97
//
// Notes:
//
INTERFACE_TYPE GetBusTypeFromName(IN PCWSTR pszBusType)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszBusType);
if (!_wcsicmp(pszBusType, c_szAfBusInternal))
return Internal;
else if (!_wcsicmp(pszBusType, c_szAfBusIsa))
return Isa;
else if (!_wcsicmp(pszBusType, c_szAfBusEisa))
return Eisa;
else if (!_wcsicmp(pszBusType, c_szAfBusMicrochannel))
return MicroChannel;
else if (!_wcsicmp(pszBusType, c_szAfBusTurbochannel))
return TurboChannel;
else if (!_wcsicmp(pszBusType, c_szAfBusPci))
return PCIBus;
else if (!_wcsicmp(pszBusType, c_szAfBusVme))
return VMEBus;
else if (!_wcsicmp(pszBusType, c_szAfBusNu))
return NuBus;
else if (!_wcsicmp(pszBusType, c_szAfBusPcmcia))
return PCMCIABus;
else if (!_wcsicmp(pszBusType, c_szAfBusC))
return CBus;
else if (!_wcsicmp(pszBusType, c_szAfBusMpi))
return MPIBus;
else if (!_wcsicmp(pszBusType, c_szAfBusMpsa))
return MPSABus;
else if (!_wcsicmp(pszBusType, c_szAfBusProcessorinternal))
return ProcessorInternal;
else if (!_wcsicmp(pszBusType, c_szAfBusInternalpower))
return InternalPowerBus;
else if (!_wcsicmp(pszBusType, c_szAfBusPnpisa))
return PNPISABus;
else
return InterfaceTypeUndefined;
};
// ----------------------------------------------------------------------
//
// Function: AddAnswerFileError
//
// Purpose: Add error with given resource id to the answerfile error-list
//
// Arguments:
// dwErrorId [in] resource id
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
void AddAnswerFileError(IN DWORD dwErrorId)
{
TraceFileFunc(ttidGuiModeSetup);
g_elAnswerFileErrors->Add(dwErrorId);
}
// ----------------------------------------------------------------------
//
// Function: AddAnswerFileError
//
// Purpose: Add error with given section name and error id
// to the answerfile error-list
//
// Arguments:
// pszSectionName [in] name of section where error occurred
// dwErrorId [in] error id
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
void AddAnswerFileError(IN PCWSTR pszSectionName, IN DWORD dwErrorId)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszSectionName);
tstring strMsgPrefix = pszSectionName;
strMsgPrefix = L"Section [" + strMsgPrefix + L"] : ";
g_elAnswerFileErrors->Add(strMsgPrefix.c_str(), dwErrorId);
}
// ----------------------------------------------------------------------
//
// Function: AddAnswerFileError
//
// Purpose: Add error with given section name, key name and error id
// to the answerfile error-list
//
// Arguments:
// pszSectionName [in] name of section where error occurred
// pszKeyName [in] name of key where error occurred
// dwErrorId [in] error id
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
void AddAnswerFileError(IN PCWSTR pszSectionName,
IN PCWSTR pszKeyName,
IN DWORD dwErrorId)
{
TraceFileFunc(ttidGuiModeSetup);
AssertValidReadPtr(pszSectionName);
AssertValidReadPtr(pszKeyName);
tstring strMsgPrefix = pszSectionName;
strMsgPrefix = L"Section [" + strMsgPrefix + L"]: Key \"" +
pszKeyName + L"\" : ";
g_elAnswerFileErrors->Add(strMsgPrefix.c_str(), dwErrorId);
}
// ----------------------------------------------------------------------
//
// Function: ShowAnswerFileErrorsIfAny
//
// Purpose: Display messagebox if there are errors in the answerfile
//
// Arguments: None
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
void ShowAnswerFileErrorsIfAny()
{
TraceFileFunc(ttidGuiModeSetup);
static const WCHAR c_szNewLine[] = L"\n";
TStringList* pslErrors=NULL;
GetAnswerFileErrorList_Internal(pslErrors);
if (pslErrors && (pslErrors->size() > 0))
{
tstring strErrors;
strErrors = SzLoadIds(IDS_E_AF_AnsFileHasErrors);
strErrors += c_szNewLine;
strErrors += c_szNewLine;
TStringListIter pos;
pos = pslErrors->begin();
while (pos != pslErrors->end())
{
strErrors += **pos++;
strErrors += c_szNewLine;
}
MessageBox (NULL, strErrors.c_str(), NULL, MB_OK | MB_TASKMODAL);
}
}
// ----------------------------------------------------------------------
//
// Function: GetAnswerFileErrorList
//
// Purpose: Return list of errors in the answerfile
//
// Arguments:
// slErrors [out] pointer to list of errors
//
// Returns: None
//
// Author: kumarp 25-November-97
//
// Notes:
//
VOID
GetAnswerFileErrorList_Internal(OUT TStringList*& slErrors)
{
TraceFileFunc(ttidGuiModeSetup);
g_elAnswerFileErrors->GetErrorList(slErrors);
}
// ----------------------------------------------------------------------
//
// Function: HrRemoveNetComponents
//
// Purpose: Remove (DeInstall) specified components
//
// Arguments:
// pnc [in] pointer to INetCfg object
// pslComponents [in] pointer to list of components to be removed
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 25-November-97
//
// Notes:
//
HRESULT HrRemoveNetComponents(IN INetCfg* pnc,
IN TStringList* pslComponents)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrDeInstallNetComponents");
AssertValidReadPtr(pslComponents);
HRESULT hr=S_OK;
TStringListIter pos;
PCWSTR szComponentId;
INetCfgComponent* pINetCfgComponent;
GUID guidClass;
for (pos = pslComponents->begin(); pos != pslComponents->end(); pos++)
{
szComponentId = (*pos)->c_str();
ShowProgressMessage(L"Trying to remove %s...", szComponentId);
hr = pnc->FindComponent(szComponentId, &pINetCfgComponent);
if (S_OK == hr)
{
hr = pINetCfgComponent->GetClassGuid(&guidClass);
if (S_OK == hr)
{
hr = HrRemoveComponentOboUser(pnc, guidClass, szComponentId);
if (S_OK == hr)
{
ShowProgressMessage(L"...successfully removed %s",
szComponentId);
}
}
if (S_OK != hr)
{
ShowProgressMessage(L"...error removing %s, error code: 0x%x",
szComponentId, hr);
}
ReleaseObj(pINetCfgComponent);
}
else
{
ShowProgressMessage(L"...component %s is not installed",
szComponentId);
}
// Remove the files.
RemoveFiles( szComponentId );
// we ignore any errors so that we can remove as many components
// as possible
//
hr = S_OK;
}
TraceError(__FUNCNAME__, hr);
return hr;
}
// ----------------------------------------------------------------------
//
// Function: RemoveFiles
//
// Purpose: Remove the files of the specified component.
//
// Arguments:
// szInfID [in] Infid of the component.
//
// Returns:
//
// Author: asinha 02-April-2001
//
// Notes:
//
VOID RemoveFiles (IN PCWSTR szInfID)
{
tstring strFilename;
WCHAR szWindowsDir[MAX_PATH+2];
int len;
if ( _wcsicmp(szInfID, sz_DLC) == 0 )
{
len = GetWindowsDirectoryW(szWindowsDir, MAX_PATH+1);
if ( szWindowsDir[len-1] != L'\\' )
{
szWindowsDir[len] = L'\\';
szWindowsDir[len+1] = NULL;
}
// Don't know if it is an upgrade from NT 4.0 or Win2k, so
// try to delete the inf file of both the OS's.
//
strFilename = szWindowsDir;
strFilename += sz_DLC_NT40_Inf;
DeleteFile( strFilename.c_str() );
strFilename = szWindowsDir;
strFilename += sz_DLC_Win2k_Inf;
DeleteFile( strFilename.c_str() );
strFilename = szWindowsDir;
strFilename += sz_DLC_Win2k_Pnf;
DeleteFile( strFilename.c_str() );
strFilename = szWindowsDir;
strFilename += sz_DLC_Sys;
DeleteFile( strFilename.c_str() );
strFilename = szWindowsDir;
strFilename += sz_DLC_Dll;
DeleteFile( strFilename.c_str() );
}
return;
}
static ProgressMessageCallbackFn g_pfnProgressMsgCallback;
EXTERN_C
VOID
WINAPI
NetSetupSetProgressCallback (
ProgressMessageCallbackFn pfn)
{
TraceFileFunc(ttidGuiModeSetup);
g_pfnProgressMsgCallback = pfn;
}
VOID
ShowProgressMessage (
IN PCWSTR szFormatStr, ...)
{
TraceFileFunc(ttidGuiModeSetup);
va_list arglist;
va_start (arglist, szFormatStr);
if (g_pfnProgressMsgCallback)
{
g_pfnProgressMsgCallback(szFormatStr, arglist);
}
#ifdef ENABLETRACE
else
{
static WCHAR szTempBuf[1024];
_vstprintf(szTempBuf, szFormatStr, arglist);
TraceTag(ttidNetSetup, "%S", szTempBuf);
}
#endif
va_end(arglist);
}
// ----------------------------------------------------------------------
//
// Function: HrMakeCopyOfAnswerFile
//
// Purpose: Make a backup copy of the answerfile. Base setup has started
// deleting it after GUI mode setup, but we want to retain
// the file for debugging/support purpose.
//
// Arguments:
// szAnswerFileName [in] full path+name of AnswerFile
//
// Returns: S_OK on success, otherwise an error code
//
// Author: kumarp 12-January-98
//
// Notes:
//
HRESULT HrMakeCopyOfAnswerFile(IN PCWSTR szAnswerFileName)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrMakeCopyOfAnswerFile");
TraceFunctionEntry(ttidNetSetup);
static const WCHAR c_szAnswerFileCopyName[] = L"af.txt";
HRESULT hr=S_OK;
WCHAR szWindowsDir[MAX_PATH+1];
tstring strAnswerFileCopyName;
DWORD cNumCharsReturned = GetSystemWindowsDirectory(szWindowsDir, MAX_PATH);
if (cNumCharsReturned)
{
static const WCHAR c_szNetsetupTempSubDir[] = L"\\netsetup\\";
strAnswerFileCopyName = szWindowsDir;
strAnswerFileCopyName += c_szNetsetupTempSubDir;
DWORD err = 0;
DWORD status;
status = CreateDirectory(strAnswerFileCopyName.c_str(), NULL);
if (!status)
{
err = GetLastError();
}
if (status || (ERROR_ALREADY_EXISTS == err))
{
hr = S_OK;
strAnswerFileCopyName += c_szAnswerFileCopyName;
status = CopyFile(szAnswerFileName,
strAnswerFileCopyName.c_str(), FALSE);
if (status)
{
hr = S_OK;
TraceTag(ttidNetSetup, "%s: AnswerFile %S copied to %S",
__FUNCNAME__, szAnswerFileName,
strAnswerFileCopyName.c_str());
}
else
{
hr = HrFromLastWin32Error();
}
}
else
{
hr = HRESULT_FROM_WIN32(err);
}
}
else
{
hr = HrFromLastWin32Error();
}
TraceError(__FUNCNAME__, hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetConnectionFromAdapterGuid
//
// Purpose: Get INetConnection* for a given adapter guid
//
// Arguments:
// pguidAdapter [in] pointer to the instance GUID of an adapter
// ppconn [out] the corresponding INetConnection*
//
// Returns: S_OK on success, otherwise an error code
// S_FALSE if connection was not found.
//
// Author: kumarp 23-September-98
//
// Notes:
//
HRESULT HrGetConnectionFromAdapterGuid(IN GUID* pguidAdapter,
OUT INetConnection** ppconn)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrGetConnectionFromAdapterGuid");
HRESULT hr=S_OK;
BOOL fFound = FALSE;
// Iterate all LAN connections
//
INetConnectionManager * pconMan;
hr = HrCreateInstance(
CLSID_LanConnectionManager,
CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
&pconMan);
TraceHr(ttidError, FAL, hr, FALSE, "HrCreateInstance");
if (SUCCEEDED(hr))
{
CIterNetCon ncIter(pconMan, NCME_DEFAULT);
INetConnection* pconn = NULL;
while (!fFound && (S_OK == (ncIter.HrNext(&pconn))))
{
if (FPconnEqualGuid(pconn, *pguidAdapter))
{
fFound = TRUE;
*ppconn = pconn;
}
else
{
ReleaseObj(pconn);
}
}
ReleaseObj(pconMan);
}
if (!fFound)
hr = S_FALSE;
TraceErrorSkip1(__FUNCNAME__, hr, S_FALSE);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrSetLanConnectionName
//
// Purpose: Rename the connection spcified by its adapter guid
// to the given name
//
// Arguments:
// pguidAdapter [in] pointer to the instance GUID of an adapter
// szConnectionName [in] name of Connection
//
// Returns: S_OK on success, otherwise an error code
// S_FALSE if connection was not found
//
// Author: kumarp 23-September-98
//
// Notes:
//
HRESULT HrSetLanConnectionName(IN GUID* pguidAdapter,
IN PCWSTR szConnectionName)
{
TraceFileFunc(ttidGuiModeSetup);
DefineFunctionName("HrSetConnectionName");
HRESULT hr=S_OK;
INetConnection* pconn;
hr = HrGetConnectionFromAdapterGuid(pguidAdapter, &pconn);
if (S_OK == hr)
{
hr = pconn->Rename(szConnectionName);
ReleaseObj(pconn);
}
TraceError(__FUNCNAME__, hr);
return hr;
}
// =======================================================================
// defunct code
// =======================================================================