939 lines
26 KiB
C++
939 lines
26 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992-2001.
|
||
|
//
|
||
|
// File: A D A P T E R . C P P
|
||
|
//
|
||
|
// Contents: Physical adapter class definition.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// Author: Alok Sinha
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "adapter.h"
|
||
|
#include "common.h"
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
#include "public.h"
|
||
|
#endif
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::CMuxPhysicalAdapter
|
||
|
//
|
||
|
// Purpose: Constructor for class CMuxPhysicalAdapter
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
CMuxPhysicalAdapter::CMuxPhysicalAdapter (INetCfg *pnc,
|
||
|
GUID *pguidAdapter)
|
||
|
{
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::CMuxPhysicalAdapter(Constructor).\n" );
|
||
|
|
||
|
m_pnc = pnc;
|
||
|
m_pnc->AddRef();
|
||
|
|
||
|
CopyMemory( &m_guidAdapter,
|
||
|
pguidAdapter,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::CMuxPhysicalAdapter(Constructor).\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::~CMuxPhysicalAdapter
|
||
|
//
|
||
|
// Purpose: Destructor for class CMuxPhysicalAdapter
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
CMuxPhysicalAdapter::~CMuxPhysicalAdapter (VOID)
|
||
|
{
|
||
|
CMuxVirtualMiniport *pMiniport;
|
||
|
DWORD dwMiniportCount;
|
||
|
DWORD i;
|
||
|
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::~CMuxPhysicalAdapter(Destructor).\n" );
|
||
|
|
||
|
//
|
||
|
// Delete all the instances representing the virtual miniports.
|
||
|
// We are only deleting the class instances, not uninstalling the
|
||
|
// the virtual miniports.
|
||
|
//
|
||
|
|
||
|
dwMiniportCount = m_MiniportList.ListCount();
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportList.Remove( &pMiniport );
|
||
|
delete pMiniport;
|
||
|
}
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToAdd.ListCount();
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToAdd.Remove( &pMiniport );
|
||
|
delete pMiniport;
|
||
|
}
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToRemove.ListCount();
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToRemove.Remove( &pMiniport );
|
||
|
delete pMiniport;
|
||
|
}
|
||
|
|
||
|
ReleaseObj( m_pnc );
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::~CMuxPhysicalAdapter(Destructor).\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::LoadConfiguration
|
||
|
//
|
||
|
// Purpose: Read the registry to get the device IDs of the
|
||
|
// virtual miniports installed on the adapter and
|
||
|
// crate an instance to represent each virtual miniport.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::LoadConfiguration (VOID)
|
||
|
{
|
||
|
HKEY hkeyAdapterGuid;
|
||
|
WCHAR szAdapterGuidKey[MAX_PATH+1];
|
||
|
WCHAR szAdapterGuid[MAX_PATH+1];
|
||
|
LPWSTR lpMiniportList;
|
||
|
LPWSTR lpMiniport;
|
||
|
LPWSTR lpMiniportGuid;
|
||
|
DWORD dwDisp;
|
||
|
CMuxVirtualMiniport *pMiniport;
|
||
|
GUID guidMiniport;
|
||
|
DWORD dwBytes;
|
||
|
LONG lResult;
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::LoadConfiguration.\n" );
|
||
|
|
||
|
//
|
||
|
// Build the registry key using the adapter guid under which
|
||
|
// device IDs of the virtual miniports are stored.
|
||
|
//
|
||
|
|
||
|
StringFromGUID2( m_guidAdapter,
|
||
|
szAdapterGuid,
|
||
|
MAX_PATH+1 );
|
||
|
|
||
|
swprintf( szAdapterGuidKey,
|
||
|
L"%s\\%s",
|
||
|
c_szAdapterList,
|
||
|
szAdapterGuid );
|
||
|
|
||
|
lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
szAdapterGuidKey,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hkeyAdapterGuid,
|
||
|
&dwDisp);
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
//
|
||
|
// If dwDisp indicates that a new key is created then, we know there
|
||
|
// is no virtual miniport currently listed underneath and we simply
|
||
|
// return.
|
||
|
//
|
||
|
|
||
|
if ( dwDisp != REG_CREATED_NEW_KEY ) {
|
||
|
|
||
|
dwBytes = 0;
|
||
|
lResult = RegQueryValueExW(
|
||
|
hkeyAdapterGuid,
|
||
|
c_szUpperBindings,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&dwBytes );
|
||
|
|
||
|
lpMiniportList = (LPWSTR)calloc( dwBytes, 1 );
|
||
|
|
||
|
if ( lpMiniportList ) {
|
||
|
|
||
|
lResult = RegQueryValueExW(
|
||
|
hkeyAdapterGuid,
|
||
|
c_szUpperBindings,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
(LPBYTE)lpMiniportList,
|
||
|
&dwBytes );
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
lpMiniport = lpMiniportList;
|
||
|
|
||
|
#ifndef PASSTHRU_NOTIFY
|
||
|
|
||
|
//
|
||
|
// In case of mux, c_szUpperBindings is a multi_sz string.
|
||
|
//
|
||
|
|
||
|
while ( wcslen(lpMiniport) ) {
|
||
|
|
||
|
lpMiniportGuid = RemoveDevicePrefix( lpMiniport );
|
||
|
|
||
|
TraceMsg( L" Loading configuration for miniport %s...\n",
|
||
|
lpMiniportGuid );
|
||
|
|
||
|
if ( lpMiniportGuid ) {
|
||
|
|
||
|
CLSIDFromString( lpMiniportGuid,
|
||
|
&guidMiniport );
|
||
|
|
||
|
//
|
||
|
// Create an instance representing the virtual miniport.
|
||
|
//
|
||
|
|
||
|
pMiniport = new CMuxVirtualMiniport( m_pnc,
|
||
|
&guidMiniport,
|
||
|
&m_guidAdapter );
|
||
|
|
||
|
if ( pMiniport ) {
|
||
|
|
||
|
//
|
||
|
// Load any miniport specific configuration.
|
||
|
//
|
||
|
|
||
|
pMiniport->LoadConfiguration();
|
||
|
|
||
|
//
|
||
|
// Save the miniport instance in a list.
|
||
|
//
|
||
|
|
||
|
m_MiniportList.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
|
||
|
}
|
||
|
|
||
|
free( lpMiniportGuid );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Get next miniport guid.
|
||
|
//
|
||
|
|
||
|
lpMiniport += wcslen(lpMiniport) + 1;
|
||
|
}
|
||
|
|
||
|
#else
|
||
|
|
||
|
//
|
||
|
// In case of the passthru driver, c_szUpperBindings is
|
||
|
// a reg_sz string.
|
||
|
//
|
||
|
|
||
|
lpMiniportGuid = RemoveDevicePrefix( lpMiniport );
|
||
|
|
||
|
TraceMsg( L" Loading configuration for miniport %s...\n",
|
||
|
lpMiniportGuid );
|
||
|
|
||
|
if ( lpMiniportGuid ) {
|
||
|
|
||
|
CLSIDFromString( lpMiniportGuid,
|
||
|
&guidMiniport );
|
||
|
|
||
|
//
|
||
|
// Create an instance representing the virtual miniport.
|
||
|
//
|
||
|
|
||
|
pMiniport = new CMuxVirtualMiniport( m_pnc,
|
||
|
&guidMiniport,
|
||
|
&m_guidAdapter );
|
||
|
|
||
|
if ( pMiniport ) {
|
||
|
|
||
|
//
|
||
|
// Load any miniport specific configuration.
|
||
|
//
|
||
|
|
||
|
pMiniport->LoadConfiguration();
|
||
|
|
||
|
//
|
||
|
// Save the miniport instance in a list.
|
||
|
//
|
||
|
|
||
|
m_MiniportList.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
}
|
||
|
|
||
|
free( lpMiniportGuid );
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" Failed to read the registry value: %s.\n",
|
||
|
c_szUpperBindings );
|
||
|
}
|
||
|
|
||
|
free( lpMiniportList );
|
||
|
}
|
||
|
else {
|
||
|
lResult = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RegCloseKey( hkeyAdapterGuid );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" Failed to open the registry key: %s.\n",
|
||
|
szAdapterGuidKey );
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::LoadConfiguration(HRESULT = %x).\n",
|
||
|
HRESULT_FROM_WIN32(lResult) );
|
||
|
|
||
|
return HRESULT_FROM_WIN32(lResult);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::GetAdapterGUID
|
||
|
//
|
||
|
// Purpose: Returns the adapter GUID.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// OUT pguidAdapter: GUID of the adapter returned.
|
||
|
//
|
||
|
// Returns: None.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
VOID CMuxPhysicalAdapter::GetAdapterGUID (GUID *pguidAdapter)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::GetAdapterGUID.\n" );
|
||
|
|
||
|
CopyMemory( pguidAdapter,
|
||
|
&m_guidAdapter,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::GetAdapterGUID.\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::AddMiniport
|
||
|
//
|
||
|
// Purpose: Puts the miniport instance into the list of newly added miniports.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN pMiniport: A newly create miniport instance.
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwize and error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::AddMiniport (CMuxVirtualMiniport *pMiniport)
|
||
|
{
|
||
|
GUID guidMiniport;
|
||
|
HRESULT hr;
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::AddMiniport.\n" );
|
||
|
|
||
|
pMiniport->GetMiniportGUID( &guidMiniport );
|
||
|
|
||
|
hr = m_MiniportsToAdd.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::AddMiniport(HRESULT = %x).\n",
|
||
|
hr );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::RemoveMiniport
|
||
|
//
|
||
|
// Purpose: Remove a specified miniport instance from the list and
|
||
|
// uninstalls the corresponding virtual miniport.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN pguidMiniportToRemove: GUID of the miniport to be removed
|
||
|
// and uninstalled. If it is NULL then,
|
||
|
// the first miniport instance is removed.
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwize and error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::RemoveMiniport (GUID *pguidMiniportToRemove)
|
||
|
{
|
||
|
CMuxVirtualMiniport *pMiniport;
|
||
|
GUID guidMiniport;
|
||
|
HRESULT hr;
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::RemoveMiniport.\n" );
|
||
|
|
||
|
//
|
||
|
// If miniport GUID specified then, delete that one.
|
||
|
//
|
||
|
|
||
|
if ( pguidMiniportToRemove ) {
|
||
|
|
||
|
hr = m_MiniportList.RemoveByKey( *pguidMiniportToRemove,
|
||
|
&pMiniport );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
//
|
||
|
// No GUID specified, so we just delete the first one.
|
||
|
//
|
||
|
|
||
|
hr = m_MiniportList.Remove( &pMiniport );
|
||
|
}
|
||
|
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
pMiniport->GetMiniportGUID( &guidMiniport );
|
||
|
|
||
|
m_MiniportsToRemove.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
pMiniport->DeInstall();
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::RemoveMiniport(HRESULT = %x).\n",
|
||
|
hr );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::Remove
|
||
|
//
|
||
|
// Purpose: Uninstall all the instances of virtual miniports.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: S_OK.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::Remove (VOID)
|
||
|
{
|
||
|
CMuxVirtualMiniport *pMiniport;
|
||
|
GUID guidMiniport;
|
||
|
DWORD dwMiniportCount;
|
||
|
DWORD i;
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::Remove.\n" );
|
||
|
|
||
|
dwMiniportCount = m_MiniportList.ListCount();
|
||
|
|
||
|
TraceMsg ( L" Removing %d miniports.\n",
|
||
|
dwMiniportCount );
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportList.Remove( &pMiniport );
|
||
|
pMiniport->GetMiniportGUID( &guidMiniport );
|
||
|
m_MiniportsToRemove.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
pMiniport->DeInstall();
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::Remove(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::ApplyRegistryChanges
|
||
|
//
|
||
|
// Purpose: Update the registry depending on the actions performed.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN eApplyAction: Action that was last performed.
|
||
|
//
|
||
|
//
|
||
|
// Returns: S_OK.
|
||
|
//
|
||
|
// Notes:
|
||
|
// More than one action could have been performed by the user
|
||
|
// but this function is called only once at the end. So, the argument
|
||
|
// only denotes the very last action performed. For example, if the
|
||
|
// user deletes one miniport and adds two miniports then, the argument
|
||
|
// will denote an add action.
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::ApplyRegistryChanges (ConfigAction eApplyAction)
|
||
|
{
|
||
|
HKEY hkeyAdapterList;
|
||
|
HKEY hkeyAdapterGuid;
|
||
|
WCHAR szAdapterGuid[MAX_PATH+1];
|
||
|
CMuxVirtualMiniport *pMiniport = NULL;
|
||
|
DWORD dwMiniportCount;
|
||
|
DWORD dwDisp;
|
||
|
DWORD i;
|
||
|
LONG lResult;
|
||
|
HRESULT hr;
|
||
|
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::ApplyRegistryChanges.\n" );
|
||
|
|
||
|
//
|
||
|
// Open/create and then close the registry key to ensure that it does exist.
|
||
|
//
|
||
|
|
||
|
StringFromGUID2( m_guidAdapter,
|
||
|
szAdapterGuid,
|
||
|
MAX_PATH+1 );
|
||
|
|
||
|
lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
c_szAdapterList,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hkeyAdapterList,
|
||
|
&dwDisp);
|
||
|
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
lResult = RegCreateKeyExW( hkeyAdapterList,
|
||
|
szAdapterGuid,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hkeyAdapterGuid,
|
||
|
&dwDisp);
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
RegCloseKey( hkeyAdapterGuid );
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" Failed to create/open the registry key: %s\\%s.\n",
|
||
|
c_szAdapterList, szAdapterGuid );
|
||
|
}
|
||
|
|
||
|
RegCloseKey( hkeyAdapterList );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" Failed to open the registry key: %s.\n",
|
||
|
c_szAdapterList );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Update the registry in case there were new miniports installed.
|
||
|
//
|
||
|
|
||
|
hr = HRESULT_FROM_WIN32( lResult );
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToAdd.ListCount();
|
||
|
|
||
|
TraceMsg( L" Applying registry changes when %d miniports added.\n",
|
||
|
dwMiniportCount );
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToAdd.Find( i,
|
||
|
&pMiniport );
|
||
|
|
||
|
//
|
||
|
// Do virtual miniport specific registry changes.
|
||
|
//
|
||
|
// We need to tell the miniport instance explicitly what the action
|
||
|
// is.
|
||
|
//
|
||
|
|
||
|
hr = pMiniport->ApplyRegistryChanges( eActAdd );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Failed to apply registry changes to miniport(%d).\n",
|
||
|
i );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// Update the registry in case one or more miniports were uninstalled.
|
||
|
//
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToRemove.ListCount();
|
||
|
|
||
|
TraceMsg( L" Applying registry changes when %d miniports removed.\n",
|
||
|
dwMiniportCount );
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToRemove.Find( i,
|
||
|
&pMiniport );
|
||
|
|
||
|
//
|
||
|
// Do virtual miniport specific registry changes.
|
||
|
//
|
||
|
// We need to tell the miniport instance explicitly what the action
|
||
|
// is.
|
||
|
//
|
||
|
|
||
|
hr = pMiniport->ApplyRegistryChanges( eActRemove );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Failed to apply registry changes to miniport(%d).\n",
|
||
|
i );
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If the adapter is being removed or the protocol is being uninstalled,
|
||
|
// delete the adatper registry key.
|
||
|
//
|
||
|
|
||
|
if ( eApplyAction == eActRemove ) {
|
||
|
|
||
|
//
|
||
|
// Delete the adapter key.
|
||
|
//
|
||
|
|
||
|
lResult = RegCreateKeyExW( HKEY_LOCAL_MACHINE,
|
||
|
c_szAdapterList,
|
||
|
0,
|
||
|
NULL,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
NULL,
|
||
|
&hkeyAdapterList,
|
||
|
&dwDisp);
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
TraceMsg( L" Deleting the registry key: %s.\n", szAdapterGuid );
|
||
|
|
||
|
RegDeleteKeyW( hkeyAdapterList,
|
||
|
szAdapterGuid );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::ApplyRegistryChanges(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::ApplyPnpChanges
|
||
|
//
|
||
|
// Purpose: Apply the PnP changes depending on the actions performed.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN pfCallback : SendPnpConfig Callback interface.
|
||
|
// IN eApplyAction: Action that was last performed.
|
||
|
//
|
||
|
//
|
||
|
// Returns: S_OK.
|
||
|
//
|
||
|
// Notes:
|
||
|
// More than one action could have been performed by the user
|
||
|
// but this function is called only once at the end. So, the argument
|
||
|
// only denotes the very last action performed. For example, if the
|
||
|
// user deletes one miniport and adds two miniports then, the argument
|
||
|
// will denote an add action.
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::ApplyPnpChanges(
|
||
|
INetCfgPnpReconfigCallback *pfCallback,
|
||
|
ConfigAction eApplyAction)
|
||
|
{
|
||
|
CMuxVirtualMiniport *pMiniport;
|
||
|
GUID guidMiniport;
|
||
|
WCHAR szMiniportGuid[MAX_PATH+1];
|
||
|
LPWSTR lpDevice;
|
||
|
DWORD dwMiniportCount;
|
||
|
DWORD i;
|
||
|
DWORD dwBytes;
|
||
|
INetCfgComponent *pncc;
|
||
|
HRESULT hr;
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
LPWSTR lpszBindName;
|
||
|
PNOTIFY_CUSTOM_EVENT lppnpEvent;
|
||
|
#endif
|
||
|
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::ApplyPnpChanges.\n" );
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
|
||
|
//
|
||
|
// Find the instance of the adapter to get its bindname.
|
||
|
//
|
||
|
|
||
|
hr = HrFindInstance( m_pnc,
|
||
|
m_guidAdapter,
|
||
|
&pncc );
|
||
|
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = pncc->GetBindName( &lpszBindName );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
TraceMsg( L" GetBindName failed.(HRESULT = %x). PnP changes will not "
|
||
|
L"be applied and the driver will not be notified.\n",
|
||
|
hr );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pncc );
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" PnP changes will not "
|
||
|
L"be applied and the driver will not be notified.\n",
|
||
|
hr );
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToAdd.ListCount();
|
||
|
|
||
|
TraceMsg( L" Applying PnP changes to %d new miniports.\n",
|
||
|
dwMiniportCount );
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToAdd.Remove( &pMiniport );
|
||
|
|
||
|
pMiniport->GetMiniportGUID( &guidMiniport );
|
||
|
|
||
|
m_MiniportList.Insert( pMiniport,
|
||
|
guidMiniport );
|
||
|
|
||
|
//
|
||
|
// Do miniport specific Pnp Changes when they are added.
|
||
|
//
|
||
|
|
||
|
hr = pMiniport->ApplyPnpChanges( pfCallback,
|
||
|
eActAdd );
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
|
||
|
|
||
|
//
|
||
|
// Notify the driver that one or more virtual miniports have been added.
|
||
|
//
|
||
|
|
||
|
StringFromGUID2( guidMiniport,
|
||
|
szMiniportGuid,
|
||
|
MAX_PATH+1 );
|
||
|
lpDevice = AddDevicePrefix( szMiniportGuid );
|
||
|
|
||
|
if ( lpDevice ) {
|
||
|
|
||
|
dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) +
|
||
|
((wcslen(lpDevice) + 1) * sizeof(WCHAR));
|
||
|
|
||
|
lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes );
|
||
|
|
||
|
if ( lppnpEvent ) {
|
||
|
|
||
|
lppnpEvent->uSignature = NOTIFY_SIGNATURE;
|
||
|
lppnpEvent->uEvent = MUX_CUSTOM_EVENT;
|
||
|
wcscpy( lppnpEvent->szMiniport,
|
||
|
lpDevice );
|
||
|
|
||
|
hr = pfCallback->SendPnpReconfig( NCRL_NDIS,
|
||
|
c_szMuxService,
|
||
|
lpszBindName,
|
||
|
(PVOID)lppnpEvent,
|
||
|
dwBytes );
|
||
|
|
||
|
TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned "
|
||
|
L"%#x.\n",
|
||
|
hr );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n",
|
||
|
i );
|
||
|
|
||
|
}
|
||
|
|
||
|
free( lppnpEvent );
|
||
|
}
|
||
|
free( lpDevice );
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
dwMiniportCount = m_MiniportsToRemove.ListCount();
|
||
|
|
||
|
TraceMsg( L" Applying PnP changes to %d removed miniports.\n",
|
||
|
dwMiniportCount );
|
||
|
|
||
|
for (i=0; i < dwMiniportCount; ++i) {
|
||
|
|
||
|
m_MiniportsToRemove.Remove( &pMiniport );
|
||
|
|
||
|
pMiniport->GetMiniportGUID( &guidMiniport );
|
||
|
|
||
|
//
|
||
|
// Do miniport specific Pnp Changes when they are uninstalled.
|
||
|
//
|
||
|
|
||
|
hr = pMiniport->ApplyPnpChanges( pfCallback,
|
||
|
eActRemove );
|
||
|
|
||
|
delete pMiniport;
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
|
||
|
//
|
||
|
// Notify the driver that one or more virtual miniports have been
|
||
|
// uninstalled.
|
||
|
//
|
||
|
// We can't notify the driver in case the adapter or the protocol is
|
||
|
// being uninstalled because the binding handle doesn't exist.
|
||
|
//
|
||
|
|
||
|
if ( eApplyAction != eActRemove ) {
|
||
|
|
||
|
StringFromGUID2( guidMiniport,
|
||
|
szMiniportGuid,
|
||
|
MAX_PATH+1 );
|
||
|
lpDevice = AddDevicePrefix( szMiniportGuid );
|
||
|
|
||
|
if ( lpDevice ) {
|
||
|
|
||
|
dwBytes = sizeof(NOTIFY_CUSTOM_EVENT) +
|
||
|
((wcslen(lpDevice) + 1) * sizeof(WCHAR));
|
||
|
|
||
|
lppnpEvent = (PNOTIFY_CUSTOM_EVENT)malloc( dwBytes );
|
||
|
|
||
|
if ( lppnpEvent ) {
|
||
|
|
||
|
lppnpEvent->uSignature = NOTIFY_SIGNATURE;
|
||
|
lppnpEvent->uEvent = MUX_CUSTOM_EVENT;
|
||
|
wcscpy( lppnpEvent->szMiniport,
|
||
|
lpDevice );
|
||
|
|
||
|
hr = pfCallback->SendPnpReconfig( NCRL_NDIS,
|
||
|
c_szMuxService,
|
||
|
lpszBindName,
|
||
|
(PVOID)lppnpEvent,
|
||
|
dwBytes );
|
||
|
TraceMsg( L" INetCfgPnpReconfigCallback->SendPnpReconfig returned "
|
||
|
L"%#x.\n",
|
||
|
hr );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Failed to apply Pnp changes, miniport(%d).\n",
|
||
|
i );
|
||
|
|
||
|
}
|
||
|
|
||
|
free( lppnpEvent );
|
||
|
}
|
||
|
|
||
|
free( lpDevice );
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
#ifdef CUSTOM_EVENTS
|
||
|
CoTaskMemFree( lpszBindName );
|
||
|
#endif
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::ApplyPnpChanges(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::CancelChanges
|
||
|
//
|
||
|
// Purpose: Cancel any changes made.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
//
|
||
|
// Returns: S_OK.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxPhysicalAdapter::CancelChanges (VOID)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxPhysicalAdapter::CancelChanges.\n" );
|
||
|
|
||
|
TraceMsg( L"<--CMuxPhysicalAdapter::CancelChanges(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxPhysicalAdapter::AllMiniportsRemoved
|
||
|
//
|
||
|
// Purpose: Find out if there is no miniport installed on the adapter.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
//
|
||
|
// Returns: TRUE if all the miniports associated with this adapter have been
|
||
|
// uninstalled and there is none pending to be added, otherwise FALSE.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
BOOL CMuxPhysicalAdapter::AllMiniportsRemoved (VOID)
|
||
|
{
|
||
|
return (m_MiniportList.ListCount() + m_MiniportsToAdd.ListCount()) == 0;
|
||
|
}
|