ReactOS 0.4.16-dev-336-gb667d82
fxobject.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxObject.cpp
8
9Abstract:
10
11 This module contains the implementation of the base object
12
13Author:
14
15
16
17
18
19Environment:
20
21 Both kernel and user mode
22
23Revision History:
24
25
26
27
28
29
30
31
32
33
34--*/
35
36#include "fxobjectpch.hpp"
37
38extern "C" {
39
40#if defined(EVENT_TRACING)
41#include "FxObject.tmh"
42#else
45#endif
46
47}
48
52 __in PFX_DRIVER_GLOBALS FxDriverGlobals
53 ) :
54 m_Type(Type),
56 m_Globals(FxDriverGlobals)
57#if FX_CORE_MODE==FX_CORE_USER_MODE
58#ifndef INLINE_WRAPPER_ALLOCATION
59 ,m_COMWrapper(NULL)
60#endif
61#endif
62{
63 ASSERT((((ULONG_PTR) this) & FxHandleFlagMask) == 0x0);
64
66}
67
71 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
73 ) :
74 m_Type(Type),
76 m_Globals(FxDriverGlobals)
77{
79 //
80 // only for non embedded objects
81 //
82 ASSERT((((ULONG_PTR) this) & FxHandleFlagMask) == 0x0);
83 }
84
86}
87
89{
90 FxTagTracker *pTagTracker;
91
92
93
94
95
96
97
98 pTagTracker = GetTagTracker();
99
100 if (pTagTracker != NULL) {
101 delete pTagTracker;
102 }
103
105
106 //
107 // We need to ensure there are no leaked child objects, or
108 // parent associations.
109 //
110 // This can occur if someone calls the C++ operator delete,
111 // or Release() to destroy the object.
112 //
113 // This is generally invalid in the framework, though certain
114 // objects may understand the underlying contract, but must
115 // make sure there are no left over un-Disposed associations.
116 //
117 // Embedded FxObject's also don't have delete called on them,
118 // and have to manually manage any child associations when
119 // their parent object disposes by calling PerformEarlyDispose.
120 //
121 // They don't have an associated lifetime parent since they
122 // are embedded.
123 //
124 if (m_ParentObject != NULL ||
126 PCSTR pHandleName;
127
128 pHandleName = FxObjectTypeToHandleName(m_Type);
129 if (pHandleName == NULL) {
130 pHandleName = "WDFOBJECT";
131 }
132
133 ASSERTMSG(
134 "Object was freed using WdfObjectDereference, not WdfObjectDelete\n",
135 m_ParentObject == NULL &&
138 );
139
142 "Handle %s %p (raw object %p) was freed using "
143 "WdfObjectDereference(), not WdfObjectDelete()",
144 pHandleName, GetObjectHandleUnchecked(), this);
145
149 (ULONG_PTR) this);
150 }
151
152 //
153 // This is called when the reference count goes to zero
154 //
156}
157
158
159VOID
160FX_VF_METHOD(FxObject, VerifyConstruct) (
161 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
163 )
164{
165 UNREFERENCED_PARAMETER(FxDriverGlobals);
166
167#if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
169#endif
170
172 "this object's type is not listed in FxObjectsInfo\n",
174
175 //
176 // If this is an embedded object, there is no possibility of having
177 // a debug extension, so do not set FXOBJECT_FLAGS_HAS_DEBUG *ever*
178 // in this case.
179 //
180 if (m_Globals->IsObjectDebugOn() && Embedded == FALSE) {
181 FxObjectDebugExtension* pExtension;
182
183 m_ObjectFlags |= FXOBJECT_FLAGS_HAS_DEBUG;
184
185 pExtension = GetDebugExtension();
187
188 //
189 // Assume that zero is an invalid state.
190 //
192 RtlZeroMemory(&pExtension->StateHistory[0],
193 ARRAY_SIZE(pExtension->StateHistory));
194 pExtension->StateHistoryIndex = 0;
195
196 //
197 // Setup the first slot to our new state.
198 //
199 pExtension->StateHistory[0] = FxObjectStateCreated;
200
201 AllocateTagTracker(m_Type);
202 }
203}
204
205
206VOID
208 VOID
209 )
210{
211
212
213
214
215
216
217
218
219
220
221
222
223 //
224 // No other access, OK to test flag without grabbing spinlock
225 // since it can only be set at create.
226 //
228 //
229 // If this is a passive level only object, ensure we only destroy
230 // it from passive level. No need to hold the object lock when
231 // changing to this state since no other thread can change our
232 // state.
233 //
235
236 //
237 // Note, we cannot be holding a lock while making this call b/c by
238 // the time it returns, it could have freed the object and the
239 // KeReleaseSpinLock call would have touched freed pool.
240 //
241
242 //FxToObjectItf::FxAddToDriverDisposeList(m_Globals, this);
243
244
246
247 }
248 else {
250 }
251}
252
257 )
258{
260
261 if (Params->Type == FX_TYPE_OBJECT) {
262 *Params->Object = this;
264 }
265 else {
267 }
268
269 return status;
270}
271
272VOID
275 )
276{
277 ASSERT(IsDebug());
278
279 if (m_Globals->DebugExtension != NULL &&
283 Type)) {
284 //
285 // Failure to CreateAndInitialize a tag tracker is no big deal, we just
286 // don't track references.
287 //
288
291 m_Globals,
293 FALSE,
294 this
295 );
296
297 //
298 // For now we overload the requirement of a tag tracker as also tracing
299 // state changes.
300 //
302 }
303}
304
305VOID
306FxObject::operator delete(
308 )
309{
310 ASSERT(Memory != NULL);
311
312
313
314
315
316
317
318
319
320
321
322
323
324 FxPoolFree(_GetBase((FxObject*) Memory));
325}
326
327VOID
329 VOID
330 )
331{
333 WDFOBJECT h;
334
335 //
336 // Deleted before Commit or it is an internal object
337 //
338 if (IsCommitted() == FALSE) {
339 return;
340 }
341
342 //
343 // We only should have an object handle when we have an external object
344 //
345 h = GetObjectHandle();
346
347 for (pHeader = GetContextHeader();
348 pHeader != NULL;
353 }
354 }
355
356 m_ObjectFlags &= ~FXOBJECT_FLAGS_HAS_CLEANUP;
357}
358
359VOID
361 VOID
362 )
363/*++
364
365Routine Description:
366
367 Clears out any assigned callbacks on the object.
368
369Arguments:
370 None
371
372Return Value:
373 None
374
375 --*/
376{
378
379 for (pHeader = GetContextHeader();
380 pHeader != NULL;
382
385 }
386
387 m_ObjectFlags &= ~FXOBJECT_FLAGS_HAS_CLEANUP;
388}
389
390VOID
392 VOID
393 )
394/*++
395
396Routine Description:
397 Clears out any assigned callbacks on the object and then deletes it. Clearing
398 out the callbacks are necessary so that the driver's callbacks are not called
399 on a buffer that they didn't initialize.
400
401Arguments:
402 None
403
404Return Value:
405 None
406
407 --*/
408{
410
411 //
412 // After this call returns "this" is destroyed is not a valid pointer!
413 //
414 DeleteObject();
415
416 //
417 // "this" is now freed memory, do not touch it!
418 //
419}
420
421//
422// FxObject Parent/Child Rules:
423//
424// The FxObject state machine protects state transitions when
425// objects are being associated with each other, and races
426// that can occur when a child and parent object are being
427// deleted at the same time. This provides the backbone of
428// assurance on the objects state.
429//
430// While transiting object states, the following must be taken
431// into consideration:
432//
433// Reference counts:
434//
435// When an object is created with operator new(), it has a reference count
436// of one.
437//
438// When a DeleteObject is done on it, the reference count is decremented
439// after delete processing is done (which can include disposing children),
440// and this results in the objects destruction.
441//
442// When an object is created by operator new() and immediately associated
443// with a parent object, its reference count remains one.
444//
445// When either the DeleteObject() method is invoked, or the parent object
446// disposes the child object with ParentDeleteEvent(), eventually the
447// object will dereference itself after delete processing is done only
448// once.
449//
450// Even in the face of race conditions, the object state machine ensures that
451// only one set of the proper delete conditions occur (dispose children, invoke
452// driver and class dispose callbacks, dereference object).
453//
454// An object is responsible for releasing its own reference count on its
455// self when it goes into the FxObjectStateDeletedAndDisposed.
456//
457// This has been *carefully* designed so that only the original object
458// references are required for this automatic lifetime case to avoid
459// extra interlocked operations in AddRef and Release frequently. These
460// extra interlocked operations can have a big performance impact on
461// the WDF main I/O paths, in which object relationship's are being used.
462//
463// A simpler implementation may try and have the parent add a reference
464// to the child, and the child add a reference to the parent, but this
465// is a tightly coupled implementation controlled by the object state
466// machine. A circular reference pattern is OK for objects that
467// do not have a formal designed in relationship that can be expressed
468// in the complex tear down contract implemented in the state machine.
469//
470// SpinLocks:
471//
472// The m_SpinLock field protects each indivdual objects m_ObjectState
473// variable, the list of child objects that it has, and the m_ParentObject
474// field.
475//
476// In addition, if any object associates itself with a parent object,
477// it effectively "lends" its m_ChildEntry field to the parent object,
478// and these are manipulated and protected by the parent objects m_SpinLock.
479//
480// Lock Order:
481//
482// Currently the lock order is Child -> Parent, meaning a child
483// can call the AddChildObjectInternal, RemoveChildObjectInternal, methods with
484// the child lock held.
485//
486// The parent object will not invoke any child object ParentDeleteEvent()
487// while holding the parents m_SpinLock.
488//
489// This order allows potential races between child DeleteObject and parent
490// Dispose to be resolved without extra reference counts and multiple
491// acquires and releases of the spinlocks in the normal cases.
492//
493//
494// AddChildObjectInternal/RemoveChildObjectInternal:
495//
496// When a child object is added to the parent, the parent can delete
497// the child object at any time when the parent object is deleted
498// or disposed.
499//
500// If a call to RemoveChildObjectInternal is made, the caller may not "win"
501// the inherent race with a parent object Dispose() occuring. This
502// is similar to the WDM IRP cancel race, and is handled in exactly
503// the same fashion.
504//
505// If an object is associated with a parent, and later removal
506// is desired, the return status of RemoveChildObjectInternal must be
507// tested, and if not success, the caller should not delete the
508// child object itself, since the parent is in the process
509// of doing so. The caller "lost the Dispose race".
510//
511//
512// m_ParentObject field:
513//
514// This field is set by the child object after it successfully
515// adds a parent object, and clear it when it is disposed by
516// the parent, or removes the parent association.
517//
518// It is protected by the childs m_SpinLock field.
519//
520
521
522
523
524
525
526
530 __in FxObject* ParentObject
531 )
532/*++
533
534Routine Description:
535 Assign a parent to the current object. The parent can not be the same
536 object.
537
538Arguments:
539 ParentObject - Object to become the parent for this object
540
541Returns:
542
543Comments:
544
545 The caller "passes" its initial object reference to us, so we
546 do not take an additional reference on the object.
547
548 If we are deleted, Dispose() will be invoked on the object, and
549 its reference will be released.
550
551 This provides automatic deletion of associated child objects if
552 the object does not keep any extra references.
553
554--*/
555{
556 KIRQL oldIrql;
558
559 m_SpinLock.Acquire(&oldIrql);
560
561 //
562 // Can't add a parent if the current object is being deleted
563 //
566 m_SpinLock.Release(oldIrql);
568 }
569
570 //
571 // Current Object can't already have a parent, and can't
572 // be its own parent.
573 //
574 if (m_ParentObject != NULL) {
575 m_SpinLock.Release(oldIrql);
577 }
578
579 if (m_ParentObject == this) {
580 m_SpinLock.Release(oldIrql);
582 }
583
584 //
585 // We don't allow a parent object to be assigned after
586 // FxObject::Commit().
587 //
588 ASSERTMSG("Parent object can not be assigned after Commit()\n", !IsCommitted());
589
591
592 status = ParentObject->AddChildObjectInternal(this);
593
594 if (NT_SUCCESS(status)) {
595 m_ParentObject = ParentObject;
596 }
597
598 m_SpinLock.Release(oldIrql);
599
600 return status;
601}
602
609 )
610{
611 FxContextHeader *pCur, **ppLast;
613 KIRQL irql;
614
616
618
619 //
620 // This should never happen since all outward facing objects have a
621 // context header; framework never calls this function on internal
622 // objects.
623 //
624 ASSERT(pCur != NULL);
625
626 //
627 // Acquire the lock to lock the object's state. A side affect of grabbing
628 // the lock is that all updaters who want to add a context are serialized.
629 // All callers who want to find a context do not need to acquire the lock
630 // becuase they are not going to update the list, just read from it.
631 //
632 // Once a context has been added, it will not be removed until the object
633 // has been deleted.
634 //
635 m_SpinLock.Acquire(&irql);
636
638 //
639 // Iterate over the list of contexts already on this object and see if
640 // this type already is attached.
641 //
642 for (ppLast = &pCur->NextHeader;
643 pCur != NULL;
644 ppLast = &pCur->NextHeader, pCur = pCur->NextHeader) {
645
646 if (pCur->ContextTypeInfo == Header->ContextTypeInfo) {
647 //
648 // Dupe found, return error but give the caller the context
649 // pointer
650 //
651 if (Context != NULL) {
652 *Context = &pCur->Context[0];
653 }
654
656 break;
657 }
658 }
659
660 if (pCur == NULL) {
661 //
662 // By using the interlocked to update, we don't need to use a lock
663 // when walking the list to find the context. The only reason
664 // we are holding the object lock is to lock the current state
665 // (m_ObjectState) of the object.
666 //
669
670 if (Context != NULL) {
671 *Context = &Header->Context[0];
672 }
673
674 //
675 // FxContextHeaderInit does not set these callbacks. If this were
676 // the creation of the object itself, FxObject::Commit would have done
677 // this assignment.
678 //
679 Header->EvtDestroyCallback = Attributes->EvtDestroyCallback;
680
681 if (Attributes->EvtCleanupCallback != NULL) {
682 Header->EvtCleanupCallback = Attributes->EvtCleanupCallback;
684 }
685
686 }
687 }
688 else {
689 //
690 // Object is being torn down, adding a context is a bad idea because we
691 // cannot guarantee that the cleanup or destroy routines will be called
692 //
694 }
695
696 m_SpinLock.Release(irql);
697
698 return status;
699}
700
704 __in FxObject* ChildObject
705 )
706
707/*++
708
709Routine Description:
710 Called by an object to be added to this objects child list
711
712Arguments:
713 ChildObject - Object to add this this objects child list
714
715Returns:
716 NTSTATUS
717
718Comments:
719 The caller "passes" its initial object reference to us, so we
720 do not take an additional reference on the object.
721
722 If we are deleted, Dispose() will be invoked on the object, and
723 its reference will be released.
724
725 This provides automatic deletion of associated child objects if
726 the object does not keep any extra references.
727
728--*/
729{
730 KIRQL oldIrql;
731
732 m_SpinLock.Acquire(&oldIrql);
733
734 //
735 // Can't add child if the current object is being deleted
736 //
739 m_SpinLock.Release(oldIrql);
741 }
742
743 //
744 // ChildObject can't already have a parent, and can't
745 // be its own parent.
746 //
747 ASSERT(ChildObject->m_ParentObject == NULL);
748 ASSERT(IsListEmpty(&ChildObject->m_ChildEntry));
749 ASSERT(ChildObject != this);
750
751 //
752 // Add to our m_ChildList
753 //
754 InsertTailList(&m_ChildListHead, &ChildObject->m_ChildEntry);
755
756 if (ChildObject->GetDeviceBase() == NULL) {
757 //
758 // Propagate the device base downward to the child
759 //
760 ChildObject->SetDeviceBase(GetDeviceBase());
761 }
762
763 m_SpinLock.Release(oldIrql);
764
765 return STATUS_SUCCESS;
766}
767
771 __in FxObject* ChildObject
772 )
773/*++
774
775Routine Description:
776
777 Remove a ChildObject from our child associations list.
778
779 The ChildObject must exist in our list if we are not
780 otherwise disposing or deleting ourselves.
781
782 If we are not disposing, the child is removed from the list
783 and its reference count is unmodified.
784
785 If we are disposing, a failure is returned so that the caller
786 does not delete or dereference the child object itself, since
787 this is similar to a cancel IRP race condition.
788
789Arguments:
790 ChildObject - the object to remove this object's list of children
791
792Returns:
793
794 STATUS_SUCCESS - Child was removed from the list, no parent Dispose()
795 can occur.
796
797 !STATUS_SUCCESS - Child can not be removed from the list, and is being
798 Disposed by the parent. The caller must *not* delete
799 the object itself.
800
801--*/
802
803{
804 KIRQL oldIrql;
805
806 m_SpinLock.Acquire(&oldIrql);
807
808 //
809 // Object is already being deleted, this object will be removed as a child
810 // by the parents Dispose()
811 //
814 m_SpinLock.Release(oldIrql);
816 }
817
818 //
819 // We should be the child object's parent
820 //
821 ASSERT(ChildObject->m_ParentObject == this);
822
823 //
824 // Child should be on our list
825 //
826 ASSERT(!IsListEmpty(&ChildObject->m_ChildEntry));
827
828 //
829 // We should have entries if someone wants to remove from our list
830 //
832
833 RemoveEntryList(&ChildObject->m_ChildEntry);
834
835 //
836 // Mark it removed
837 //
838 InitializeListHead(&ChildObject->m_ChildEntry);
839
840 //
841 // We did not take a reference on the child object when it
842 // was added to the list, so we do not dereference it
843 // on the remove call.
844 //
845 // Note: We only dereference child objects when we are deleted
846 // ourselves, not when the child object manually breaks the
847 // association by calling this method.
848 //
849 m_SpinLock.Release(oldIrql);
850
851 return STATUS_SUCCESS;
852}
853
858 )
859
860/*++
861
862Routine Description:
863 Return this objects parent, which could be NULL if
864 the object is not part of an association, or this or
865 the parent object is deleting.
866
867 An extra reference is taken on the parent object which
868 must eventually be released by the caller.
869
870Arguments:
871 Tag - Tag to use when referencing the parent
872
873Returns:
874
875 Parent object, otherwise NULL if no parent for this object
876
877--*/
878
879{
880 KIRQL oldIrql;
881 FxObject* parentObject;
882
883 m_SpinLock.Acquire(&oldIrql);
884
886 parentObject = m_ParentObject;
887 }
888 else {
889 // Parent is disposing us, or we are being disposed
890 parentObject = NULL;
891 }
892
893 if (parentObject != NULL) {
894 parentObject->ADDREF(Tag);
895 }
896
897 m_SpinLock.Release(oldIrql);
898
899 return parentObject;
900}
901
906 __out_opt WDFOBJECT* ObjectHandle,
908 __in BOOLEAN AssignDriverAsDefaultParent
909 )
910/*++
911
912Routine Description:
913 Commit the object before returning the handle to the caller.
914
915Arguments:
916 Attributes - PWDF_OBJECT_ATTRIBUTES to assign to this object
917
918 ObjectHandle - Location to return the objects handle
919
920Returns:
921 NTSTATUS of the result. STATUS_SUCCESS if success.
922
923 Returns WDFOBJECT handle if success.
924
925--*/
926{
930
931 parent = NULL;
932
933 if (m_ObjectSize == 0) {
934 ASSERTMSG("Only external objects can call Commit()\n",
935 m_ObjectSize != 0);
937 }
938
939 //
940 // For an object to be committed into a handle, it needs to have an object
941 // size. Internal objects set their size to zero as the indication they
942 // are internal and will not be converted into handles.
943 //
944 ASSERT(m_ObjectSize != 0);
945
946 //
947 // Caller has already validated basic WDF_OBJECT_ATTRIBUTES
948 // with FxValidateObjectAttributes
949 //
950
951 //
952 // Set object execution level constraint if specified
953 //
954 if (Attributes != NULL &&
955 Attributes->ExecutionLevel == WdfExecutionLevelPassive) {
957 }
958
959 //
960 // Assign parent if supplied
961 //
962 if (Parent != NULL) {
963 parent = Parent;
964 }
965 else if (Attributes != NULL && Attributes->ParentObject != NULL) {
967 m_Globals,
968 Attributes->ParentObject,
970 (PVOID*)&parent
971 );
972 }
973 else {
974
975 //
976 // If the object already does not have a parent, and
977 // one has not been specified we default it to FxDriver.
978 //
979 // We check to ensure we are not FxDriver being created.
980 //
981 if (AssignDriverAsDefaultParent &&
982 m_ParentObject == NULL) {
983
984 //parent = FxToObjectItf::FxGetDriverAsDefaultParent(m_Globals, this);
985
986
987 if (m_Globals->Driver != this) {
989 }
990
991 }
992 }
993
994 ASSERT(parent != this);
995
996 if (parent != NULL) {
997 //
998 // Make it the parent of this object
999 //
1001
1002 if (!NT_SUCCESS(status)) {
1003 return status;
1004 }
1005 }
1006
1007 //
1008 // Now assign the optional EvtObjectCleanup, EvtObjectDestroy callbacks
1009 //
1010 if (Attributes != NULL) {
1012
1014
1015 if (Attributes->EvtDestroyCallback != NULL) {
1016 pHeader->EvtDestroyCallback = Attributes->EvtDestroyCallback;
1017 }
1018
1019 if (Attributes->EvtCleanupCallback != NULL) {
1020 pHeader->EvtCleanupCallback = Attributes->EvtCleanupCallback;
1022 }
1023 }
1024
1025 //
1026 // We mark the handle as committed so that we can create the handle.
1027 //
1028 MarkCommitted();
1029
1030 //
1031 // Create the object handle, assign EvtObjectCleanup, EvtObjectDestroy
1032 //
1033 FxObjectHandleCreate(this, &object);
1034
1035 if (ObjectHandle != NULL) {
1036 *ObjectHandle = object;
1037 }
1038
1039 return STATUS_SUCCESS;
1040}
1041
1047 __in BOOLEAN AutomaticLocking,
1048 __in BOOLEAN PassiveCallbacks,
1049 __out FxCallbackLock** CallbackLock,
1050 __out_opt FxObject** CallbackLockObject
1051 )
1052/*++
1053
1054Routine Description:
1055
1056 This gets the effective lock based on the callback constraints
1057 configuration of the supplied object.
1058
1059 This is a common routine shared by all FxObject's that utilize
1060 DPC's. Currently, this is FxDpc, FxTimer, and FxInterrupt.
1061
1062 This contains the common serialization configuration logic for these
1063 objects.
1064
1065Arguments:
1066
1067 Object - Object to serialize with
1068
1069 Callbacks - Optional interface for acquiring constraints and locking pointers
1070
1071 AutomaticLocking - TRUE if automatic serialization with Object is required
1072
1073 PassiveCallbacks - TRUE if the caller requires passive level callback, FALSE
1074 if the
1075 CallbackLock - Lock that is in effect for Object
1076
1077 CallbackLockOjbect - FxObject that contains the callback lock
1078
1079Returns:
1080
1081 NTSTATUS
1082
1083--*/
1084{
1086 WDF_EXECUTION_LEVEL parentLevel;
1087 WDF_SYNCHRONIZATION_SCOPE parentScope;
1088
1089 pFxDriverGlobals = Object->GetDriverGlobals();
1090 *CallbackLock = NULL;
1091 *CallbackLockObject = NULL;
1092
1093 //
1094 // No automatic locking, nothing to do
1095 //
1096 if (AutomaticLocking == FALSE) {
1097 return STATUS_SUCCESS;
1098 }
1099
1100 //
1101 // Objects that have callback locks must support this interface.
1102 //
1103 if (Callbacks == NULL) {
1105 }
1106
1107 //
1108 // Get the callback constraints in effect for the object
1109 //
1110 Callbacks->GetConstraints(&parentLevel, &parentScope);
1111
1112 if (parentScope == WdfSynchronizationScopeInheritFromParent ||
1113 parentScope == WdfSynchronizationScopeNone) {
1114 //
1115 // Do nothing, no synchronization specified
1116 //
1117 DO_NOTHING();
1118 }
1119 else {
1120 //
1121 // If the caller wants passive callbacks and the object does not support
1122 // it, failure.
1123 //
1124 // If the caller wants non passive callbacks and the object supports
1125 // passive only callbacks, failure.
1126 //
1127 if ((PassiveCallbacks && Object->IsPassiveCallbacks() == FALSE) ||
1128 (PassiveCallbacks == FALSE && Object->IsPassiveCallbacks())) {
1131 }
1132
1133 *CallbackLock = Callbacks->GetCallbackLockPtr(CallbackLockObject);
1134 }
1135
1136 return STATUS_SUCCESS;
1137}
unsigned char BOOLEAN
Type
Definition: Type.h:7
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
VOID Add(FxObject *object)
__inline FxDisposeList * GetDisposeList()
Definition: fxdriver.hpp:354
FxObjectDebugExtension * GetDebugExtension(VOID)
Definition: fxobject.hpp:401
USHORT m_ObjectState
Definition: fxobject.hpp:290
VOID FinalRelease(VOID)
Definition: fxobject.cpp:207
WDFTYPE m_Type
Definition: fxobject.hpp:247
USHORT m_ObjectSize
Definition: fxobject.hpp:254
PFX_DRIVER_GLOBALS m_Globals
Definition: fxobject.hpp:259
_Must_inspect_result_ NTSTATUS AssignParentObject(__in FxObject *ParentObject)
Definition: fxobject.cpp:529
_Must_inspect_result_ NTSTATUS AddChildObjectInternal(__in FxObject *ChildObject)
Definition: fxobject.cpp:703
MxLock m_SpinLock
Definition: fxobject.hpp:296
VOID CallCleanupCallbacks(VOID)
Definition: fxobject.cpp:328
_Must_inspect_result_ NTSTATUS RemoveChildObjectInternal(__in FxObject *ChildObject)
Definition: fxobject.cpp:770
USHORT PassiveCallbacks
Definition: fxobject.hpp:273
LIST_ENTRY m_ChildListHead
Definition: fxobject.hpp:293
_Must_inspect_result_ NTSTATUS AddContext(__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: fxobject.cpp:605
PVOID __inline GetObjectHandleUnchecked(VOID)
Definition: fxobject.hpp:446
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
SINGLE_LIST_ENTRY m_DisposeSingleEntry
Definition: fxobject.hpp:316
VOID __inline Construct(__in BOOLEAN Embedded)
Definition: fxobject.hpp:349
USHORT m_ObjectFlags
Definition: fxobject.hpp:263
VOID __inline TraceDroppedEvent(__in FxObjectDroppedEvent Event)
Definition: fxobject.hpp:930
FxObject * m_ParentObject
Definition: fxobject.hpp:303
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)
Definition: fxobject.cpp:1044
BOOLEAN IsDebug(VOID)
Definition: fxobject.hpp:409
BOOLEAN ShouldDeferDisposeLocked(__out_opt PKIRQL PreviousIrql=NULL)
Definition: fxobject.hpp:1383
VOID ClearEvtCallbacks(VOID)
Definition: fxobject.cpp:360
virtual ~FxObject(VOID)
Definition: fxobject.cpp:88
CfxDeviceBase * GetDeviceBase(VOID)
Definition: fxobject.hpp:789
VOID ProcessDestroy(VOID)
FxTagTracker * GetTagTracker(VOID)
Definition: fxobject.hpp:766
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
__inline FxContextHeader * GetContextHeader(VOID)
Definition: fxobject.hpp:720
LIST_ENTRY m_ChildEntry
Definition: fxobject.hpp:311
VOID MarkPassiveCallbacks(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:972
FxObject(VOID)
Definition: fxobject.hpp:333
_Must_inspect_result_ FxObject * GetParentObjectReferenced(__in PVOID Tag)
Definition: fxobject.cpp:856
VOID __inline SetObjectStateLocked(__in FxObjectState NewState)
Definition: fxobject.hpp:369
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
BOOLEAN IsCommitted(VOID)
Definition: fxobject.hpp:1087
VOID AllocateTagTracker(__in WDFTYPE Type)
Definition: fxobject.cpp:273
VOID MarkCommitted(VOID)
Definition: fxobject.hpp:1074
_Must_inspect_result_ NTSTATUS Commit(__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
Definition: fxobject.cpp:904
static _Must_inspect_result_ NTSTATUS __inline CreateAndInitialize(__out FxTagTracker **TagTracker, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxTagTrackerType Type, __in BOOLEAN CaptureStack, __in FxObject *Owner, __in_opt PVOID CreateTag=NULL)
Definition: Header.h:9
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGOBJECT
Definition: dbgtrace.h:59
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
r parent
Definition: btrfs.c:3010
KIRQL irql
Definition: wave.h:1
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
return pObject GetObjectHandle()
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
SINGLE_LIST_ENTRY * pCur
FxVerifierDbgBreakPoint(pFxDriverGlobals)
_Must_inspect_result_ BOOLEAN FxVerifyObjectTypeInTable(__in USHORT ObjectType)
Definition: globals.cpp:117
_Must_inspect_result_ BOOLEAN FxVerifierGetTrackReferences(__in FxObjectDebugInfo *DebugInfo, __in WDFTYPE ObjectType)
Definition: globals.cpp:338
PCSTR FxObjectTypeToHandleName(__in WDFTYPE ObjectType)
Definition: globals.cpp:316
VOID __inline FxObjectHandleCreate(__in FxObject *Object, __out PWDFOBJECT Handle)
Definition: fxhandle.h:176
#define FX_VF_METHOD(classname, fnName)
Definition: fxmacros.hpp:43
PAGED_CODE_LOCKED()
ULONG DebugLevel
Definition: fxobject.cpp:43
ULONG DebugFlag
Definition: fxobject.cpp:44
VOID _In_ BOOLEAN Embedded
Definition: fxobject.cpp:164
@ FxObjectStateDestroyed
Definition: fxobject.hpp:171
@ FxObjectStateCreated
Definition: fxobject.hpp:160
@ FxObjectStateDeferedDestroy
Definition: fxobject.hpp:170
@ FxObjectStateInvalid
Definition: fxobject.hpp:159
@ FXOBJECT_FLAGS_HAS_DEBUG
Definition: fxobject.hpp:147
@ FXOBJECT_FLAGS_TRACE_STATE
Definition: fxobject.hpp:149
@ FXOBJECT_FLAGS_HAS_CLEANUP
Definition: fxobject.hpp:150
@ FxObjectDebugExtensionSignature
Definition: fxobject.hpp:227
@ FxObjectDroppedEventAssignParentObject
Definition: fxobject.hpp:176
@ FxObjectDroppedEventAddChildObjectInternal
Definition: fxobject.hpp:177
@ FxObjectDroppedEventRemoveChildObjectInternal
Definition: fxobject.hpp:178
@ FxHandleFlagMask
Definition: fxobject.hpp:62
FxObjectType
Definition: fxobject.hpp:117
@ FxObjectTypeEmbedded
Definition: fxobject.hpp:121
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
pKey DeleteObject()
@ FxTagTrackerTypeHandle
USHORT WDFTYPE
Definition: fxtypes.h:29
@ FX_TYPE_OBJECT
Definition: fxtypes.h:45
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
FxContextHeader * pHeader
Definition: handleapi.cpp:604
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
ObjectType
Definition: metafile.c:81
#define DO_NOTHING()
Definition: mxgeneral.h:32
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define _In_
Definition: no_sal2.h:158
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define STATUS_NOINTERFACE
Definition: ntstatus.h:812
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
FxContextHeader * NextHeader
Definition: fxhandle.h:71
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback
Definition: fxhandle.h:82
PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback
Definition: fxhandle.h:76
FxObjectDebugInfo * ObjectDebugInfo
Definition: fxglobals.h:118
FxTagTracker * TagTracker
Definition: fxobject.hpp:208
FxDriver * Driver
Definition: fxglobals.h:374
FxDriverGlobalsDebugExtension * DebugExtension
Definition: fxglobals.h:376
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:637
Definition: ps.c:97
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WDFCASSERT(c)
Definition: wdfassert.h:93
@ WDF_OBJECT_ERROR
Definition: wdfbugcodes.h:64
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
@ WdfSynchronizationScopeInheritFromParent
Definition: wdfobject.h:63
@ WdfSynchronizationScopeNone
Definition: wdfobject.h:66
@ WdfExecutionLevelPassive
Definition: wdfobject.h:54
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
#define STATUS_WDF_INCOMPATIBLE_EXECUTION_LEVEL
Definition: wdfstatus.h:198
#define STATUS_WDF_PARENT_ALREADY_ASSIGNED
Definition: wdfstatus.h:207
#define STATUS_WDF_PARENT_IS_SELF
Definition: wdfstatus.h:216