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
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
|
|
// =======================================================================
|