ReactOS  0.4.15-dev-3297-g037c744
fxobject.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxObject.cpp
8 
9 Abstract:
10 
11  This module contains the implementation of the base object
12 
13 Author:
14 
15 
16 
17 
18 
19 Environment:
20 
21  Both kernel and user mode
22 
23 Revision History:
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 --*/
35 
36 #include "fxobjectpch.hpp"
37 
38 extern "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
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 
159 VOID
160 FX_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 
171  ASSERTMSG(
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  //
181  FxObjectDebugExtension* pExtension;
182 
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 
202  }
203 }
204 
205 
206 VOID
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  //
227  if (ShouldDeferDisposeLocked()) {
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 
245  m_Globals->Driver->GetDisposeList()->Add(this);
246 
247  }
248  else {
249  ProcessDestroy();
250  }
251 }
252 
254 NTSTATUS
257  )
258 {
260 
261  if (Params->Type == FX_TYPE_OBJECT) {
262  *Params->Object = this;
264  }
265  else {
267  }
268 
269  return status;
270 }
271 
272 VOID
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 
305 VOID
308  )
309 {
310  ASSERT(Memory != NULL);
311 
312 
313 
314 
315 
316 
317 
318 
319 
320 
321 
322 
323 
325 }
326 
327 VOID
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;
350  if (pHeader->EvtCleanupCallback != NULL) {
353  }
354  }
355 
357 }
358 
359 VOID
361  VOID
362  )
363 /*++
364 
365 Routine Description:
366 
367  Clears out any assigned callbacks on the object.
368 
369 Arguments:
370  None
371 
372 Return Value:
373  None
374 
375  --*/
376 {
378 
379  for (pHeader = GetContextHeader();
380  pHeader != NULL;
382 
385  }
386 
388 }
389 
390 VOID
392  VOID
393  )
394 /*++
395 
396 Routine 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 
401 Arguments:
402  None
403 
404 Return 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 
528 NTSTATUS
530  __in FxObject* ParentObject
531  )
532 /*++
533 
534 Routine Description:
535  Assign a parent to the current object. The parent can not be the same
536  object.
537 
538 Arguments:
539  ParentObject - Object to become the parent for this object
540 
541 Returns:
542 
543 Comments:
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);
567  return STATUS_DELETE_PENDING;
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 
604 NTSTATUS
607  __in PVOID* Context,
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 
702 NTSTATUS
704  __in FxObject* ChildObject
705  )
706 
707 /*++
708 
709 Routine Description:
710  Called by an object to be added to this objects child list
711 
712 Arguments:
713  ChildObject - Object to add this this objects child list
714 
715 Returns:
716  NTSTATUS
717 
718 Comments:
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);
740  return STATUS_DELETE_PENDING;
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 
769 NTSTATUS
771  __in FxObject* ChildObject
772  )
773 /*++
774 
775 Routine 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 
789 Arguments:
790  ChildObject - the object to remove this object's list of children
791 
792 Returns:
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);
815  return STATUS_DELETE_PENDING;
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 
855 FxObject*
857  __in PVOID Tag
858  )
859 
860 /*++
861 
862 Routine 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 
870 Arguments:
871  Tag - Tag to use when referencing the parent
872 
873 Returns:
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 
903 NTSTATUS
906  __out_opt WDFOBJECT* ObjectHandle,
908  __in BOOLEAN AssignDriverAsDefaultParent
909  )
910 /*++
911 
912 Routine Description:
913  Commit the object before returning the handle to the caller.
914 
915 Arguments:
916  Attributes - PWDF_OBJECT_ATTRIBUTES to assign to this object
917 
918  ObjectHandle - Location to return the objects handle
919 
920 Returns:
921  NTSTATUS of the result. STATUS_SUCCESS if success.
922 
923  Returns WDFOBJECT handle if success.
924 
925 --*/
926 {
929  FxObject* parent;
930 
931  parent = NULL;
932 
933  if (m_ObjectSize == 0) {
934  ASSERTMSG("Only external objects can call Commit()\n",
935  m_ObjectSize != 0);
936  return STATUS_INVALID_HANDLE;
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 
1043 NTSTATUS
1045  __in FxObject* Object,
1047  __in BOOLEAN AutomaticLocking,
1049  __out FxCallbackLock** CallbackLock,
1050  __out_opt FxObject** CallbackLockObject
1051  )
1052 /*++
1053 
1054 Routine 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 
1065 Arguments:
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 
1079 Returns:
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 }
VOID _In_ BOOLEAN Embedded
Definition: fxobject.cpp:164
ObjectType
Definition: metafile.c:80
virtual VOID DeleteObject(VOID)
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
VOID AllocateTagTracker(__in WDFTYPE Type)
Definition: fxobject.cpp:273
VOID __inline SetObjectStateLocked(__in FxObjectState NewState)
Definition: fxobject.hpp:369
USHORT PassiveCallbacks
Definition: fxobject.hpp:273
FxContextHeader * NextHeader
Definition: fxhandle.h:71
FxObjectDebugInfo * ObjectDebugInfo
Definition: fxglobals.h:118
_Must_inspect_result_ NTSTATUS AddChildObjectInternal(__in FxObject *ChildObject)
Definition: fxobject.cpp:703
VOID FinalRelease(VOID)
Definition: fxobject.cpp:207
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
FxTagTracker * GetTagTracker(VOID)
Definition: fxobject.hpp:766
PVOID m_COMWrapper
Definition: fxobject.hpp:243
coclass MSXML2::XSLTemplate40 object
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
GLint x0
Definition: linetemp.h:95
_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
VOID ProcessDestroy(VOID)
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
static PVOID _GetBase(__in FxObject *Object)
Definition: fxobject.hpp:418
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
FxObject * m_ParentObject
Definition: fxobject.hpp:303
WDFCASSERT(sizeof(WDF_DRIVER_CONFIG_V1_0)==sizeof(WDF_DRIVER_CONFIG_V1_1))
LIST_ENTRY m_ChildEntry
Definition: fxobject.hpp:311
_Must_inspect_result_ NTSTATUS AddContext(__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: fxobject.cpp:605
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
PCSTR FxObjectTypeToHandleName(__in WDFTYPE ObjectType)
Definition: globals.cpp:316
operator
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
KIRQL irql
Definition: wave.h:1
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), Fdo, FX_TYPE_DEVICE,(PVOID *)&pFdo)
FxDriverGlobalsDebugExtension * DebugExtension
Definition: fxglobals.h:376
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:728
PFN_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback
Definition: fxhandle.h:76
MxLock m_SpinLock
Definition: fxobject.hpp:296
#define InsertTailList(ListHead, Entry)
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID FX_VF_METHOD(FxObject, VerifyConstruct)(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals
VOID __inline Construct(__in BOOLEAN Embedded)
Definition: fxobject.hpp:349
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_WDF_PARENT_IS_SELF
Definition: wdfstatus.h:216
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
FxObjectType
Definition: fxobject.hpp:117
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)
#define __out_opt
Definition: dbghelp.h:65
PAGED_CODE_LOCKED()
#define FALSE
Definition: types.h:117
Definition: Header.h:8
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
FxDriver * Driver
Definition: fxglobals.h:374
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define STATUS_WDF_INCOMPATIBLE_EXECUTION_LEVEL
Definition: wdfstatus.h:198
FxContextHeader * pHeader
Definition: handleapi.cpp:604
#define __out
Definition: dbghelp.h:62
#define TRACINGOBJECT
Definition: dbgtrace.h:59
unsigned char BOOLEAN
#define _In_
Definition: ms_sal.h:308
SINGLE_LIST_ENTRY m_DisposeSingleEntry
Definition: fxobject.hpp:316
_Must_inspect_result_ BOOLEAN FxVerifierGetTrackReferences(__in FxObjectDebugInfo *DebugInfo, __in WDFTYPE ObjectType)
Definition: globals.cpp:338
VOID MarkPassiveCallbacks(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:972
_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
enum _WDF_SYNCHRONIZATION_SCOPE WDF_SYNCHRONIZATION_SCOPE
VOID MarkCommitted(VOID)
Definition: fxobject.hpp:1074
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define STATUS_NOINTERFACE
Definition: ntstatus.h:812
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxObject(VOID)
Definition: fxobject.hpp:333
PFN_WDF_OBJECT_CONTEXT_DESTROY EvtDestroyCallback
Definition: fxhandle.h:82
if(m_Globals->IsObjectDebugOn() &&Embedded==FALSE)
Definition: fxobject.cpp:180
#define ASSERT(a)
Definition: mode.c:44
r parent
Definition: btrfs.c:2944
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID Add(FxObject *object)
Type
Definition: Type.h:6
BOOLEAN IsCommitted(VOID)
Definition: fxobject.hpp:1087
USHORT m_ObjectState
Definition: fxobject.hpp:290
_Must_inspect_result_ BOOLEAN FxVerifyObjectTypeInTable(__in USHORT ObjectType)
Definition: globals.cpp:117
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
FxObjectDebugExtension * GetDebugExtension(VOID)
Definition: fxobject.hpp:401
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
PVOID __inline GetObjectHandleUnchecked(VOID)
Definition: fxobject.hpp:446
ULONG DebugLevel
Definition: fxobject.cpp:43
VOID __inline FxObjectHandleCreate(__in FxObject *Object, __out PWDFOBJECT Handle)
Definition: fxhandle.h:176
VOID ClearEvtCallbacks(VOID)
Definition: fxobject.cpp:360
ULONG DebugFlag
Definition: fxobject.cpp:44
_Must_inspect_result_ NTSTATUS AssignParentObject(__in FxObject *ParentObject)
Definition: fxobject.cpp:529
VOID CallCleanupCallbacks(VOID)
Definition: fxobject.cpp:328
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4061
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
__inline FxDisposeList * GetDisposeList()
Definition: fxdriver.hpp:354
USHORT m_ObjectSize
Definition: fxobject.hpp:254
__inline FxContextHeader * GetContextHeader(VOID)
Definition: fxobject.hpp:720
BOOLEAN IsObjectDebugOn(VOID)
Definition: fxglobals.h:223
USHORT m_ObjectFlags
Definition: fxobject.hpp:263
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
WDFTYPE m_Type
Definition: fxobject.hpp:247
unsigned short USHORT
Definition: pedump.c:61
SINGLE_LIST_ENTRY * pCur
ASSERTMSG("this object's type is not listed in FxObjectsInfo\n", FxVerifyObjectTypeInTable(m_Type))
#define ARRAY_SIZE(a)
Definition: main.h:24
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
USHORT WDFTYPE
Definition: fxtypes.h:29
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS m_Globals
Definition: fxobject.hpp:259
#define NULL
Definition: types.h:112
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
FxTagTracker * TagTracker
Definition: fxobject.hpp:208
unsigned int ULONG
Definition: retypes.h:1
WDF_EXTERN_C_START enum _WDF_EXECUTION_LEVEL WDF_EXECUTION_LEVEL
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
const char * PCSTR
Definition: typedefs.h:52
BOOLEAN IsDebug(VOID)
Definition: fxobject.hpp:409
virtual _Must_inspect_result_ NTSTATUS QueryInterface(__in FxQueryInterfaceParams *Params)
Definition: fxobject.cpp:255
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_WDF_PARENT_ALREADY_ASSIGNED
Definition: wdfstatus.h:207
LIST_ENTRY m_ChildListHead
Definition: fxobject.hpp:293
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
BOOLEAN ShouldDeferDisposeLocked(__out_opt PKIRQL PreviousIrql=NULL)
Definition: fxobject.hpp:1383
#define __in
Definition: dbghelp.h:35
_Must_inspect_result_ FxObject * GetParentObjectReferenced(__in PVOID Tag)
Definition: fxobject.cpp:856
static SERVICE_STATUS status
Definition: service.c:31
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
CfxDeviceBase * GetDeviceBase(VOID)
Definition: fxobject.hpp:789
VOID __inline TraceDroppedEvent(__in FxObjectDroppedEvent Event)
Definition: fxobject.hpp:930
virtual ~FxObject(VOID)
Definition: fxobject.cpp:88
FxVerifierDbgBreakPoint(pFxDriverGlobals)
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define DO_NOTHING()
Definition: mxgeneral.h:32
_Must_inspect_result_ NTSTATUS RemoveChildObjectInternal(__in FxObject *ChildObject)
Definition: fxobject.cpp:770
Definition: ps.c:97