ReactOS  0.4.15-dev-3308-g9455def
FxChildList Class Reference

#include <fxchildlist.hpp>

Inheritance diagram for FxChildList:
Collaboration diagram for FxChildList:

Public Member Functions

WDFCHILDLIST GetHandle (VOID)
 
MxEventGetScanEvent (VOID)
 
WDFDEVICE GetDevice (VOID)
 
CfxDeviceGetDeviceFromId (__inout PWDF_CHILD_RETRIEVE_INFO Info)
 
_Must_inspect_result_ NTSTATUS GetAddressDescription (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, __out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription)
 
VOID GetAddressDescriptionFromEntry (__in FxDeviceDescriptionEntry *Entry, __out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription)
 
VOID BeginScan (__out_opt PULONG ScanTag=NULL)
 
VOID EndScan (__inout_opt PULONG ScanTag=NULL)
 
VOID CancelScan (__in BOOLEAN EndTheScan, __inout_opt PULONG ScanTag)
 
VOID BeginIteration (__inout PWDF_CHILD_LIST_ITERATOR Iterator)
 
VOID EndIteration (__inout PWDF_CHILD_LIST_ITERATOR Iterator)
 
VOID InitIterator (__inout PWDF_CHILD_LIST_ITERATOR Iterator)
 
_Must_inspect_result_ NTSTATUS GetNextDevice (__out WDFDEVICE *Device, __inout PWDF_CHILD_LIST_ITERATOR Iterator, __inout_opt PWDF_CHILD_RETRIEVE_INFO Info)
 
WDFDEVICE GetNextStaticDevice (__in WDFDEVICE PreviousDevice, __in ULONG Flags)
 
BOOLEAN IsScanCancelled (__in PULONG ScanTag)
 
_Must_inspect_result_ NTSTATUS UpdateAsMissing (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Description)
 
_Must_inspect_result_ NTSTATUS UpdateDeviceAsMissing (__in CfxDevice *Device)
 
VOID ReenumerateEntry (__inout FxDeviceDescriptionEntry *Entry)
 
VOID UpdateAllAsPresent (__in_opt PULONG ScanTag=NULL)
 
_Must_inspect_result_ NTSTATUS Add (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription, __in_opt PULONG ScanTag=NULL)
 
VOID UpdateAddressDescriptionFromEntry (__inout FxDeviceDescriptionEntry *Entry, __in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription)
 
BOOLEAN HasAddressDescriptions (VOID)
 
ULONG GetAddressDescriptionSize (VOID)
 
ULONG GetIdentificationDescriptionSize (VOID)
 
VOID CopyId (__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
 
_Must_inspect_result_ NTSTATUS ProcessBusRelations (__inout PDEVICE_RELATIONS *DeviceRelations)
 
VOID InvokeReportedMissingCallback (VOID)
 
VOID PostParentToD0 (VOID)
 
VOID IndicateWakeStatus (__in NTSTATUS WakeWakeStatus)
 
VOID ScanForChildren (VOID)
 
VOID NotifyDeviceSurpriseRemove (VOID)
 
VOID NotifyDeviceRemove (__inout PLONG ChildCount)
 
BOOLEAN IsStaticList (VOID)
 
ULONG GetScanCount (VOID)
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Static Public Member Functions

static _Must_inspect_result_ NTSTATUS _CreateAndInit (__out FxChildList **ChildList, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES ListAttributes, __in size_t TotalDescriptionSize, __in CfxDevice *Device, __in PWDF_CHILD_LIST_CONFIG ListConfig, __in BOOLEAN Static=FALSE)
 
static _Must_inspect_result_ NTSTATUS _ValidateConfig (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_CHILD_LIST_CONFIG Config, __in size_t *TotalDescriptionSize)
 
static _Must_inspect_result_ NTSTATUS _ComputeTotalDescriptionSize (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_CHILD_LIST_CONFIG Config, __in size_t *TotalDescriptionSize)
 
static size_t _ComputeRelationsSize (__in ULONG Count)
 
static FxChildList_FromEntry (__in FxTransactionedEntry *Entry)
 
- Static Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Public Attributes

FxTransactionedEntry m_TransactionLink
 

Protected Member Functions

 FxChildList (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in size_t TotalDescriptionSize, __in CfxDevice *Device, __in BOOLEAN Static)
 
virtual BOOLEAN Dispose (VOID)
 
VOID Initialize (__in PWDF_CHILD_LIST_CONFIG Config)
 
BOOLEAN ReenumerateEntryLocked (__inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
 
BOOLEAN CloneEntryLocked (__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
 
VOID ProcessModificationsLocked (__inout PLIST_ENTRY FreeListHead)
 
VOID MarkDescriptionNotPresentWorker (__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
 
VOID MarkModificationNotPresentWorker (__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *ModificationEntry)
 
VOID DrainFreeListHead (__inout PLIST_ENTRY FreeListHead)
 
FxDeviceDescriptionEntrySearchBackwardsForMatchingModificationLocked (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
 
FxDeviceDescriptionEntrySearchBackwardsForMatchingDescriptionLocked (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
 
_Must_inspect_result_ NTSTATUS VerifyDescriptionEntry (__in PLIST_ENTRY Entry)
 
_Must_inspect_result_ NTSTATUS VerifyModificationEntry (__in PLIST_ENTRY Entry)
 
BOOLEAN CreateDevice (__inout FxDeviceDescriptionEntry *Entry, __inout PBOOLEAN InvalidateRelations)
 
_Must_inspect_result_ NTSTATUS DuplicateId (__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
 
BOOLEAN CompareId (__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Lhs, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Rhs)
 
_Must_inspect_result_ NTSTATUS DuplicateAddress (__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
 
VOID CopyAddress (__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
 
VOID CleanupDescriptions (__in_opt PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdDescription, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddrDescription)
 
- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 

Protected Attributes

size_t m_TotalDescriptionSize
 
ULONG m_IdentificationDescriptionSize
 
ULONG m_AddressDescriptionSize
 
FxChildListCreateDeviceCallback m_EvtCreateDevice
 
FxChildListScanForChildrenCallback m_EvtScanForChildren
 
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY m_EvtIdentificationDescriptionCopy
 
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE m_EvtIdentificationDescriptionDuplicate
 
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP m_EvtIdentificationDescriptionCleanup
 
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE m_EvtIdentificationDescriptionCompare
 
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY m_EvtAddressDescriptionCopy
 
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE m_EvtAddressDescriptionDuplicate
 
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP m_EvtAddressDescriptionCleanup
 
PFN_WDF_CHILD_LIST_DEVICE_REENUMERATED m_EvtChildListDeviceReenumerated
 
KSPIN_LOCK m_ListLock
 
LIST_ENTRY m_DescriptionListHead
 
LIST_ENTRY m_ModificationListHead
 
FxChildListState m_State
 
BOOLEAN m_InvalidationNeeded
 
BOOLEAN m_StaticList
 
BOOLEAN m_IsAdded
 
UCHAR m_EnumRetries
 
PULONG m_ScanTag
 
ULONG m_ScanCount
 
MxEvent m_ScanEvent
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Friends

struct FxDeviceDescriptionEntry
 

Additional Inherited Members

- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 

Detailed Description

Definition at line 102 of file fxchildlist.hpp.

Constructor & Destructor Documentation

◆ FxChildList()

FxChildList::FxChildList ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in size_t  TotalDescriptionSize,
__in CfxDevice Device,
__in BOOLEAN  Static 
)
protected

Definition at line 298 of file fxchildlist.cpp.

303  :
304  FxNonPagedObject(FX_TYPE_CHILD_LIST,sizeof(FxChildList), FxDriverGlobals),
305  m_TotalDescriptionSize(TotalDescriptionSize),
306  m_EvtCreateDevice(FxDriverGlobals),
307  m_EvtScanForChildren(FxDriverGlobals)
308 {
309  //
310  // Transaction link into list of FxChildList pointers maintained by
311  // FxDevice's pnp package.
312  //
314 
315  m_Device = Device;
316 
319 
324 
328 
332 
334 
337  m_IsAdded = FALSE;
338 
339  m_EnumRetries = 0;
340 
341  m_ScanTag = NULL;
342  m_ScanCount = 0;
343 
344  //
345  // We want all waiters on the event to be satisfied, not just the first one
346  //
348 
350 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
FxNonPagedObject(__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY m_EvtIdentificationDescriptionCopy
pInit Pdo Static
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE m_EvtAddressDescriptionDuplicate
BOOLEAN m_InvalidationNeeded
#define TRUE
Definition: types.h:120
FxChildListScanForChildrenCallback m_EvtScanForChildren
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY m_EvtAddressDescriptionCopy
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP m_EvtAddressDescriptionCleanup
VOID SetTransactionedObject(__in FxObject *Object)
PULONG m_ScanTag
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP m_EvtIdentificationDescriptionCleanup
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
#define FALSE
Definition: types.h:117
KSPIN_LOCK m_ListLock
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
FxTransactionedEntry m_TransactionLink
UCHAR m_EnumRetries
MxEvent m_ScanEvent
BOOLEAN m_IsAdded
FxChildListCreateDeviceCallback m_EvtCreateDevice
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE m_EvtIdentificationDescriptionCompare
ULONG m_AddressDescriptionSize
ULONG m_ScanCount
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
FxChildListState m_State
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
size_t m_TotalDescriptionSize
#define NULL
Definition: types.h:112
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE m_EvtIdentificationDescriptionDuplicate
ULONG m_IdentificationDescriptionSize
BOOLEAN m_StaticList

Referenced by _CreateAndInit().

Member Function Documentation

◆ _ComputeRelationsSize()

static size_t FxChildList::_ComputeRelationsSize ( __in ULONG  Count)
inlinestatic

Definition at line 361 of file fxchildlist.hpp.

364  {
365  if (Count == 0) {
366  return sizeof(((PDEVICE_RELATIONS) NULL)->Count);
367  }
368  else {
369  return sizeof(DEVICE_RELATIONS) + (Count-1)*sizeof(PDEVICE_OBJECT);
370  }
371  }
struct _DEVICE_OBJECT * PDEVICE_OBJECT
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
int Count
Definition: noreturn.cpp:7
struct _DEVICE_RELATIONS DEVICE_RELATIONS
#define NULL
Definition: types.h:112

Referenced by FxPkgPnp::HandleQueryDeviceRelations(), and ProcessBusRelations().

◆ _ComputeTotalDescriptionSize()

_Must_inspect_result_ NTSTATUS FxChildList::_ComputeTotalDescriptionSize ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_CHILD_LIST_CONFIG  Config,
__in size_t TotalDescriptionSize 
)
static

Definition at line 3194 of file fxchildlist.cpp.

3199 {
3200  size_t addressAligned, idAligned;
3201  NTSTATUS status;
3202 
3203  *TotalDescriptionSize = 0;
3204 
3205  //
3206  // FxDeviceDescriptionEntry::operator new() will allocate a block of memory
3207  // that is
3208  // size =
3209  // WDF_ALIGN_SIZE_UP(sizeof(FxDeviceDescriptionEntry), sizeof(PVOID)) +
3210  // WDF_ALIGN_SIZE_UP(AddressDescriptionSize, sizeof(PVOID)) +
3211  // WDF_ALIGN_SIZE_UP(IdentificationDescriptionSize, sizeof(PVOID));
3212  //
3213  // Validate the size now beforehand, not every we allocate
3214  //
3215  //
3216  // Test for overflow
3217  //
3218  idAligned = WDF_ALIGN_SIZE_UP(Config->IdentificationDescriptionSize,
3219  sizeof(PVOID));
3220  if (idAligned < Config->IdentificationDescriptionSize) {
3223  "Config->IdentificationDescriptionSize %d too large"
3224  "%!STATUS!", Config->IdentificationDescriptionSize,
3225  status);
3226  return status;
3227  }
3228 
3229  addressAligned = WDF_ALIGN_SIZE_UP(Config->AddressDescriptionSize,
3230  sizeof(PVOID));
3231  if (addressAligned < Config->AddressDescriptionSize) {
3234  "Config->AddressDescriptionSize %d too large, %!STATUS!",
3235  Config->AddressDescriptionSize, status);
3236  return status;
3237  }
3238 
3239  status = RtlSizeTAdd(
3241  idAligned,
3242  TotalDescriptionSize
3243  );
3244  if (!NT_SUCCESS(status)) {
3246  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
3247  "Could not add ID description size to block size, %!STATUS!",
3248  status);
3249  return status;
3250  }
3251 
3252  status = RtlSizeTAdd(*TotalDescriptionSize,
3253  addressAligned,
3254  TotalDescriptionSize);
3255  if (!NT_SUCCESS(status)) {
3257  FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
3258  "Could not add address description size to block size, %!STATUS!",
3259  status);
3260  return status;
3261  }
3262 
3263  return STATUS_SUCCESS;
3264 }
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
description Header IdentificationDescriptionSize
Definition: ps.c:97

Referenced by _ValidateConfig(), FxPkgFdo::CreateDefaultDeviceList(), and FxPkgFdo::Initialize().

◆ _CreateAndInit()

_Must_inspect_result_ NTSTATUS FxChildList::_CreateAndInit ( __out FxChildList **  ChildList,
__in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_OBJECT_ATTRIBUTES  ListAttributes,
__in size_t  TotalDescriptionSize,
__in CfxDevice Device,
__in PWDF_CHILD_LIST_CONFIG  ListConfig,
__in BOOLEAN  Static = FALSE 
)
static

Definition at line 367 of file fxchildlist.cpp.

376 {
377  NTSTATUS ntStatus;
378  FxChildList *childList = NULL;
379 
380  //
381  // Initialize
382  //
383  *ChildList = NULL;
384 
385  //
386  // Allocate a new child list object
387  //
388  childList = new(FxDriverGlobals, ListAttributes)
389  FxChildList(FxDriverGlobals, TotalDescriptionSize, Device, Static);
390  if (childList == NULL) {
393  "No memory for WDFCHILDLIST handle, %!STATUS!",
394  ntStatus);
395  goto exit;
396  }
397 
398  //
399  // Initialize the child list object
400  //
401  childList->Initialize(ListConfig);
402 
403  *ChildList = childList;
404  ntStatus = STATUS_SUCCESS;
405 
406 exit:
407  if (!NT_SUCCESS(ntStatus)) {
408  if (NULL != childList) {
409  childList->DeleteFromFailedCreate();
410  }
411  }
412  return ntStatus;
413 }
Definition: window.h:584
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
FxChildList(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in size_t TotalDescriptionSize, __in CfxDevice *Device, __in BOOLEAN Static)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID Initialize(__in PWDF_CHILD_LIST_CONFIG Config)
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:474
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
#define STATUS_SUCCESS
Definition: shellext.h:65
void exit(int exitcode)
Definition: _exit.c:33

Referenced by FxPkgFdo::CreateDefaultDeviceList(), and FxPkgFdo::Initialize().

◆ _FromEntry()

static FxChildList* FxChildList::_FromEntry ( __in FxTransactionedEntry Entry)
inlinestatic

Definition at line 375 of file fxchildlist.hpp.

378  {
380  }
FxTransactionedEntry m_TransactionLink
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
base of all file and directory entries
Definition: entries.h:82

Referenced by FxPkgPnp::ChildListNotifyRemove(), FxPkgPnp::HandleQueryBusRelations(), and FxPkgPnp::PnpEventSurpriseRemovePendingOverload().

◆ _ValidateConfig()

_Must_inspect_result_ NTSTATUS FxChildList::_ValidateConfig ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in PWDF_CHILD_LIST_CONFIG  Config,
__in size_t TotalDescriptionSize 
)
static

Definition at line 3150 of file fxchildlist.cpp.

3155 {
3156  NTSTATUS status;
3157 
3158  if (Config == NULL) {
3161  "Invalid Config, NULL is not allowed, %!STATUS!", status);
3162  return status;
3163  }
3164 
3165  if (Config->Size != sizeof(WDF_CHILD_LIST_CONFIG)) {
3168  "Config->Size incorrect, expected %d, got %d, %!STATUS!",
3169  sizeof(WDF_CHILD_LIST_CONFIG), Config->Size, status);
3170  return status;
3171  }
3172  if (Config->IdentificationDescriptionSize == 0) {
3175  "Config->IdentificationDescriptionSize must be non zero, "
3176  "%!STATUS!", status);
3177  return status;
3178  }
3179  if (Config->EvtChildListCreateDevice == NULL) {
3182  "Config->EvtChildListCreateDevice, NULL is not allowed, "
3183  "%!STATUS!", status);
3184  return status;
3185  }
3186 
3187  return _ComputeTotalDescriptionSize(FxDriverGlobals,
3188  Config,
3189  TotalDescriptionSize);
3190 }
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
static _Must_inspect_result_ NTSTATUS _ComputeTotalDescriptionSize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_CHILD_LIST_CONFIG Config, __in size_t *TotalDescriptionSize)
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ Add()

_Must_inspect_result_ NTSTATUS FxChildList::Add ( __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER  IdentificationDescription,
__in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  AddressDescription,
__in_opt PULONG  ScanTag = NULL 
)

Definition at line 1488 of file fxchildlist.cpp.

1493 {
1494  LIST_ENTRY freeHead;
1495  KIRQL irql;
1496  NTSTATUS status;
1498  BOOLEAN allocNewEntry;
1499 
1500  if (ScanTag != NULL) {
1501  if (*ScanTag != ScanTagActive) {
1502  ASSERT(*ScanTag == ScanTagCancelled);
1503 
1504  //
1505  // The descriptions are duplicated if needed, so no need to clean
1506  // them up
1507  //
1508  // CleanupDescriptions(IdentificationDescription,
1509  // AddressDescription);
1510 
1511  return STATUS_CANCELLED;
1512  }
1513  }
1514 
1516  allocNewEntry = FALSE;
1517  InitializeListHead(&freeHead);
1518 
1520 
1523  );
1524 
1525  if (pEntry != NULL) {
1526  switch (pEntry->m_ModificationState) {
1527  case ModificationInsert:
1528  if (HasAddressDescriptions()) {
1529  CopyAddress(pEntry->m_AddressDescription,
1531  }
1532 
1533  //
1534  // There is already a pending insert operation. All we need do is
1535  // update the stored description.
1536  //
1537  pEntry->m_FoundInLastScan = TRUE;
1538 
1540  break;
1541 
1542  case ModificationRemove:
1544  //
1545  // We found a pending remove. Therefore we need to add an insert
1546  // operation to the end of the mod list.
1547  //
1548  allocNewEntry = TRUE;
1549  break;
1550 
1551  default:
1552  ASSERTMSG("Invalid description modification state\n", FALSE);
1553  break;
1554  }
1555  }
1556  else {
1557  //
1558  // There are no matching modifications queued in the list. Go examine
1559  // the main list. We can't modify any of the child links right now
1560  // because the list might be locked down, but it is scannable!
1561  //
1564  );
1565 
1566  if (pEntry != NULL && pEntry->IsPresent()) {
1567  //
1568  // This is an update. Enqueue it through this node.
1569  //
1570  ASSERT(pEntry->m_ModificationState == ModificationUnspecified);
1571 
1572  if (HasAddressDescriptions()) {
1573  CopyAddress(pEntry->m_AddressDescription,
1575  }
1576 
1577  pEntry->m_FoundInLastScan = TRUE;
1579  }
1580  else {
1581  //
1582  // Either no entry was found, or a "missing" entry was identified
1583  // instead. In both cases we need to add an insert operation to the
1584  // end of the modification list.
1585  //
1586  allocNewEntry = TRUE;
1587  }
1588  }
1589 
1590  if (allocNewEntry) {
1591 
1592  pEntry =
1597 
1598  if (pEntry != NULL) {
1599  status = DuplicateId(pEntry->m_IdentificationDescription,
1601 
1603  status = DuplicateAddress(pEntry->m_AddressDescription,
1605  }
1606 
1607  if (NT_SUCCESS(status)) {
1608  pEntry->m_FoundInLastScan = TRUE;
1610  &pEntry->m_ModificationLink);
1611 
1612  if (m_StaticList) {
1613  FxDevice* pPdo;
1614 
1615  pPdo = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
1617  Header)->Pdo;
1618 
1619  //
1620  // The device is no longer deletable by the driver writer
1621  //
1622  pPdo->MarkNoDeleteDDI();
1623 
1624  //
1625  // Plug in the description like we do for dynamic PDOs in
1626  // FxPkgPdo::Initialize.
1627  //
1629 
1630  //
1631  // Let the device know it was inserted into the list. This
1632  // used to know in pPdo::DeleteObject how to proceed.
1633  //
1635  }
1636  }
1637  else {
1638  InsertTailList(&freeHead, &pEntry->m_DescriptionLink);
1639  }
1640  }
1641  else {
1643  }
1644  }
1645 
1646  ProcessModificationsLocked(&freeHead);
1647 
1649 
1650  DrainFreeListHead(&freeHead);
1651 
1652  return status;
1653 }
FxDeviceDescriptionEntry * SearchBackwardsForMatchingDescriptionLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
BOOLEAN HasAddressDescriptions(VOID)
LIST_ENTRY m_ModificationListHead
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
FxDeviceDescriptionEntry * SearchBackwardsForMatchingModificationLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
#define TRUE
Definition: types.h:120
_Must_inspect_result_ NTSTATUS DuplicateAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
FxDevice * pPdo
KIRQL irql
Definition: wave.h:1
BOOLEAN m_AddedToStaticList
Definition: fxpkgpdo.hpp:63
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ NTSTATUS DuplicateId(__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
#define FALSE
Definition: types.h:117
Definition: Header.h:8
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
friend struct FxDeviceDescriptionEntry
_Inout_ PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription
Definition: wdfchildlist.h:255
unsigned char BOOLEAN
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription
Definition: wdfchildlist.h:124
__inline FxPkgPdo * GetPdoPkg(VOID)
Definition: fxdevice.hpp:1254
ULONG m_AddressDescriptionSize
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
FxDeviceDescriptionEntry * m_Description
Definition: fxpkgpdo.hpp:40
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
size_t m_TotalDescriptionSize
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
ULONG m_IdentificationDescriptionSize
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static SERVICE_STATUS status
Definition: service.c:31
BOOLEAN m_StaticList
Definition: ps.c:97

◆ BeginIteration()

VOID FxChildList::BeginIteration ( __inout PWDF_CHILD_LIST_ITERATOR  Iterator)

Definition at line 820 of file fxchildlist.cpp.

823 {
824  KIRQL irql;
825 
826  //
827  // Almost the same semantic as BeginScan except we don't mark all of the
828  // children as missing when we start.
829  //
831 
833  //
834  // Set the scanevent to non-signaled state. Some code paths such as
835  // PDO eject will wait for the completion of child list iteration or scan
836  // so that a QDR that follows eject is guaranteed to pick up the change in
837  // PDO state that the code path made. Note that scan and iteration can be
838  // nested and in that case this event will be clear each time but it will be
839  // set (signalled) only after all the iteration and scan opeartions have
840  // completed.
841  //
842  m_ScanEvent.Clear();
843  m_ScanCount++;
844 
846  "Begin iteration on WDFCHILDLIST %p, scan count %d",
848 
850 }
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
KSPIN_LOCK m_ListLock
__inline VOID Clear()
Definition: mxeventkm.h:102
MxEvent m_ScanEvent
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:653
WDFCHILDLIST GetHandle(VOID)
ULONG m_ScanCount
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID InitIterator(__inout PWDF_CHILD_LIST_ITERATOR Iterator)

◆ BeginScan()

VOID FxChildList::BeginScan ( __out_opt PULONG  ScanTag = NULL)

Definition at line 555 of file fxchildlist.cpp.

558 {
561  KIRQL irql;
562 
564 
565  // KeClearEvent is faster than KeResetEvent for putting event to not-signaled state
566  m_ScanEvent.Clear();
567  m_ScanCount++;
568 
571  "Begin scan on WDFCHILDLIST %p, scan count %d",
573 
574  if (ScanTag != NULL) {
575  if (m_ScanTag != NULL) {
577  }
578 
579  *ScanTag = ScanTagActive;
580  m_ScanTag = ScanTag;
581  }
582 
583  //
584  // Start by walking over all entries and setting their FoundInLastScan
585  // fields to FALSE. We need to set both present items in the Desc list
586  // and inserts in the Mod list. It's actually easier just to walk over
587  // everything.
588  //
591  ple = ple->Flink) {
593  pEntry->m_FoundInLastScan = FALSE;
594  }
595 
598  ple = ple->Flink) {
600  pEntry->m_FoundInLastScan = FALSE;
601  }
602 
604 }
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
PULONG m_ScanTag
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
KSPIN_LOCK m_ListLock
__inline VOID Clear()
Definition: mxeventkm.h:102
MxEvent m_ScanEvent
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
WDFCHILDLIST GetHandle(VOID)
ULONG m_ScanCount
Definition: typedefs.h:119
#define TRACINGPNP
Definition: dbgtrace.h:67
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

◆ CancelScan()

VOID FxChildList::CancelScan ( __in BOOLEAN  EndTheScan,
__inout_opt PULONG  ScanTag 
)

Definition at line 795 of file fxchildlist.cpp.

799 {
800  *ScanTag = ScanTagCancelled;
801 
802  if (EndTheScan) {
803  EndScan(ScanTag);
804  }
805 }
VOID EndScan(__inout_opt PULONG ScanTag=NULL)

◆ CleanupDescriptions()

VOID FxChildList::CleanupDescriptions ( __in_opt PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER  IdDescription,
__in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  AddrDescription 
)
inlineprotected

Definition at line 544 of file fxchildlist.hpp.

548  {
549  if (m_EvtAddressDescriptionCleanup != NULL && AddrDescription != NULL) {
550  m_EvtAddressDescriptionCleanup(GetHandle(), AddrDescription);
551  }
552 
553  if (m_EvtIdentificationDescriptionCleanup != NULL && IdDescription != NULL) {
555  }
556  }
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP m_EvtAddressDescriptionCleanup
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP m_EvtIdentificationDescriptionCleanup
WDFCHILDLIST GetHandle(VOID)
#define NULL
Definition: types.h:112

Referenced by DrainFreeListHead().

◆ CloneEntryLocked()

BOOLEAN FxChildList::CloneEntryLocked ( __inout PLIST_ENTRY  FreeListHead,
__inout FxDeviceDescriptionEntry Entry,
__in BOOLEAN  FromQDR 
)
protected

Definition at line 1675 of file fxchildlist.cpp.

1680 {
1681  FxDeviceDescriptionEntry* pClone;
1682  BOOLEAN invalidateRelations;
1683 
1686  "attempting to clone PDO WDFDEVICE %p, !devobj %p, From QDR %d",
1687  Entry->m_Pdo->GetHandle(), Entry->m_Pdo->GetDeviceObject(), FromQDR);
1688 
1689  invalidateRelations = FALSE;
1690 
1691  pClone = Entry->Clone(FreeListHead);
1692 
1693  if (pClone != NULL) {
1694  //
1695  // Check to see if the driver writer OKs the cloning, aka
1696  // reenumeration.
1697  //
1700  GetHandle(),
1701  Entry->m_Pdo->GetHandle(),
1702  Entry->m_AddressDescription,
1703  pClone->m_AddressDescription) == FALSE){
1704  //
1705  // The clone will be freed later by the caller by placing
1706  // it on the free list.
1707  //
1708  InsertTailList(FreeListHead, &pClone->m_DescriptionLink);
1709  }
1710  else {
1713  "clone successful (new entry is %p), marking PDO "
1714  "WDFDEVICE %p, !devobj %p as missing", pClone,
1715  Entry->m_Pdo->GetHandle(), Entry->m_Pdo->GetDeviceObject());
1716 
1717  //
1718  // Setup the state of the clone
1719  //
1722 
1723  //
1724  // This is important that this is last. If a subsequent
1725  // modification arrives for this device, we want to find the
1726  // clone before the old device. Since all changes search the
1727  // list backwards, inserting at the tail accomplishes this.
1728  //
1730  &pClone->m_DescriptionLink);
1731 
1732  if (FromQDR == FALSE) {
1733  Entry->m_DescriptionState = DescriptionNotPresent;
1734  invalidateRelations = TRUE;
1735  }
1736  }
1737  }
1738  else {
1739  //
1740  // Could not allocate a clone, do not anything.
1741  //
1742  DO_NOTHING();
1743  }
1744 
1745  //
1746  // Convert the original device's modification state back to a
1747  // unspecified in all cases.
1748  //
1749  Entry->m_ModificationState = ModificationUnspecified;
1750 
1751  return invalidateRelations;
1752 }
LIST_ENTRY m_DescriptionListHead
#define TRUE
Definition: types.h:120
#define InsertTailList(ListHead, Entry)
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
PFN_WDF_CHILD_LIST_DEVICE_REENUMERATED m_EvtChildListDeviceReenumerated
unsigned char BOOLEAN
FxChildListModificationState m_ModificationState
FxChildListDescriptionState m_DescriptionState
PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER m_AddressDescription
WDFCHILDLIST GetHandle(VOID)
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82
#define DO_NOTHING()
Definition: mxgeneral.h:32

Referenced by ProcessBusRelations(), and ProcessModificationsLocked().

◆ CompareId()

Definition at line 492 of file fxchildlist.hpp.

496  {
499  Lhs,
500  Rhs);
501  }
502  else {
504  RtlCompareMemory(Lhs,
505  Rhs,
507  : FALSE;
508  }
509  }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
WDFCHILDLIST GetHandle(VOID)
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE m_EvtIdentificationDescriptionCompare
#define NULL
Definition: types.h:112
ULONG m_IdentificationDescriptionSize
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by SearchBackwardsForMatchingDescriptionLocked(), and SearchBackwardsForMatchingModificationLocked().

◆ CopyAddress()

VOID FxChildList::CopyAddress ( __out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  Dest,
__in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  Source 
)
inlineprotected

Definition at line 528 of file fxchildlist.hpp.

532  {
533  if (Source != NULL) {
536  }
537  else {
539  }
540  }
541  }
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY m_EvtAddressDescriptionCopy
WDFCHILDLIST GetHandle(VOID)
ULONG m_AddressDescriptionSize
#define NULL
Definition: types.h:112
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167

Referenced by Add(), GetAddressDescription(), GetAddressDescriptionFromEntry(), GetDeviceFromId(), GetNextDevice(), and UpdateAddressDescriptionFromEntry().

◆ CopyId()

Definition at line 273 of file fxchildlist.hpp.

277  {
280  }
281  else {
283  }
284  }
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY m_EvtIdentificationDescriptionCopy
WDFCHILDLIST GetHandle(VOID)
#define NULL
Definition: types.h:112
ULONG m_IdentificationDescriptionSize
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167

Referenced by GetNextDevice().

◆ CreateDevice()

BOOLEAN FxChildList::CreateDevice ( __inout FxDeviceDescriptionEntry Entry,
__inout PBOOLEAN  InvalidateRelations 
)
protected

Definition at line 2251 of file fxchildlist.cpp.

2255 {
2257  NTSTATUS status;
2258  KIRQL irql;
2259 
2260  init.CreatedOnStack = TRUE;
2261  init.SetPdo(m_Device);
2262  init.Pdo.DescriptionEntry = Entry;
2263 
2264  if (m_StaticList) {
2265  init.CreatedDevice =
2266  CONTAINING_RECORD(Entry->m_IdentificationDescription,
2268  Header)->Pdo;
2269  }
2270  else {
2271  //
2272  // This description needs a device, create it now.
2273  //
2275  GetHandle(), Entry->m_IdentificationDescription, &init);
2276 
2277  if (status == STATUS_RETRY) {
2278  if (init.CreatedDevice != NULL) {
2279  //
2280  // Destroy any allocations assocated with the device.
2281  //
2282  init.CreatedDevice->Destroy();
2283  }
2284 
2285  *InvalidateRelations = TRUE;
2286 
2287  return FALSE;
2288  }
2289 
2290  if (NT_SUCCESS(status)) {
2291  //
2292  // Make sure that a framework device was actually created
2293  //
2294  if (init.CreatedDevice == NULL) {
2295  //
2296  // Driver didn't actually create the device, even though its
2297  // EvtChildListCreateDevice returned a successful return code.
2298  // Change the status to indicate an error, so that we enter the
2299  // error handling code below.
2300  //
2303  "EvtChildListCreateDevice returned a successful status "
2304  "%!STATUS! but did not create a device object", status);
2305 
2307 
2309  }
2310  }
2311 
2312  if (!NT_SUCCESS(status)) {
2313  if (init.CreatedDevice != NULL) {
2315  //
2316  // Set to missing so that when the pnp machine evaluates whether the
2317  // PDO has been reported missing or not, it chooses missing and
2318  // deletes the PDO immediately.
2319  //
2320  Entry->m_DescriptionState = DescriptionReportedMissing;
2321 
2322  if (Entry->m_ModificationState != ModificationUnspecified) {
2323  //
2324  // Cannot be ModificationInsert since this device ID is already
2325  // in the list.
2326  //
2327  // Cannot be ModificationClone since the FDO for this device
2328  // is the only one who can ask for that and since PDO creation
2329  // failed, there is no FDO.
2330  //
2331  // Cannot be ModificationRemove because the list is locked
2332  // against changes and ModificationRemoveNotify becomes
2333  // ModificationRemove only after the list has been unlocked.
2334  //
2335  ASSERT(Entry->m_ModificationState == ModificationRemoveNotify);
2336 
2337  //
2338  // Remove the modification from the list. The call to
2339  // DeleteDeviceFromFailedCreate below will destroy this
2340  // Entry due to the pnp state machine deleting the PDO.
2341  //
2342  RemoveEntryList(&Entry->m_ModificationLink);
2343  }
2345 
2346  ASSERT(init.CreatedDevice->IsPnp());
2347  ASSERT(init.CreatedDevice->GetDevicePnpState() == WdfDevStatePnpInit);
2348  ASSERT(init.CreatedDevice->GetPdoPkg()->m_Description != NULL);
2349 
2350  ASSERT(Entry->m_Pdo == NULL);
2351 
2354  "WDFDEVICE %p !devobj %p created, but EvtChildListCreateDevice "
2355  "returned status %!STATUS!", init.CreatedDevice->GetHandle(),
2356  init.CreatedDevice->GetDeviceObject(), status);
2357 
2358  //
2359  // Simulate a remove event coming to the device. After this call
2360  // returns, init.CreatedDevice is no longer a valid pointer!
2361  //
2362  // Please note that DeleteDeviceFromFailedCreate just returns
2363  // the passed status back unless device is a filter, in which
2364  // case it changes it to success.
2365  //
2366  // It is not really the status of DeleteDeviceFromFailedCreate
2367  // operation, which is why we don't check it.
2368  //
2369  (void) init.CreatedDevice->DeleteDeviceFromFailedCreate(
2370  status,
2371  TRUE);
2372 
2373  init.CreatedDevice = NULL;
2374  }
2375  else {
2376  LIST_ENTRY freeHead;
2377 
2378  InitializeListHead(&freeHead);
2379 
2380  //
2381  // Add a modification that this entry is now gone. If there is
2382  // an active scan and it has added this device, there would
2383  // be no entry in the modification case list because the add
2384  // would have updated the description entry.
2385  //
2388  ProcessModificationsLocked(&freeHead);
2390 
2391  //
2392  // Free structures outside of any internal WDF lock
2393  //
2394  DrainFreeListHead(&freeHead);
2395  }
2396 
2397  return FALSE;
2398  }
2399  }
2400 
2401  //
2402  // Assign m_Pdo here once we have a fully baked and created device. We only
2403  // assign m_Pdo after we have completely initalized device because we check
2404  // for m_Pdo in PostParentToD0.
2405  //
2406  Entry->m_Pdo = init.CreatedDevice;
2407  Entry->m_DescriptionState = DescriptionInstantiatedHasObject;
2408 
2409  return TRUE;
2410 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
struct _Entry Entry
Definition: kefuncs.h:627
_Must_inspect_result_ NTSTATUS Invoke(__in WDFCHILDLIST DeviceList, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, __in PWDFDEVICE_INIT ChildInit)
Definition: fxchildlist.hpp:46
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
static int init
Definition: wintirpc.c:33
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
Definition: Header.h:8
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FxChildListCreateDeviceCallback m_EvtCreateDevice
WDFCHILDLIST GetHandle(VOID)
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID MarkDescriptionNotPresentWorker(__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER
Definition: ntstatus.h:915
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define STATUS_RETRY
Definition: udferr_usr.h:182
static SERVICE_STATUS status
Definition: service.c:31
base of all file and directory entries
Definition: entries.h:82
BOOLEAN m_StaticList
FxVerifierDbgBreakPoint(pFxDriverGlobals)
Definition: ps.c:97

Referenced by ProcessBusRelations().

◆ Dispose()

BOOLEAN FxChildList::Dispose ( VOID  )
protectedvirtual

Reimplemented from FxObject.

Definition at line 353 of file fxchildlist.cpp.

356 {
357  if (m_IsAdded) {
358  ASSERT(m_Device != NULL);
359  m_Device->RemoveChildList(this);
360  }
361 
362  return TRUE;
363 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
#define TRUE
Definition: types.h:120
BOOLEAN m_IsAdded
#define ASSERT(a)
Definition: mode.c:44
#define NULL
Definition: types.h:112
virtual VOID RemoveChildList(__inout FxChildList *List)
Definition: fxdevicekm.cpp:441

◆ DrainFreeListHead()

VOID FxChildList::DrainFreeListHead ( __inout PLIST_ENTRY  FreeListHead)
protected

Definition at line 2075 of file fxchildlist.cpp.

2078 {
2080  FxDevice* pPdo;
2081  PLIST_ENTRY pCur;
2082 
2083  while (!IsListEmpty(FreeListHead)) {
2084  pCur = RemoveHeadList(FreeListHead);
2086 
2088 
2089  //
2090  // If this is a static list and the entry has not yet been instantiated,
2091  // tell PnP to remove the device.
2092  //
2093  // There is a corner case of a static PDO being added and
2094  // immediately marked as missing before it has a chance to move to
2095  // description list. This case is handled here by checking the
2096  // modification state of ModificationNeedsPnpRemoval. Fx cannot just
2097  // delete the description because there is a driver-created PDO
2098  // associated with the description and it needs to be cleaned up.
2099  //
2100  if (m_StaticList &&
2101  (pEntry->m_DescriptionState == DescriptionPresentNeedsInstantiation ||
2102  pEntry->m_ModificationState == ModificationNeedsPnpRemoval )) {
2103 
2104  pPdo = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
2106  Header)->Pdo;
2107 
2108  //
2109  // The pnp removal path expects that there is no modifcation pending
2110  // when removing the description.
2111  //
2112  if (pEntry->m_ModificationState == ModificationNeedsPnpRemoval) {
2113  ASSERT(pEntry->m_DescriptionState == DescriptionUnspecified);
2114  ASSERT(IsListEmpty(&pEntry->m_ModificationLink));
2115 
2116  pEntry->m_ModificationState = ModificationUnspecified;
2117  }
2118 
2119  //
2120  // Change the state to reported missing (which is what we are basically
2121  // simulating here anyways) so that when we process the entry again
2122  // when the PDO really goes away we cleanup the entry.
2123  //
2124  // Also, when posting PnpEventRemove to the child, child will
2125  // call FxDeviceDescriptionEntry::IsDeviceRemoved which checks for
2126  // reported missing before reporting if the device has been removed
2127  // (and we want the device to be reported as removed).
2128  //
2129  pEntry->m_DescriptionState = DescriptionReportedMissing;
2130 
2131  //
2132  // Not yet reported to PnP, so it should be in the initial state
2133  //
2135 
2136  //
2137  // m_Description should be set when the FxPkgPdo was created
2138  //
2140 
2141  //
2142  // Since the pPdo->m_PkgPnp->m_DeviceRemoveProcessed == NULL, the
2143  // pnp state machine will delete the PDO. We are simulating the same
2144  // situation where an FDO is in the remove path and is telling each
2145  // of its removed PDOs to delete themselves.
2146  //
2148  }
2149  else {
2150  CleanupDescriptions(pEntry->m_IdentificationDescription,
2151  pEntry->m_AddressDescription);
2152 
2153  delete pEntry;
2154  }
2155  }
2156 }
VOID PnpProcessEvent(__in FxPnpEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
VOID CleanupDescriptions(__in_opt PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdDescription, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddrDescription)
FxDevice * pPdo
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
Definition: Header.h:8
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ASSERT(a)
Definition: mode.c:44
__inline FxPkgPdo * GetPdoPkg(VOID)
Definition: fxdevice.hpp:1254
__inline WDF_DEVICE_PNP_STATE GetDevicePnpState()
Definition: fxdevice.hpp:1149
Definition: typedefs.h:119
FxPkgPnp * m_PkgPnp
Definition: fxdevice.hpp:670
FxDeviceDescriptionEntry * m_Description
Definition: fxpkgpdo.hpp:40
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
SINGLE_LIST_ENTRY * pCur
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
BOOLEAN m_StaticList

Referenced by Add(), CreateDevice(), EndScan(), InvokeReportedMissingCallback(), NotifyDeviceRemove(), NotifyDeviceSurpriseRemove(), ProcessBusRelations(), FxDeviceDescriptionEntry::ProcessDeviceRemoved(), ReenumerateEntry(), UpdateAllAsPresent(), UpdateAsMissing(), and UpdateDeviceAsMissing().

◆ DuplicateAddress()

_Must_inspect_result_ NTSTATUS FxChildList::DuplicateAddress ( __out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  Dest,
__in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  Source 
)
inlineprotected

Definition at line 513 of file fxchildlist.hpp.

517  {
520  }
521  else {
523  return STATUS_SUCCESS;
524  }
525  }
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE m_EvtAddressDescriptionDuplicate
WDFCHILDLIST GetHandle(VOID)
ULONG m_AddressDescriptionSize
#define NULL
Definition: types.h:112
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by Add(), and FxDeviceDescriptionEntry::Clone().

◆ DuplicateId()

Definition at line 475 of file fxchildlist.hpp.

479  {
482  Source,
483  Dest);
484  }
485  else {
487  return STATUS_SUCCESS;
488  }
489  }
WDFCHILDLIST GetHandle(VOID)
#define NULL
Definition: types.h:112
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE m_EvtIdentificationDescriptionDuplicate
ULONG m_IdentificationDescriptionSize
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by Add(), and FxDeviceDescriptionEntry::Clone().

◆ EndIteration()

VOID FxChildList::EndIteration ( __inout PWDF_CHILD_LIST_ITERATOR  Iterator)

Definition at line 853 of file fxchildlist.cpp.

856 {
858  "end iteration on WDFCHILDLIST");
859 
860  //
861  // Semantic is exactly the same as EndScan. Basically, all changes are
862  // delayed until there are no more active scans, so the end of an interation
863  // is the same as the end of a scan.
864  //
865  EndScan();
866 
867  RtlZeroMemory(&Iterator->Reserved[0], sizeof(Iterator->Reserved));
868 }
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
VOID EndScan(__inout_opt PULONG ScanTag=NULL)
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:653
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ EndScan()

VOID FxChildList::EndScan ( __inout_opt PULONG  ScanTag = NULL)

Definition at line 607 of file fxchildlist.cpp.

610 {
611  PLIST_ENTRY pCur, pNext;
612  LIST_ENTRY freeHead;
614  KIRQL irql;
615 
616  InitializeListHead(&freeHead);
617 
619 
620  if (ScanTag != NULL) {
621  if (*ScanTag != ScanTagActive) {
622  ASSERT(*ScanTag == ScanTagCancelled);
624  return;
625  }
626 
627  *ScanTag = ScanTagFinished;
628  m_ScanTag = NULL;
629  }
630 
631  m_ScanCount--;
632 
635  "End scan on WDFCHILDLIST %p, scan count %d",
637 
638  if (m_ScanCount == 0) {
639  //
640  // Walk over all modification entries and remove any pending insert that
641  // wasn't seen in the scan. Note that MarkDescriptionNotPresentWorker will
642  // enqueue the entry to be freed later.
643  //
644  // Also, convert any clones of devices not reported as present to
645  // removal modifications so that the original is still reported missing.
646  //
649  pCur = pNext) {
650 
651  pNext = pCur->Flink;
652 
654 
657  "entry %p modified in last scan, "
658  "mod state %!FxChildListModificationState!,"
659  "desc state %!FxChildListDescriptionState!",
660  pEntry, pEntry->m_ModificationState,
661  pEntry->m_DescriptionState);
662 
663  if (pEntry->m_FoundInLastScan == FALSE) {
664  switch (pEntry->m_ModificationState) {
665  case ModificationInsert:
666  //
667  // Insertion that never made through to the end of a scan.
668  //
670  break;
671 
672  case ModificationClone:
675  "clone of PDO WDFDEVICE %p, !devobj %p dropped because "
676  "it is missing", pEntry->m_Pdo->GetHandle(),
677  pEntry->m_Pdo->GetDeviceObject());
678 
679  //
680  // We were asked for a clone in the middle of a scan and the
681  // device was not reported, so it is now missing. Convert
682  // the clone modification to a remove modification.
683  //
684  pEntry->m_ModificationState = ModificationRemoveNotify;
685 
686  //
687  // Remove the modification from the current mod list. It
688  // will be re-added below when we iterate over the
689  // descriptions list.
690  //
691  RemoveEntryList(&pEntry->m_ModificationLink);
692  InitializeListHead(&pEntry->m_ModificationLink);
693 
694  //
695  // We can only have been cloning a device which is present
696  // and not yet reported missing to the OS.
697  //
698  ASSERT(pEntry->m_DescriptionState ==
700  break;
701  }
702  }
703  }
704 
705  //
706  // Walk over all desc entries and remove anything that wasn't found in the
707  // scan. Since MarkDescriptionNotPresentWorker doesn't drain the
708  // modifications, we don't have to worry about any entries disappearing.
709  //
712  pCur = pCur->Flink) {
713 
715 
716  if (pEntry->m_PendingDeleteOnScanEnd) {
717  //
718  // The entry was pnp removed but was not removed from list
719  // because scan count was > 0. It is safe to remove and delete
720  // it now.
721 
722  // Update the current pointer before the entry is removed.
723  pCur = pCur->Blink;
724 
725  RemoveEntryList(&pEntry->m_DescriptionLink);
726  InsertTailList(&freeHead, &pEntry->m_DescriptionLink);
727  pEntry = NULL;
728  continue;
729  }
730  else if (pEntry->IsPresent() && pEntry->m_FoundInLastScan == FALSE) {
731  if (pEntry->m_Pdo != NULL) {
734  "marking PDO WDFDEVICE %p, !devobj %p as not present",
735  pEntry->m_Pdo->GetHandle(),
736  pEntry->m_Pdo->GetDeviceObject());
737 
738  }
739  else {
742  "marking PDO (entry %p) which needs instantiation as "
743  "not present", pEntry);
744  }
745 
747  }
748  }
749 
750  //
751  // Attempt to drain any mods we made.
752  //
753  ProcessModificationsLocked(&freeHead);
754 
755  //
756  // We need to check m_KnownPdo here because if this
757  // object is attached to a PDO, the PDO's devobj could be in a state where
758  // PnP does not know it is a PDO yet. m_KnownPdo
759  // is set when the PDO receives a start device and by the time start
760  // device arrives, we definitely know the PDO is known the PnP.
761  //
762  // No need to hold a lock while checking m_KnownPdo
763  // because if miss the transition from FALSE to TRUE, relations will
764  // automaticaly be invalidated by the cause of that transition (start
765  // device arrival). PnP automatically sends a QDR after a successful
766  // start.
767  //
768 
769  if (m_InvalidationNeeded) {
770  PDEVICE_OBJECT pdo;
771 
772  //
773  // This does the m_KnownPdo check.
774  //
776 
777  if (pdo != NULL) {
780  }
781  }
782 
783  m_ScanEvent.Set();
784  }
785 
787 
788  //
789  // Free structures outside of any internal WDF lock
790  //
791  DrainFreeListHead(&freeHead);
792 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
VOID MarkModificationNotPresentWorker(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *ModificationEntry)
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
BOOLEAN m_InvalidationNeeded
#define TRUE
Definition: types.h:120
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
__inline VOID Set()
Definition: mxeventkm.h:91
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
PULONG m_ScanTag
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
MxEvent m_ScanEvent
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
WDFCHILDLIST GetHandle(VOID)
ULONG m_ScanCount
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
MdDeviceObject __inline GetSafePhysicalDevice(VOID)
Definition: fxdevice.hpp:1005
#define TRACINGPNP
Definition: dbgtrace.h:67
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2342
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID MarkDescriptionNotPresentWorker(__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
SINGLE_LIST_ENTRY * pCur
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by CancelScan(), and EndIteration().

◆ GetAddressDescription()

_Must_inspect_result_ NTSTATUS FxChildList::GetAddressDescription ( __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER  IdentificationDescription,
__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  AddressDescription 
)

Definition at line 509 of file fxchildlist.cpp.

513 {
516  KIRQL irql;
517 
519 
522 
523  if (pEntry == NULL) {
526  }
527 
528  if (pEntry != NULL) {
529  CopyAddress(AddressDescription, pEntry->m_AddressDescription);
531  }
532  else {
534  }
535 
537 
538  return status;
539 }
FxDeviceDescriptionEntry * SearchBackwardsForMatchingDescriptionLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
FxDeviceDescriptionEntry * SearchBackwardsForMatchingModificationLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK m_ListLock
_Inout_ PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription
Definition: wdfchildlist.h:255
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_In_ PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription
Definition: wdfchildlist.h:124
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define STATUS_SUCCESS
Definition: shellext.h:65
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ GetAddressDescriptionFromEntry()

VOID FxChildList::GetAddressDescriptionFromEntry ( __in FxDeviceDescriptionEntry Entry,
__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  AddressDescription 
)

Definition at line 542 of file fxchildlist.cpp.

546 {
547  KIRQL irql;
548 
550  CopyAddress(AddressDescription, Entry->m_AddressDescription);
552 }
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK m_ListLock
_Inout_ PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription
Definition: wdfchildlist.h:255
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
base of all file and directory entries
Definition: entries.h:82

◆ GetAddressDescriptionSize()

ULONG FxChildList::GetAddressDescriptionSize ( VOID  )
inline

Definition at line 257 of file fxchildlist.hpp.

260  {
262  }
ULONG m_AddressDescriptionSize

Referenced by if().

◆ GetDevice()

WDFDEVICE FxChildList::GetDevice ( VOID  )

Definition at line 450 of file fxchildlist.cpp.

453 {
454  return m_Device->GetHandle();
455 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237

◆ GetDeviceFromId()

CfxDevice * FxChildList::GetDeviceFromId ( __inout PWDF_CHILD_RETRIEVE_INFO  Info)

Definition at line 458 of file fxchildlist.cpp.

461 {
463  FxDevice* device;
465  KIRQL irql;
466 
467  device = NULL;
468 
470 
472  Info->IdentificationDescription);
473 
474  if (pEntry != NULL && pEntry->m_ModificationState == ModificationInsert) {
476  }
477  else {
479  Info->IdentificationDescription);
480 
481  if (pEntry != NULL) {
482  if (pEntry->m_DescriptionState == DescriptionPresentNeedsInstantiation) {
484  }
485  else {
487  device = pEntry->m_Pdo;
488  }
489  }
490  else {
492  }
493  }
494 
495  if (pEntry != NULL && Info->AddressDescription != NULL) {
496  CopyAddress(Info->AddressDescription,
497  pEntry->m_AddressDescription);
498  }
499 
501 
502  Info->Status = status;
503 
504  return device;
505 }
FxDeviceDescriptionEntry * SearchBackwardsForMatchingDescriptionLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
FxDeviceDescriptionEntry * SearchBackwardsForMatchingModificationLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
FxDevice * device
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
UCHAR KIRQL
Definition: env_spec_w32.h:591
Definition: devices.h:37
KSPIN_LOCK m_ListLock
WDF_EXTERN_C_START enum _WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ GetHandle()

WDFCHILDLIST FxChildList::GetHandle ( VOID  )
inline

◆ GetIdentificationDescriptionSize()

ULONG FxChildList::GetIdentificationDescriptionSize ( VOID  )
inline

Definition at line 265 of file fxchildlist.hpp.

268  {
270  }
ULONG m_IdentificationDescriptionSize

Referenced by if().

◆ GetNextDevice()

_Must_inspect_result_ NTSTATUS FxChildList::GetNextDevice ( __out WDFDEVICE *  Device,
__inout PWDF_CHILD_LIST_ITERATOR  Iterator,
__inout_opt PWDF_CHILD_RETRIEVE_INFO  Info 
)

Definition at line 872 of file fxchildlist.cpp.

877 {
882  ULONG cur, i;
883  KIRQL irql;
884  BOOLEAN found;
885 
886  pEntry = NULL;
888 
890 
891  ASSERT(m_ScanCount > 0);
892  if (m_ScanCount == 0) {
894 
897  "WDFCHILDLIST %p cannot retrieve next device if the list is not "
898  "locked for iteration, %!STATUS!", GetHandle(), status);
899 
900  goto Done;
901  }
902 
903  ple = (PLIST_ENTRY) Iterator->Reserved[DescriptionIndex];
904 
905  if (ple != NULL) {
908  if (!NT_SUCCESS(status)) {
909  goto Done;
910  }
911  }
912 
913  found = FALSE;
914 
915  //
916  // Try to find the next entry
917  //
918  for (ple = ple->Flink; ple != &m_DescriptionListHead; ple = ple->Flink) {
920 
921  if (pEntry->MatchStateToFlags(Iterator->Flags)) {
922  //
923  // An item was found
924  //
925  found = TRUE;
926 
927  //
928  // Call the caller's compare function to further refine the match
929  // if necessary.
930  //
931  if (Info != NULL &&
932  Info->EvtChildListIdentificationDescriptionCompare != NULL) {
933 
934  found = Info->EvtChildListIdentificationDescriptionCompare(
935  GetHandle(),
936  Info->IdentificationDescription,
937  pEntry->m_IdentificationDescription);
938  }
939 
940  if (found) {
941  break;
942  }
943  }
944  }
945 
946  if (found) {
947  //
948  // We can safely store the description entry because we are
949  // guaranteed it will stay in the description list until m_ScanCount
950  // reaches zero. In that case, the caller would need to call
951  // EndIteration
952  //
953  Iterator->Reserved[DescriptionIndex] = ple;
954 
955  if (pEntry->m_Pdo != NULL) {
956  *Device = pEntry->m_Pdo->GetHandle();
958  }
959  else {
961  }
962 
963  if (Info != NULL) {
964  if (Info->IdentificationDescription != NULL) {
965  CopyId(Info->IdentificationDescription,
966  pEntry->m_IdentificationDescription);
967  }
968  if (Info->AddressDescription != NULL) {
969  CopyAddress(Info->AddressDescription,
970  pEntry->m_AddressDescription);
971  }
972 
973  Info->Status = dstatus;
974  }
975 
977  }
978  else {
979  Iterator->Reserved[DescriptionIndex] = NULL;
980  ple = NULL;
982  }
983  }
984 
986 
987  if ((Iterator->Flags & WdfRetrievePendingChildren) == 0 ||
988  cur == 0) {
989  goto Done;
990  }
991 
992 
993  //
994  // Walk the modification list. Since this list can change from call to call
995  // to GetNextDevice we can't rely on the previous entry still being present
996  // so we must use an index into the list. This is not guaranteed to
997  // enumerate all pending additions, but it should be good enough.
998  //
999  found = FALSE;
1000 
1001  for (i = 1, ple = m_ModificationListHead.Flink;
1003  ple = ple->Flink) {
1004 
1006 
1007  if (pEntry->m_ModificationState == ModificationInsert) {
1008  i++;
1009 
1010  if (i > cur) {
1011  found = TRUE;
1012 
1013  if (Info != NULL &&
1014  Info->EvtChildListIdentificationDescriptionCompare != NULL) {
1015 
1016  found = Info->EvtChildListIdentificationDescriptionCompare(
1017  GetHandle(),
1018  Info->IdentificationDescription,
1019  pEntry->m_IdentificationDescription);
1020  }
1021 
1022  if (found) {
1023  //
1024  // Store the next item number
1025  //
1026  Iterator->Reserved[ModificationIndex] = ULongToPtr(i);
1027 
1028  if (Info != NULL) {
1029  if (Info->IdentificationDescription != NULL) {
1030  CopyId(Info->IdentificationDescription,
1031  pEntry->m_IdentificationDescription);
1032  }
1033  if (Info->AddressDescription != NULL) {
1034  CopyAddress(Info->AddressDescription,
1035  pEntry->m_AddressDescription);
1036  }
1037 
1039  }
1040 
1042  break;
1043  }
1044  }
1045  }
1046  }
1047 
1048  if (found == FALSE) {
1049  Iterator->Reserved[ModificationIndex] = ULongToPtr(0);
1050  }
1051 
1052 Done:
1054 
1055  return status;
1056 }
struct _LIST_ENTRY * PLIST_ENTRY
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
#define ULongToPtr(ul)
Definition: basetsd.h:92
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
if(dx==0 &&dy==0)
Definition: linetemp.h:174
PSINGLE_LIST_ENTRY ple
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
KSPIN_LOCK m_ListLock
unsigned char BOOLEAN
#define PtrToUlong(u)
Definition: config.h:107
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
WDF_EXTERN_C_START enum _WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:653
WDFCHILDLIST GetHandle(VOID)
ULONG m_ScanCount
Definition: typedefs.h:119
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
FxCollectionEntry * cur
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
_Must_inspect_result_ NTSTATUS VerifyDescriptionEntry(__in PLIST_ENTRY Entry)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID CopyId(__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ GetNextStaticDevice()

WDFDEVICE FxChildList::GetNextStaticDevice ( __in WDFDEVICE  PreviousDevice,
__in ULONG  Flags 
)

Definition at line 1059 of file fxchildlist.cpp.

1063 {
1064  FxStaticChildDescription *pStatic;
1066  WDFDEVICE result;
1067  PLIST_ENTRY ple;
1068  KIRQL irql;
1069  BOOLEAN isNext;
1070 
1072 
1073  result = NULL;
1074 
1075  if (PreviousDevice == NULL) {
1076  //
1077  // No previous handle, we want the first device we find
1078  //
1079  isNext = TRUE;
1080  }
1081  else {
1082  //
1083  // We have a previuos handle, find it in the list first before setting
1084  // isNext.
1085  //
1086  isNext = FALSE;
1087  }
1088 
1090 
1091  ASSERT(m_ScanCount > 0);
1092  if (m_ScanCount == 0) {
1093  goto Done;
1094  }
1095 
1096  //
1097  // Try to find the next entry
1098  //
1102  ple = ple->Flink) {
1104 
1105  //
1106  // If the entry is marked pending delete, skip it, because the
1107  // relationship between entry and its PDO has been removed and PDO
1108  // may have actually been deleted by this time. The only reason
1109  // this entry is here is because there is still a scan going on
1110  // and the entry can't be removed in the midst of a scan.
1111  //
1112  if (pEntry->m_PendingDeleteOnScanEnd) {
1113  continue;
1114  }
1115 
1116  pStatic = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
1118  Header);
1119 
1120  //
1121  // Only return a handle if it is in a state in which the caller is
1122  // interested in hearing about.
1123  //
1124  if (isNext && pEntry->MatchStateToFlags(Flags)) {
1125  result = pStatic->Pdo->GetHandle();
1126  break;
1127  }
1128  else if (pStatic->Pdo->GetHandle() == PreviousDevice) {
1129  isNext = TRUE;
1130  }
1131  }
1132  }
1133 
1134  //
1135  // We have taken care of all the other states (reported, pending removal,
1136  // removed) in the previuos loop.
1137  //
1138  if (result == NULL && (Flags & WdfRetrievePendingChildren)) {
1139  //
1140  // Walk the modification list. Since this list can change from call to
1141  // call, there is no way to definitively give the driver a snapshot of
1142  // this list of modifications.
1143  //
1146  ple = ple->Flink) {
1147 
1149 
1150  if (pEntry->m_PendingDeleteOnScanEnd) {
1151  continue;
1152  }
1153 
1154  pStatic = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
1156  Header);
1157 
1158  //
1159  // Only return a handle if it is in a state in which the caller is
1160  // interested in hearing about.
1161  //
1162  if (isNext && pEntry->m_ModificationState == ModificationInsert) {
1163  result = pStatic->Pdo->GetHandle();
1164  break;
1165  }
1166  else if (pStatic->Pdo->GetHandle() == PreviousDevice) {
1167  isNext = TRUE;
1168  }
1169  }
1170  }
1171 
1172 Done:
1174 
1175  return result;
1176 }
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
GLuint64EXT * result
Definition: glext.h:11304
#define TRUE
Definition: types.h:120
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
Definition: Header.h:8
KSPIN_LOCK m_ListLock
unsigned char BOOLEAN
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ASSERT(a)
Definition: mode.c:44
ULONG m_ScanCount
Definition: typedefs.h:119
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
BOOLEAN m_StaticList

◆ GetScanCount()

ULONG FxChildList::GetScanCount ( VOID  )
inline

Definition at line 383 of file fxchildlist.hpp.

386  {
387  return m_ScanCount;
388  }
ULONG m_ScanCount

Referenced by FxDeviceDescriptionEntry::IsDeviceRemoved(), and FxDeviceDescriptionEntry::ProcessDeviceRemoved().

◆ GetScanEvent()

MxEvent* FxChildList::GetScanEvent ( VOID  )
inline

Definition at line 129 of file fxchildlist.hpp.

132  {
133  return m_ScanEvent.GetSelfPointer();
134  }
MxEvent * GetSelfPointer(VOID)
Definition: mxevent.h:110
MxEvent m_ScanEvent

Referenced by FxPkgPdo::PnpEventEjectHardwareOverload().

◆ HasAddressDescriptions()

BOOLEAN FxChildList::HasAddressDescriptions ( VOID  )
inline

Definition at line 249 of file fxchildlist.hpp.

252  {
253  return m_AddressDescriptionSize > 0 ? TRUE : FALSE;
254  }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG m_AddressDescriptionSize

Referenced by Add(), FxDeviceDescriptionEntry::Clone(), and if().

◆ IndicateWakeStatus()

VOID FxChildList::IndicateWakeStatus ( __in NTSTATUS  WakeWakeStatus)

Definition at line 2911 of file fxchildlist.cpp.

2928 {
2930  PLIST_ENTRY ple;
2931  KIRQL irql;
2932 
2936  ple = ple->Flink) {
2937 
2939 
2940  if (pEntry->m_PendingDeleteOnScanEnd) {
2941  COVERAGE_TRAP();
2942  continue;
2943  }
2944 
2945  if (pEntry->m_Pdo != NULL) {
2946  ASSERT(pEntry->m_Pdo->m_PkgPnp->m_SharedPower.m_WaitWakeOwner == TRUE);
2947  pEntry->m_Pdo->m_PkgPnp->PowerIndicateWaitWakeStatus(WaitWakeStatus);
2948  }
2949  }
2951 }
LIST_ENTRY m_DescriptionListHead
#define TRUE
Definition: types.h:120
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_ WDFDEVICE _In_ NTSTATUS WaitWakeStatus
Definition: wdfdevice.h:3942
KSPIN_LOCK m_ListLock
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
Definition: typedefs.h:119
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

◆ Initialize()

VOID FxChildList::Initialize ( __in PWDF_CHILD_LIST_CONFIG  Config)
protected

Definition at line 416 of file fxchildlist.cpp.

419 {
420  //
421  // Driver cannot call WdfObjectDelete on this handle
422  //
423  MarkNoDeleteDDI();
424 
425  m_IdentificationDescriptionSize = Config->IdentificationDescriptionSize;
426  m_AddressDescriptionSize = Config->AddressDescriptionSize;
427 
428  m_EvtCreateDevice.m_Method = Config->EvtChildListCreateDevice;
429  m_EvtScanForChildren.m_Method = Config->EvtChildListScanForChildren;
430 
431  m_EvtIdentificationDescriptionDuplicate = Config->EvtChildListIdentificationDescriptionDuplicate;
432  m_EvtIdentificationDescriptionCopy = Config->EvtChildListIdentificationDescriptionCopy;
433  m_EvtIdentificationDescriptionCleanup = Config->EvtChildListIdentificationDescriptionCleanup;
434  m_EvtIdentificationDescriptionCompare = Config->EvtChildListIdentificationDescriptionCompare;
435 
436  m_EvtAddressDescriptionDuplicate = Config->EvtChildListAddressDescriptionDuplicate;
437  m_EvtAddressDescriptionCopy = Config->EvtChildListAddressDescriptionCopy;
438  m_EvtAddressDescriptionCleanup = Config->EvtChildListAddressDescriptionCleanup;
439 
440  m_EvtChildListDeviceReenumerated = Config->EvtChildListDeviceReenumerated;
441 
442  //
443  // Add this ChildList to the parent device's list of children lists.
444  //
445  m_Device->AddChildList(this);
446  m_IsAdded = TRUE;
447 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY m_EvtIdentificationDescriptionCopy
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE m_EvtAddressDescriptionDuplicate
#define TRUE
Definition: types.h:120
FxChildListScanForChildrenCallback m_EvtScanForChildren
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY m_EvtAddressDescriptionCopy
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP m_EvtAddressDescriptionCleanup
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP m_EvtIdentificationDescriptionCleanup
PFN_WDF_CHILD_LIST_DEVICE_REENUMERATED m_EvtChildListDeviceReenumerated
PFN_WDF_CHILD_LIST_CREATE_DEVICE m_Method
Definition: fxchildlist.hpp:61
BOOLEAN m_IsAdded
FxChildListCreateDeviceCallback m_EvtCreateDevice
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE m_EvtIdentificationDescriptionCompare
ULONG m_AddressDescriptionSize
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
PFN_WDF_CHILD_LIST_SCAN_FOR_CHILDREN m_Method
Definition: fxchildlist.hpp:86
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE m_EvtIdentificationDescriptionDuplicate
virtual VOID AddChildList(__inout FxChildList *List)
Definition: fxdevicekm.cpp:431
ULONG m_IdentificationDescriptionSize

Referenced by _CreateAndInit().

◆ InitIterator()

VOID FxChildList::InitIterator ( __inout PWDF_CHILD_LIST_ITERATOR  Iterator)

Definition at line 808 of file fxchildlist.cpp.

811 {
813 
814  if (Iterator->Flags & WdfRetrievePendingChildren) {
815  Iterator->Reserved[ModificationIndex] = ULongToPtr(1);
816  }
817 }
LIST_ENTRY m_DescriptionListHead
#define ULongToPtr(ul)
Definition: basetsd.h:92
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:653

Referenced by BeginIteration().

◆ InvokeReportedMissingCallback()

VOID FxChildList::InvokeReportedMissingCallback ( VOID  )

Definition at line 2836 of file fxchildlist.cpp.

2839 {
2840  PLIST_ENTRY ple, pNext;
2841  KIRQL irql;
2843  LIST_ENTRY freeHead;
2844 
2845  InitializeListHead(&freeHead);
2846 
2847  //
2848  // Prevent modification list processing so that we can walk the
2849  // description list safely.
2850  //
2854 
2855  //
2856  // Invoke the ReportedMissing callback if present for children reported
2857  // missing.
2858  //
2861  ple = pNext) {
2862  pNext = ple->Flink;
2863 
2865 
2866  if (pEntry->m_ReportedMissingCallbackState == CallbackNeedsToBeInvoked) {
2867  (pEntry->m_Pdo->GetPdoPkg())->m_DeviceReportedMissing.Invoke(
2868  pEntry->m_Pdo->GetHandle());
2869 
2870  pEntry->m_ReportedMissingCallbackState = CallbackInvoked;
2871  }
2872  }
2873 
2876  ProcessModificationsLocked(&freeHead);
2878 
2879  DrainFreeListHead(&freeHead);
2880 }
LIST_ENTRY m_DescriptionListHead
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
FxChildListState m_State
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by FxPkgPnp::HandleQueryBusRelations().

◆ IsScanCancelled()

BOOLEAN FxChildList::IsScanCancelled ( __in PULONG  ScanTag)
inline

Definition at line 205 of file fxchildlist.hpp.

208  {
209  return *ScanTag == ScanTagCancelled ? TRUE : FALSE;
210  }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117

◆ IsStaticList()

BOOLEAN FxChildList::IsStaticList ( VOID  )
inline

Definition at line 334 of file fxchildlist.hpp.

337  {
338  return m_StaticList;
339  }
BOOLEAN m_StaticList

Referenced by MarkModificationNotPresentWorker().

◆ MarkDescriptionNotPresentWorker()

VOID FxChildList::MarkDescriptionNotPresentWorker ( __inout FxDeviceDescriptionEntry DescriptionEntry,
__in BOOLEAN  ModificationCanBeQueued 
)
protected

Definition at line 1935 of file fxchildlist.cpp.

1961 {
1962  BOOLEAN queueMod;
1963 
1964  ASSERT(DescriptionEntry->IsPresent());
1965 
1966  queueMod = FALSE;
1967 
1968  if (ModificationCanBeQueued) {
1969  if (IsListEmpty(&DescriptionEntry->m_ModificationLink)) {
1970  queueMod = TRUE;
1971  }
1972  else {
1973  //
1974  // If the modification is queued, it must be removal
1975  //
1976  ASSERT(DescriptionEntry->m_ModificationState ==
1978  ASSERT(DescriptionEntry->m_FoundInLastScan == FALSE);
1979  }
1980  }
1981  else {
1982  queueMod = TRUE;
1983  }
1984 
1985  if (queueMod) {
1986  ASSERT(IsListEmpty(&DescriptionEntry->m_ModificationLink));
1987  ASSERT(DescriptionEntry->m_ModificationState == ModificationUnspecified);
1988 
1989  //
1990  // Add a removal modification entry into the modification list.
1991  // The ModificationRemoveNotify state will be converted into
1992  // ModificationRemove later while the list lock is still being held.
1993  //
1994  DescriptionEntry->m_ModificationState = ModificationRemoveNotify;
1995  DescriptionEntry->m_FoundInLastScan = FALSE;
1996 
1998  &DescriptionEntry->m_ModificationLink);
1999  }
2000 }
LIST_ENTRY m_ModificationListHead
#define TRUE
Definition: types.h:120
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define ASSERT(a)
Definition: mode.c:44

Referenced by CreateDevice(), EndScan(), MarkModificationNotPresentWorker(), NotifyDeviceSurpriseRemove(), UpdateAsMissing(), and UpdateDeviceAsMissing().

◆ MarkModificationNotPresentWorker()

VOID FxChildList::MarkModificationNotPresentWorker ( __inout PLIST_ENTRY  FreeListHead,
__inout FxDeviceDescriptionEntry ModificationEntry 
)
protected

Definition at line 2003 of file fxchildlist.cpp.

2025 {
2026  switch (ModificationEntry->m_ModificationState) {
2027  case ModificationInsert:
2028  //
2029  // This one was never reported to the OS. Remove it now.
2030  //
2031  RemoveEntryList(&ModificationEntry->m_ModificationLink);
2032  InitializeListHead(&ModificationEntry->m_ModificationLink);
2033 
2034  if (IsStaticList()) {
2035  //
2036  // There is a corner case of a static PDO being added and
2037  // immediately marked as missing before it has a chance to move to
2038  // description list. This case is handled here by marking the
2039  // modification state to ModificationNeedsPnpRemoval. Fx cannot just
2040  // delete the description because there is a driver-created PDO
2041  // associated with the description and it needs to be cleaned up.
2042  //
2043  ModificationEntry->m_ModificationState = ModificationNeedsPnpRemoval;
2044  ASSERT(ModificationEntry->m_DescriptionState == DescriptionUnspecified);
2045  }
2046 
2047  ASSERT(IsListEmpty(&ModificationEntry->m_DescriptionLink));
2048  InsertTailList(FreeListHead, &ModificationEntry->m_DescriptionLink);
2049  break;
2050 
2051  case ModificationClone:
2052  //
2053  // In between the PDOs stack asking for a reenumeration and applying
2054  // this change, the bus driver has reported the child as missing.
2055  // Convert the clone modification to a removal modification.
2056  //
2057 
2058  //
2059  // MarkDescriptionNotPresentWorker expects that m_ModificationEntry is
2060  // not in any list and points to itself.
2061  //
2062  RemoveEntryList(&ModificationEntry->m_ModificationLink);
2063  InitializeListHead(&ModificationEntry->m_ModificationLink);
2064 
2065  MarkDescriptionNotPresentWorker(ModificationEntry, FALSE);
2066  break;
2067 
2068  default:
2069  DO_NOTHING();
2070  break;
2071  }
2072 }
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
BOOLEAN IsStaticList(VOID)
#define ASSERT(a)
Definition: mode.c:44
VOID MarkDescriptionNotPresentWorker(__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DO_NOTHING()
Definition: mxgeneral.h:32

Referenced by EndScan(), NotifyDeviceSurpriseRemove(), UpdateAsMissing(), and UpdateDeviceAsMissing().

◆ NotifyDeviceRemove()

VOID FxChildList::NotifyDeviceRemove ( __inout PLONG  ChildCount)

Definition at line 3041 of file fxchildlist.cpp.

3057 {
3058  PLIST_ENTRY pCur;
3059  LIST_ENTRY freeHead;
3061  KIRQL irql;
3062 
3064  "WDFCHILDLIST %p: removing children", GetHandle());
3065 
3066  InitializeListHead(&freeHead);
3067  pEntry = NULL;
3068 
3070 
3071  //
3072  // Surprise remove handling covers the first stage of processing. This will
3073  // process the modification list, esp the insert modifications which will
3074  // be cleaned up.
3075  //
3077 
3079 
3080  ProcessModificationsLocked(&freeHead);
3081 
3083 
3084  for ( ; ; ) {
3085 
3086  //
3087  // Find the first child which was not surprise removed. If surprise
3088  // removed and not yet removed, then there is an outstanding handle
3089  // which has not yet been closed.
3090  //
3093  pCur = pCur->Flink) {
3094 
3096 
3097  ASSERT(pEntry->m_DescriptionState == DescriptionReportedMissing);
3098 
3099  if (pEntry->m_ProcessingSurpriseRemove == FALSE) {
3100  break;
3101  }
3102  }
3103 
3104  //
3105  // If we are at the end of the list, we are done
3106  //
3107  if (pCur == &m_DescriptionListHead) {
3108  break;
3109  }
3110 
3112  "Removing entry %p, WDFDEVICE %p, PDO %p",
3113  pEntry, pEntry->m_Pdo->GetHandle(),
3114  pEntry->m_Pdo->GetPhysicalDevice());
3115 
3116  ASSERT(pEntry->m_ModificationState == ModificationUnspecified);
3117  RemoveEntryList(&pEntry->m_DescriptionLink);
3118  InitializeListHead(&pEntry->m_DescriptionLink);
3119 
3121 
3122  //
3123  // Go through FxPkgPdo to handle cleanup. CleanupOrphanedDevice will
3124  // free this entry.
3125  //
3126  ASSERT(pEntry->m_Pdo != NULL);
3127  ASSERT(pEntry->m_PendingDeleteOnScanEnd == FALSE);
3128 
3129  pEntry->m_Pdo->SetParentWaitingOnRemoval();
3130  InterlockedIncrement(ChildCount);
3131 
3132  //
3133  // Start the child going away
3134  //
3135  pEntry->m_Pdo->m_PkgPnp->PnpProcessEvent(PnpEventParentRemoved);
3136 
3138  }
3139 
3141  ProcessModificationsLocked(&freeHead);
3142 
3144 
3145  DrainFreeListHead(&freeHead);
3146 }
LIST_ENTRY m_DescriptionListHead
VOID NotifyDeviceSurpriseRemove(VOID)
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
#define ASSERT(a)
Definition: mode.c:44
WDFCHILDLIST GetHandle(VOID)
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
#define InterlockedIncrement
Definition: armddk.h:53
FxChildListState m_State
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
SINGLE_LIST_ENTRY * pCur
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by FxPkgPnp::ChildListNotifyRemove().

◆ NotifyDeviceSurpriseRemove()

VOID FxChildList::NotifyDeviceSurpriseRemove ( VOID  )

Definition at line 2954 of file fxchildlist.cpp.

2970 {
2971  PLIST_ENTRY pCur, pNext;
2972  LIST_ENTRY freeHead;
2974  KIRQL irql;
2975 
2976  InitializeListHead(&freeHead);
2977 
2979 
2981 
2982  //
2983  // Walk over all mod entries and remove any pending inserts. Note that
2984  // MarkModificationNotPresentWorker will add any such INSERTs found in the
2985  // mod list to the free list.
2986  //
2989  pCur = pNext) {
2990 
2991  pNext = pCur->Flink;
2992 
2994 
2995  if (pEntry->m_ModificationState == ModificationInsert) {
2997  }
2998  }
2999 
3000  //
3001  // Walk over all desc entries and remove them. Since
3002  // MarkDescriptionNotPresentWorker doesn't drain the mods,
3003  // we don't have to worry about any entries disappearing.
3004  //
3007  pCur = pCur->Flink) {
3008 
3010 
3011  if (pEntry->IsPresent()) {
3013  }
3014  }
3015 
3016  //
3017  // Attempt to drain any mods we made.
3018  //
3019  ProcessModificationsLocked(&freeHead);
3020 
3021  //
3022  // Walk over all desc entries and advance them to missing.
3023  //
3026  pCur = pCur->Flink) {
3027 
3029 
3030  if (pEntry->m_DescriptionState == DescriptionNotPresent) {
3031  pEntry->m_DescriptionState = DescriptionReportedMissing;
3032  }
3033  }
3034 
3036 
3037  DrainFreeListHead(&freeHead);
3038 }
VOID MarkModificationNotPresentWorker(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *ModificationEntry)
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
#define TRUE
Definition: types.h:120
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID MarkDescriptionNotPresentWorker(__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
SINGLE_LIST_ENTRY * pCur
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by NotifyDeviceRemove(), and FxPkgPnp::PnpEventSurpriseRemovePendingOverload().

◆ PostParentToD0()

VOID FxChildList::PostParentToD0 ( VOID  )

Definition at line 2883 of file fxchildlist.cpp.

2886 {
2888  PLIST_ENTRY ple;
2889  KIRQL irql;
2890 
2894  ple = ple->Flink) {
2895 
2897 
2898  if (pEntry->m_PendingDeleteOnScanEnd) {
2899  COVERAGE_TRAP();
2900  continue;
2901  }
2902 
2903  if (pEntry->m_Pdo != NULL) {
2904  pEntry->m_Pdo->m_PkgPnp->PowerProcessEvent(PowerParentToD0);
2905  }
2906  }
2908 }
LIST_ENTRY m_DescriptionListHead
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
KIRQL irql
Definition: wave.h:1
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
KSPIN_LOCK m_ListLock
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

◆ ProcessBusRelations()

_Must_inspect_result_ NTSTATUS FxChildList::ProcessBusRelations ( __inout PDEVICE_RELATIONS DeviceRelations)

Definition at line 2414 of file fxchildlist.cpp.

2417 {
2418  LIST_ENTRY freeHead;
2419  PLIST_ENTRY ple, pNext;
2421  PDEVICE_RELATIONS pPriorRelations, pNewRelations;
2423  BOOLEAN needToReportMissingChildren, invalidateRelations, cleanupRelations;
2424  ULONG additionalCount, totalCount, i;
2425  size_t size;
2426  NTSTATUS status;
2427  KIRQL irql;
2429 
2431 
2432  pNewRelations = NULL;
2433  invalidateRelations = FALSE;
2434  cleanupRelations = TRUE;
2435  InitializeListHead(&freeHead);
2437 
2438  //
2439  // Get the count of DO's we will need to add. While we're at it, free any
2440  // extensions that never got a chance for a DO, and note extensions that
2441  // will need to wait for a remove IRP.
2442  //
2444 
2446 
2447  additionalCount = 0;
2448  needToReportMissingChildren = FALSE;
2449 
2452  ple = ple->Flink) {
2453 
2455 
2456  switch (pEntry->m_DescriptionState) {
2457 
2460  //
2461  // We'll be needing a DO here.
2462  //
2463  additionalCount++;
2464  break;
2465 
2466  case DescriptionNotPresent:
2467  //
2468  // We will now report the description as missing
2469  //
2472  "PDO WDFDEVICE %p !devobj %p in a not present state, need to "
2473  "report as missing",
2474  pEntry->m_Pdo->GetHandle(), pEntry->m_Pdo->GetDeviceObject());
2475 
2476  needToReportMissingChildren = TRUE;
2477  break;
2478 
2480  //
2481  // Already reported missing in a previous handling of QDR
2482  //
2483  break;
2484 
2485  default:
2486  ASSERTMSG("Invalid description state\n", FALSE);
2487  break;
2488  }
2489  }
2490 
2492 
2493  pPriorRelations = *DeviceRelations;
2494 
2495  //
2496  // If we have
2497  // 1) no devices in the list AND
2498  // a) we have nothing to report OR
2499  // b) we have something to report and there are previous relations (which
2500  // if left unchanged will be used to report our missing devices)
2501  //
2502  // THEN nothing else to do except marking the NotPresent children as
2503  // missing, unlock the list and return the special return
2504  // code STATUS_NOT_SUPPORTED indicating this condition.
2505  //
2506  if (additionalCount == 0 &&
2507  (needToReportMissingChildren == FALSE || pPriorRelations != NULL)) {
2508  //
2509  // We have nothing to add, nor subtract from prior allocations. Note
2510  // the careful logic with counting missing children - the OS does not
2511  // treat no list and an empty list identically. As such we must be
2512  // sure to return some kind of list in the case where we reported
2513  // something previously.
2514  //
2515  // Mark the NotPresent children as Missing
2516  // We can walk the ChildList without holding the spinlock because we set
2517  // m_State to ListLockedForEnum.
2518  //
2519  if (needToReportMissingChildren) {
2522  ple = pNext) {
2523  pNext = ple->Flink;
2524 
2526 
2527  if (pEntry->m_DescriptionState == DescriptionNotPresent) {
2528  //
2529  // We will now report the description as missing
2530  //
2533  "PDO WDFDEVICE %p !devobj %p reported as missing to pnp",
2534  pEntry->m_Pdo->GetHandle(), pEntry->m_Pdo->GetDeviceObject());
2535 
2536  pEntry->m_DescriptionState = DescriptionReportedMissing;
2537  pEntry->m_ReportedMissingCallbackState = CallbackNeedsToBeInvoked;
2538  }
2539  }
2540  }
2541  else {
2544  "Nothing to report on WDFCHILDLIST %p, returning early", GetHandle());
2545  }
2546 
2547  cleanupRelations = FALSE;
2549  goto Done;
2550  }
2551 
2552  //
2553  // Adjust the count for any existing relations.
2554  //
2555  totalCount = additionalCount;
2556  if (pPriorRelations != NULL) {
2557  totalCount += pPriorRelations->Count;
2558  }
2559 
2560  size = _ComputeRelationsSize(totalCount);
2561 
2562  pNewRelations = (PDEVICE_RELATIONS)
2564 
2565  if (pNewRelations == NULL) {
2566  //
2567  // We can't add our information.
2568  //
2570  "Could not allocate relations for %d devices",
2571  totalCount);
2572 
2573  //
2574  // Just like above, STATUS_NOT_SUPPORTED is a special value indicating
2575  // to the caller that the QDR has not been handled and that the caller
2576  // should not change the status or the existing relations in the irp.
2577  //
2578  cleanupRelations = FALSE;
2580 
2581  m_EnumRetries++;
2583  invalidateRelations = TRUE;
2584  }
2585  else {
2586  if (needToReportMissingChildren) {
2589  "WDFCHILDLIST %p could not allocate relations required for "
2590  "reporting children as missing after max retries",
2591  GetHandle());
2592  }
2593 
2596  "WDFCHILDLIST %p retried %d times to report relations, but "
2597  "failed each time", GetHandle(), FX_CHILD_LIST_MAX_RETRIES);
2598  }
2599 
2600  if (pPriorRelations == NULL) {
2601  //
2602  // If the prior relations are NULL we can just return failure and
2603  // not affect anyone else's state that had previous thought they
2604  // committed a relations structure back to pnp (which we tried to
2605  // update but could not b/c of no memory).
2606  //
2607  // By returning failure that is != STATUS_NOT_SUPPORTED, the pnp
2608  // manager will not process a change in the relations.
2609  //
2611  }
2612  else {
2613  //
2614  // Do *not* throw away the old list and return error because that
2615  // will put the driver which created the existing relations into an
2616  // inconsistent state with respect to the pnp manager state if we
2617  // fail it here and the pnp manager never seeds the changes.
2618  //
2619  // Instead, we must process the failure locally and mark each object
2620  // which is already reported as present as missing.
2621  //
2624  ple = pNext) {
2625 
2626  pNext = ple->Flink;
2628 
2629  switch (pEntry->m_DescriptionState) {
2631  //
2632  // This description can stay in this state b/c we will just
2633  // ask for another QDR.
2634  //
2635  break;
2636 
2640  "PDO WDFDEVICE %p !devobj %p being marked as missing "
2641  "because of failure to allocate device relations and "
2642  "an already existing relations %p",
2643  pEntry->m_Pdo->GetHandle(),
2644  pEntry->m_Pdo->GetDeviceObject(), pPriorRelations);
2645 
2647  if (m_StaticList == FALSE) {
2652  "PDO WDFDEVICE %p !devobj %p being cloned "
2653  "because of the failure to allocate device "
2654  "relations",
2655  pEntry->m_Pdo->GetHandle(),
2656  pEntry->m_Pdo->GetDeviceObject());
2657 
2658  (void) CloneEntryLocked(&freeHead, pEntry, TRUE);
2659  }
2660  }
2661  else {
2665  "PDO WDFDEVICE %p !devobj %p is a statically "
2666  "enumerated PDO therefore can not be cloned and is "
2667  "being marked missing because of failure to "
2668  "allocate device relations. It will be surprise "
2669  "removed by pnp manager. Bus driver may continue "
2670  "to function normally but will lose this child PDO",
2671  pEntry->m_Pdo->GetHandle(),
2672  pEntry->m_Pdo->GetDeviceObject());
2673  }
2674  pEntry->m_DescriptionState = DescriptionReportedMissing;
2675  pEntry->m_ReportedMissingCallbackState = CallbackNeedsToBeInvoked;
2677  break;
2678 
2679  case DescriptionNotPresent:
2680  //
2681  // We will now report the description as missing
2682  //
2685  "PDO WDFDEVICE %p !devobj %p reported as missing to pnp "
2686  "(by using existing relations)",
2687  pEntry->m_Pdo->GetHandle(),
2688  pEntry->m_Pdo->GetDeviceObject());
2689 
2690  pEntry->m_DescriptionState = DescriptionReportedMissing;
2691  pEntry->m_ReportedMissingCallbackState = CallbackNeedsToBeInvoked;
2692  break;
2693  }
2694  }
2695  }
2696 
2697  goto Done;
2698  }
2699 
2700  RtlZeroMemory(pNewRelations, size);
2701 
2702  if (pPriorRelations != NULL && pPriorRelations->Count > 0) {
2705  "WDFCHILDLIST %p prior relations %p contained %d objects",
2706  GetHandle(), pPriorRelations, pPriorRelations->Count
2707  );
2708 
2709  RtlCopyMemory(pNewRelations,
2710  pPriorRelations,
2711  _ComputeRelationsSize(pPriorRelations->Count));
2712  }
2713 
2714  //
2715  // We can walk the ChildList without holding the spinlock because we set
2716  // m_State to ListLockedForEnum.
2717  //
2719 
2722  ple = pNext) {
2723  pNext = ple->Flink;
2724 
2726 
2727  switch (pEntry->m_DescriptionState) {
2729  //
2730  // This extension needs a device handle. Create one now.
2731  //
2733  "Creating PDO device object from reported device");
2734  if (CreateDevice(pEntry, &invalidateRelations) == FALSE) {
2735  break;
2736  }
2737 
2740  "PDO created successfully, WDFDEVICE %p !devobj %p",
2741  pEntry->m_Pdo->GetHandle(), pEntry->m_Pdo->GetDeviceObject());
2742 
2743  // || || Fall through || ||
2744  // \/ \/ \/ \/
2746 
2748  "Reporting PDO WDFDEVICE %p !devobj %p",
2749  pEntry->m_Pdo->GetHandle(),
2750  pEntry->m_Pdo->GetDeviceObject());
2751 
2752  pDevice = pEntry->m_Pdo->GetDeviceObject();
2754  pNewRelations->Objects[pNewRelations->Count] = pDevice;
2755  pNewRelations->Count++;
2756  break;
2757 
2758  case DescriptionNotPresent:
2759  //
2760  // We will now report the description as missing
2761  //
2764  "PDO WDFDEVICE %p !devobj %p reported as missing to pnp",
2765  pEntry->m_Pdo->GetHandle(), pEntry->m_Pdo->GetDeviceObject());
2766 
2767  pEntry->m_DescriptionState = DescriptionReportedMissing;
2768  pEntry->m_ReportedMissingCallbackState = CallbackNeedsToBeInvoked;
2769 
2770  break;
2771 
2773  break;
2774 
2775  default:
2776  ASSERTMSG("Invalid description state\n", FALSE);
2777  break;
2778  }
2779  }
2780 
2781 Done:
2783 
2784  //
2785  // Make sure that the description we just dequeued is not on the modification
2786  // list.
2787  //
2789  ProcessModificationsLocked(&freeHead);
2790 
2791  if (NT_SUCCESS(status)) {
2792  m_EnumRetries = 0;
2793  }
2794 
2796 
2797  if (invalidateRelations) {
2798  //
2799  // We failed for some reason or other. Queue up a new attempt.
2800  //
2801  // NOTE: no need to check m_Device->m_KnownPdo here
2802  // because we are in the middle of a QDR for m_Device which means
2803  // that it, or its stack, is already known to PnP.
2804  //
2806  }
2807 
2808  DrainFreeListHead(&freeHead);
2809 
2810  if (cleanupRelations) {
2811  if (pPriorRelations != NULL) {
2814  "Freeing prior relations %p", pPriorRelations);
2815 
2816  ExFreePool(pPriorRelations);
2817  pPriorRelations = NULL;
2818  }
2819 
2820  if (!NT_SUCCESS(status) && pNewRelations != NULL) {
2821  for(i = 0; i < pNewRelations->Count; i++) {
2822  ObDereferenceObject(pNewRelations->Objects[i]);
2823  }
2824 
2825  ExFreePool(pNewRelations);
2826  pNewRelations = NULL;
2827  }
2828 
2829  *DeviceRelations = pNewRelations;
2830  }
2831 
2832  return status;
2833 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
return STATUS_NOT_SUPPORTED
LIST_ENTRY m_DescriptionListHead
BOOLEAN CloneEntryLocked(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define TRUE
Definition: types.h:120
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
static size_t _ComputeRelationsSize(__in ULONG Count)
KIRQL irql
Definition: wave.h:1
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PSINGLE_LIST_ENTRY ple
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
KSPIN_LOCK m_ListLock
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
unsigned char BOOLEAN
UCHAR m_EnumRetries
FxDevice * pDevice
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
GLsizeiptr size
Definition: glext.h:5919
PFX_DRIVER_GLOBALS pFxDriverGlobals
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
WDFCHILDLIST GetHandle(VOID)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
Definition: typedefs.h:119
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACINGPNP
Definition: dbgtrace.h:67
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:2342
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
FxChildListState m_State
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define ObReferenceObject
Definition: obfuncs.h:204
BOOLEAN CreateDevice(__inout FxDeviceDescriptionEntry *Entry, __inout PBOOLEAN InvalidateRelations)
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static SERVICE_STATUS status
Definition: service.c:31
BOOLEAN ReenumerateEntryLocked(__inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
BOOLEAN m_StaticList
Definition: ps.c:97

Referenced by FxPkgPnp::HandleQueryBusRelations().

◆ ProcessModificationsLocked()

VOID FxChildList::ProcessModificationsLocked ( __inout PLIST_ENTRY  FreeListHead)
protected

Definition at line 1755 of file fxchildlist.cpp.

1758 {
1760  PLIST_ENTRY pCur, pNext;
1761  BOOLEAN invalidateRelations;
1762 
1763  //
1764  // If the list is locked or there are still active scans, we must not process
1765  // any modifications.
1766  //
1767  if (m_State != ListUnlocked || m_ScanCount > 0) {
1770  "Not processing modifications on WDFCHILDLIST %p (list state %d, "
1771  "scan count %d)", GetObjectHandle(), m_State, m_ScanCount);
1772  return;
1773  }
1774 
1777  "Begin processing modifications on WDFCHILDLIST %p", GetObjectHandle());
1778 
1779  //
1780  // First do the mod updates. As quick as possible. Note that we need to
1781  // update
1782  //
1785  pCur = pNext) {
1786 
1787  pNext = pCur->Flink;
1788 
1790 
1791  switch (pEntry->m_ModificationState) {
1793 
1794 
1795 
1796 
1797 
1798 
1799 
1800 
1801 
1802 
1803 
1804 
1805 
1806 
1807 
1808  pEntry->m_ModificationState = ModificationRemove;
1809  break;
1810 
1811  default:
1812  break;
1813  }
1814  }
1815 
1816  invalidateRelations = FALSE;
1819 
1822 
1823  ASSERT(pEntry->m_ModificationState == ModificationInsert ||
1824  pEntry->m_ModificationState == ModificationClone ||
1825  pEntry->m_ModificationState == ModificationRemove);
1826 
1829  "entry %p, mod state is %!FxChildListModificationState!",
1830  pEntry, pEntry->m_ModificationState);
1831 
1832  switch (pEntry->m_ModificationState) {
1833  case ModificationRemove:
1834  //
1835  // Remove's are stacked on top of the entry they need to take out.
1836  //
1837  ASSERT(pEntry->IsPresent());
1838 
1839  pEntry->m_ModificationState = ModificationUnspecified;
1840 
1843  "processing remove on entry %p, description state is "
1844  "%!FxChildListDescriptionState!",
1845  pEntry, pEntry->m_DescriptionState);
1846 
1847  switch (pEntry->m_DescriptionState) {
1849  //
1850  // We got to the entry before a DO could be created for it or
1851  // an instantiation failed. If deleeted before creation, the
1852  // list entry points to itself. If the instantiation failed,
1853  // the list entry is in the description list and must be
1854  // removed from it.
1855  //
1856  // Mark it for deletion now (outside of the lock being held).
1857  //
1860  "entry %p never reported to pnp, mark for deletion", pEntry);
1861 
1862  RemoveEntryList(&pEntry->m_DescriptionLink);
1863  InsertTailList(FreeListHead, &pEntry->m_DescriptionLink);
1864  break;
1865 
1869  "committing PDO WDFDEVICE %p, !devobj %p as not present",
1870  pEntry->m_Pdo->GetHandle(), pEntry->m_Pdo->GetDeviceObject());
1871 
1872  pEntry->m_DescriptionState = DescriptionNotPresent;
1873  invalidateRelations = TRUE;
1874  break;
1875 
1876  default:
1877  ASSERTMSG("Invalid description state\n", FALSE);
1878  break;
1879  }
1880 
1881  break;
1882 
1883  case ModificationInsert:
1884  //
1885  // CurEntry is our entry to insert into the list. We simply "move"
1886  // the mod entries to desc entries.
1887  //
1888  ASSERT(pEntry->m_DescriptionState == DescriptionUnspecified);
1889  pEntry->m_DescriptionState = DescriptionPresentNeedsInstantiation;
1890 
1893  "marking entry %p as needing instantiation", pEntry);
1894 
1895  InsertTailList(&m_DescriptionListHead, &pEntry->m_DescriptionLink);
1896  pEntry->m_ModificationState = ModificationUnspecified;
1897  invalidateRelations = TRUE;
1898  break;
1899 
1900  case ModificationClone:
1901  invalidateRelations = CloneEntryLocked(FreeListHead, pEntry, FALSE);
1902  break;
1903 
1904  default:
1905  ASSERTMSG("Invalid description modification state\n", FALSE);
1906  break;
1907  }
1908  }
1909 
1910  if (invalidateRelations) {
1911  PDEVICE_OBJECT pdo;
1912 
1913  if (m_ScanCount) {
1915  }
1916  else if ((pdo = m_Device->GetSafePhysicalDevice()) != NULL) {
1917  //
1918  // See previous usage of m_Device->m_KnownPdo for
1919  // comments on why a lock is not necessary when reading its value.
1920  //
1923  }
1924  else {
1926  }
1927  }
1928 
1931  "end processing modifications on WDFCHILDLIST %p", GetObjectHandle());
1932 }
CfxDevice * m_Device
Definition: fxobject.hpp:329
LIST_ENTRY m_ModificationListHead
LIST_ENTRY m_DescriptionListHead
BOOLEAN CloneEntryLocked(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
BOOLEAN m_InvalidationNeeded
#define TRUE
Definition: types.h:120
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603