mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1779 lines
50 KiB
1779 lines
50 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
// File: A L A N E O B J . C P P
|
|
//
|
|
// Contents: Implementation of the CALaneCfg notify object model
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: v-lcleet 01 Aug 97
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include "alaneobj.h"
|
|
#include "alanepsh.h"
|
|
#include "ncreg.h"
|
|
#include "netconp.h"
|
|
#include "ncpnp.h"
|
|
|
|
#include "alanehlp.h"
|
|
|
|
static const WCHAR c_szAtmLane[] = L"AtmLane";
|
|
static const WCHAR c_szElanList[] = L"ElanList";
|
|
static const WCHAR c_szElanDevice[] = L"Device";
|
|
static const WCHAR c_szElanName[] = L"ElanName";
|
|
|
|
extern const WCHAR c_szDevice[];
|
|
|
|
extern const WCHAR c_szInfId_MS_AtmElan[];
|
|
|
|
const WCHAR c_szAtmAdapterPnpId[] = L"AtmAdapterPnpId";
|
|
|
|
//
|
|
// CALaneCfg
|
|
//
|
|
// Constructor/Destructor methods
|
|
//
|
|
|
|
CALaneCfg::CALaneCfg(VOID) :
|
|
m_pncc(NULL),
|
|
m_pnc(NULL),
|
|
m_ppsp(NULL),
|
|
m_pAdapterSecondary(NULL),
|
|
m_pUnkContext(NULL)
|
|
{
|
|
m_fDirty = FALSE;
|
|
m_fValid = FALSE;
|
|
m_fUpgrade = FALSE;
|
|
m_fNoElanInstalled = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
CALaneCfg::~CALaneCfg(VOID)
|
|
{
|
|
ClearAdapterList(&m_lstAdaptersPrimary);
|
|
ClearAdapterInfo(m_pAdapterSecondary);
|
|
|
|
ReleaseObj(m_pncc);
|
|
ReleaseObj(m_pnc);
|
|
|
|
delete m_ppsp;
|
|
|
|
// Just a safty check to make sure the context is released.
|
|
AssertSz((m_pUnkContext == NULL), "Why is context not released ?");
|
|
ReleaseObj(m_pUnkContext) ;
|
|
|
|
return;
|
|
}
|
|
|
|
//
|
|
// CALaneCfg
|
|
//
|
|
// INetCfgComponentControl interface methods
|
|
//
|
|
|
|
STDMETHODIMP CALaneCfg::Initialize (INetCfgComponent* pncc,
|
|
INetCfg* pnc,
|
|
BOOL fInstalling)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
Validate_INetCfgNotify_Initialize(pncc, pnc, fInstalling);
|
|
|
|
// reference and save away the component and interface.
|
|
AddRefObj(m_pncc = pncc);
|
|
AddRefObj(m_pnc = pnc);
|
|
|
|
// if not installing then load the current config from registry
|
|
if (!fInstalling)
|
|
{
|
|
hr = HrLoadConfiguration();
|
|
}
|
|
|
|
Validate_INetCfgNotify_Initialize_Return(hr);
|
|
|
|
TraceError("CALaneCfg::Initialize", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::Validate ()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::CancelChanges ()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::ApplyRegistryChanges ()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fValid && m_fDirty)
|
|
{
|
|
UpdateElanDisplayNames();
|
|
|
|
// flush out the registry and send reconfig notifications
|
|
hr = HrFlushConfiguration();
|
|
}
|
|
else
|
|
{
|
|
// no change
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
TraceError("CALaneCfg::ApplyRegistryChanges",
|
|
(hr == S_FALSE) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
// INetCfgComponentSetup interface methods
|
|
//
|
|
STDMETHODIMP CALaneCfg::Install (DWORD dwSetupFlags)
|
|
{
|
|
// mark configuration as valid (but empty)
|
|
m_fValid = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::Upgrade( DWORD dwSetupFlags,
|
|
DWORD dwUpgradeFomBuildNo )
|
|
{
|
|
// mark configuration as valid (but empty)
|
|
m_fValid = TRUE;
|
|
m_fUpgrade = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::ReadAnswerFile (PCWSTR pszAnswerFile,
|
|
PCWSTR pszAnswerSection)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::Removing ()
|
|
{
|
|
// mark everything for deletion
|
|
(VOID) HrMarkAllDeleted();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// CALaneCfg
|
|
//
|
|
// INetCfgProperties interface methods
|
|
//
|
|
|
|
STDMETHODIMP CALaneCfg::QueryPropertyUi(IUnknown* pUnk)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if (pUnk)
|
|
{
|
|
// Is this a lan connection ?
|
|
INetLanConnectionUiInfo * pLanConnUiInfo;
|
|
hr = pUnk->QueryInterface( IID_INetLanConnectionUiInfo,
|
|
reinterpret_cast<LPVOID *>(&pLanConnUiInfo));
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
// don't show UI
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::QueryPropertyUi", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::SetContext(IUnknown * pUnk)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// release previous context, if any
|
|
if (m_pUnkContext)
|
|
ReleaseObj(m_pUnkContext);
|
|
m_pUnkContext = NULL;
|
|
|
|
if (pUnk) // set the new context
|
|
{
|
|
m_pUnkContext = pUnk;
|
|
m_pUnkContext->AddRef();
|
|
}
|
|
|
|
TraceError("CALaneCfg::SetContext", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::MergePropPages (
|
|
IN OUT DWORD* pdwDefPages,
|
|
OUT LPBYTE* pahpspPrivate,
|
|
OUT UINT* pcPages,
|
|
IN HWND hwndParent,
|
|
OUT PCWSTR* pszStartPage)
|
|
{
|
|
Validate_INetCfgProperties_MergePropPages(pdwDefPages, pahpspPrivate,
|
|
pcPages, hwndParent, pszStartPage);
|
|
|
|
// Don't show any default pages
|
|
*pdwDefPages = 0;
|
|
*pcPages = 0;
|
|
*pahpspPrivate = NULL;
|
|
|
|
HPROPSHEETPAGE* ahpsp = NULL;
|
|
HRESULT hr = HrALaneSetupPsh(&ahpsp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pahpspPrivate = (LPBYTE)ahpsp;
|
|
*pcPages = c_cALanePages;
|
|
}
|
|
|
|
Validate_INetCfgProperties_MergePropPages_Return(hr);
|
|
|
|
TraceError("CALaneCfg::MergePropPages", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::ValidateProperties (HWND hwndSheet)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::CancelProperties ()
|
|
{
|
|
// throw away the secondary adapter list
|
|
ClearAdapterInfo(m_pAdapterSecondary);
|
|
m_pAdapterSecondary = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::ApplyProperties ()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
INetCfgComponent * pnccAtmElan = NULL;
|
|
tstring strAtmElan;
|
|
|
|
// go thru the secondary adapter info and
|
|
// add miniports for elans that were added and
|
|
// remove miniports for elans that were deleted.
|
|
|
|
// loop thru the elan list on this adapter
|
|
|
|
BOOL bCommitNow = FALSE;
|
|
|
|
for (iterLstElans = m_pAdapterSecondary->m_lstElans.begin();
|
|
iterLstElans != m_pAdapterSecondary->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
|
|
if (pElanInfo->m_fCreateMiniportOnPropertyApply)
|
|
{
|
|
bCommitNow = TRUE;
|
|
|
|
// create associated miniport
|
|
hr = HrAddOrRemoveAdapter(m_pnc,
|
|
c_szInfId_MS_AtmElan, ARA_ADD,
|
|
NULL, 1, &pnccAtmElan);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// This is a new Elan
|
|
pElanInfo->m_fNewElan = TRUE;
|
|
|
|
// BindName
|
|
PWSTR pszTmpBindName;
|
|
hr = pnccAtmElan->GetBindName(&pszTmpBindName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pElanInfo->SetElanBindName(pszTmpBindName);
|
|
CoTaskMemFree(pszTmpBindName);
|
|
|
|
// Device param
|
|
strAtmElan = c_szDevice;
|
|
strAtmElan.append(pElanInfo->SzGetElanBindName());
|
|
|
|
pElanInfo->SetElanDeviceName(strAtmElan.c_str());
|
|
}
|
|
|
|
ReleaseObj(pnccAtmElan);
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CALaneCfg::ApplyProperties, failed creating an Elan", hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
if (pElanInfo->m_fRemoveMiniportOnPropertyApply)
|
|
{
|
|
bCommitNow = TRUE;
|
|
|
|
pElanInfo = *iterLstElans;
|
|
|
|
hr = HrRemoveMiniportInstance(pElanInfo->SzGetElanBindName());
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
pElanInfo->m_fDeleted = FALSE;
|
|
|
|
TraceError("CALaneCfg::ApplyProperties, failed removing an Elan", hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
// all is well
|
|
// copy secondary list to primary
|
|
CopyAdapterInfoSecondaryToPrimary();
|
|
m_fDirty = TRUE;
|
|
|
|
|
|
ClearAdapterInfo(m_pAdapterSecondary);
|
|
m_pAdapterSecondary = NULL;
|
|
|
|
Validate_INetCfgProperties_ApplyProperties_Return(hr);
|
|
|
|
if(bCommitNow && SUCCEEDED(hr))
|
|
{
|
|
hr = NETCFG_S_COMMIT_NOW;
|
|
}
|
|
|
|
TraceError("CALaneCfg::ApplyProperties", hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// CALaneCfg
|
|
//
|
|
// INetCfgBindNotify interface methods
|
|
//
|
|
STDMETHODIMP CALaneCfg::QueryBindingPath (DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CALaneCfg::NotifyBindingPath (DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
Assert(!(dwChangeFlag & NCN_ADD && dwChangeFlag & NCN_REMOVE));
|
|
Assert(!(dwChangeFlag & NCN_ENABLE && dwChangeFlag & NCN_DISABLE));
|
|
|
|
// If we are told to add a card, we must be told at the same time whether the
|
|
// binding is enabled or disabled
|
|
Assert(FImplies((dwChangeFlag & NCN_ADD),
|
|
((dwChangeFlag & NCN_ENABLE)||(dwChangeFlag & NCN_DISABLE))));
|
|
|
|
INetCfgComponent * pnccLastComponent;
|
|
HRESULT hr = HrGetLastComponentAndInterface(pncbp,
|
|
&pnccLastComponent, NULL);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
PWSTR pszBindName;
|
|
hr = pnccLastComponent->GetBindName(&pszBindName);
|
|
if (S_OK == hr)
|
|
{
|
|
if (dwChangeFlag & NCN_ADD)
|
|
{
|
|
hr = HrNotifyBindingAdd(pnccLastComponent, pszBindName);
|
|
}
|
|
else if (dwChangeFlag & NCN_REMOVE)
|
|
{
|
|
hr = HrNotifyBindingRemove(pnccLastComponent, pszBindName);
|
|
}
|
|
else
|
|
{
|
|
// simply mark the adapter as binding changed so we don't
|
|
// send Elan add\remove notifications (Raid #255910)
|
|
|
|
// Get the adapter component's instance name
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
|
|
// search the in-memory list for this adapter
|
|
BOOL fFound;
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin(), fFound = FALSE;
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
if (!lstrcmpiW(pszBindName, pAdapterInfo->SzGetAdapterBindName()))
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fFound)
|
|
{
|
|
// mark it as changed
|
|
pAdapterInfo->m_fBindingChanged = TRUE;
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree (pszBindName);
|
|
}
|
|
|
|
ReleaseObj (pnccLastComponent);
|
|
}
|
|
|
|
TraceError("CALaneCfg::NotifyBindingPath", hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// CALaneCfg
|
|
//
|
|
// Private methods
|
|
//
|
|
HRESULT
|
|
CALaneCfg::HrNotifyBindingAdd (
|
|
INetCfgComponent* pnccAdapter,
|
|
PCWSTR pszBindName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// $REVIEW(tongl 1/25/98): Added this: we should see if this adapter is
|
|
// is already in our list but marked as for deletion. If so, simply unmark
|
|
// the adapter and all of it's Elans. The Binding Add could be a fake one
|
|
// when it is in uprade process.
|
|
|
|
BOOL fFound;
|
|
CALaneCfgAdapterInfo* pAdapterInfo = NULL;
|
|
|
|
// search the in-memory list for this adapter
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin(), fFound = FALSE;
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
if (!lstrcmpiW(pszBindName, pAdapterInfo->SzGetAdapterBindName()))
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fFound) // Add an old adapter back
|
|
{
|
|
Assert(pAdapterInfo->m_fDeleted);
|
|
|
|
// mark it un-deleted
|
|
pAdapterInfo->m_fDeleted = FALSE;
|
|
|
|
if (m_fUpgrade)
|
|
{
|
|
// the Elans are not deleted, just mark them as un-deleted
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
for (iterLstElans = pAdapterInfo->m_lstElans.begin();
|
|
iterLstElans!= pAdapterInfo->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
Assert((*iterLstElans)->m_fDeleted);
|
|
(*iterLstElans)->m_fDeleted = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if this is a new atm adapter
|
|
|
|
// Create a new in-memory adapter object
|
|
pAdapterInfo = new CALaneCfgAdapterInfo;
|
|
|
|
if (pAdapterInfo)
|
|
{
|
|
GUID guidAdapter;
|
|
hr = pnccAdapter->GetInstanceGuid(&guidAdapter);
|
|
if (S_OK == hr)
|
|
{
|
|
pAdapterInfo->m_guidInstanceId = guidAdapter;
|
|
}
|
|
|
|
// the adapter is newly added
|
|
pAdapterInfo->m_fBindingChanged = TRUE;
|
|
|
|
// Set the bind name of the adapter
|
|
pAdapterInfo->SetAdapterBindName(pszBindName);
|
|
|
|
// Set the PnpId of the adapter
|
|
PWSTR pszPnpDevNodeId;
|
|
hr = pnccAdapter->GetPnpDevNodeId(&pszPnpDevNodeId);
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(pszPnpDevNodeId);
|
|
|
|
pAdapterInfo->SetAdapterPnpId(pszPnpDevNodeId);
|
|
CoTaskMemFree(pszPnpDevNodeId);
|
|
}
|
|
|
|
// Create a new in-memory elan object
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
pElanInfo = new CALaneCfgElanInfo;
|
|
|
|
if (pElanInfo)
|
|
{
|
|
pElanInfo->m_fNewElan = TRUE;
|
|
|
|
// Install a virtual miniport for a default ELAN
|
|
INetCfgComponent* pnccAtmElan;
|
|
|
|
hr = HrAddOrRemoveAdapter(m_pnc, c_szInfId_MS_AtmElan,
|
|
ARA_ADD, NULL, 1, &pnccAtmElan);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
Assert(pnccAtmElan);
|
|
|
|
// Update the BindName
|
|
PWSTR pszElanBindName;
|
|
hr = pnccAtmElan->GetBindName(&pszElanBindName);
|
|
if (S_OK == hr)
|
|
{
|
|
pElanInfo->SetElanBindName(pszElanBindName);
|
|
CoTaskMemFree(pszElanBindName);
|
|
}
|
|
|
|
// Update the Device param
|
|
tstring strAtmElan;
|
|
strAtmElan = c_szDevice;
|
|
strAtmElan.append(pElanInfo->SzGetElanBindName());
|
|
|
|
pElanInfo->SetElanDeviceName(strAtmElan.c_str());
|
|
|
|
// Push the Elan onto the the adapter's list
|
|
pAdapterInfo->m_lstElans.push_back(pElanInfo);
|
|
|
|
// Push the Adapter onto the adapter list
|
|
m_lstAdaptersPrimary.push_back(pAdapterInfo);
|
|
|
|
// Mark the in-memory configuration dirty
|
|
m_fDirty = TRUE;
|
|
|
|
ReleaseObj(pnccAtmElan);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrNotifyBindingAdd", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CALaneCfg::HrNotifyBindingRemove (
|
|
INetCfgComponent* pnccAdapter,
|
|
PCWSTR pszBindName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
|
|
// search the in-memory list for this adapter
|
|
BOOL fFound;
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin(), fFound = FALSE;
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
if (!lstrcmpiW (pszBindName, pAdapterInfo->SzGetAdapterBindName()))
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fFound)
|
|
{
|
|
// mark it deleted
|
|
pAdapterInfo->m_fDeleted = TRUE;
|
|
|
|
// mark as binding changed
|
|
pAdapterInfo->m_fBindingChanged = TRUE;
|
|
|
|
// if this is upgrade, then mark all associated ELANs deleted
|
|
// otherwise, delete them now
|
|
HRESULT hrElan = S_OK;
|
|
|
|
for (ELAN_INFO_LIST::iterator iterLstElans = pAdapterInfo->m_lstElans.begin();
|
|
iterLstElans!= pAdapterInfo->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
if (!m_fUpgrade)
|
|
{
|
|
// Remove corresponding miniport.
|
|
hrElan = HrRemoveMiniportInstance((*iterLstElans)->SzGetElanBindName());
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
(*iterLstElans)->m_fDeleted = TRUE;
|
|
}
|
|
else
|
|
{
|
|
TraceError("HrRemoveMiniportInstance failed", hrElan);
|
|
hrElan = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
// mark the in-memory configuration dirty
|
|
m_fDirty = TRUE;
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrNotifyBindingRemove", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrLoadConfiguration()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// mark the memory version of the registy valid
|
|
m_fValid = TRUE;
|
|
|
|
// open adapter list subkey
|
|
HKEY hkeyAdapterList = NULL;
|
|
|
|
// Try to open an existing key first.
|
|
//
|
|
hr = HrRegOpenAdapterKey(c_szAtmLane, FALSE, &hkeyAdapterList);
|
|
if (FAILED(hr))
|
|
{
|
|
// Only on failure do we try to create it
|
|
//
|
|
hr = HrRegOpenAdapterKey(c_szAtmLane, TRUE, &hkeyAdapterList);
|
|
}
|
|
if (S_OK == hr)
|
|
{
|
|
WCHAR szBuf[MAX_PATH+1];
|
|
FILETIME time;
|
|
DWORD dwSize;
|
|
DWORD dwRegIndex = 0;
|
|
|
|
dwSize = celems(szBuf);
|
|
while (S_OK == (hr = HrRegEnumKeyEx (hkeyAdapterList, dwRegIndex,
|
|
szBuf, &dwSize, NULL, NULL, &time)))
|
|
{
|
|
Assert(szBuf);
|
|
|
|
// load this adapter's config
|
|
hr = HrLoadAdapterConfiguration (hkeyAdapterList, szBuf);
|
|
if (S_OK != hr)
|
|
{
|
|
TraceTag (ttidAtmLane, "CALaneCfg::HrLoadConfiguration failed on adapter %S", szBuf);
|
|
hr = S_OK;
|
|
}
|
|
|
|
// increment index and reset size variable
|
|
dwRegIndex++;
|
|
dwSize = celems (szBuf);
|
|
}
|
|
|
|
if (HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS) == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
RegCloseKey (hkeyAdapterList);
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrLoadConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrLoadAdapterConfiguration(HKEY hkeyAdapterList,
|
|
PWSTR pszAdapterName)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// load this adapter
|
|
CALaneCfgAdapterInfo* pAdapterInfo;
|
|
pAdapterInfo = new CALaneCfgAdapterInfo;
|
|
|
|
if (pAdapterInfo)
|
|
{
|
|
pAdapterInfo->SetAdapterBindName(pszAdapterName);
|
|
m_lstAdaptersPrimary.push_back(pAdapterInfo);
|
|
|
|
// open this adapter's subkey
|
|
HKEY hkeyAdapter = NULL;
|
|
DWORD dwDisposition;
|
|
|
|
hr = HrRegCreateKeyEx(
|
|
hkeyAdapterList,
|
|
pszAdapterName,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyAdapter,
|
|
&dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// load the PnpId
|
|
INetCfgComponent* pnccAdapter = NULL;
|
|
hr = HrFindNetCardInstance(pszAdapterName, &pnccAdapter);
|
|
if (S_OK == hr)
|
|
{
|
|
PWSTR pszPnpDevNodeId;
|
|
hr = pnccAdapter->GetPnpDevNodeId(&pszPnpDevNodeId);
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(pszPnpDevNodeId);
|
|
pAdapterInfo->SetAdapterPnpId(pszPnpDevNodeId);
|
|
CoTaskMemFree(pszPnpDevNodeId);
|
|
}
|
|
|
|
GUID guidAdapter;
|
|
hr = pnccAdapter->GetInstanceGuid(&guidAdapter);
|
|
if (S_OK == hr)
|
|
{
|
|
pAdapterInfo->m_guidInstanceId = guidAdapter;
|
|
}
|
|
|
|
// load the ElanList
|
|
hr = HrLoadElanListConfiguration(hkeyAdapter, pAdapterInfo);
|
|
|
|
ReleaseObj(pnccAdapter);
|
|
}
|
|
else if (S_FALSE == hr)
|
|
{
|
|
// nromalize return
|
|
hr = S_OK;
|
|
}
|
|
|
|
RegCloseKey(hkeyAdapter);
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrLoadAdapterConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CALaneCfg::HrLoadElanListConfiguration(
|
|
HKEY hkeyAdapter,
|
|
CALaneCfgAdapterInfo* pAdapterInfo)
|
|
{
|
|
HRESULT hr;
|
|
|
|
// open the ElanList subkey
|
|
HKEY hkeyElanList = NULL;
|
|
DWORD dwDisposition;
|
|
hr = HrRegCreateKeyEx(hkeyAdapter, c_szElanList, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, NULL, &hkeyElanList, &dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
|
|
WCHAR szBuf[MAX_PATH+1];
|
|
FILETIME time;
|
|
DWORD dwSize;
|
|
DWORD dwRegIndex = 0;
|
|
|
|
dwSize = celems(szBuf);
|
|
while(SUCCEEDED(hr = HrRegEnumKeyEx(hkeyElanList, dwRegIndex, szBuf,
|
|
&dwSize, NULL, NULL, &time)))
|
|
{
|
|
Assert(szBuf);
|
|
|
|
// load this ELAN's config
|
|
hr = HrLoadElanConfiguration(hkeyElanList,
|
|
szBuf,
|
|
pAdapterInfo);
|
|
if (S_OK != hr)
|
|
{
|
|
TraceTag(ttidAtmLane, "CALaneCfg::HrLoadConfiguration failed on Elan %S", szBuf);
|
|
hr = S_OK;
|
|
}
|
|
else if (m_fNoElanInstalled)
|
|
{
|
|
m_fNoElanInstalled = FALSE;
|
|
}
|
|
|
|
// increment index and reset size variable
|
|
dwRegIndex ++;
|
|
dwSize = celems(szBuf);
|
|
}
|
|
|
|
if(hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
|
|
hr = S_OK;
|
|
|
|
RegCloseKey(hkeyElanList);
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrLoadElanListConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CALaneCfg::HrLoadElanConfiguration(
|
|
HKEY hkeyElanList,
|
|
PWSTR pszElan,
|
|
CALaneCfgAdapterInfo* pAdapterInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
do
|
|
{
|
|
// load this ELAN info
|
|
CALaneCfgElanInfo * pElanInfo = NULL;
|
|
pElanInfo = new CALaneCfgElanInfo;
|
|
|
|
CALaneCfgElanInfo * pOldElanInfo = NULL;
|
|
pOldElanInfo = new CALaneCfgElanInfo;
|
|
|
|
if ((pElanInfo == NULL) ||
|
|
(pOldElanInfo == NULL))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
if (pElanInfo)
|
|
{
|
|
delete pElanInfo;
|
|
}
|
|
if (pOldElanInfo)
|
|
{
|
|
delete pOldElanInfo;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
pAdapterInfo->m_lstElans.push_back(pElanInfo);
|
|
pElanInfo->SetElanBindName(pszElan);
|
|
|
|
pAdapterInfo->m_lstOldElans.push_back(pOldElanInfo);
|
|
pOldElanInfo->SetElanBindName(pszElan);
|
|
|
|
// open the ELAN's key
|
|
HKEY hkeyElan = NULL;
|
|
DWORD dwDisposition;
|
|
hr = HrRegCreateKeyEx (hkeyElanList, pszElan, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, NULL, &hkeyElan, &dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// read the Device parameter
|
|
PWSTR pszElanDevice;
|
|
hr = HrRegQuerySzWithAlloc (hkeyElan, c_szElanDevice, &pszElanDevice);
|
|
if (S_OK == hr)
|
|
{
|
|
// load the Device name
|
|
pElanInfo->SetElanDeviceName(pszElanDevice);
|
|
pOldElanInfo->SetElanDeviceName(pszElanDevice);
|
|
MemFree (pszElanDevice);
|
|
|
|
// read the ELAN Name parameter
|
|
PWSTR pszElanName;
|
|
hr = HrRegQuerySzWithAlloc (hkeyElan, c_szElanName, &pszElanName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// load the ELAN name
|
|
pElanInfo->SetElanName (pszElanName);
|
|
pOldElanInfo->SetElanName (pszElanName);
|
|
MemFree (pszElanName);
|
|
}
|
|
}
|
|
RegCloseKey (hkeyElan);
|
|
}
|
|
}
|
|
while (FALSE);
|
|
|
|
TraceError ("CALaneCfg::HrLoadElanConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrFlushConfiguration()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HKEY hkeyAdapterList = NULL;
|
|
|
|
// Open the "Adapters" list key
|
|
hr = ::HrRegOpenAdapterKey(c_szAtmLane, TRUE, &hkeyAdapterList);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
|
|
HRESULT hrTmp;
|
|
|
|
// Iterate thru the adapters
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin();
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
// Flush this adapter's configuration
|
|
hrTmp = HrFlushAdapterConfiguration(hkeyAdapterList, pAdapterInfo);
|
|
if (SUCCEEDED(hrTmp))
|
|
{
|
|
// Raid #255910: only send Elan change notification if the
|
|
// binding to the physical adapter has not changed
|
|
if (!pAdapterInfo->m_fBindingChanged)
|
|
{
|
|
// Compare Elan list and send notifications
|
|
hrTmp = HrReconfigLane(pAdapterInfo);
|
|
|
|
if (FAILED(hrTmp))
|
|
hrTmp = NETCFG_S_REBOOT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TraceTag(ttidAtmLane,"HrFlushAdapterConfiguration failed for adapter %S", pAdapterInfo->SzGetAdapterBindName());
|
|
hrTmp = S_OK;
|
|
}
|
|
|
|
if (S_OK ==hr)
|
|
hr = hrTmp;
|
|
}
|
|
RegCloseKey(hkeyAdapterList);
|
|
}
|
|
|
|
if (hr != NETCFG_S_REBOOT) {
|
|
TraceError("CALaneCfg::HrFlushConfiguration", hr);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrFlushAdapterConfiguration(HKEY hkeyAdapterList,
|
|
CALaneCfgAdapterInfo *pAdapterInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
HKEY hkeyAdapter = NULL;
|
|
DWORD dwDisposition;
|
|
|
|
if (pAdapterInfo->m_fDeleted)
|
|
{
|
|
// Adapter is marked for deletion
|
|
// Delete this adapter's whole registry branch
|
|
hr = HrRegDeleteKeyTree(hkeyAdapterList,
|
|
pAdapterInfo->SzGetAdapterBindName());
|
|
}
|
|
else
|
|
{
|
|
// open this adapter's subkey
|
|
hr = HrRegCreateKeyEx(
|
|
hkeyAdapterList,
|
|
pAdapterInfo->SzGetAdapterBindName(),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyAdapter,
|
|
&dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// Flush the ELAN configuration
|
|
hr = HrFlushElanListConfiguration(hkeyAdapter, pAdapterInfo);
|
|
|
|
RegCloseKey(hkeyAdapter);
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrFlushAdapterConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrFlushElanListConfiguration(HKEY hkeyAdapter,
|
|
CALaneCfgAdapterInfo *pAdapterInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
HKEY hkeyElanList = NULL;
|
|
DWORD dwDisposition;
|
|
|
|
// Open the Elan list subkey
|
|
hr = HrRegCreateKeyEx(
|
|
hkeyAdapter,
|
|
c_szElanList,
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyElanList,
|
|
&dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
|
|
// iterate thru the Elans
|
|
for (iterLstElans = pAdapterInfo->m_lstElans.begin();
|
|
iterLstElans != pAdapterInfo->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
|
|
hr = HrFlushElanConfiguration(hkeyElanList, pElanInfo);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("HrFlushElanConfiguration failure", hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
// $REVIEW(tongl 9/9/98): write ATM adapter's pnp id to registry (#169025)
|
|
if ((!pElanInfo->m_fDeleted) && (pElanInfo->m_fNewElan))
|
|
{
|
|
INetCfgComponent * pnccAtmElan;
|
|
hr = HrFindNetCardInstance(pElanInfo->SzGetElanBindName(),
|
|
&pnccAtmElan);
|
|
if (S_OK == hr)
|
|
{
|
|
HKEY hkeyElan = NULL;
|
|
|
|
hr = pnccAtmElan->OpenParamKey(&hkeyElan);
|
|
if (S_OK == hr)
|
|
{
|
|
Assert(hkeyElan);
|
|
HrRegSetSz(hkeyElan, c_szAtmAdapterPnpId,
|
|
pAdapterInfo->SzGetAdapterPnpId());
|
|
}
|
|
RegSafeCloseKey(hkeyElan);
|
|
}
|
|
ReleaseObj(pnccAtmElan);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkeyElanList);
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrFlushElanListConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrFlushElanConfiguration(HKEY hkeyElanList,
|
|
CALaneCfgElanInfo *pElanInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pElanInfo->m_fDeleted)
|
|
{
|
|
PCWSTR szBindName = pElanInfo->SzGetElanBindName();
|
|
|
|
if (lstrlenW(szBindName)) // only if the bindname is not empty
|
|
{
|
|
// Elan is marked for deletion
|
|
// Delete this Elan's whole registry branch
|
|
hr = HrRegDeleteKeyTree(hkeyElanList,
|
|
pElanInfo->SzGetElanBindName());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HKEY hkeyElan = NULL;
|
|
DWORD dwDisposition;
|
|
|
|
// open/create this Elan's key
|
|
hr = HrRegCreateKeyEx(
|
|
hkeyElanList,
|
|
pElanInfo->SzGetElanBindName(),
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS,
|
|
NULL,
|
|
&hkeyElan,
|
|
&dwDisposition);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// Write the Device parameter
|
|
hr = HrRegSetSz(hkeyElan, c_szElanDevice,
|
|
pElanInfo->SzGetElanDeviceName());
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("Failed save Elan device parameter", hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
// Write the ElanName parameter
|
|
hr = HrRegSetSz(hkeyElan, c_szElanName,
|
|
pElanInfo->SzGetElanName());
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("Failed save Elan name parameter", hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
RegSafeCloseKey(hkeyElan);
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrFlushElanConfiguration", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrRemoveMiniportInstance(PCWSTR pszBindNameToRemove)
|
|
{
|
|
// Enumerate adapters in the system.
|
|
//
|
|
HRESULT hr = S_OK;
|
|
CIterNetCfgComponent nccIter (m_pnc, &GUID_DEVCLASS_NET);
|
|
BOOL fFound = FALSE;
|
|
|
|
INetCfgComponent* pnccAdapter;
|
|
while ((!fFound) && SUCCEEDED(hr) &&
|
|
S_OK == (hr = nccIter.HrNext (&pnccAdapter)))
|
|
{
|
|
if (FIsComponentId(c_szInfId_MS_AtmElan, pnccAdapter))
|
|
{
|
|
// Get the bindname of the miniport
|
|
PWSTR pszBindName;
|
|
hr = pnccAdapter->GetBindName(&pszBindName);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// If the right one tell it to remove itself and end
|
|
BOOL fRemove = !lstrcmpiW (pszBindName, pszBindNameToRemove);
|
|
|
|
if (fRemove)
|
|
{
|
|
fFound = TRUE;
|
|
hr = HrRemoveComponent( m_pnc, pnccAdapter, NULL, NULL);
|
|
}
|
|
|
|
CoTaskMemFree (pszBindName);
|
|
}
|
|
}
|
|
ReleaseObj (pnccAdapter);
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrRemoveMiniportInstance", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CALaneCfg::HrFindNetCardInstance(
|
|
PCWSTR pszBindNameToFind,
|
|
INetCfgComponent** ppncc)
|
|
{
|
|
*ppncc = NULL;
|
|
|
|
// Enumerate adapters in the system.
|
|
//
|
|
HRESULT hr = S_OK;
|
|
CIterNetCfgComponent nccIter (m_pnc, &GUID_DEVCLASS_NET);
|
|
BOOL fFound = FALSE;
|
|
|
|
INetCfgComponent* pnccAdapter;
|
|
while ((!fFound) && SUCCEEDED(hr) &&
|
|
S_OK == (hr = nccIter.HrNext (&pnccAdapter)))
|
|
{
|
|
// Get the bindname of the miniport
|
|
PWSTR pszBindName;
|
|
hr = pnccAdapter->GetBindName(&pszBindName);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
// If the right one tell it to remove itself and end
|
|
fFound = !lstrcmpiW(pszBindName, pszBindNameToFind);
|
|
CoTaskMemFree (pszBindName);
|
|
|
|
if (fFound)
|
|
{
|
|
*ppncc = pnccAdapter;
|
|
}
|
|
}
|
|
|
|
if (!fFound)
|
|
{
|
|
ReleaseObj (pnccAdapter);
|
|
}
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, (S_FALSE == hr),
|
|
"CALaneCfg::HrFindNetCardInstance", hr);
|
|
return hr;
|
|
}
|
|
|
|
VOID CALaneCfg::HrMarkAllDeleted()
|
|
{
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
|
|
// loop thru the adapter list
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin();
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
(*iterLstAdapters)->m_fDeleted = TRUE;
|
|
|
|
// loop thru the ELAN list
|
|
for (iterLstElans = (*iterLstAdapters)->m_lstElans.begin();
|
|
iterLstElans != (*iterLstAdapters)->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
(*iterLstElans)->m_fDeleted = TRUE;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID CALaneCfg::UpdateElanDisplayNames()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// loop thru the adapter list
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin();
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
// loop thru the ELAN list
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
|
|
for (iterLstElans = (*iterLstAdapters)->m_lstElans.begin();
|
|
iterLstElans != (*iterLstAdapters)->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
|
|
// Update the miniport's display name with
|
|
// the ELAN name appended.
|
|
INetCfgComponent* pnccAtmElan = NULL;
|
|
hr = HrFindNetCardInstance(pElanInfo->SzGetElanBindName(),
|
|
&pnccAtmElan);
|
|
if (S_OK == hr)
|
|
{
|
|
PWSTR pszDisplayName;
|
|
hr = pnccAtmElan->GetDisplayName(&pszDisplayName);
|
|
if (S_OK == hr)
|
|
{
|
|
tstring strNewDisplayName;
|
|
int pos;
|
|
|
|
strNewDisplayName = pszDisplayName;
|
|
pos = strNewDisplayName.find_last_of(L"(");
|
|
if (pos != strNewDisplayName.npos)
|
|
strNewDisplayName.resize(pos);
|
|
strNewDisplayName.append(L"(");
|
|
|
|
if (lstrlenW(pElanInfo->SzGetElanName()) > 0)
|
|
{
|
|
strNewDisplayName.append(pElanInfo->SzGetElanName());
|
|
}
|
|
else
|
|
{
|
|
strNewDisplayName.append(SzLoadIds(IDS_ALANECFG_UNSPECIFIEDNAME));
|
|
}
|
|
|
|
strNewDisplayName.append(L")");
|
|
|
|
(VOID)pnccAtmElan->SetDisplayName(strNewDisplayName.c_str());
|
|
CoTaskMemFree(pszDisplayName);
|
|
}
|
|
|
|
ReleaseObj(pnccAtmElan);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrALaneSetupPsh(HPROPSHEETPAGE** pahpsp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HPROPSHEETPAGE* ahpsp = NULL;
|
|
|
|
AssertSz(pahpsp, "We must have a place to put prop sheets");
|
|
|
|
// set connections context
|
|
hr = HrSetConnectionContext();
|
|
if SUCCEEDED(hr)
|
|
{
|
|
// copy the primary adapter list to the secondary adapters list
|
|
CopyAdapterInfoPrimaryToSecondary();
|
|
|
|
*pahpsp = NULL;
|
|
|
|
// Allocate a buffer large enough to hold the handles to all of our
|
|
// property pages.
|
|
ahpsp = (HPROPSHEETPAGE*)CoTaskMemAlloc(sizeof(HPROPSHEETPAGE));
|
|
if (ahpsp)
|
|
{
|
|
if (!m_ppsp)
|
|
delete m_ppsp;
|
|
|
|
// Allocate each of the CPropSheetPage objects
|
|
m_ppsp = new CALanePsh(this, m_pAdapterSecondary, g_aHelpIDs_IDD_MAIN);
|
|
|
|
// Create the actual PROPSHEETPAGE for each object.
|
|
// This needs to be done regardless of whether the classes existed before.
|
|
ahpsp[0] = m_ppsp->CreatePage(IDD_MAIN, PSP_DEFAULT);
|
|
|
|
*pahpsp = ahpsp;
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrALaneSetupPsh", hr);
|
|
return hr;
|
|
}
|
|
|
|
// Added by tongl at 12\11\97
|
|
HRESULT CALaneCfg::HrSetConnectionContext()
|
|
{
|
|
AssertSz(m_pUnkContext, "Invalid IUnknown pointer passed to CALaneCfg::SetContext?");
|
|
|
|
if (!m_pUnkContext)
|
|
return E_FAIL;
|
|
|
|
HRESULT hr = S_OK;
|
|
GUID guidConn;
|
|
|
|
// Is this a lan connection ?
|
|
INetLanConnectionUiInfo * pLanConnUiInfo;
|
|
hr = m_pUnkContext->QueryInterface( IID_INetLanConnectionUiInfo,
|
|
reinterpret_cast<LPVOID *>(&pLanConnUiInfo));
|
|
if (S_OK == hr)
|
|
{
|
|
// yes, lan connection
|
|
pLanConnUiInfo->GetDeviceGuid(&guidConn);
|
|
|
|
WCHAR szGuid[c_cchGuidWithTerm];
|
|
INT cch = StringFromGUID2(guidConn, szGuid, c_cchGuidWithTerm);
|
|
Assert(cch);
|
|
m_strGuidConn = szGuid;
|
|
}
|
|
ReleaseObj(pLanConnUiInfo);
|
|
|
|
TraceError("CALaneCfg::HrSetConnectionContext", hr);
|
|
return hr;
|
|
}
|
|
|
|
VOID CALaneCfg::CopyAdapterInfoPrimaryToSecondary()
|
|
{
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
CALaneCfgElanInfo * pElanInfoNew;
|
|
|
|
// free any existing secondary data
|
|
ClearAdapterInfo(m_pAdapterSecondary);
|
|
m_pAdapterSecondary = NULL;
|
|
|
|
// loop thru the primary adapter list
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin();
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
// create new and copy from primary
|
|
if (FIsSubstr(m_strGuidConn.c_str(), pAdapterInfo->SzGetAdapterBindName()))
|
|
{
|
|
// we found a match
|
|
m_pAdapterSecondary = new CALaneCfgAdapterInfo;
|
|
|
|
m_pAdapterSecondary->m_guidInstanceId = pAdapterInfo-> m_guidInstanceId;
|
|
m_pAdapterSecondary->m_fDeleted = pAdapterInfo->m_fDeleted;
|
|
m_pAdapterSecondary->SetAdapterBindName(pAdapterInfo->SzGetAdapterBindName());
|
|
m_pAdapterSecondary->SetAdapterPnpId(pAdapterInfo->SzGetAdapterPnpId());
|
|
|
|
// loop thru the elan list on this adapter
|
|
|
|
for (iterLstElans = pAdapterInfo->m_lstElans.begin();
|
|
iterLstElans != pAdapterInfo->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
|
|
// create new and copy from primary
|
|
pElanInfoNew = new CALaneCfgElanInfo;
|
|
|
|
pElanInfoNew->SetElanBindName(pElanInfo->SzGetElanBindName());
|
|
pElanInfoNew->SetElanDeviceName(pElanInfo->SzGetElanDeviceName());
|
|
pElanInfoNew->SetElanName(pElanInfo->SzGetElanName());
|
|
pElanInfoNew->m_fDeleted = pElanInfo->m_fDeleted;
|
|
pElanInfoNew->m_fNewElan = pElanInfo->m_fNewElan;
|
|
pElanInfoNew->m_fRemoveMiniportOnPropertyApply = FALSE;
|
|
pElanInfoNew->m_fCreateMiniportOnPropertyApply = FALSE;
|
|
|
|
// push onto new secondary adapter's elan list
|
|
|
|
m_pAdapterSecondary->m_lstElans.push_back(pElanInfoNew);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
Assert(m_pAdapterSecondary != NULL);
|
|
return;
|
|
}
|
|
|
|
VOID CALaneCfg::CopyAdapterInfoSecondaryToPrimary()
|
|
{
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
CALaneCfgAdapterInfo * pAdapterInfoNew;
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
CALaneCfgElanInfo * pElanInfoNew;
|
|
|
|
// loop thru the primary adapter list
|
|
for (iterLstAdapters = m_lstAdaptersPrimary.begin();
|
|
iterLstAdapters != m_lstAdaptersPrimary.end();
|
|
iterLstAdapters++)
|
|
{
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
if (FIsSubstr(m_strGuidConn.c_str(), pAdapterInfo->SzGetAdapterBindName()))
|
|
{
|
|
pAdapterInfo->m_fDeleted = m_pAdapterSecondary->m_fDeleted;
|
|
pAdapterInfo->SetAdapterBindName(m_pAdapterSecondary->SzGetAdapterBindName());
|
|
pAdapterInfo->SetAdapterPnpId(m_pAdapterSecondary->SzGetAdapterPnpId());
|
|
|
|
// rebuild Elan list
|
|
ClearElanList(&pAdapterInfo->m_lstElans);
|
|
|
|
// loop thru the elan list on this adapter
|
|
for (iterLstElans = m_pAdapterSecondary->m_lstElans.begin();
|
|
iterLstElans != m_pAdapterSecondary->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
|
|
// create new and copy from secondary
|
|
pElanInfoNew = new CALaneCfgElanInfo;
|
|
|
|
pElanInfoNew->SetElanBindName(pElanInfo->SzGetElanBindName());
|
|
pElanInfoNew->SetElanDeviceName(pElanInfo->SzGetElanDeviceName());
|
|
pElanInfoNew->SetElanName(pElanInfo->SzGetElanName());
|
|
pElanInfoNew->m_fDeleted = pElanInfo->m_fDeleted;
|
|
pElanInfoNew->m_fNewElan = pElanInfo->m_fNewElan;
|
|
pElanInfoNew->m_fRemoveMiniportOnPropertyApply = FALSE;
|
|
pElanInfoNew->m_fCreateMiniportOnPropertyApply = FALSE;
|
|
|
|
// add to adapter's elan list
|
|
pAdapterInfo->m_lstElans.push_back(pElanInfoNew);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrReconfigLane(CALaneCfgAdapterInfo * pAdapterInfo)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// Note: if atm physical adapter is deleted, no notification of removing elan
|
|
// is necessary. Lane protocol driver will know to delete all the elans
|
|
// (confirmed above with ArvindM 3/12).
|
|
|
|
// Raid #371343, don't send notification if ATM card not connected
|
|
if ((!pAdapterInfo->m_fDeleted) &&
|
|
FIsAdapterEnabled(&(pAdapterInfo->m_guidInstanceId)))
|
|
{
|
|
ElanChangeType elanChangeType;
|
|
|
|
// loop thru the elan list on this adapter
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
|
|
for (iterLstElans = pAdapterInfo->m_lstElans.begin();
|
|
iterLstElans != pAdapterInfo->m_lstElans.end();
|
|
iterLstElans++)
|
|
{
|
|
CALaneCfgElanInfo * pElanInfo = *iterLstElans;
|
|
|
|
// if this Elan is marked as for delete
|
|
if (pElanInfo->m_fDeleted)
|
|
{
|
|
PCWSTR szBindName = pElanInfo->SzGetElanBindName();
|
|
|
|
if (lstrlenW(szBindName)) // only if the bindname is not empty
|
|
{
|
|
// notify deletion
|
|
elanChangeType = DEL_ELAN;
|
|
hr = HrNotifyElanChange(pAdapterInfo, pElanInfo,
|
|
elanChangeType);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BOOL fFound = FALSE;
|
|
|
|
ELAN_INFO_LIST::iterator iterLstOldElans;
|
|
|
|
// loop through the old elan list, see if we can find a match
|
|
for (iterLstOldElans = pAdapterInfo->m_lstOldElans.begin();
|
|
iterLstOldElans != pAdapterInfo->m_lstOldElans.end();
|
|
iterLstOldElans++)
|
|
{
|
|
CALaneCfgElanInfo * pOldElanInfo = * iterLstOldElans;
|
|
|
|
if (0 == lstrcmpiW(pElanInfo->SzGetElanBindName(),
|
|
pOldElanInfo->SzGetElanBindName()))
|
|
{
|
|
// we found a match
|
|
fFound = TRUE;
|
|
|
|
// has the elan name changed ?
|
|
if (lstrcmpiW(pElanInfo->SzGetElanName(),
|
|
pOldElanInfo->SzGetElanName()) != 0)
|
|
{
|
|
elanChangeType = MOD_ELAN;
|
|
hr = HrNotifyElanChange(pAdapterInfo, pElanInfo,
|
|
elanChangeType);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!fFound)
|
|
{
|
|
elanChangeType = ADD_ELAN;
|
|
hr = HrNotifyElanChange(pAdapterInfo, pElanInfo,
|
|
elanChangeType);
|
|
|
|
// Raid #384380: If no ELAN was installed, ignore the error
|
|
if ((S_OK != hr) &&(m_fNoElanInstalled))
|
|
{
|
|
TraceError("Adding ELAN failed but error ignored since there was no ELAN installed so LANE driver is not started, reset hr to S_OK", hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TraceError("CALaneCfg::HrReconfigLane", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CALaneCfg::HrNotifyElanChange(CALaneCfgAdapterInfo * pAdapterInfo,
|
|
CALaneCfgElanInfo * pElanInfo,
|
|
ElanChangeType elanChangeType)
|
|
{
|
|
// ATMLANE_PNP_RECONFIG_REQUEST is defined in \nt\private\inc\laneinfo.h
|
|
|
|
const DWORD dwBytes = sizeof(ATMLANE_PNP_RECONFIG_REQUEST) +
|
|
CbOfSzAndTerm (pElanInfo->SzGetElanBindName());
|
|
|
|
ATMLANE_PNP_RECONFIG_REQUEST* pLaneReconfig;
|
|
|
|
HRESULT hr = HrMalloc (dwBytes, (PVOID*)&pLaneReconfig);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pLaneReconfig->Version =1;
|
|
pLaneReconfig->OpType = elanChangeType;
|
|
pLaneReconfig->ElanKeyLength = lstrlenW(pElanInfo->SzGetElanBindName())+1;
|
|
lstrcpyW(pLaneReconfig->ElanKey, pElanInfo->SzGetElanBindName());
|
|
|
|
hr = HrSendNdisPnpReconfig( NDIS, c_szAtmLane,
|
|
pAdapterInfo->SzGetAdapterBindName(),
|
|
pLaneReconfig,
|
|
dwBytes);
|
|
if ( S_OK != hr)
|
|
{
|
|
TraceError("Notifying LANE of ELAN change returns failure, prompt for reboot ...", hr);
|
|
hr = NETCFG_S_REBOOT;
|
|
}
|
|
|
|
MemFree (pLaneReconfig);
|
|
}
|
|
TraceError("CALaneCfg::HrNotifyElanChange", hr);
|
|
return hr;
|
|
}
|
|
|
|
BOOL CALaneCfg::FIsAdapterEnabled(const GUID* pguidId)
|
|
{
|
|
FARPROC pfnHrGetPnpDeviceStatus;
|
|
HMODULE hNetman;
|
|
|
|
HRESULT hr = S_OK;
|
|
NETCON_STATUS ncStatus = NCS_CONNECTED;
|
|
|
|
hr = HrLoadLibAndGetProc(L"netman.dll", "HrGetPnpDeviceStatus",
|
|
&hNetman, &pfnHrGetPnpDeviceStatus);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = (*(PHRGETPNPDEVICESTATUS)pfnHrGetPnpDeviceStatus)(
|
|
pguidId, &ncStatus);
|
|
|
|
FreeLibrary(hNetman);
|
|
}
|
|
|
|
return (NCS_CONNECTED == ncStatus);
|
|
}
|
|
|
|
//
|
|
// CALaneCfgAdapterInfo
|
|
//
|
|
|
|
CALaneCfgAdapterInfo::CALaneCfgAdapterInfo(VOID)
|
|
{
|
|
m_fDeleted = FALSE;
|
|
m_fBindingChanged = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
CALaneCfgAdapterInfo::~CALaneCfgAdapterInfo(VOID)
|
|
{
|
|
ClearElanList(&m_lstElans);
|
|
ClearElanList(&m_lstOldElans);
|
|
return;
|
|
}
|
|
|
|
VOID CALaneCfgAdapterInfo::SetAdapterBindName(PCWSTR pszAdapterBindName)
|
|
{
|
|
m_strAdapterBindName = pszAdapterBindName;
|
|
return;
|
|
}
|
|
|
|
PCWSTR CALaneCfgAdapterInfo::SzGetAdapterBindName(VOID)
|
|
{
|
|
return m_strAdapterBindName.c_str();
|
|
}
|
|
|
|
VOID CALaneCfgAdapterInfo::SetAdapterPnpId(PCWSTR pszAdapterPnpId)
|
|
{
|
|
m_strAdapterPnpId = pszAdapterPnpId;
|
|
return;
|
|
}
|
|
|
|
PCWSTR CALaneCfgAdapterInfo::SzGetAdapterPnpId(VOID)
|
|
{
|
|
return m_strAdapterPnpId.c_str();
|
|
}
|
|
|
|
//
|
|
// CALaneCfgElanInfo
|
|
//
|
|
|
|
CALaneCfgElanInfo::CALaneCfgElanInfo(VOID)
|
|
{
|
|
m_fDeleted = FALSE;
|
|
m_fNewElan = FALSE;
|
|
|
|
m_fCreateMiniportOnPropertyApply = FALSE;
|
|
m_fRemoveMiniportOnPropertyApply = FALSE;
|
|
return;
|
|
}
|
|
|
|
VOID CALaneCfgElanInfo::SetElanBindName(PCWSTR pszElanBindName)
|
|
{
|
|
m_strElanBindName = pszElanBindName;
|
|
return;
|
|
}
|
|
|
|
PCWSTR CALaneCfgElanInfo::SzGetElanBindName(VOID)
|
|
{
|
|
return m_strElanBindName.c_str();
|
|
}
|
|
|
|
VOID CALaneCfgElanInfo::SetElanDeviceName(PCWSTR pszElanDeviceName)
|
|
{
|
|
m_strElanDeviceName = pszElanDeviceName;
|
|
return;
|
|
}
|
|
|
|
PCWSTR CALaneCfgElanInfo::SzGetElanDeviceName(VOID)
|
|
{
|
|
return m_strElanDeviceName.c_str();
|
|
}
|
|
|
|
VOID CALaneCfgElanInfo::SetElanName(PCWSTR pszElanName)
|
|
{
|
|
m_strElanName = pszElanName;
|
|
return;
|
|
}
|
|
|
|
VOID CALaneCfgElanInfo::SetElanName(PWSTR pszElanName)
|
|
{
|
|
m_strElanName = pszElanName;
|
|
return;
|
|
}
|
|
|
|
PCWSTR CALaneCfgElanInfo::SzGetElanName(VOID)
|
|
{
|
|
return m_strElanName.c_str();
|
|
}
|
|
|
|
// utility functions
|
|
|
|
void ClearElanList(ELAN_INFO_LIST *plstElans)
|
|
{
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
CALaneCfgElanInfo * pElanInfo;
|
|
|
|
for (iterLstElans = plstElans->begin();
|
|
iterLstElans != plstElans->end();
|
|
iterLstElans++)
|
|
{
|
|
pElanInfo = *iterLstElans;
|
|
delete pElanInfo;
|
|
}
|
|
|
|
plstElans->clear();
|
|
return;
|
|
}
|
|
|
|
void ClearAdapterList(ATMLANE_ADAPTER_INFO_LIST *plstAdapters)
|
|
{
|
|
ATMLANE_ADAPTER_INFO_LIST::iterator iterLstAdapters;
|
|
CALaneCfgAdapterInfo * pAdapterInfo;
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
|
|
for (iterLstAdapters = plstAdapters->begin();
|
|
iterLstAdapters != plstAdapters->end();
|
|
iterLstAdapters++)
|
|
{
|
|
|
|
pAdapterInfo = *iterLstAdapters;
|
|
|
|
ClearElanList(&pAdapterInfo->m_lstElans);
|
|
|
|
delete pAdapterInfo;
|
|
}
|
|
|
|
plstAdapters->clear();
|
|
|
|
return;
|
|
}
|
|
|
|
void ClearAdapterInfo(CALaneCfgAdapterInfo * pAdapterInfo)
|
|
{
|
|
ELAN_INFO_LIST::iterator iterLstElans;
|
|
|
|
if (pAdapterInfo)
|
|
{
|
|
ClearElanList(&pAdapterInfo->m_lstElans);
|
|
delete pAdapterInfo;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|