499 lines
13 KiB
C++
499 lines
13 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992-2001.
|
||
|
//
|
||
|
// File: V I R T U A L . C P P
|
||
|
//
|
||
|
// Contents: Virtual miniport class definition.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
// Author: Alok Sinha
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "virtual.h"
|
||
|
#include "common.h"
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::CMuxVirtualMiniport
|
||
|
//
|
||
|
// Purpose: Constructor for class CMuxVirtualMiniport
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
CMuxVirtualMiniport::CMuxVirtualMiniport(INetCfg *pnc,
|
||
|
GUID *pguidMiniport,
|
||
|
GUID *pguidAdapter)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::CMuxVirtualMiniport(Constructor).\n" );
|
||
|
|
||
|
m_pnc = pnc;
|
||
|
m_pnc->AddRef();
|
||
|
|
||
|
CopyMemory( &m_guidAdapter,
|
||
|
pguidAdapter,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
if ( pguidMiniport ) {
|
||
|
|
||
|
CopyMemory( &m_guidMiniport,
|
||
|
pguidMiniport,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
ZeroMemory( &m_guidMiniport,
|
||
|
sizeof(GUID) );
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::CMuxVirtualMiniport(Constructor).\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::~CMuxVirtualMiniport
|
||
|
//
|
||
|
// Purpose: Destructor for class CMuxVirtualMiniport
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
CMuxVirtualMiniport::~CMuxVirtualMiniport(VOID)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::~CMuxVirtualMiniport(Destructor).\n" );
|
||
|
|
||
|
ReleaseObj( m_pnc );
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::~CMuxVirtualMiniport(Destructor).\n" );
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::LoadConfiguration
|
||
|
//
|
||
|
// Purpose: Load miniport configuration from the registry.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxVirtualMiniport::LoadConfiguration(VOID)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::LoadConfiguration.\n" );
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::LoadConfiguration(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::GetAdapterGUID
|
||
|
//
|
||
|
// Purpose: Returns the adapter GUID.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// OUT pguidAdapter: GUID of the adapter returned.
|
||
|
//
|
||
|
// Returns: None.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
VOID CMuxVirtualMiniport::GetAdapterGUID (GUID *pguidAdapter)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::GetAdapterGUID.\n" );
|
||
|
|
||
|
CopyMemory( pguidAdapter,
|
||
|
&m_guidAdapter,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::GetAdapterGUID.\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::GetMiniportGUID
|
||
|
//
|
||
|
// Purpose: Returns the miniport GUID.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// OUT pguidMiniport: GUID of the miniport returned.
|
||
|
//
|
||
|
// Returns: None.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
VOID CMuxVirtualMiniport::GetMiniportGUID (GUID *pguidMiniport)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::GetMiniportGUID.\n" );
|
||
|
|
||
|
CopyMemory( pguidMiniport,
|
||
|
&m_guidMiniport,
|
||
|
sizeof(GUID) );
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::GetMiniportGUID.\n" );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::Install
|
||
|
//
|
||
|
// Purpose: Installs a virtual miniport.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxVirtualMiniport::Install (VOID)
|
||
|
{
|
||
|
INetCfgClass *pncClass;
|
||
|
INetCfgClassSetup *pncClassSetup;
|
||
|
INetCfgComponent *pnccMiniport;
|
||
|
HRESULT hr;
|
||
|
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::Install.\n" );
|
||
|
|
||
|
hr = m_pnc->QueryNetCfgClass( &GUID_DEVCLASS_NET,
|
||
|
IID_INetCfgClass,
|
||
|
(void **)&pncClass );
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
|
||
|
(void **)&pncClassSetup );
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = pncClassSetup->Install( c_szMuxMiniport,
|
||
|
NULL,
|
||
|
0,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
&pnccMiniport );
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = pnccMiniport->GetInstanceGuid( &m_guidMiniport );
|
||
|
|
||
|
if ( hr != S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Failed to get the instance guid, uninstalling "
|
||
|
L" the miniport.\n" );
|
||
|
|
||
|
pncClassSetup->DeInstall( pnccMiniport,
|
||
|
NULL,
|
||
|
NULL );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pnccMiniport );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" Failed to install the miniport.\n" );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pncClassSetup );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" QueryInterface failed.\n" );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pncClass );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" QueryNetCfgClass failed.\n" );
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::Install(HRESULT = %x).\n",
|
||
|
hr );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::DeInstall
|
||
|
//
|
||
|
// Purpose: Uninstalls the virtual miniport.
|
||
|
//
|
||
|
// Arguments: None
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxVirtualMiniport::DeInstall (VOID)
|
||
|
{
|
||
|
INetCfgClass *pncClass;
|
||
|
INetCfgClassSetup *pncClassSetup;
|
||
|
INetCfgComponent *pnccMiniport;
|
||
|
HRESULT hr;
|
||
|
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::DeInstall.\n" );
|
||
|
|
||
|
hr = m_pnc->QueryNetCfgClass( &GUID_DEVCLASS_NET,
|
||
|
IID_INetCfgClass,
|
||
|
(void **)&pncClass );
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = pncClass->QueryInterface( IID_INetCfgClassSetup,
|
||
|
(void **)&pncClassSetup );
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
hr = HrFindInstance( m_pnc,
|
||
|
m_guidMiniport,
|
||
|
&pnccMiniport );
|
||
|
|
||
|
if ( hr == S_OK ) {
|
||
|
|
||
|
TraceMsg( L" Found the miniport instance to uninstall.\n" );
|
||
|
|
||
|
hr = pncClassSetup->DeInstall( pnccMiniport,
|
||
|
NULL,
|
||
|
NULL );
|
||
|
ReleaseObj( pnccMiniport );
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" Didn't find the miniport instance to uninstall.\n" );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pncClassSetup );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" QueryInterface failed.\n" );
|
||
|
}
|
||
|
|
||
|
ReleaseObj( pncClass );
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
TraceMsg( L" QueryNetCfgClass failed.\n" );
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::DeInstall(HRESULT = %x).\n",
|
||
|
hr );
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::ApplyRegistryChanges
|
||
|
//
|
||
|
// Purpose: Store the changes in the registry.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN eApplyAction: Action performed.
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxVirtualMiniport::ApplyRegistryChanges(ConfigAction eApplyAction)
|
||
|
{
|
||
|
HKEY hkeyAdapterGuid;
|
||
|
WCHAR szAdapterGuid[MAX_PATH+1];
|
||
|
WCHAR szAdapterGuidKey[MAX_PATH+1];
|
||
|
WCHAR szMiniportGuid[MAX_PATH+1];
|
||
|
LPWSTR lpDevice;
|
||
|
LONG lResult = 0;
|
||
|
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::ApplyRegistryChanges.\n" );
|
||
|
|
||
|
switch( eApplyAction ) {
|
||
|
|
||
|
case eActAdd: // Virtual miniport added.
|
||
|
|
||
|
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,
|
||
|
NULL);
|
||
|
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
StringFromGUID2( m_guidMiniport,
|
||
|
szMiniportGuid,
|
||
|
MAX_PATH+1 );
|
||
|
|
||
|
lpDevice = AddDevicePrefix( szMiniportGuid );
|
||
|
|
||
|
if ( lpDevice ) {
|
||
|
|
||
|
#ifndef PASSTHRU_NOTIFY
|
||
|
|
||
|
lResult = AddToMultiSzValue( hkeyAdapterGuid,
|
||
|
lpDevice );
|
||
|
#else
|
||
|
|
||
|
lResult = RegSetValueExW( hkeyAdapterGuid,
|
||
|
c_szUpperBindings,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(LPBYTE)lpDevice,
|
||
|
(wcslen(lpDevice) + 1) *
|
||
|
sizeof(WCHAR) );
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
if ( lResult != ERROR_SUCCESS ) {
|
||
|
|
||
|
TraceMsg( L" Failed to save %s at %s\\%s.\n",
|
||
|
lpDevice,
|
||
|
szAdapterGuidKey,
|
||
|
c_szUpperBindings );
|
||
|
|
||
|
}
|
||
|
|
||
|
free( lpDevice );
|
||
|
}
|
||
|
else {
|
||
|
lResult = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
}
|
||
|
|
||
|
RegCloseKey( hkeyAdapterGuid );
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" Failed to open the registry key: %s.\n",
|
||
|
szAdapterGuidKey );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case eActRemove: // Virtual miniport removed.
|
||
|
|
||
|
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,
|
||
|
NULL);
|
||
|
|
||
|
|
||
|
if ( lResult == ERROR_SUCCESS ) {
|
||
|
|
||
|
StringFromGUID2( m_guidMiniport,
|
||
|
szMiniportGuid,
|
||
|
MAX_PATH+1 );
|
||
|
|
||
|
lpDevice = AddDevicePrefix( szMiniportGuid );
|
||
|
TraceMsg( L" Deleting %s at %s.\n",
|
||
|
lpDevice,
|
||
|
szAdapterGuidKey );
|
||
|
|
||
|
if ( lpDevice ) {
|
||
|
|
||
|
#ifndef PASSTHRU_NOTIFY
|
||
|
|
||
|
lResult = DeleteFromMultiSzValue( hkeyAdapterGuid,
|
||
|
lpDevice );
|
||
|
#else
|
||
|
|
||
|
lResult = RegDeleteValueW( hkeyAdapterGuid,
|
||
|
c_szUpperBindings );
|
||
|
#endif
|
||
|
|
||
|
if ( lResult != ERROR_SUCCESS ) {
|
||
|
|
||
|
TraceMsg( L" Failed to delete %s at %s\\%s.\n",
|
||
|
lpDevice,
|
||
|
szAdapterGuidKey,
|
||
|
c_szUpperBindings );
|
||
|
|
||
|
}
|
||
|
|
||
|
free( lpDevice );
|
||
|
}
|
||
|
|
||
|
RegCloseKey( hkeyAdapterGuid );
|
||
|
}
|
||
|
else {
|
||
|
TraceMsg( L" Failed to open the registry key: %s.\n",
|
||
|
szAdapterGuidKey );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::ApplyRegistryChanges(HRESULT = %x).\n",
|
||
|
HRESULT_FROM_WIN32(lResult) );
|
||
|
|
||
|
return HRESULT_FROM_WIN32(lResult);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CMuxVirtualMiniport::ApplyPnpChanges
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Arguments:
|
||
|
// IN eApplyAction: Action performed.
|
||
|
//
|
||
|
// Returns: S_OK on success, otherwise an error code.
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
|
||
|
HRESULT CMuxVirtualMiniport::ApplyPnpChanges
|
||
|
(INetCfgPnpReconfigCallback *pfCallback,
|
||
|
ConfigAction eApplyAction)
|
||
|
{
|
||
|
TraceMsg( L"-->CMuxVirtualMiniport::ApplyPnpChanges.\n" );
|
||
|
|
||
|
TraceMsg( L"<--CMuxVirtualMiniport::ApplyPnpChanges(HRESULT = %x).\n",
|
||
|
S_OK );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|