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.
 
 
 
 
 
 

388 lines
10 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1999.
//
// File: N E T C F G . H
//
// Contents: Defines the overall datatype for representing the network
// bindings engine. This datatype, CNetConfig, is a
// collection of components and their binding relationships
// to each other.
//
// Notes:
//
// Author: shaunco 15 Jan 1999
//
//----------------------------------------------------------------------------
#pragma once
#include "complist.h"
#include "diagctx.h"
#include "install.h"
#include "notify.h"
#include "stable.h"
#include "util.h"
// Flags for HrGetBindingsXXX.
//
enum GB_FLAGS
{
GBF_DEFAULT = 0x00000000,
GBF_ADD_TO_BINDSET = 0x00000001,
GBF_PRUNE_DISABLED_BINDINGS = 0x00000002,
GBF_ONLY_WHICH_CONTAIN_COMPONENT = 0x00000004,
};
// Flags for FIsBindPathDisabled.
//
enum IBD_FLAGS
{
IBD_EXACT_MATCH_ONLY = 0x00000001,
IBD_MATCH_SUBPATHS_TOO = 0x00000002,
};
class CNetConfigCore
{
public:
CComponentList Components;
CStackTable StackTable;
CBindingSet DisabledBindings;
#if DBG
private:
BOOL m_fRemovedAComponent;
#endif
public:
VOID Clear ();
VOID Free ();
BOOL FIsEmpty () const;
BOOL
FContainsFilterComponent () const;
BOOL
FIsBindPathDisabled (
IN const CBindPath* pBindPath,
IN DWORD dwFlags /* IBD_FLAGS */) const;
BOOL
FIsLength2BindPathDisabled (
IN const CComponent* pUpper,
IN const CComponent* pLower) const;
VOID
EnableBindPath (
IN const CBindPath* pBindPath)
{
TraceFileFunc(ttidNetCfgBind);
DisabledBindings.RemoveBindPath (pBindPath);
DbgVerifyBindingSet (&DisabledBindings);
}
VOID
EnsureComponentNotReferencedByOthers (
IN const CComponent* pComponent);
HRESULT
HrDisableBindPath (
IN const CBindPath* pBindPath);
HRESULT
HrCopyCore (
IN const CNetConfigCore* pSourceCore);
HRESULT
HrGetBindingsInvolvingComponent (
IN const CComponent* pComponent,
IN DWORD dwFlags,
IN OUT CBindingSet* pBindSet);
HRESULT
HrGetComponentBindings (
IN const CComponent* pComponent,
IN DWORD dwFlags /* GB_FLAGS */,
OUT CBindingSet* pBindSet);
HRESULT
HrGetComponentUpperBindings (
IN const CComponent* pComponent,
IN DWORD dwFlags,
OUT CBindingSet* pBindSet);
HRESULT
HrGetFiltersEnabledForAdapter (
IN const CComponent* pAdapter,
OUT CComponentList* pFilters);
HRESULT
HrAddComponentToCore (
IN CComponent* pComponent,
IN DWORD dwFlags /* INS_FLAGS */);
VOID
RemoveComponentFromCore (
IN const CComponent* pComponent);
#if DBG
VOID DbgVerifyData () const;
VOID DbgVerifyExternalDataLoadedForAllComponents () const;
VOID DbgVerifyBindingSet (
const CBindingSet* pBindSet) const;
#else
VOID DbgVerifyData () const {}
VOID DbgVerifyExternalDataLoadedForAllComponents () const {}
VOID DbgVerifyBindingSet (
const CBindingSet* /*pBindSet*/) const {}
#endif
};
class CNetConfig;
class CFilterDevices;
class CRegistryBindingsContext
{
private:
CNetConfig* m_pNetConfig;
CBindingSet m_BindSet;
CDynamicBuffer m_BindValue;
CDynamicBuffer m_ExportValue;
CDynamicBuffer m_RouteValue;
public:
HRESULT
HrPrepare (
IN CNetConfig* pNetConfig);
HRESULT
HrGetAdapterUpperBindValue (
IN const CComponent* pAdapter);
HRESULT
HrWriteBindingsForComponent (
IN const CComponent* pComponent);
HRESULT
HrWriteBindingsForFilterDevices (
IN CFilterDevices* pFilterDevices);
HRESULT
HrDeleteBindingsForComponent (
IN const CComponent* pComponent);
VOID
PnpBindOrUnbindBindPaths (
IN UINT unOperation,
IN const CBindingSet* pBindSet,
OUT BOOL* pfRebootNeeded);
};
enum IOR_ACTION
{
IOR_INSTALL,
IOR_REMOVE,
};
enum EBO_FLAG
{
EBO_COMMIT_NOW = 1,
EBO_DEFER_COMMIT_UNTIL_APPLY,
};
class CModifyContext
{
public:
// This is the core data we started with before the modification began.
// In the event the modification fails, we will revert to this data.
// We also use this data when we apply the changes. We compare what
// we started with to what we have as a result of the modification and
// the differences represent the things we need to change.
//
CNetConfigCore m_CoreStartedWith;
// These bindings are the added bindpaths (due to adding components)
// These represent bindings that have been queried and notified to
// notify objects.
//
CBindingSet m_AddedBindPaths;
// These bindings are the deleted bindpaths (due to removing components)
// These represent bindings that have been notified to notify objects.
//
CBindingSet m_DeletedBindPaths;
// These components are all the components involved in m_AddedBindPaths
// and m_DeletedBindPaths. As such, they are the components we need
// to visit during Apply to write bindings for, delete bindings for,
// or finish removal of depending on whether the components exist in
// the core we started with. Components can get in this list if they
// have had their bind order changed, or if they were involved in a
// binding that has been enabled or disabled.
//
CComponentList m_DirtyComponents;
// The purpose of the binding context is just to allow us to make one
// allocation (and use it over and over) for the buffer which holds the
// bind strings that get written to the registry. We make this allocation
// up front when the modify context is prepared. Doing so minimizes the
// risk of getting half-way through apply and then finding out we are so
// low on memory that we cannot allocate a buffer to write the registry
// bindings with.
//
CRegistryBindingsContext m_RegBindCtx;
ULONG m_ulRecursionDepth;
HRESULT m_hr;
BOOLEAN m_fPrepared;
// Set when a notify object says they need to reboot in order for changes
// to take affect. Setting this will not REQUIRE us to reboot, it will
// only cause NETCFG_S_REBOOT to be returned from the install or remove
// operation.
//
BOOLEAN m_fRebootRecommended;
// Set when a component that is being removed fails to stop. When it
// does, its service will be marked as 'pending delete'. We cannot allow
// any other config changes to happen when we are in this state because
// if that service ever needs to be re-installed, we will fail.
//
BOOLEAN m_fRebootRequired;
#if DBG
// This flag indicates that we've dirtied a component outside of
// ApplyChanges. We will do this when bind order changes, and when
// INetCfgComponentPrivate::SetDirty or
// INetCfgComponentPrivate::NotifyUpperEdgeConfigChange are called.
// If this flag is TRUE, m_fDirtyComponents will not be empty upon
// entering ApplyChanges. Normally, when this flag is FALSE,
// m_fDirtyComponents should be empty when entering ApplyChanges.
// If it were not, it would probably mean we forgot to empty it after
// the last Apply or Cancel and are now risking applying changes to
// components which really are not dirty.
//
BOOLEAN m_fComponentExplicitlyDirtied;
#endif
private:
VOID
PushRecursionDepth ();
HRESULT
HrPopRecursionDepth ();
VOID
ApplyChanges ();
VOID
InstallAndAddAndNotifyComponent (
IN const COMPONENT_INSTALL_PARAMS& Params,
OUT CComponent** ppComponent);
VOID
InstallConvenienceComponentsForUser (
IN const CComponent* pComponent);
VOID
InstallOrRemoveRequiredComponents (
IN CComponent* pComponent,
IN IOR_ACTION Action);
VOID
NotifyAndRemoveComponent (
IN CComponent* pComponent);
HRESULT
HrProcessWinsockRemove (
IN const CComponent* pComponent);
public:
CNetConfig*
PNetConfig ();
HRESULT
HrBeginBatchOperation ();
HRESULT
HrEndBatchOperation (
IN EBO_FLAG Flag);
HRESULT
HrDirtyComponent (
IN const CComponent* pComponent);
HRESULT
HrDirtyComponentAndComponentsAbove (
IN const CComponent* pComponent);
HRESULT
HrApplyIfOkOrCancel (
IN BOOL fApply);
HRESULT
HrPrepare ();
HRESULT
HrEnableOrDisableBindPath (
IN DWORD dwChangeFlag,
IN CBindPath* pBindPath,
IN INetCfgBindingPath* pIPath OPTIONAL);
HRESULT
HrInstallNewOrReferenceExistingComponent (
IN const COMPONENT_INSTALL_PARAMS& Params,
OUT CComponent** ppComponent);
HRESULT
HrRemoveComponentIfNotReferenced (
IN CComponent* pComponent,
IN OBO_TOKEN* pOboToken OPTIONAL,
OUT PWSTR* ppmszwRefs OPTIONAL);
HRESULT
HrUpdateComponent (
IN CComponent* pComponent,
IN DWORD dwSetupFlags,
IN DWORD dwUpgradeFromBuildNo);
};
class CNetConfig
{
public:
// This is the core data managed by this object. The reason it
// is encapsulated by NETCFG_CORE is so that we can save it away before
// we being any modify operation. (We save it into
// CModifyContext.m_StartedWith.) In the event of a failure to modify
// we restore the core data from what we started with.
//
CNetConfigCore Core;
// The interface to all notify objects representing the components.
//
CGlobalNotifyInterface Notify;
CModifyContext ModifyCtx;
public:
CNetConfig ()
{
TraceFileFunc(ttidNetcfgBase);
ZeroMemory (this, sizeof(*this));
}
~CNetConfig ();
HRESULT
HrEnsureExternalDataLoadedForAllComponents ();
static HRESULT
HrCreateInstance (
IN class CImplINetCfg* pINetCfg,
OUT CNetConfig** ppNetConfig);
};