|
|
//+---------------------------------------------------------------------------
//
// 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_ALL { 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_ALL { 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 = 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 = pwisParams->GetIntValue(c_szAfIoAddr, dwDefault);
//IRQ
m_wIRQ = pwisParams->GetIntValue(c_szAfIrq, dwDefault);
//DMA
m_wDMA = pwisParams->GetIntValue(c_szAfDma, dwDefault);
//MEM
m_dwMem = pwisParams->GetIntValue(c_szAfMem, dwDefault);
//NetCardAddr
pwisParams->GetQwordValue(c_szAfNetCardAddr, &m_qwNetCardAddress);
// BusNumber
m_PciBusNumber = pwisParams->GetIntValue (L"PciBusNumber", 0xFFFF); if (0xFFFF != m_PciBusNumber) { // DeviceNumber
m_PciDeviceNumber = pwisParams->GetIntValue (L"PciDeviceNumber", 0xFFFF); if (0xFFFF != m_PciDeviceNumber) { // FunctionNumber
m_PciFunctionNumber = 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
// =======================================================================
|