ReactOS 0.4.15-dev-8231-g29a56f3
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)
 
virtual BOOLEAN Dispose (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
316
319
324
328
332
334
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}
MxEvent m_ScanEvent
KSPIN_LOCK m_ListLock
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE m_EvtAddressDescriptionDuplicate
BOOLEAN m_IsAdded
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE m_EvtIdentificationDescriptionDuplicate
ULONG m_IdentificationDescriptionSize
ULONG m_ScanCount
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP m_EvtIdentificationDescriptionCleanup
BOOLEAN m_StaticList
UCHAR m_EnumRetries
LIST_ENTRY m_ModificationListHead
FxTransactionedEntry m_TransactionLink
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY m_EvtAddressDescriptionCopy
PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP m_EvtAddressDescriptionCleanup
PULONG m_ScanTag
FxChildListCreateDeviceCallback m_EvtCreateDevice
ULONG m_AddressDescriptionSize
FxChildListScanForChildrenCallback m_EvtScanForChildren
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE m_EvtIdentificationDescriptionCompare
PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY m_EvtIdentificationDescriptionCopy
LIST_ENTRY m_DescriptionListHead
FxChildListState m_State
BOOLEAN m_InvalidationNeeded
size_t m_TotalDescriptionSize
CfxDevice * m_Device
Definition: fxobject.hpp:329
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
CHECK_RETURN_IF_USER_MODE __inline NTSTATUS Initialize(__in EVENT_TYPE Type, __in BOOLEAN InitialState)
Definition: mxeventkm.h:55
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
@ ListUnlocked
Definition: fxchildlist.hpp:90
@ ObjectDoNotLock
Definition: fxobject.hpp:128
@ FX_TYPE_CHILD_LIST
Definition: fxtypes.h:82
@ NotificationEvent
VOID SetTransactionedObject(__in FxObject *Object)
Definition: window.h:585
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474

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
int Count
Definition: noreturn.cpp:7
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
struct _DEVICE_RELATIONS DEVICE_RELATIONS

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;
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}
LONG NTSTATUS
Definition: precomp.h:26
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
description Header IdentificationDescriptionSize
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
Definition: ps.c:97
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129

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
406exit:
407 if (!NT_SUCCESS(ntStatus)) {
408 if (NULL != childList) {
409 childList->DeleteFromFailedCreate();
410 }
411 }
412 return ntStatus;
413}
VOID Initialize(__in PWDF_CHILD_LIST_CONFIG Config)
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
#define exit(n)
Definition: config.h:202
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:481

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 }
base of all file and directory entries
Definition: entries.h:83
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

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{
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}
static _Must_inspect_result_ NTSTATUS _ComputeTotalDescriptionSize(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_CHILD_LIST_CONFIG Config, __in size_t *TotalDescriptionSize)
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

◆ 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;
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 //
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}
unsigned char BOOLEAN
BOOLEAN HasAddressDescriptions(VOID)
friend struct FxDeviceDescriptionEntry
VOID DrainFreeListHead(__inout PLIST_ENTRY FreeListHead)
VOID CopyAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
VOID ProcessModificationsLocked(__inout PLIST_ENTRY FreeListHead)
FxDeviceDescriptionEntry * SearchBackwardsForMatchingDescriptionLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
FxDeviceDescriptionEntry * SearchBackwardsForMatchingModificationLocked(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Id)
_Must_inspect_result_ NTSTATUS DuplicateId(__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
_Must_inspect_result_ NTSTATUS DuplicateAddress(__out PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER Source)
__inline FxPkgPdo * GetPdoPkg(VOID)
Definition: fxdevice.hpp:1254
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
VOID MarkNoDeleteDDI(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1118
BOOLEAN m_AddedToStaticList
Definition: fxpkgpdo.hpp:63
FxDeviceDescriptionEntry * m_Description
Definition: fxpkgpdo.hpp:40
Definition: Header.h:9
KIRQL irql
Definition: wave.h:1
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
@ ModificationRemoveNotify
@ ModificationRemove
@ ModificationUnspecified
@ ModificationInsert
@ ScanTagActive
Definition: fxchildlist.hpp:97
@ ScanTagCancelled
Definition: fxchildlist.hpp:98
FxDevice * pPdo
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
#define ASSERT(a)
Definition: mode.c:44
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
Definition: typedefs.h:120
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription
Definition: wdfchildlist.h:124
_Inout_ PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddressDescription
Definition: wdfchildlist.h:255

◆ 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 //
843 m_ScanCount++;
844
846 "Begin iteration on WDFCHILDLIST %p, scan count %d",
848
850}
VOID InitIterator(__inout PWDF_CHILD_LIST_ITERATOR Iterator)
__inline VOID Clear()
Definition: mxeventkm.h:102
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define GetHandle(h)
Definition: treelist.c:116
_In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR Iterator
Definition: wdfchildlist.h:656

◆ 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
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}
PSINGLE_LIST_ENTRY ple
static FxDeviceDescriptionEntry * _FromDescriptionLink(__in PLIST_ENTRY Link)
static FxDeviceDescriptionEntry * _FromModificationLink(__in PLIST_ENTRY Link)
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

◆ 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}
pList EndScan()

◆ 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 }

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{
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}
PFN_WDF_CHILD_LIST_DEVICE_REENUMERATED m_EvtChildListDeviceReenumerated
@ DescriptionNotPresent
@ DescriptionPresentNeedsInstantiation
#define DO_NOTHING()
Definition: mxgeneral.h:32
FxChildListDescriptionState m_DescriptionState
PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER m_AddressDescription
FxChildListModificationState m_ModificationState

Referenced by ProcessBusRelations(), and ProcessModificationsLocked().

◆ CompareId()

Definition at line 492 of file fxchildlist.hpp.

496 {
499 Lhs,
500 Rhs);
501 }
502 else {
505 Rhs,
507 : FALSE;
508 }
509 }
#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 }
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

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

◆ CopyId()

Definition at line 273 of file fxchildlist.hpp.

Referenced by GetNextDevice().

◆ CreateDevice()

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

Definition at line 2251 of file fxchildlist.cpp.

2255{
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}
VOID MarkDescriptionNotPresentWorker(__inout FxDeviceDescriptionEntry *DescriptionEntry, __in BOOLEAN ModificationCanBeQueued)
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
@ DescriptionReportedMissing
@ DescriptionInstantiatedHasObject
FxVerifierDbgBreakPoint(pFxDriverGlobals)
#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER
Definition: ntstatus.h:915
_Must_inspect_result_ NTSTATUS Invoke(__in WDFCHILDLIST DeviceList, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, __in PWDFDEVICE_INIT ChildInit)
Definition: fxchildlist.hpp:46
#define STATUS_RETRY
Definition: udferr_usr.h:182
@ WdfDevStatePnpInit
Definition: wdfdevice.h:69
static int init
Definition: wintirpc.c:33

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);
360 }
361
362 return TRUE;
363}
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;
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 CleanupDescriptions(__in_opt PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdDescription, __in_opt PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER AddrDescription)
FxPkgPnp * m_PkgPnp
Definition: fxdevice.hpp:670
__inline WDF_DEVICE_PNP_STATE GetDevicePnpState()
Definition: fxdevice.hpp:1149
VOID PnpProcessEvent(__in FxPnpEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
@ ModificationNeedsPnpRemoval
@ DescriptionUnspecified
SINGLE_LIST_ENTRY * pCur
@ PnpEventRemove

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 }

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 }

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 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) {
666 //
667 // Insertion that never made through to the end of a scan.
668 //
670 break;
671
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 //
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
770 PDEVICE_OBJECT pdo;
771
772 //
773 // This does the m_KnownPdo check.
774 //
776
777 if (pdo != NULL) {
780 }
781 }
782
784 }
785
787
788 //
789 // Free structures outside of any internal WDF lock
790 //
791 DrainFreeListHead(&freeHead);
792}
VOID MarkModificationNotPresentWorker(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *ModificationEntry)
MdDeviceObject __inline GetSafePhysicalDevice(VOID)
Definition: fxdevice.hpp:1005
__inline VOID Set()
Definition: mxeventkm.h:91
@ ModificationClone
@ ScanTagFinished
Definition: fxchildlist.hpp:99
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
@ BusRelations
Definition: iotypes.h:2152

◆ 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}
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136

◆ 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}

◆ GetAddressDescriptionSize()

ULONG FxChildList::GetAddressDescriptionSize ( VOID  )
inline

Definition at line 257 of file fxchildlist.hpp.

260 {
262 }

Referenced by if().

◆ GetDevice()

WDFDEVICE FxChildList::GetDevice ( VOID  )

Definition at line 450 of file fxchildlist.cpp.

453{
454 return m_Device->GetHandle();
455}
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{
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}
Definition: devices.h:37
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
@ WdfChildListRetrieveDeviceNotYetCreated
Definition: wdfchildlist.h:55
@ WdfChildListRetrieveDeviceNoSuchDevice
Definition: wdfchildlist.h:56
@ WdfChildListRetrieveDeviceSuccess
Definition: wdfchildlist.h:54
WDF_EXTERN_C_START enum _WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS WDF_CHILD_LIST_RETRIEVE_DEVICE_STATUS

◆ GetHandle()

WDFCHILDLIST FxChildList::GetHandle ( VOID  )
inline

Definition at line 121 of file fxchildlist.hpp.

124 {
125 return (WDFCHILDLIST) GetObjectHandle();
126 }
return pObject GetObjectHandle()

Referenced by FxPkgPnp::HandleQueryBusRelations().

◆ GetIdentificationDescriptionSize()

ULONG FxChildList::GetIdentificationDescriptionSize ( VOID  )
inline

Definition at line 265 of file fxchildlist.hpp.

268 {
270 }

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
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
1052Done:
1054
1055 return status;
1056}
#define ULongToPtr(ul)
Definition: basetsd.h:92
_Must_inspect_result_ NTSTATUS VerifyDescriptionEntry(__in PLIST_ENTRY Entry)
VOID CopyId(__out PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Dest, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Source)
#define PtrToUlong(u)
Definition: config.h:107
@ ModificationIndex
Definition: fxchildlist.hpp:31
@ DescriptionIndex
Definition: fxchildlist.hpp:30
FxCollectionEntry * cur
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
if(dx< 0)
Definition: linetemp.h:194
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
struct _LIST_ENTRY * PLIST_ENTRY
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
@ WdfRetrievePendingChildren
Definition: wdfchildlist.h:63

◆ 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;
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 //
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
1172Done:
1174
1175 return result;
1176}
GLuint64EXT * result
Definition: glext.h:11304
@ WdfRetrievePresentChildren
Definition: wdfchildlist.h:61
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

◆ GetScanCount()

ULONG FxChildList::GetScanCount ( VOID  )
inline

◆ GetScanEvent()

MxEvent * FxChildList::GetScanEvent ( VOID  )
inline

Definition at line 129 of file fxchildlist.hpp.

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

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 }

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

◆ IndicateWakeStatus()

VOID FxChildList::IndicateWakeStatus ( __in NTSTATUS  WakeWakeStatus)

Definition at line 2911 of file fxchildlist.cpp.

2928{
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}
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
_Must_inspect_result_ _In_ WDFDEVICE _In_ NTSTATUS WaitWakeStatus
Definition: wdfdevice.h:3945

◆ 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 //
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}
virtual VOID AddChildList(__inout FxChildList *List)
Definition: fxdevicekm.cpp:431
PFN_WDF_CHILD_LIST_CREATE_DEVICE m_Method
Definition: fxchildlist.hpp:61
PFN_WDF_CHILD_LIST_SCAN_FOR_CHILDREN m_Method
Definition: fxchildlist.hpp:86

Referenced by _CreateAndInit().

◆ InitIterator()

VOID FxChildList::InitIterator ( __inout PWDF_CHILD_LIST_ITERATOR  Iterator)

Definition at line 808 of file fxchildlist.cpp.

811{
813
815 Iterator->Reserved[ModificationIndex] = ULongToPtr(1);
816 }
817}

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}
@ ListLockedForEnum
Definition: fxchildlist.hpp:91
@ CallbackInvoked
@ CallbackNeedsToBeInvoked

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 }

◆ IsStaticList()

BOOLEAN FxChildList::IsStaticList ( VOID  )
inline

Definition at line 334 of file fxchildlist.hpp.

337 {
338 return m_StaticList;
339 }

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}

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}
BOOLEAN IsStaticList(VOID)

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

◆ NotifyDeviceRemove()

VOID FxChildList::NotifyDeviceRemove ( __inout PLONG  ChildCount)

Definition at line 3041 of file fxchildlist.cpp.

3057{
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}
#define InterlockedIncrement
Definition: armddk.h:53
VOID NotifyDeviceSurpriseRemove(VOID)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
@ ListLockedForParentRemove
Definition: fxchildlist.hpp:92
@ PnpEventParentRemoved
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29

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}

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

◆ PostParentToD0()

VOID FxChildList::PostParentToD0 ( VOID  )

Definition at line 2883 of file fxchildlist.cpp.

2886{
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}
@ PowerParentToD0

◆ 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;
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
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
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
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
2781Done:
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}
BOOLEAN CreateDevice(__inout FxDeviceDescriptionEntry *Entry, __inout PBOOLEAN InvalidateRelations)
BOOLEAN ReenumerateEntryLocked(__inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
static size_t _ComputeRelationsSize(__in ULONG Count)
BOOLEAN CloneEntryLocked(__inout PLIST_ENTRY FreeListHead, __inout FxDeviceDescriptionEntry *Entry, __in BOOLEAN FromQDR)
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
@ FX_CHILD_LIST_MAX_RETRIES
FxDevice * pDevice
PFX_DRIVER_GLOBALS pFxDriverGlobals
GLsizeiptr size
Definition: glext.h:5919
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204

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}

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

◆ ReenumerateEntry()

VOID FxChildList::ReenumerateEntry ( __inout FxDeviceDescriptionEntry Entry)

Definition at line 1402 of file fxchildlist.cpp.

1405{
1406 LIST_ENTRY freeHead;
1407 KIRQL irql;
1408
1409 InitializeListHead(&freeHead);
1410
1413 ProcessModificationsLocked(&freeHead);
1415
1416 DrainFreeListHead(&freeHead);
1417}

Referenced by FxPkgPdo::AskParentToRemoveAndReenumerate().

◆ ReenumerateEntryLocked()

BOOLEAN FxChildList::ReenumerateEntryLocked ( __inout FxDeviceDescriptionEntry Entry,
__in BOOLEAN  FromQDR 
)
protected

Definition at line 1339 of file fxchildlist.cpp.

1343{
1345
1346 //
1347 // Check to see if there are modifications pending
1348 //
1349 if (IsListEmpty(&Entry->m_ModificationLink) && Entry->IsPresent()) {
1350 //
1351 // No mods pending...
1352 //
1353
1354 //
1355 // We can only go down this path if the device was reported to the system
1356 // b/c the stack on our PDO is the one invoking this call.
1357 //
1358 ASSERT(Entry->m_DescriptionState == DescriptionInstantiatedHasObject);
1359
1360 if (FromQDR == FALSE) {
1361 //
1362 // The entry has not been reported as missing by the driver, try to
1363 // clone it and insert a modification.
1364 //
1365 Entry->m_ModificationState = ModificationClone;
1366 InsertTailList(&m_ModificationListHead, &Entry->m_ModificationLink);
1367 }
1368
1371 "Inserting clone modification for PDO WDFDEVICE %p, !devobj %p",
1372 Entry->m_Pdo->GetHandle(), Entry->m_Pdo->GetDeviceObject());
1373
1374 result = TRUE;
1375 }
1376 else {
1377 //
1378 // If there is a pending modification, we don't do anything.
1379 // If the device is already not present, we don't do anything.
1380 //
1381 // ModficiationRemove or
1382 // ModficiationRemoveNotify: we would be reenumerating a device which
1383 // is being removed which is not what we want
1384 //
1385 // ModificationClone: we would be cloning a clone which is not what
1386 // we want either
1387 //
1390 "Requested reenumeration for PDO WDFDEVICE %p, !devobj %p"
1391 " no possible (pending mod %d, currently present %d)",
1392 Entry->m_Pdo->GetHandle(), Entry->m_Pdo->GetDeviceObject(),
1393 IsListEmpty(&Entry->m_ModificationLink), Entry->IsPresent());
1394
1395 result = FALSE;
1396 }
1397
1398 return result;
1399}

Referenced by ProcessBusRelations(), and ReenumerateEntry().

◆ ScanForChildren()

VOID FxChildList::ScanForChildren ( VOID  )
inline

Definition at line 308 of file fxchildlist.hpp.

311 {
313 }
VOID Invoke(__in WDFCHILDLIST DeviceList)
Definition: fxchildlist.hpp:75

◆ SearchBackwardsForMatchingDescriptionLocked()

FxDeviceDescriptionEntry * FxChildList::SearchBackwardsForMatchingDescriptionLocked ( __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER  Id)
protected

Definition at line 2181 of file fxchildlist.cpp.

2184{
2187
2190 ple = ple->Blink) {
2191
2193
2194 if (CompareId(pEntry->m_IdentificationDescription, Id)) {
2195 return pEntry;
2196 }
2197 }
2198
2199 return NULL;
2200}
DWORD Id
BOOLEAN CompareId(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Lhs, __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Rhs)
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by Add(), GetAddressDescription(), GetDeviceFromId(), and UpdateAsMissing().

◆ SearchBackwardsForMatchingModificationLocked()

FxDeviceDescriptionEntry * FxChildList::SearchBackwardsForMatchingModificationLocked ( __in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER  Id)
protected

Definition at line 2159 of file fxchildlist.cpp.

2162{
2165
2168 ple = ple->Blink) {
2169
2171
2172 if (CompareId(pEntry->m_IdentificationDescription, Id)) {
2173 return pEntry;
2174 }
2175 }
2176
2177 return NULL;
2178}

Referenced by Add(), GetAddressDescription(), GetDeviceFromId(), and UpdateAsMissing().

◆ UpdateAddressDescriptionFromEntry()

VOID FxChildList::UpdateAddressDescriptionFromEntry ( __inout FxDeviceDescriptionEntry Entry,
__in PWDF_CHILD_ADDRESS_DESCRIPTION_HEADER  AddressDescription 
)

Definition at line 1656 of file fxchildlist.cpp.

1660{
1661 KIRQL irql;
1662
1664 CopyAddress(Entry->m_AddressDescription, AddressDescription);
1666
1667
1668
1669
1670
1671
1672}

◆ UpdateAllAsPresent()

VOID FxChildList::UpdateAllAsPresent ( __in_opt PULONG  ScanTag = NULL)

Definition at line 1421 of file fxchildlist.cpp.

1424{
1425 PLIST_ENTRY pCur, pNext;
1426 LIST_ENTRY freeHead;
1428 KIRQL irql;
1429
1431
1432 if (ScanTag != NULL) {
1433 if (*ScanTag != ScanTagActive) {
1434 ASSERT(*ScanTag == ScanTagCancelled);
1436 return;
1437 }
1438 }
1439
1440 //
1441 // Walk over all mod entries and ensure any inserts are still marked
1442 // present.
1443 //
1446 pCur = pNext) {
1447
1448 pNext = pCur->Flink;
1449
1451
1452 if (pEntry->m_ModificationState == ModificationInsert) {
1453 pEntry->m_FoundInLastScan = TRUE;
1454 }
1455 }
1456
1457 //
1458 // Walk over all desc entries and ensure they are marked present.
1459 //
1462 pCur = pCur->Flink) {
1463
1465
1466 if (pEntry->IsPresent()) {
1467 ASSERT(pEntry->m_ModificationState != ModificationRemoveNotify);
1468
1469 if (pEntry->m_ModificationState != ModificationRemove) {
1470 pEntry->m_FoundInLastScan = TRUE;
1471 }
1472 }
1473 }
1474
1475 //
1476 // Attempt to drain any mods we made.
1477 //
1478 InitializeListHead(&freeHead);
1479 ProcessModificationsLocked(&freeHead);
1480
1482
1483 DrainFreeListHead(&freeHead);
1484}

◆ UpdateAsMissing()

Definition at line 1180 of file fxchildlist.cpp.

1183{
1185 LIST_ENTRY freeHead;
1187 KIRQL irql;
1188
1189 //
1190 // Assume success
1191 //
1193 InitializeListHead(&freeHead);
1194
1196
1198
1199 if (pEntry != NULL) {
1200
1201
1202
1203
1204
1205
1206
1207
1209 }
1210 else {
1212
1213 if (pEntry != NULL) {
1214 if (pEntry->IsPresent()) {
1216 }
1217 }
1218 else {
1219 //
1220 // Couldn't find anything
1221 //
1223 }
1224 }
1225
1226 ProcessModificationsLocked(&freeHead);
1227
1229
1230 DrainFreeListHead(&freeHead);
1231
1232 return status;
1233}
static const WCHAR Description[]
Definition: oid.c:1266

Referenced by FxPkgPdo::PnpEventEjectHardwareOverload().

◆ UpdateDeviceAsMissing()

_Must_inspect_result_ NTSTATUS FxChildList::UpdateDeviceAsMissing ( __in CfxDevice Device)

Definition at line 1237 of file fxchildlist.cpp.

1253{
1255 LIST_ENTRY freeHead, *ple;
1256 KIRQL irql;
1257 BOOLEAN found;
1258 CfxDevice *pdo;
1259
1260 found = FALSE;
1261 pdo = NULL;
1262 InitializeListHead(&freeHead);
1263
1265
1268 ple = ple->Blink) {
1269
1271
1272 //
1273 // Static PDO may not be populated in m_Pdo yet, so check the PDO
1274 // from id description.
1275 //
1276 if (m_StaticList) {
1277 pdo = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
1279 Header)->Pdo;
1280 }
1281 else {
1282 pdo = pEntry->m_Pdo;
1283 }
1284
1285 if (pdo == Device) {
1286 found = TRUE;
1288 break;
1289 }
1290 }
1291
1292 if (found == FALSE) {
1295 ple = ple->Blink) {
1296
1298
1299 //
1300 // Static PDO may not be populated in m_Pdo yet, so check the PDO
1301 // from id description.
1302 //
1303 if (m_StaticList) {
1304 pdo = CONTAINING_RECORD(pEntry->m_IdentificationDescription,
1306 Header)->Pdo;
1307 }
1308 else {
1309 pdo = pEntry->m_Pdo;
1310 }
1311
1312 if (pdo == Device) {
1313 found = TRUE;
1314
1315 if (pEntry->IsPresent()) {
1317 }
1318
1319 break;
1320 }
1321 }
1322 }
1323
1324 ProcessModificationsLocked(&freeHead);
1325
1327
1328 DrainFreeListHead(&freeHead);
1329
1330 if (found) {
1331 return STATUS_SUCCESS;
1332 }
1333 else {
1334 return STATUS_NO_SUCH_DEVICE;
1335 }
1336}

Referenced by if().

◆ VerifyDescriptionEntry()

_Must_inspect_result_ NTSTATUS FxChildList::VerifyDescriptionEntry ( __in PLIST_ENTRY  Entry)
protected

Definition at line 2204 of file fxchildlist.cpp.

2207{
2208 if (Entry == &m_DescriptionListHead) {
2209 return STATUS_SUCCESS;
2210 }
2211 else {
2213
2216 ple = ple->Flink) {
2217 if (Entry == ple) {
2218 return STATUS_SUCCESS;
2219 }
2220 }
2221
2223 }
2224}

Referenced by GetNextDevice().

◆ VerifyModificationEntry()

_Must_inspect_result_ NTSTATUS FxChildList::VerifyModificationEntry ( __in PLIST_ENTRY  Entry)
protected

Definition at line 2228 of file fxchildlist.cpp.

2231{
2232 if (Entry == &m_ModificationListHead) {
2233 return STATUS_SUCCESS;
2234 }
2235 else {
2237
2240 ple = ple->Flink) {
2241 if (Entry == ple) {
2242 return STATUS_SUCCESS;
2243 }
2244 }
2245
2247 }
2248}

Friends And Related Function Documentation

◆ FxDeviceDescriptionEntry

Definition at line 103 of file fxchildlist.hpp.

Referenced by Add().

Member Data Documentation

◆ m_AddressDescriptionSize

ULONG FxChildList::m_AddressDescriptionSize
protected

◆ m_DescriptionListHead

◆ m_EnumRetries

UCHAR FxChildList::m_EnumRetries
protected

Definition at line 624 of file fxchildlist.hpp.

Referenced by FxChildList(), and ProcessBusRelations().

◆ m_EvtAddressDescriptionCleanup

PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_CLEANUP FxChildList::m_EvtAddressDescriptionCleanup
protected

Definition at line 602 of file fxchildlist.hpp.

Referenced by CleanupDescriptions(), FxChildList(), and Initialize().

◆ m_EvtAddressDescriptionCopy

PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_COPY FxChildList::m_EvtAddressDescriptionCopy
protected

Definition at line 596 of file fxchildlist.hpp.

Referenced by CopyAddress(), FxChildList(), and Initialize().

◆ m_EvtAddressDescriptionDuplicate

PFN_WDF_CHILD_LIST_ADDRESS_DESCRIPTION_DUPLICATE FxChildList::m_EvtAddressDescriptionDuplicate
protected

Definition at line 599 of file fxchildlist.hpp.

Referenced by DuplicateAddress(), FxChildList(), and Initialize().

◆ m_EvtChildListDeviceReenumerated

PFN_WDF_CHILD_LIST_DEVICE_REENUMERATED FxChildList::m_EvtChildListDeviceReenumerated
protected

Definition at line 605 of file fxchildlist.hpp.

Referenced by CloneEntryLocked(), and Initialize().

◆ m_EvtCreateDevice

FxChildListCreateDeviceCallback FxChildList::m_EvtCreateDevice
protected

Definition at line 574 of file fxchildlist.hpp.

Referenced by CreateDevice(), and Initialize().

◆ m_EvtIdentificationDescriptionCleanup

PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_CLEANUP FxChildList::m_EvtIdentificationDescriptionCleanup
protected

Definition at line 590 of file fxchildlist.hpp.

Referenced by CleanupDescriptions(), FxChildList(), and Initialize().

◆ m_EvtIdentificationDescriptionCompare

PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COMPARE FxChildList::m_EvtIdentificationDescriptionCompare
protected

Definition at line 593 of file fxchildlist.hpp.

Referenced by CompareId(), FxChildList(), and Initialize().

◆ m_EvtIdentificationDescriptionCopy

PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_COPY FxChildList::m_EvtIdentificationDescriptionCopy
protected

Definition at line 584 of file fxchildlist.hpp.

Referenced by CopyId(), FxChildList(), and Initialize().

◆ m_EvtIdentificationDescriptionDuplicate

PFN_WDF_CHILD_LIST_IDENTIFICATION_DESCRIPTION_DUPLICATE FxChildList::m_EvtIdentificationDescriptionDuplicate
protected

Definition at line 587 of file fxchildlist.hpp.

Referenced by DuplicateId(), FxChildList(), and Initialize().

◆ m_EvtScanForChildren

FxChildListScanForChildrenCallback FxChildList::m_EvtScanForChildren
protected

Definition at line 576 of file fxchildlist.hpp.

Referenced by Initialize(), and ScanForChildren().

◆ m_IdentificationDescriptionSize

ULONG FxChildList::m_IdentificationDescriptionSize
protected

◆ m_InvalidationNeeded

BOOLEAN FxChildList::m_InvalidationNeeded
protected

Definition at line 615 of file fxchildlist.hpp.

Referenced by EndScan(), FxChildList(), and ProcessModificationsLocked().

◆ m_IsAdded

BOOLEAN FxChildList::m_IsAdded
protected

Definition at line 622 of file fxchildlist.hpp.

Referenced by Dispose(), FxChildList(), and Initialize().

◆ m_ListLock

◆ m_ModificationListHead

◆ m_ScanCount

ULONG FxChildList::m_ScanCount
protected

◆ m_ScanEvent

MxEvent FxChildList::m_ScanEvent
protected

Definition at line 630 of file fxchildlist.hpp.

Referenced by BeginIteration(), BeginScan(), EndScan(), FxChildList(), and GetScanEvent().

◆ m_ScanTag

PULONG FxChildList::m_ScanTag
protected

Definition at line 626 of file fxchildlist.hpp.

Referenced by BeginScan(), EndScan(), and FxChildList().

◆ m_State

◆ m_StaticList

◆ m_TotalDescriptionSize

size_t FxChildList::m_TotalDescriptionSize
protected

Definition at line 568 of file fxchildlist.hpp.

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

◆ m_TransactionLink

FxTransactionedEntry FxChildList::m_TransactionLink

Definition at line 565 of file fxchildlist.hpp.

Referenced by _FromEntry(), and FxChildList().


The documentation for this class was generated from the following files: