Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

249 lines
5.3 KiB

// nwlnknb.cpp : Implementation of CNwlnkNB
#include "pch.h"
#pragma hdrstop
#include <ncxbase.h>
#include "ncreg.h"
#include "ncsvc.h"
#include "nwlnknb.h"
#include "nwlnkipx.h"
CNwlnkNB::CNwlnkNB() :
m_pnccMe(NULL),
m_pNetCfg(NULL),
m_eInstallAction(eActUnknown),
m_eNbState(eStateNoChange)
{
}
CNwlnkNB::~CNwlnkNB()
{
ReleaseObj(m_pNetCfg);
ReleaseObj(m_pnccMe);
}
// INetCfgNotify
STDMETHODIMP CNwlnkNB::Initialize (
INetCfgComponent* pncc,
INetCfg* pNetCfg,
BOOL fInstalling)
{
Validate_INetCfgNotify_Initialize(pncc, pNetCfg, fInstalling);
// Hold on to our the component representing us and our host
// INetCfg object.
AddRefObj (m_pnccMe = pncc);
AddRefObj (m_pNetCfg = pNetCfg);
// See if DNS is already installed. If it is we need to be disabled
if (fInstalling &&
(S_OK == m_pNetCfg->FindComponent(L"MS_DNSServer", NULL)))
{
m_eNbState = eStateDisable;
}
return S_OK;
}
STDMETHODIMP CNwlnkNB::ReadAnswerFile (
PCWSTR pszAnswerFile,
PCWSTR pszAnswerSection)
{
Validate_INetCfgNotify_ReadAnswerFile(pszAnswerFile, pszAnswerSection);
return S_OK;
}
STDMETHODIMP CNwlnkNB::Install (
DWORD dwSetupFlags)
{
m_eInstallAction = eActInstall;
return S_OK;
}
STDMETHODIMP CNwlnkNB::Removing ()
{
m_eInstallAction = eActRemove;
return S_OK;
}
STDMETHODIMP CNwlnkNB::Validate ()
{
return S_OK;
}
STDMETHODIMP CNwlnkNB::CancelChanges ()
{
return S_OK;
}
STDMETHODIMP CNwlnkNB::ApplyRegistryChanges ()
{
UpdateBrowserDirectHostBinding ();
if ((eActRemove != m_eInstallAction) &&
(eStateNoChange != m_eNbState))
{
UpdateNwlnkNbStartType();
}
return S_OK;
}
// INetCfgSystemNotify
STDMETHODIMP CNwlnkNB::GetSupportedNotifications (
DWORD* pdwSupportedNotifications )
{
Validate_INetCfgSystemNotify_GetSupportedNotifications(pdwSupportedNotifications);
// Want to know when DNS comes and goes
*pdwSupportedNotifications = NCN_NETSERVICE | NCN_ADD | NCN_REMOVE;
return S_OK;
}
STDMETHODIMP CNwlnkNB::SysQueryBindingPath (
DWORD dwChangeFlag,
INetCfgBindingPath* pIPath)
{
return S_OK;
}
STDMETHODIMP CNwlnkNB::SysQueryComponent (
DWORD dwChangeFlag,
INetCfgComponent* pIComp)
{
return S_OK;
}
STDMETHODIMP CNwlnkNB::SysNotifyBindingPath (
DWORD dwChangeFlag,
INetCfgBindingPath* pIPath)
{
return S_OK;
}
STDMETHODIMP CNwlnkNB::SysNotifyComponent (
DWORD dwChangeFlag,
INetCfgComponent* pnccItem)
{
Validate_INetCfgSystemNotify_SysNotifyComponent(dwChangeFlag, pnccItem);
// Assume we won't be dirty as a result of this notification.
//
HRESULT hr = S_FALSE;
// If this component does not identify itself as DNS then skip it...
if (FIsComponentId(L"MS_DNSServer", pnccItem))
{
// Disable/Enable NetBIOS when DNS is Added/Removed
if (dwChangeFlag & NCN_ADD)
{
// Disable and shutdown NwlnkNb
m_eNbState = eStateDisable;
hr = S_OK;
}
else if (dwChangeFlag & NCN_REMOVE)
{
// Re-enable NwlnkNb
m_eNbState = eStateEnable;
hr = S_OK;
}
}
return hr;
}
//
// Function: CNwlnkNB::UpdateNwlnkNbStartType
//
// Purpose: Enable or disable NwlnkNb
//
//
VOID
CNwlnkNB::UpdateNwlnkNbStartType(
VOID)
{
HRESULT hr;
CServiceManager scm;
CService svc;
hr = scm.HrOpenService(&svc, L"NwlnkNb");
if (S_OK == hr)
{
if (eStateDisable == m_eNbState)
{
(VOID) svc.HrSetStartType(SERVICE_DISABLED);
svc.Close();
(VOID) scm.HrStopServiceNoWait(L"NwlnkNb");
}
else if (eStateEnable == m_eNbState)
{
(VOID) svc.HrSetStartType(SERVICE_DEMAND_START);
}
}
}
VOID
CNwlnkNB::UpdateBrowserDirectHostBinding(
VOID)
{
HRESULT hr;
BOOL fBound = FALSE;
// We don't need to check if client is bound to us if we are being
// removed.
//
if (eActRemove != m_eInstallAction)
{
INetCfgComponent* pMsClient;
hr = m_pNetCfg->FindComponent (L"ms_msclient", &pMsClient);
if (S_OK == hr)
{
INetCfgComponentBindings* pMsClientBindings;
hr = pMsClient->QueryInterface (IID_INetCfgComponentBindings,
(VOID**)&pMsClientBindings);
if (S_OK == hr)
{
fBound = (S_OK == pMsClientBindings->IsBoundTo (m_pnccMe));
ReleaseObj (pMsClientBindings);
}
ReleaseObj (pMsClient);
}
}
HKEY hkey;
hr = HrRegOpenKeyEx (
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\Browser\\Parameters",
KEY_ALL_ACCESS, &hkey);
if (S_OK == hr)
{
static const WCHAR c_szDirectHostBinding[] = L"DirectHostBinding";
if (fBound)
{
// Write the DirectHostBinding info since we are directly bound
//
hr = HrRegSetMultiSz (hkey,
c_szDirectHostBinding,
L"\\Device\\NwlnkIpx\0\\Device\\NwlnkNb\0");
}
else
{
// Remove the DirectHostBinding value
//
(VOID) HrRegDeleteValue (hkey, c_szDirectHostBinding);
}
RegCloseKey (hkey);
}
}