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.
444 lines
12 KiB
444 lines
12 KiB
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include <atlbase.h>
|
|
extern CComModule _Module; // required by atlcom.h
|
|
#include <atlcom.h>
|
|
#include <netcfgx.h>
|
|
|
|
#include "brdgobj.h"
|
|
#include "trace.h"
|
|
#include "ncbase.h"
|
|
#include "ncmem.h"
|
|
#include "ncreg.h"
|
|
|
|
// =================================================================
|
|
// string constants
|
|
//
|
|
const WCHAR c_szSBridgeNOParams[] = L"System\\CurrentControlSet\\Services\\BridgeMP";
|
|
const WCHAR c_szSBridgeDeviceValueName[] = L"Device";
|
|
const WCHAR c_szSBridgeDevicePrefix[] = L"\\Device\\";
|
|
const WCHAR c_szSBrigeMPID[] = L"ms_bridgemp";
|
|
|
|
// =================================================================
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::CBridgeNO
|
|
//
|
|
// Purpose: constructor for class CBridgeNO
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: None
|
|
//
|
|
// Notes:
|
|
//
|
|
CBridgeNO::CBridgeNO(VOID) :
|
|
m_pncc(NULL),
|
|
m_pnc(NULL),
|
|
m_eApplyAction(eBrdgActUnknown)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::CBridgeNO()" );
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::~CBridgeNO
|
|
//
|
|
// Purpose: destructor for class CBridgeNO
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: None
|
|
//
|
|
// Notes:
|
|
//
|
|
CBridgeNO::~CBridgeNO(VOID)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::~CBridgeNO()" );
|
|
|
|
// release interfaces if acquired
|
|
ReleaseObj(m_pncc);
|
|
ReleaseObj(m_pnc);
|
|
}
|
|
|
|
// =================================================================
|
|
// INetCfgNotify
|
|
//
|
|
// The following functions provide the INetCfgNotify interface
|
|
// =================================================================
|
|
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::Initialize
|
|
//
|
|
// Purpose: Initialize the notify object
|
|
//
|
|
// Arguments:
|
|
// pnccItem [in] pointer to INetCfgComponent object
|
|
// pnc [in] pointer to INetCfg object
|
|
// fInstalling [in] TRUE if we are being installed
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::Initialize(INetCfgComponent* pnccItem,
|
|
INetCfg* pnc, BOOL fInstalling)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::Initialize()" );
|
|
|
|
// save INetCfg & INetCfgComponent and add refcount
|
|
m_pncc = pnccItem;
|
|
m_pnc = pnc;
|
|
|
|
AddRefObj( m_pncc );
|
|
AddRefObj( m_pnc );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::ReadAnswerFile
|
|
//
|
|
// Purpose: Read settings from answerfile and configure the bridge
|
|
//
|
|
// Arguments:
|
|
// pszAnswerFile [in] name of AnswerFile
|
|
// pszAnswerSection [in] name of parameters section
|
|
//
|
|
// Returns:
|
|
//
|
|
// Notes: Dont do anything irreversible (like modifying registry) yet
|
|
// since the config. actually complete only when Apply is called!
|
|
//
|
|
STDMETHODIMP CBridgeNO::ReadAnswerFile(PCWSTR pszAnswerFile,
|
|
PCWSTR pszAnswerSection)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::ReadAnswerFile()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::Install
|
|
//
|
|
// Purpose: Do operations necessary for install.
|
|
//
|
|
// Arguments:
|
|
// dwSetupFlags [in] Setup flags
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes: Dont do anything irreversible (like modifying registry) yet
|
|
// since the config. actually complete only when Apply is called!
|
|
//
|
|
STDMETHODIMP CBridgeNO::Install(DWORD dw)
|
|
{
|
|
//
|
|
// Remember that we're installing. If the user doesn't cancel, we'll actually perform
|
|
// our work in ApplyRegistryChanges().
|
|
//
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::Install()" );
|
|
m_eApplyAction = eBrdgActInstall;
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::Removing
|
|
//
|
|
// Purpose: Do necessary cleanup when being removed
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes: Dont do anything irreversible (like modifying registry) yet
|
|
// since the removal is actually complete only when Apply is called!
|
|
//
|
|
STDMETHODIMP CBridgeNO::Removing(VOID)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::Removing()" );
|
|
m_eApplyAction = eBrdgActRemove;
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::CancelChanges
|
|
//
|
|
// Purpose: Cancel any changes made to internal data
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::CancelChanges(VOID)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::CancelChanges()" );
|
|
m_eApplyAction = eBrdgActUnknown;
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::ApplyRegistryChanges
|
|
//
|
|
// Purpose: Apply changes.
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes: We can make changes to registry etc. here.
|
|
//
|
|
STDMETHODIMP CBridgeNO::ApplyRegistryChanges(VOID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::ApplyRegistryChanges()" );
|
|
|
|
//
|
|
// We only do work on install
|
|
//
|
|
if( m_eApplyAction == eBrdgActInstall )
|
|
{
|
|
INetCfgComponent *pNetCfgComp;
|
|
|
|
TraceTag( ttidBrdgCfg, "Attempting to write device name in CBridgeNO::ApplyRegistryChanges()" );
|
|
hr = m_pnc->FindComponent( c_szSBrigeMPID, &pNetCfgComp );
|
|
|
|
if( SUCCEEDED ( hr) )
|
|
{
|
|
LPWSTR wszBindName;
|
|
|
|
hr = pNetCfgComp->GetBindName(&wszBindName);
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
UINT BindNameLen, PrefixLen;
|
|
LPWSTR wszDeviceName;
|
|
|
|
// Get enough memory to build a string with the device prefix and the bind name
|
|
// concatenated
|
|
BindNameLen = wcslen(wszBindName);
|
|
PrefixLen = wcslen(c_szSBridgeDevicePrefix);
|
|
wszDeviceName = (WCHAR*)malloc( sizeof(WCHAR) * (BindNameLen + PrefixLen + 1) );
|
|
|
|
if( wszDeviceName != NULL )
|
|
{
|
|
HKEY hkeyServiceParams;
|
|
|
|
// Create the concatenated string
|
|
wcscpy( wszDeviceName, c_szSBridgeDevicePrefix );
|
|
wcscat( wszDeviceName, wszBindName );
|
|
|
|
// Create the reg key where we need to stash the device name
|
|
hr = HrRegCreateKeyEx( HKEY_LOCAL_MACHINE, c_szSBridgeNOParams, REG_OPTION_NON_VOLATILE,
|
|
KEY_ALL_ACCESS, NULL, &hkeyServiceParams, NULL );
|
|
|
|
if( SUCCEEDED(hr) )
|
|
{
|
|
// Write out the device name
|
|
hr = HrRegSetSz( hkeyServiceParams, c_szSBridgeDeviceValueName, wszDeviceName );
|
|
|
|
if( FAILED(hr) )
|
|
{
|
|
TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "HrRegSetSz failed in CBridgeNO::ApplyRegistryChanges()");
|
|
}
|
|
|
|
RegCloseKey( hkeyServiceParams );
|
|
}
|
|
else
|
|
{
|
|
TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "HrRegCreateKeyEx failed in CBridgeNO::ApplyRegistryChanges()");
|
|
}
|
|
|
|
free( wszDeviceName );
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "malloc failed in CBridgeNO::ApplyRegistryChanges()");
|
|
}
|
|
|
|
CoTaskMemFree( wszBindName );
|
|
}
|
|
else
|
|
{
|
|
TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "pNetCfgComp->GetBindName failed in CBridgeNO::ApplyRegistryChanges()");
|
|
}
|
|
|
|
pNetCfgComp->Release();
|
|
}
|
|
else
|
|
{
|
|
TraceHr( ttidBrdgCfg, FAL, hr, FALSE, "m_pnc->FindComponent failed in CBridgeNO::ApplyRegistryChanges()");
|
|
}
|
|
}
|
|
|
|
// Paranoia
|
|
m_eApplyAction = eBrdgActUnknown;
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CBridgeNO::ApplyPnpChanges(
|
|
IN INetCfgPnpReconfigCallback* pICallback)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::ApplyPnpChanges()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// =================================================================
|
|
// INetCfgSystemNotify
|
|
// =================================================================
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::GetSupportedNotifications
|
|
//
|
|
// Purpose: Tell the system which notifications we are interested in
|
|
//
|
|
// Arguments:
|
|
// pdwNotificationFlag [out] pointer to NotificationFlag
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::GetSupportedNotifications(
|
|
OUT DWORD* pdwNotificationFlag)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::GetSupportedNotifications()" );
|
|
*pdwNotificationFlag = NCN_ADD | NCN_ENABLE | NCN_UPDATE | NCN_BINDING_PATH;
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::SysQueryBindingPath
|
|
//
|
|
// Purpose: Allow or veto formation of a binding path
|
|
//
|
|
// Arguments:
|
|
// dwChangeFlag [in] type of binding change
|
|
// pncbp [in] pointer to INetCfgBindingPath object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::SysQueryBindingPath(DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOLEAN bReject = FALSE;
|
|
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::SysQueryBindingPath()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::SysNotifyBindingPath
|
|
//
|
|
// Purpose: System tells us by calling this function which
|
|
// binding path has just been formed.
|
|
//
|
|
// Arguments:
|
|
// dwChangeFlag [in] type of binding change
|
|
// pncbpItem [in] pointer to INetCfgBindingPath object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::SysNotifyBindingPath(DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbpItem)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::SysNotifyBindingPath()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::SysNotifyComponent
|
|
//
|
|
// Purpose: System tells us by calling this function which
|
|
// component has undergone a change (installed/removed)
|
|
//
|
|
// Arguments:
|
|
// dwChangeFlag [in] type of system change
|
|
// pncc [in] pointer to INetCfgComponent object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::SysNotifyComponent(DWORD dwChangeFlag,
|
|
INetCfgComponent* pncc)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::SysNotifyComponent()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// =================================================================
|
|
// INetCfgBindNotify
|
|
// =================================================================
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::QueryBindingPath
|
|
//
|
|
// Purpose: Allow or veto a binding path involving us
|
|
//
|
|
// Arguments:
|
|
// dwChangeFlag [in] type of binding change
|
|
// pncbi [in] pointer to INetCfgBindingPath object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::QueryBindingPath(DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::QueryBindingPath()" );
|
|
|
|
// The bridge protocol should never be enabled by default; it
|
|
// should only be enabled programatically by the implementation
|
|
// of our UI code which allows the activation of the bridge.
|
|
return NETCFG_S_DISABLE_QUERY;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Function: CBridgeNO::NotifyBindingPath
|
|
//
|
|
// Purpose: System tells us by calling this function which
|
|
// binding path involving us has just been formed.
|
|
//
|
|
// Arguments:
|
|
// dwChangeFlag [in] type of binding change
|
|
// pncbp [in] pointer to INetCfgBindingPath object
|
|
//
|
|
// Returns: S_OK on success, otherwise an error code
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CBridgeNO::NotifyBindingPath(DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
TraceTag( ttidBrdgCfg, "CBridgeNO::NotifyBindingPath()" );
|
|
return S_OK;
|
|
}
|
|
|
|
// ------------ END OF NOTIFY OBJECT FUNCTIONS --------------------
|