//+--------------------------------------------------------------------------- // // 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(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(&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(&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(&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(&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""; 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 // =======================================================================