|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1999.
//
// File: I N E T C F G . C P P
//
// Contents: Implements the COM interfaces on the top-level NetCfg object.
// These interfaces are: INetCfg and INetCfgLock. Also
// implements a base C++ class inherited by sub-level NetCfg
// objects which hold a reference to the top-level object.
//
// Notes:
//
// Author: shaunco 15 Jan 1999
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "classinst.h"
#include "iclass.h"
#include "icomp.h"
#include "ienum.h"
#include "inetcfg.h"
#include "ncperms.h"
#include "ncras.h"
#include "ncreg.h"
#include "ncui.h"
#include "ncvalid.h"
#include "ndispnp.h"
#include "netcfg.h"
#include "obotoken.h"
#include "resource.h"
// static
HRESULT CImplINetCfg::HrCreateInstance ( CNetConfig* pNetConfig, CImplINetCfg** ppINetCfg) { Assert (pNetConfig); Assert (ppINetCfg);
HRESULT hr = E_OUTOFMEMORY;
CImplINetCfg* pObj; pObj = new CComObject <CImplINetCfg>; if (pObj) { // Initialize our members.
//
pObj->m_pNetConfig = pNetConfig; Assert (!pObj->m_fOwnNetConfig);
// Do the standard CComCreator::CreateInstance stuff.
//
pObj->SetVoid (NULL); pObj->InternalFinalConstructAddRef (); hr = pObj->FinalConstruct (); pObj->InternalFinalConstructRelease ();
if (S_OK == hr) { AddRefObj (pObj->GetUnknown()); *ppINetCfg = pObj; }
if (S_OK != hr) { delete pObj; } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::HrCreateInstance"); return hr; }
HRESULT CImplINetCfg::HrCoCreateWrapper ( IN REFCLSID rclsid, IN LPUNKNOWN punkOuter, IN DWORD dwClsContext, IN REFIID riid, OUT LPVOID FAR* ppv) { /*
HRESULT hr = S_OK;
if (!m_fComInitialized) { m_fComInitialized = TRUE;
hr = CoInitializeEx ( NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED); if (SUCCEEDED(hr)) { m_fUninitCom = TRUE; hr = S_OK; // mask S_FALSE
} else if (RPC_E_CHANGED_MODE == hr) { hr = S_OK; Assert (!m_fUninitCom); } }
if (S_OK == hr) { hr = CoCreateInstance (rclsid, punkOuter, dwClsContext, riid, ppv); } */
HRESULT hr; hr = CoCreateInstance (rclsid, punkOuter, dwClsContext, riid, ppv);
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::HrCoCreateWrapper"); return hr; }
HRESULT CImplINetCfg::HrCheckForReentrancy ( IN DWORD dwFlags) { Assert (FImplies(dwFlags & IF_ALLOW_INSTALL_OR_REMOVE, dwFlags & IF_REFUSE_REENTRANCY));
if (dwFlags & IF_ALLOW_INSTALL_OR_REMOVE) { if (m_LastAllowedSetupRpl != m_CurrentRpl) { return E_FAIL; } } else if (0 != m_CurrentRpl) { return E_FAIL; }
return S_OK; }
HRESULT CImplINetCfg::HrIsValidInterface ( IN DWORD dwFlags) { HRESULT hr;
// Check if we need to refuse re-entrancy.
//
if (dwFlags & IF_REFUSE_REENTRANCY) { hr = HrCheckForReentrancy (dwFlags); if (S_OK != hr) { return hr; } }
// Check if initialized/uninitalized as required.
//
if ((dwFlags & IF_NEED_UNINITIALIZED) && m_pNetConfig) { return NETCFG_E_ALREADY_INITIALIZED; } else if (!(dwFlags & IF_NEED_UNINITIALIZED) && !m_pNetConfig) { return NETCFG_E_NOT_INITIALIZED; }
// Check for the write lock.
//
if (dwFlags & IF_NEED_WRITE_LOCK) { if (!m_WriteLock.FIsOwnedByMe ()) { return NETCFG_E_NO_WRITE_LOCK; }
// Needing the write lock means we need the modify context to
// be prepared (unless the caller specified
// IF_DONT_PREPARE_MODIFY_CONTEXT).
//
if (!m_pNetConfig->ModifyCtx.m_fPrepared && !(dwFlags & IF_DONT_PREPARE_MODIFY_CONTEXT)) { hr = m_pNetConfig->ModifyCtx.HrPrepare (); if (S_OK != hr) { return hr; } } }
if (!(dwFlags & IF_UNINITIALIZING)) { // Check for an error that occured during the current modification
// that has not been rolled back yet. i.e. keep people out until
// we unwind enough to cleanup our modify context.
//
if (m_pNetConfig && (S_OK != m_pNetConfig->ModifyCtx.m_hr)) { return m_pNetConfig->ModifyCtx.m_hr; } }
Assert (FImplies(!m_pNetConfig, (dwFlags & IF_NEED_UNINITIALIZED)));
return S_OK; }
VOID CImplINetCfg::LowerRpl ( IN RPL_FLAGS Flags) { if (RPL_ALLOW_INSTALL_REMOVE == Flags) { Assert (m_LastAllowedSetupRpl > 0); m_LastAllowedSetupRpl--; }
Assert (m_CurrentRpl > 0); m_CurrentRpl--; }
VOID CImplINetCfg::RaiseRpl ( IN RPL_FLAGS Flags) { m_CurrentRpl++;
if (RPL_ALLOW_INSTALL_REMOVE == Flags) { m_LastAllowedSetupRpl++; } }
HRESULT CImplINetCfg::HrLockAndTestForValidInterface ( DWORD dwFlags) { HRESULT hr;
Lock();
hr = HrIsValidInterface (dwFlags);
if (S_OK != hr) { Unlock(); }
return hr; }
//+---------------------------------------------------------------------------
// INetCfg -
//
STDMETHODIMP CImplINetCfg::Initialize ( IN PVOID pvReserved) { HRESULT hr;
ULONG* pReserved = (ULONG*)pvReserved;
// Validate parameters.
//
if (FBadInPtrOptional(pReserved)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface ( IF_NEED_UNINITIALIZED | IF_REFUSE_REENTRANCY); if (S_OK == hr) { Assert (!m_pNetConfig);
hr = CNetConfig::HrCreateInstance ( this, &m_pNetConfig);
if (S_OK == hr) { Assert (m_pNetConfig);
m_fOwnNetConfig = TRUE; } Unlock(); } }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::Initialize"); return hr; }
STDMETHODIMP CImplINetCfg::Uninitialize () { HRESULT hr;
hr = HrLockAndTestForValidInterface ( IF_REFUSE_REENTRANCY | IF_UNINITIALIZING); if (S_OK == hr) { Assert (m_pNetConfig); Assert (m_fOwnNetConfig);
delete m_pNetConfig;
// CGlobalNotifyInterface::ReleaseINetCfg (called via the above
// delete call) will set m_pNetConfig to NULL for us.
// Verify it is so.
//
Assert (!m_pNetConfig);
// Release our cache of INetCfgClass pointers.
//
ReleaseIUnknownArray (celems(m_apINetCfgClass), (IUnknown**)m_apINetCfgClass); ZeroMemory (m_apINetCfgClass, sizeof(m_apINetCfgClass));
Unlock(); }
TraceHr (ttidError, FAL, hr, NETCFG_E_NOT_INITIALIZED == hr, "CImplINetCfg::Uninitialize"); return hr; }
STDMETHODIMP CImplINetCfg::Validate () { HRESULT hr;
hr = HrLockAndTestForValidInterface (IF_REFUSE_REENTRANCY); if (S_OK == hr) {
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::Validate"); return hr; }
STDMETHODIMP CImplINetCfg::Cancel () { HRESULT hr;
hr = HrLockAndTestForValidInterface (IF_REFUSE_REENTRANCY); if (S_OK == hr) { // Only cancel the changes if we have a prepared modify context.
//
if (m_pNetConfig->ModifyCtx.m_fPrepared) { hr = m_pNetConfig->ModifyCtx.HrApplyIfOkOrCancel (FALSE); }
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::Cancel"); return hr; }
STDMETHODIMP CImplINetCfg::Apply () { HRESULT hr;
// We need the write lock to Apply, but we don't want to prepare the
// modify context if it has not been prepared. (This case amounts to
// applying no changes.) Hence we use the IF_DONT_PREPARE_MODIFY_CONTEXT
// flag.
//
hr = HrLockAndTestForValidInterface ( IF_NEED_WRITE_LOCK | IF_REFUSE_REENTRANCY | IF_DONT_PREPARE_MODIFY_CONTEXT); if (S_OK == hr) { // Only apply the changes if we have a prepared modify context.
//
if (m_pNetConfig->ModifyCtx.m_fPrepared) { hr = m_pNetConfig->ModifyCtx.HrApplyIfOkOrCancel (TRUE); }
// If there is nothing to apply, but we've previously applied
// something that indicated a reboot was recommened or required,
// return an indication.
//
else if (m_pNetConfig->ModifyCtx.m_fRebootRecommended || m_pNetConfig->ModifyCtx.m_fRebootRequired) { hr = NETCFG_S_REBOOT; }
Unlock(); }
TraceHr (ttidError, FAL, hr, NETCFG_S_REBOOT == hr, "CImplINetCfg::Apply"); return hr; }
STDMETHODIMP CImplINetCfg::EnumComponents ( IN const GUID* pguidClass OPTIONAL, OUT IEnumNetCfgComponent** ppIEnum) { HRESULT hr; NETCLASS Class;
// Validate parameters.
//
if (FBadInPtrOptional(pguidClass) || FBadOutPtr(ppIEnum)) { hr = E_POINTER; } else if (pguidClass && (NC_INVALID == (Class = NetClassEnumFromGuid(*pguidClass)))) { hr = E_INVALIDARG; *ppIEnum = NULL; } else { *ppIEnum = NULL;
hr = HrLockAndTestForValidInterface (IF_DEFAULT); if (S_OK == hr) { hr = CImplIEnumNetCfgComponent::HrCreateInstance ( this, (pguidClass) ? Class : NC_INVALID, ppIEnum);
Unlock(); } }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::EnumComponents"); return hr; }
STDMETHODIMP CImplINetCfg::FindComponent ( IN PCWSTR pszInfId, OUT INetCfgComponent** ppIComp OPTIONAL) { HRESULT hr;
// Validate parameters.
//
if (FBadInPtr(pszInfId) || FBadOutPtrOptional(ppIComp)) { hr = E_POINTER; } else { if (ppIComp) { *ppIComp = NULL; }
hr = HrLockAndTestForValidInterface (IF_DEFAULT); if (S_OK == hr) { CComponent* pComponent;
pComponent = m_pNetConfig->Core.Components. PFindComponentByInfId (pszInfId, NULL);
// Don't return interfaces to components that have had
// problem loading.
//
if (pComponent && pComponent->Ext.FLoadedOkayIfLoadedAtAll()) { hr = S_OK;
if (ppIComp) { hr = pComponent->HrGetINetCfgComponentInterface ( this, ppIComp); } } else { hr = S_FALSE; }
Unlock(); } }
TraceHr (ttidError, FAL, hr, (S_FALSE == hr), "CImplINetCfg::FindComponent"); return hr; }
STDMETHODIMP CImplINetCfg::QueryNetCfgClass ( IN const GUID* pguidClass, IN REFIID riid, OUT VOID** ppv) { HRESULT hr; NETCLASS Class;
// Validate parameters.
//
if (FBadInPtr(pguidClass) || FBadInPtr(&riid) || FBadOutPtr(ppv)) { hr = E_POINTER; } else if (NC_INVALID == (Class = NetClassEnumFromGuid(*pguidClass))) { hr = E_INVALIDARG; *ppv = NULL; } else { *ppv = NULL;
hr = HrLockAndTestForValidInterface (IF_DEFAULT); if (S_OK == hr) { // Get the INetCfgClass interface from our cache.
//
Assert(Class < celems(m_apINetCfgClass)); INetCfgClass* pIClass = m_apINetCfgClass[Class];
// If we don't have it yet, create it.
//
if (!pIClass) { hr = CImplINetCfgClass::HrCreateInstance ( this, Class, &pIClass); if (S_OK == hr) { pIClass = m_apINetCfgClass[Class] = pIClass; Assert(pIClass); } }
// Give the caller the requested interface.
//
if (S_OK == hr) { hr = pIClass->QueryInterface (riid, ppv); }
Unlock(); } }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::QueryNetCfgClass"); return hr; }
//+---------------------------------------------------------------------------
// INetCfgLock -
//
STDMETHODIMP CImplINetCfg::AcquireWriteLock ( IN DWORD cmsTimeout, IN PCWSTR pszClientDescription, OUT PWSTR* ppszClientDescription OPTIONAL) { HRESULT hr;
// Validate parameters.
//
if (FBadInPtr (pszClientDescription) || FBadOutPtrOptional (ppszClientDescription)) { hr = E_POINTER; } else { TraceTag (ttidNetcfgBase, "%S is asking for the write lock", pszClientDescription);
// Initialize the optional output parameter.
//
if (ppszClientDescription) { *ppszClientDescription = NULL; }
// Only administrators and netconfig operators can make changes requiring the write lock.
//
if (!FIsUserAdmin() && !FIsUserNetworkConfigOps()) { hr = E_ACCESSDENIED; } else { hr = HrLockAndTestForValidInterface ( IF_NEED_UNINITIALIZED | IF_REFUSE_REENTRANCY); if (S_OK == hr) { // Wait for the mutex to become available.
//
if (m_WriteLock.WaitToAcquire (cmsTimeout, pszClientDescription, ppszClientDescription)) { hr = S_OK; } else { hr = S_FALSE; }
Unlock(); } } }
TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfg::AcquireWriteLock"); return hr; }
STDMETHODIMP CImplINetCfg::ReleaseWriteLock () { HRESULT hr;
// This method that can be called whether we are initialized or
// not. That is why we don't call HrLockAndTestForValidInterface.
//
Lock ();
// Check if we need to refuse re-entrancy.
//
hr = HrCheckForReentrancy (IF_DEFAULT); if (S_OK == hr) { m_WriteLock.ReleaseIfOwned (); }
Unlock();
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::ReleaseWriteLock"); return hr; }
STDMETHODIMP CImplINetCfg::IsWriteLocked ( OUT PWSTR* ppszClientDescription) { HRESULT hr;
// Validate parameters.
//
if (FBadOutPtrOptional (ppszClientDescription)) { hr = E_POINTER; } else { if (ppszClientDescription) { *ppszClientDescription = NULL; }
// This method that can be called whether we are initialized or
// not. That is why we don't call HrLockAndTestForValidInterface.
//
Lock ();
// Check if we need to refuse re-entrancy.
//
hr = HrCheckForReentrancy (IF_DEFAULT); if (S_OK == hr) { hr = (m_WriteLock.FIsLockedByAnyone (ppszClientDescription)) ? S_OK : S_FALSE; }
Unlock (); }
TraceHr (ttidError, FAL, hr, S_FALSE == hr, "CImplINetCfg::IsWriteLocked"); return hr; }
//+---------------------------------------------------------------------------
// INetCfgInternalSetup -
//
STDMETHODIMP CImplINetCfg::BeginBatchOperation () { HRESULT hr;
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK);
if (S_OK == hr) { hr = m_pNetConfig->ModifyCtx.HrBeginBatchOperation ();
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "BeginBatchOperation"); return hr; }
STDMETHODIMP CImplINetCfg::CommitBatchOperation () { HRESULT hr;
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK);
if (S_OK == hr) { hr = m_pNetConfig->ModifyCtx.HrEndBatchOperation (EBO_COMMIT_NOW);
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "CommitBatchOperation"); return hr; }
STDMETHODIMP CImplINetCfg::SelectWithFilterAndInstall ( IN HWND hwndParent, IN const GUID* pClassGuid, IN OBO_TOKEN* pOboToken OPTIONAL, IN const CI_FILTER_INFO* pcfi OPTIONAL, OUT INetCfgComponent** ppIComp OPTIONAL) { Assert (pClassGuid); HRESULT hr; NETCLASS Class;
if (FBadInPtr(pClassGuid)) { hr = E_POINTER; } else if (FIsEnumerated ((Class = NetClassEnumFromGuid(*pClassGuid)))) { // This fcn is only for selecting non-enumerated components.
//
return E_INVALIDARG; } else if (!FOboTokenValidForClass(pOboToken, Class) || FBadOutPtrOptional(ppIComp)) { hr = E_POINTER; } else if (hwndParent && !IsWindow(hwndParent)) { hr = E_INVALIDARG; } else if (S_OK == (hr = HrProbeOboToken(pOboToken))) { if (ppIComp) { *ppIComp = NULL; }
hr = HrLockAndTestForValidInterface ( IF_NEED_WRITE_LOCK | IF_ALLOW_INSTALL_OR_REMOVE);
if (S_OK == hr) { Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
// if a filter info was specified, and it is for FC_LAN or FC_ATM,
// we need to set up the reserved member of the filter info for
// the class installer.
//
if (pcfi && ((FC_LAN == pcfi->eFilter) || (FC_ATM == pcfi->eFilter))) { // If the pIComp member was NULL, then return invalid
// argument.
//
Assert (pcfi->pIComp); CImplINetCfgComponent* pICompImpl; pICompImpl = (CImplINetCfgComponent*)pcfi->pIComp;
hr = pICompImpl->HrIsValidInterface (IF_NEED_COMPONENT_DATA);
if (S_OK == hr) { // The class installer only needs the component's
// range of upper interfaces so we need to store that in the
// reserved field of the filter info
Assert (pICompImpl->m_pComponent); ((CI_FILTER_INFO*)pcfi)->pvReserved = (void*) pICompImpl->m_pComponent->Ext.PszUpperRange(); } }
COMPONENT_INSTALL_PARAMS* pParams; hr = HrCiSelectComponent (Class, hwndParent, pcfi, &pParams);
if (pcfi) { // Don't want to return the private data to the client.
//
((CI_FILTER_INFO*)pcfi)->pvReserved = NULL; }
// Check for installing a NET_SERVICE and active RAS connections
// exist. If so, warn the user that this may disconnect those
// connections. (This assumes that all filter components are
// of class NET_SERVICE.)
//
if (S_OK == hr) { Assert (pParams); if ((NC_NETSERVICE == pParams->Class) && FExistActiveRasConnections ()) { INT nRet;
nRet = NcMsgBox ( _Module.GetResourceInstance(), hwndParent, IDS_WARNING_CAPTION, IDS_ACTIVE_RAS_CONNECTION_WARNING, MB_ICONQUESTION | MB_YESNO);
if (IDYES != nRet) { hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); } } }
if (S_OK == hr) { Assert(pParams); CComponent* pComponent;
// Check to see if the user selected a component that
// is already installed. If so, we need to reinstall.
//
pComponent = m_pNetConfig->Core.Components. PFindComponentByInfId(pParams->pszInfId, NULL);
if (!pComponent) { pParams->pOboToken = pOboToken; hr = m_pNetConfig->ModifyCtx. HrInstallNewOrReferenceExistingComponent ( *pParams, &pComponent); } else { // reinstall. call Update.
hr = UpdateNonEnumeratedComponent ( pComponent->GetINetCfgComponentInterface(), NSF_COMPONENT_UPDATE, 0); }
// The above may return NETCFG_S_REBOOT so use SUCCEEDED instead
// of checking for S_OK only.
//
if (SUCCEEDED(hr) && ppIComp) { pComponent->HrGetINetCfgComponentInterface ( this, ppIComp); }
delete pParams; }
Unlock(); } }
TraceHr (ttidError, FAL, hr, (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) || (NETCFG_S_REBOOT == hr), "SelectWithFilterAndInstall"); return hr; }
STDMETHODIMP CImplINetCfg::EnumeratedComponentInstalled ( IN PVOID pv /* type of CComponent */) { HRESULT hr; CComponent* pComponent;
pComponent = (CComponent*)pv;
Assert (pComponent); Assert (FIsEnumerated(pComponent->Class())); Assert (pComponent->m_pszInfId && *pComponent->m_pszInfId); Assert (pComponent->m_pszPnpId && *pComponent->m_pszPnpId);
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK | IF_ALLOW_INSTALL_OR_REMOVE);
if (S_OK == hr) { COMPONENT_INSTALL_PARAMS Params; CComponent* pReturned;
Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
ZeroMemory(&Params, sizeof(Params)); Params.pComponent = (CComponent*)pComponent;
hr = m_pNetConfig->ModifyCtx.HrInstallNewOrReferenceExistingComponent ( Params, &pReturned);
if (S_OK == hr) { Assert (pComponent == pReturned); }
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "EnumeratedComponentInstalled"); return hr; }
STDMETHODIMP CImplINetCfg::EnumeratedComponentUpdated ( IN PCWSTR pszPnpId) { HRESULT hr;
Assert (pszPnpId && *pszPnpId);
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK);
if (S_OK == hr) { CComponent* pComponent;
Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
pComponent = m_pNetConfig->Core.Components. PFindComponentByPnpId (pszPnpId);
if (pComponent) { // Note: Core info may have changed so load core info from driver key.
// If not a remote boot adapter, do a binding analysis to see if
// anything has changed.
hr = S_OK; }
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "EnumeratedComponentUpdated"); return hr; }
STDMETHODIMP CImplINetCfg::UpdateNonEnumeratedComponent ( IN INetCfgComponent* pIComp, IN DWORD dwSetupFlags, IN DWORD dwUpgradeFromBuildNo) { HRESULT hr;
Assert (pIComp);
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK | IF_ALLOW_INSTALL_OR_REMOVE);
if (S_OK == hr) { CImplINetCfgComponent* pICompToUpdate;
Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
pICompToUpdate = (CImplINetCfgComponent*)pIComp; if (pICompToUpdate == NULL) { return E_OUTOFMEMORY; }
hr = pICompToUpdate->HrIsValidInterface (IF_NEED_COMPONENT_DATA);
if (S_OK == hr) { HKEY hkeyInstance; CComponent* pComponent = pICompToUpdate->m_pComponent;
hr = pComponent->HrOpenInstanceKey (KEY_READ_WRITE_DELETE, &hkeyInstance, NULL, NULL);
if (S_OK == hr) { DWORD dwNewCharacter; COMPONENT_INSTALL_PARAMS Params; ZeroMemory (&Params, sizeof (Params));
Params.Class = pComponent->Class(); Params.pszInfId = pComponent->m_pszInfId;
hr = HrCiInstallComponent (Params, NULL, &dwNewCharacter);
// The driver could not be selected because
// this component's section or inf is missing.
// We will remove the component in this case.
//
if (SPAPI_E_NO_DRIVER_SELECTED == hr) { pComponent->Refs.RemoveAllReferences();
hr = m_pNetConfig->ModifyCtx. HrRemoveComponentIfNotReferenced (pComponent, NULL, NULL); } else if (S_OK == hr) { pComponent->m_dwCharacter = dwNewCharacter;
AddOrRemoveDontExposeLowerCharacteristicIfNeeded ( pComponent);
hr = m_pNetConfig->ModifyCtx.HrUpdateComponent ( pComponent, dwSetupFlags, dwUpgradeFromBuildNo); } RegCloseKey (hkeyInstance); } }
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "UpdateNonEnumeratedComponent"); return S_OK; }
STDMETHODIMP CImplINetCfg::EnumeratedComponentRemoved ( IN PCWSTR pszPnpId) { HRESULT hr;
Assert (pszPnpId);
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK | IF_ALLOW_INSTALL_OR_REMOVE);
if (S_OK == hr) { CComponent* pComponent;
Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
pComponent = m_pNetConfig->Core.Components. PFindComponentByPnpId (pszPnpId);
// If we found it, remove it. Otherwise our work here is done.
//
if (pComponent) { hr = m_pNetConfig->ModifyCtx. HrRemoveComponentIfNotReferenced (pComponent, NULL, NULL); }
Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "EnumeratedComponentRemoved"); return hr; }
//+---------------------------------------------------------------------------
// INetCfgSpecialCase -
//
STDMETHODIMP CImplINetCfg::GetAdapterOrder ( OUT DWORD* pcAdapters, OUT INetCfgComponent*** papAdapters, OUT BOOL* pfWanAdaptersFirst) { return E_NOTIMPL; }
STDMETHODIMP CImplINetCfg::SetAdapterOrder ( IN DWORD cAdapters, IN INetCfgComponent** apAdapters, IN BOOL fWanAdaptersFirst) { return E_NOTIMPL; }
STDMETHODIMP CImplINetCfg::GetWanAdaptersFirst ( OUT BOOL* pfWanAdaptersFirst) { HRESULT hr;
// Validate parameters.
//
if (FBadOutPtr (pfWanAdaptersFirst)) { hr = E_POINTER; } else { hr = HrLockAndTestForValidInterface (IF_DEFAULT); if (S_OK == hr) { *pfWanAdaptersFirst = m_pNetConfig->Core. StackTable.m_fWanAdaptersFirst;
Unlock(); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::GetWanAdaptersFirst"); return hr; }
STDMETHODIMP CImplINetCfg::SetWanAdaptersFirst ( IN BOOL fWanAdaptersFirst) { HRESULT hr;
hr = HrLockAndTestForValidInterface (IF_NEED_WRITE_LOCK); if (S_OK == hr) { Assert (m_pNetConfig->ModifyCtx.m_fPrepared);
m_pNetConfig->Core.StackTable.SetWanAdapterOrder (!!fWanAdaptersFirst);
Unlock(); } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::SetWanAdaptersFirst"); return hr; }
//+---------------------------------------------------------------------------
// INetCfgPnpReconfigCallback -
//
STDMETHODIMP CImplINetCfg::SendPnpReconfig ( IN NCPNP_RECONFIG_LAYER Layer, IN PCWSTR pszUpper, IN PCWSTR pszLower, IN PVOID pvData, IN DWORD dwSizeOfData) { HRESULT hr;
if ((NCRL_NDIS != Layer) && (NCRL_TDI != Layer)) { hr = E_INVALIDARG; } else if (FBadInPtr(pszUpper) || FBadInPtr(pszLower) || IsBadReadPtr(pvData, dwSizeOfData)) { hr = E_POINTER; } else { BOOL fOk; UNICODE_STRING LowerString; UNICODE_STRING UpperString; UNICODE_STRING BindList; WCHAR szLower [_MAX_PATH];
hr = S_OK;
*szLower = 0; if (*pszLower) { wcscpy (szLower, L"\\Device\\"); wcsncat (szLower, pszLower, celems(szLower) - wcslen(szLower)); }
RtlInitUnicodeString (&LowerString, szLower); RtlInitUnicodeString (&UpperString, pszUpper); RtlInitUnicodeString (&BindList, NULL);
fOk = NdisHandlePnPEvent ( (NCRL_NDIS == Layer) ? NDIS : TDI, RECONFIGURE, &LowerString, &UpperString, &BindList, pvData, dwSizeOfData);
if (!fOk) { hr = HrFromLastWin32Error (); } } TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfg::SendPnpReconfig"); return hr; }
//+---------------------------------------------------------------------------
// CImplINetCfgHolder -
//
VOID CImplINetCfgHolder::HoldINetCfg ( CImplINetCfg* pINetCfg) { Assert(pINetCfg); AddRefObj (pINetCfg->GetUnknown()); m_pINetCfg = pINetCfg; }
HRESULT CImplINetCfgHolder::HrLockAndTestForValidInterface ( DWORD dwFlags) { HRESULT hr;
Lock();
hr = m_pINetCfg->HrIsValidInterface (dwFlags);
if (S_OK != hr) { Unlock(); }
TraceHr (ttidError, FAL, hr, FALSE, "CImplINetCfgHolder::HrLockAndTestForValidInterface"); return hr; }
|