817 lines
24 KiB
C++
817 lines
24 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: A F I L E X P . C P P
|
|
//
|
|
// Contents: Functions exported from netsetup for answerfile related work.
|
|
//
|
|
// Author: kumarp 25-November-97
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "afileint.h"
|
|
#include "afilexp.h"
|
|
#include "compid.h"
|
|
#include "kkenet.h"
|
|
#include "kkutils.h"
|
|
#include "ncerror.h"
|
|
#include "ncnetcfg.h"
|
|
#include "ncsetup.h"
|
|
#include "nsbase.h"
|
|
#include "oemupgrd.h"
|
|
#include "resource.h"
|
|
#include "upgrade.h"
|
|
#include <wdmguid.h>
|
|
#include "nslog.h"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Global variables
|
|
//
|
|
CNetInstallInfo* g_pnii;
|
|
CNetInstallInfo* g_pniiTemp;
|
|
DWORD g_dwOperationFlags = 0;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrDoUnattend
|
|
//
|
|
// Purpose: call member function of CNetInstallInfo to perform
|
|
// answerfile based install/upgrade work
|
|
//
|
|
// Arguments:
|
|
// hwndParent [in] handle of parent window
|
|
// punk [in] pointer to an interface
|
|
// idPage [in] id indicating which section to run
|
|
// ppdm [out] pointer to page display mode
|
|
// pfAllowChanges [out] pointer to flag controlling read/write behavior
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
EXTERN_C
|
|
HRESULT
|
|
WINAPI
|
|
HrDoUnattend (
|
|
IN HWND hwndParent,
|
|
IN IUnknown* punk,
|
|
IN EUnattendWorkType uawType,
|
|
OUT EPageDisplayMode* ppdm,
|
|
OUT BOOL* pfAllowChanges)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(punk);
|
|
Assert(ppdm);
|
|
Assert(pfAllowChanges);
|
|
Assert(g_pnii);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
#if DBG
|
|
if (FIsDebugFlagSet (dfidBreakOnDoUnattend))
|
|
{
|
|
AssertSz(FALSE, "THIS IS NOT A BUG! The debug flag "
|
|
"\"BreakOnDoUnattend\" has been set. Set your breakpoints now.");
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
hr = g_pnii->HrDoUnattended(hwndParent, punk, uawType, ppdm, pfAllowChanges);
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "HrDoUnattend");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrInitForRepair
|
|
//
|
|
// Purpose: Initialize in repair mode.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: asinha 17-October-2001
|
|
//
|
|
HRESULT
|
|
HrInitForRepair (VOID)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
g_pnii = NULL;
|
|
|
|
hr = CNetInstallInfo::HrCreateInstance (
|
|
NULL,
|
|
&g_pnii);
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE,
|
|
"HrInitForRepair");
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrInitForUnattendedNetSetup
|
|
//
|
|
// Purpose: Initialize net setup for answerfile processing
|
|
//
|
|
// Arguments:
|
|
// pnc [in] pointer to INetCfg object
|
|
// pisd [in] pointer to private data supplied by base setup
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
HRESULT
|
|
HrInitForUnattendedNetSetup (
|
|
IN INetCfg* pnc,
|
|
IN PINTERNAL_SETUP_DATA pisd)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(pnc);
|
|
Assert(pisd);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
g_dwOperationFlags = pisd->OperationFlags;
|
|
if (pisd->OperationFlags & SETUPOPER_BATCH)
|
|
{
|
|
Assert(pisd->UnattendFile);
|
|
AssertSz(!g_pnii, "who initialized g_pnii ??");
|
|
|
|
hr = HrInitAnswerFileProcessing(pisd->UnattendFile, &g_pnii);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr,
|
|
(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
|
|
(hr == NETSETUP_E_NO_ANSWERFILE),
|
|
"HrInitNetSetup");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrCleanupNetSetup
|
|
//
|
|
// Purpose: Do cleanup work in NetSetup
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
VOID
|
|
HrCleanupNetSetup()
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
DeleteIfNotNull(g_pnii);
|
|
DeleteIfNotNull(g_pniiTemp);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrGetAnswerFileName
|
|
//
|
|
// Purpose: Generate full path to the answerfile
|
|
//
|
|
// Arguments:
|
|
// pstrAnswerFileName [out] pointer to name of answerfile
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
// Notes: !!!This function has a dependency on the base setup.!!!
|
|
// If base setup changes name of the answerfile, this fn
|
|
// function will break.
|
|
//
|
|
HRESULT
|
|
HrGetAnswerFileName(
|
|
OUT tstring* pstrAnswerFileName)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
static const WCHAR c_szAfSubDirAndName[] = L"\\system32\\$winnt$.inf";
|
|
|
|
HRESULT hr=S_OK;
|
|
|
|
WCHAR szWinDir[MAX_PATH+1];
|
|
DWORD cNumCharsReturned = GetSystemWindowsDirectory(szWinDir, MAX_PATH);
|
|
|
|
if (cNumCharsReturned)
|
|
{
|
|
*pstrAnswerFileName = szWinDir;
|
|
*pstrAnswerFileName += c_szAfSubDirAndName;
|
|
}
|
|
else
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "HrGetAnswerFileName");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrInitAnswerFileProcessing
|
|
//
|
|
// Purpose: Initialize answerfile processing
|
|
//
|
|
// Arguments:
|
|
// szAnswerFileName [in] name of answerfile
|
|
// ppnii [out] pointer to pointer to CNetInstallInfo object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
HRESULT
|
|
HrInitAnswerFileProcessing (
|
|
IN PCWSTR szAnswerFileName,
|
|
OUT CNetInstallInfo** ppnii)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(ppnii);
|
|
|
|
HRESULT hr = S_OK;
|
|
tstring strAnswerFileName;
|
|
|
|
*ppnii = NULL;
|
|
|
|
if (!szAnswerFileName)
|
|
{
|
|
hr = HrGetAnswerFileName(&strAnswerFileName);
|
|
}
|
|
else
|
|
{
|
|
strAnswerFileName = szAnswerFileName;
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
hr = CNetInstallInfo::HrCreateInstance (
|
|
strAnswerFileName.c_str(),
|
|
ppnii);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr,
|
|
(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
|
|
(hr == NETSETUP_E_NO_ANSWERFILE),
|
|
"HrInitAnswerFileProcessing");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrOemUpgrade
|
|
//
|
|
// Purpose: Process special OEM upgrades by running an inf section
|
|
//
|
|
// Arguments:
|
|
// hkeyDriver [in] the driver key
|
|
// pszAnswerFile [in] pointer to answer filename string.
|
|
// pszAnswerSection [in] pointer to answer filname sections string
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Date: 30 Mar 1998
|
|
//
|
|
EXTERN_C
|
|
HRESULT
|
|
WINAPI
|
|
HrOemUpgrade(
|
|
IN HKEY hkeyDriver,
|
|
IN PCWSTR pszAnswerFile,
|
|
IN PCWSTR pszAnswerSection)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(hkeyDriver);
|
|
Assert(pszAnswerFile);
|
|
Assert(pszAnswerSection);
|
|
|
|
// Open the answer file.
|
|
HINF hinf;
|
|
HRESULT hr = HrSetupOpenInfFile(pszAnswerFile, NULL,
|
|
INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL, &hinf);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
tstring strInfToRun;
|
|
tstring strSectionToRun;
|
|
tstring strInfToRunType;
|
|
|
|
// Get the file and section to run for upgrade
|
|
hr = HrAfGetInfToRunValue(hinf, pszAnswerFile, pszAnswerSection,
|
|
I2R_AfterInstall, &strInfToRun, &strSectionToRun, &strInfToRunType);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
HINF hinfToRun;
|
|
// Open the inf file containing the section to run
|
|
hr = HrSetupOpenInfFile(strInfToRun.c_str(), NULL,
|
|
INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL,
|
|
&hinfToRun);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
TraceTag(ttidNetSetup, "Running section %S in %S",
|
|
strSectionToRun.c_str(), strInfToRun.c_str());
|
|
|
|
// Run the section against the key
|
|
hr = HrSetupInstallFromInfSection (NULL,
|
|
hinfToRun, strSectionToRun.c_str(), SPINST_REGISTRY,
|
|
hkeyDriver, NULL, 0, NULL, NULL, NULL, NULL);
|
|
|
|
NetSetupLogHrStatusV(hr, SzLoadIds (IDS_STATUS_OF_APPLYING),
|
|
pszAnswerSection,
|
|
strInfToRunType.c_str(),
|
|
strSectionToRun.c_str(),
|
|
strInfToRun.c_str());
|
|
SetupCloseInfFile(hinfToRun);
|
|
}
|
|
}
|
|
else if (SPAPI_E_LINE_NOT_FOUND == hr)
|
|
{
|
|
// Nothing to run.
|
|
hr = S_FALSE;
|
|
}
|
|
SetupCloseInfFile(hinf);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "HrOemUpgrade");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrGetAnswerFileParametersForComponent
|
|
//
|
|
// Purpose: Search in answerfile for a component whose InfId matches
|
|
// the one specified.
|
|
//
|
|
// Arguments:
|
|
// pszInfId [in] inf id of component
|
|
// ppszAnswerFile [out] pointer to answer filename string.
|
|
// ppszAnswerSection [out] pointer to answer filename section string
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: billbe 12 July 1999
|
|
//
|
|
// Notes: This fcn is not for adapters. If you need the answerfile
|
|
// parameters for an adapter, use
|
|
// HrGetAnswerFileParametersForNetCard.
|
|
//
|
|
HRESULT
|
|
HrGetAnswerFileParametersForComponent (
|
|
IN PCWSTR pszInfId,
|
|
OUT PWSTR* ppszAnswerFile,
|
|
OUT PWSTR* ppszAnswerSection)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(pszInfId);
|
|
Assert(ppszAnswerFile);
|
|
Assert(ppszAnswerSection);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag (ttidNetSetup, "In HrGetAnswerFileParametersForComponent");
|
|
|
|
*ppszAnswerFile = NULL;
|
|
*ppszAnswerSection = NULL;
|
|
|
|
// If we don't already have a cached pointer...
|
|
if (!g_pniiTemp)
|
|
{
|
|
// Initialize our net install info.
|
|
hr = HrInitAnswerFileProcessing(NULL, &g_pniiTemp);
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(g_pniiTemp);
|
|
if (!g_pniiTemp->AnswerFileInitialized())
|
|
{
|
|
hr = NETSETUP_E_NO_ANSWERFILE;
|
|
TraceTag (ttidNetSetup, "No answerfile");
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// Find the component in the list of component's with
|
|
// answer file sections.
|
|
CNetComponent* pnetcomp;
|
|
pnetcomp = g_pniiTemp->FindFromInfID (pszInfId);
|
|
|
|
if (!pnetcomp)
|
|
{
|
|
// The component doesn't have a section. Return
|
|
// no answer file.
|
|
hr = NETSETUP_E_NO_ANSWERFILE;
|
|
TraceTag (ttidNetSetup, "Component not found");
|
|
}
|
|
else
|
|
{
|
|
if (NCT_Adapter == pnetcomp->Type())
|
|
{
|
|
// We don't support getting answerfile parameters
|
|
// for adapters. HrGetAnswerFileParametersForNetCard
|
|
// is the fcn for adapters.
|
|
hr = NETSETUP_E_NO_ANSWERFILE;
|
|
}
|
|
else
|
|
{
|
|
// Allocate and save the answerfile name and the
|
|
// component's section.
|
|
hr = HrCoTaskMemAllocAndDupSz (g_pniiTemp->AnswerFileName(),
|
|
ppszAnswerFile);
|
|
if (S_OK == hr)
|
|
{
|
|
hr = HrCoTaskMemAllocAndDupSz (
|
|
pnetcomp->ParamsSections().c_str(),
|
|
ppszAnswerSection);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceTag (ttidNetSetup, "Answerfile could not be initialized");
|
|
}
|
|
|
|
TraceHr (ttidError, FAL, hr,
|
|
(NETSETUP_E_NO_ANSWERFILE == hr) ||
|
|
(HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND) == hr),
|
|
"HrGetAnswerFileParametersForComponent");
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrGetAnswerFileParametersForNetCard
|
|
//
|
|
// Purpose: Search in answerfile for a net card whose InfID matches
|
|
// at least one in the supplied multi-sz list.
|
|
//
|
|
// Arguments:
|
|
// mszInfIDs [in] list of InfIDs
|
|
// pszDeviceName [in] exported device name of the card to search
|
|
// pguidNetCardInstance [in] pointer to instance guid of the card
|
|
// pszAnswerFile [out] pointer to answer filename string.
|
|
// pszAnswerSection [out] pointer to answer filname sections string
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Author: kumarp 26-November-97
|
|
//
|
|
// Notes: If more than one such card is found in the answerfile, then
|
|
// resolve between the cards by finding out the net-card-address
|
|
// of the pszServiceInstance and matching it against that
|
|
// stored in the answerfile.
|
|
//
|
|
EXTERN_C
|
|
HRESULT
|
|
WINAPI
|
|
HrGetAnswerFileParametersForNetCard(
|
|
IN HDEVINFO hdi,
|
|
IN PSP_DEVINFO_DATA pdeid,
|
|
IN PCWSTR pszDeviceName,
|
|
IN const GUID* pguidNetCardInstance,
|
|
OUT PWSTR* ppszwAnswerFile,
|
|
OUT PWSTR* ppszwAnswerSections)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(IsValidHandle(hdi));
|
|
Assert(pdeid);
|
|
Assert(pguidNetCardInstance);
|
|
Assert(ppszwAnswerFile);
|
|
Assert(ppszwAnswerSections);
|
|
|
|
HRESULT hr=E_FAIL;
|
|
CNetAdapter* pna=NULL;
|
|
WORD wNumAdapters=0;
|
|
QWORD qwNetCardAddr=0;
|
|
|
|
*ppszwAnswerFile = NULL;
|
|
*ppszwAnswerSections = NULL;
|
|
|
|
if (!g_pniiTemp)
|
|
{
|
|
hr = HrInitAnswerFileProcessing(NULL, &g_pniiTemp);
|
|
#if DBG
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(g_pniiTemp);
|
|
}
|
|
#endif
|
|
if (FAILED(hr) || !g_pniiTemp->AnswerFileInitialized())
|
|
{
|
|
TraceHr (ttidNetSetup, FAL, hr, (hr == NETSETUP_E_NO_ANSWERFILE) ||
|
|
hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
|
|
"HrGetAnswerFileParametersForNetCard");
|
|
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
// 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) )
|
|
|
|
hr = HrGetNetCardAddr(pszDeviceName, &qwNetCardAddr);
|
|
if ((S_OK == hr) && qwNetCardAddr)
|
|
{
|
|
// there is a bug in wvsprintfA (used in trace.cpp) which does not
|
|
// handle %I64x therefore we need to show the QWORD addr as follows
|
|
//
|
|
TraceTag(ttidNetSetup, "net card address of %S is 0x%x%x",
|
|
pszDeviceName, HIDWORD(qwNetCardAddr),
|
|
LODWORD(qwNetCardAddr));
|
|
|
|
hr = g_pniiTemp->FindAdapter(qwNetCardAddr, &pna);
|
|
|
|
if (NETSETUP_E_NO_EXACT_MATCH == hr)
|
|
{
|
|
TraceTag(ttidError, "there is no card with this netcard address in the answer-file");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidError, "error getting netcard address of %S",
|
|
pszDeviceName);
|
|
|
|
// if we either (a) failed to get the NetCard address, or
|
|
// (b) if the netcard address was 0 (ISDN adapters), we try other means
|
|
//
|
|
hr = NETSETUP_E_AMBIGUOUS_MATCH;
|
|
}
|
|
|
|
if (NETSETUP_E_AMBIGUOUS_MATCH == hr)
|
|
{
|
|
// could not match netcard using the mac addr. If this device is
|
|
// PCI, try to match using location info.
|
|
//
|
|
|
|
TraceTag (ttidNetSetup, "Did not find a match for netcard address. "
|
|
"But there was at least one section that did not specify an "
|
|
"address.\nChecking bus type of installed adapter.");
|
|
|
|
GUID BusTypeGuid;
|
|
hr = HrSetupDiGetDeviceRegistryProperty (hdi, pdeid,
|
|
SPDRP_BUSTYPEGUID, NULL, (BYTE*)&BusTypeGuid,
|
|
sizeof (BusTypeGuid), NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
if (GUID_BUS_TYPE_PCI == BusTypeGuid)
|
|
{
|
|
TraceTag (ttidNetSetup, "Installed adapter is PCI. "
|
|
"Retrieving its location info.");
|
|
|
|
DWORD BusNumber;
|
|
hr = HrSetupDiGetDeviceRegistryProperty (hdi, pdeid,
|
|
SPDRP_BUSNUMBER, NULL, (BYTE*)&BusNumber,
|
|
sizeof (BusNumber), NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
DWORD Address;
|
|
hr = HrSetupDiGetDeviceRegistryProperty (hdi, pdeid,
|
|
SPDRP_ADDRESS, NULL, (BYTE*)&Address,
|
|
sizeof (Address), NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
TraceTag (ttidNetSetup, "Installed device location: "
|
|
"Bus: %X, Device %x, Function %x\n Will try to "
|
|
"use location info to find a match with the "
|
|
"remaining ambiguous sections.", BusNumber,
|
|
HIWORD(Address), LOWORD(Address));
|
|
|
|
hr = g_pniiTemp->FindAdapter (BusNumber,
|
|
Address, &pna);
|
|
|
|
#ifdef ENABLETRACE
|
|
if (NETSETUP_E_NO_EXACT_MATCH == hr)
|
|
{
|
|
TraceTag (ttidNetSetup, "No match was found "
|
|
"using PCI location info.");
|
|
}
|
|
else if (NETSETUP_E_AMBIGUOUS_MATCH == hr)
|
|
{
|
|
TraceTag (ttidNetSetup, "Location info did not "
|
|
"match but some sections did not specify "
|
|
"location info.");
|
|
}
|
|
#endif // ENABLETRACE
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = NETSETUP_E_AMBIGUOUS_MATCH;
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr) && (NETSETUP_E_AMBIGUOUS_MATCH != hr) &&
|
|
(NETSETUP_E_NO_EXACT_MATCH != hr))
|
|
{
|
|
TraceHr(ttidNetSetup, FAL, hr, FALSE, "Trying to retrieve/use "
|
|
"PCI location info.");
|
|
hr = NETSETUP_E_AMBIGUOUS_MATCH;
|
|
}
|
|
|
|
|
|
if (NETSETUP_E_AMBIGUOUS_MATCH == hr)
|
|
{
|
|
// could not match netcard using the mac addr. try to match
|
|
// using the PnP ID
|
|
|
|
TraceTag (ttidNetSetup, "Will try to use pnp id to find a match "
|
|
"with the remaining ambiguous sections.");
|
|
|
|
PWSTR mszInfIds;
|
|
hr = HrGetCompatibleIds (hdi, pdeid, &mszInfIds);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
#ifdef ENABLETRACE
|
|
TStringList slInfIds;
|
|
tstring strInfIds;
|
|
MultiSzToColString(mszInfIds, &slInfIds);
|
|
ConvertStringListToCommaList(slInfIds, strInfIds);
|
|
TraceTag(ttidNetSetup, "(InfIDs (%d): %S\tDeviceName: %S)",
|
|
slInfIds.size(), strInfIds.c_str(), pszDeviceName);
|
|
#endif
|
|
// find out how many adapters have this InfID
|
|
wNumAdapters = g_pniiTemp->AdaptersPage()->GetNumCompatibleAdapters(mszInfIds);
|
|
|
|
TraceTag(ttidNetSetup, "%d adapters of type '%S' found in the answer-file",
|
|
wNumAdapters, mszInfIds);
|
|
|
|
if (wNumAdapters == 1)
|
|
{
|
|
// a definite match found
|
|
pna = (CNetAdapter*) g_pniiTemp->AdaptersPage()->FindCompatibleAdapter(mszInfIds);
|
|
Assert(pna);
|
|
|
|
// Since matching by inf id can cause one section to be
|
|
// matched to multiple adapters, we pass on sections that
|
|
// have already been give to an adapter.
|
|
//
|
|
GUID guid = GUID_NULL;
|
|
pna->GetInstanceGuid(&guid);
|
|
|
|
if (GUID_NULL == guid)
|
|
{
|
|
// The section is still available.
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
// This section was given to another adapter.
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// either there are no adapters of this type in the answerfile
|
|
// or there are multiple adapters of the same type.
|
|
// we couldn't match the card using the mac addr earlier.
|
|
// must return error
|
|
//
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
MemFree (mszInfIds);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(pna);
|
|
pna->SetInstanceGuid(pguidNetCardInstance);
|
|
|
|
hr = HrCoTaskMemAllocAndDupSz(g_pniiTemp->AnswerFileName(),
|
|
(PWSTR*) ppszwAnswerFile);
|
|
if (S_OK == hr)
|
|
{
|
|
hr = HrCoTaskMemAllocAndDupSz(pna->ParamsSections().c_str(),
|
|
(PWSTR*) ppszwAnswerSections);
|
|
}
|
|
}
|
|
|
|
if (S_OK != hr && (NETSETUP_E_NO_ANSWERFILE != hr))
|
|
{
|
|
// add log so that we know why adapter specific params
|
|
// are lost after upgrade
|
|
//
|
|
if (g_dwOperationFlags & SETUPOPER_NTUPGRADE)
|
|
{ // bug 124805 - We only want to see this during upgradres
|
|
WCHAR szGuid[c_cchGuidWithTerm];
|
|
StringFromGUID2(*pguidNetCardInstance, szGuid, c_cchGuidWithTerm);
|
|
NetSetupLogStatusV(LogSevWarning,
|
|
SzLoadIds (IDS_ANSWERFILE_SECTION_NOT_FOUND),
|
|
szGuid);
|
|
}
|
|
}
|
|
|
|
if ((NETSETUP_E_AMBIGUOUS_MATCH == hr) ||
|
|
(NETSETUP_E_NO_EXACT_MATCH == hr))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr,
|
|
(hr == NETSETUP_E_NO_ANSWERFILE) ||
|
|
(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)),
|
|
"HrGetAnswerFileParametersForNetCard");
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrGetInstanceGuidOfPreNT5NetCardInstance
|
|
//
|
|
// Purpose: Finds the instance guid of a component specified in the answerfile
|
|
// or an already installed component
|
|
//
|
|
// Arguments:
|
|
// szPreNT5NetCardInstance [in] pre-NT5 net card instance name e.g. "ieepro2"
|
|
// pguid [out] instance guid of the same card
|
|
//
|
|
// Returns: S_OK if found, S_FALSE if not, or an error code.
|
|
//
|
|
// Author: kumarp 12-AUG-97
|
|
//
|
|
// Notes:
|
|
//
|
|
EXTERN_C
|
|
HRESULT
|
|
WINAPI
|
|
HrGetInstanceGuidOfPreNT5NetCardInstance (
|
|
IN PCWSTR szPreNT5NetCardInstance,
|
|
OUT LPGUID pguid)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(szPreNT5NetCardInstance);
|
|
Assert(pguid);
|
|
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (IsBadStringPtr(szPreNT5NetCardInstance, 64) ||
|
|
IsBadWritePtr(pguid, sizeof(GUID)))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
}
|
|
else if (g_pnii)
|
|
{
|
|
hr = g_pnii->HrGetInstanceGuidOfPreNT5NetCardInstance (
|
|
szPreNT5NetCardInstance, pguid);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE,
|
|
"HrGetInstanceGuidOfPreNT5NetCardInstance");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
HrResolveAnswerFileAdapters (
|
|
IN INetCfg* pnc)
|
|
{
|
|
TraceFileFunc(ttidGuiModeSetup);
|
|
|
|
Assert(g_pnii);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (g_pnii)
|
|
{
|
|
hr = g_pnii->AdaptersPage()->HrResolveNetAdapters(pnc);
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "HrResolveAnswerFileAdapters");
|
|
return hr;
|
|
}
|