Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418/*++
Copyright (c) Microsoft Corporation
Module Name:
FxDeviceBase.cpp
Abstract:
This is the class implementation for the base device class.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#include "coreprivshared.hpp"
extern "C" {// #include "FxDeviceBase.tmh"}
FxDeviceBase::FxDeviceBase( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxDriver* Driver, __in WDFTYPE Type, __in USHORT Size ) : FxNonPagedObject(Type, Size, FxDriverGlobals){ m_Driver = Driver;
m_CallbackLockPtr = NULL; m_CallbackLockObjectPtr = NULL;
m_DisposeList = NULL;
m_DmaPacketTransactionStatus = FxDmaPacketTransactionCompleted;
m_ExecutionLevel = WdfExecutionLevelInheritFromParent; m_SynchronizationScope = WdfSynchronizationScopeInheritFromParent;
MarkPassiveDispose(ObjectDoNotLock); SetDeviceBase(this);}
FxDeviceBase::~FxDeviceBase( VOID ){ if (m_DisposeList != NULL) { m_DisposeList->DeleteObject(); m_DisposeList = NULL; }
if (m_CallbackLockPtr != NULL) { delete m_CallbackLockPtr; m_CallbackLockPtr = NULL; }}
_Must_inspect_result_NTSTATUSFxDeviceBase::QueryInterface( __inout FxQueryInterfaceParams* Params ){ switch (Params->Type) { case FX_TYPE_DEVICE_BASE: *Params->Object = this; break;
case FX_TYPE_IHASCALLBACKS: *Params->Object = (IFxHasCallbacks*) this; break;
default: return FxNonPagedObject::QueryInterface(Params); // __super call }
return STATUS_SUCCESS;}
NTSTATUSFxDeviceBase::ConfigureConstraints( __in_opt PWDF_OBJECT_ATTRIBUTES ObjectAttributes ){ NTSTATUS status; WDF_EXECUTION_LEVEL driverLevel; WDF_SYNCHRONIZATION_SCOPE driverScope;
ASSERT(m_Driver != NULL);
// // If WDF_OBJECT_ATTRIBUTES is specified, these override any // default settings. // if (ObjectAttributes != NULL) { m_ExecutionLevel = ObjectAttributes->ExecutionLevel; m_SynchronizationScope = ObjectAttributes->SynchronizationScope; }
// // If no WDFDEVICE specific attributes are specified, we // get them from WDFDRIVER, which allows WDFDRIVER to // provide a default for all WDFDEVICE's created. // m_Driver->GetConstraints(&driverLevel, &driverScope);
if (m_ExecutionLevel == WdfExecutionLevelInheritFromParent) { m_ExecutionLevel = driverLevel; }
if (m_SynchronizationScope == WdfSynchronizationScopeInheritFromParent) { m_SynchronizationScope = driverScope; }
// // Configure The Execution Level Constraint // if (m_ExecutionLevel == WdfExecutionLevelPassive) { m_CallbackLockPtr = new(GetDriverGlobals()) FxCallbackMutexLock(GetDriverGlobals()); // // Currently, all event callbacks from FxDevice into the driver // are from PASSIVE_LEVEL threads, and there is no need to defer // to a system workitem like IoQueue. So we don't allocate and // setup an FxSystemWorkItem here. // // If the FxDevice starts raising events to the device driver // whose thread starts out above PASSIVE_LEVEL, then an FxSystemWorkItem // would need to be allocated when WdfExecutionLevelPassive is specified. // // (FDO and PDO variants of FxDevice may own their own event dispatch // and deferral logic separate from FxDevice.) // } else { m_CallbackLockPtr = new(GetDriverGlobals()) FxCallbackSpinLock(GetDriverGlobals()); }
// // Finish initializing the spin/mutex lock. // if (NULL == m_CallbackLockPtr) { status = STATUS_INSUFFICIENT_RESOURCES; DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGOBJECT, "WDFDEVICE %p, could not allocate callback lock, %!STATUS!", GetHandle(), status); goto Done; }
m_CallbackLockPtr->Initialize(this); m_CallbackLockObjectPtr = this;
status = STATUS_SUCCESS;
Done: return status;}
VOIDFxDeviceBase::GetConstraints( __out_opt WDF_EXECUTION_LEVEL* ExecutionLevel, __out_opt WDF_SYNCHRONIZATION_SCOPE* SynchronizationScope ){ if (ExecutionLevel != NULL) { *ExecutionLevel = m_ExecutionLevel; }
if (SynchronizationScope != NULL) { *SynchronizationScope = m_SynchronizationScope; }}
FxCallbackLock*FxDeviceBase::GetCallbackLockPtr( __out_opt FxObject** LockObject ){ if (LockObject != NULL) { *LockObject = m_CallbackLockObjectPtr; }
return m_CallbackLockPtr;}
VOIDFxDeviceBase::Init( __in MdDeviceObject DeviceObject, __in MdDeviceObject AttachedDevice, __in MdDeviceObject PhysicalDevice ){ m_DeviceObject.SetObject(DeviceObject); m_AttachedDevice.SetObject(AttachedDevice); m_PhysicalDevice.SetObject(PhysicalDevice);}
FxDeviceBase*FxDeviceBase::_SearchForDevice( __in FxObject* Object, __out_opt IFxHasCallbacks** Callbacks ){ FxObject* pParent, *pOrigParent; FxDeviceBase* pDeviceBase; FxQueryInterfaceParams cbParams = { (PVOID*) Callbacks, FX_TYPE_IHASCALLBACKS, 0 }; PVOID pTag;
pDeviceBase = Object->GetDeviceBase(); if (pDeviceBase == NULL) { DoTraceLevelMessage( Object->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGOBJECT, "WDFHANDLE %p does not have a WDFDEVICE as an ancestor", Object->GetObjectHandle()); return NULL; }
if (Callbacks == NULL) { // // Caller is not interested in the callbacks interface, just return // now without searching for it. // return pDeviceBase; }
// // Init out parameter. // *Callbacks = NULL;
pOrigParent = Object; pTag = pOrigParent;
// // By adding a reference now, we simulate what GetParentObjectReferenced // does later, thus allowing simple logic on when/how to release the // reference on exit. // Object->ADDREF(pTag);
do { // // If successful, Callbacks will be != NULL // if (NT_SUCCESS(Object->QueryInterface(&cbParams))) { ASSERT(*Callbacks != NULL); // // Release the reference previously taken by the top of the function // or GetParentObjectReferenced in a previous pass in the loop. // Object->RELEASE(pTag); return pDeviceBase; }
pParent = Object->GetParentObjectReferenced(pTag);
// // Release the reference previously taken by the top of the function // or GetParentObjectReferenced in a previous pass in the loop. // Object->RELEASE(pTag);
Object = pParent; } while (Object != NULL);
ASSERT(Object == NULL);
// // Queue presented requests do not have parents (to increase performance). // Try to find the callback interface on this object's device base. // if (NT_SUCCESS(pDeviceBase->QueryInterface(&cbParams))) { ASSERT(*Callbacks != NULL); // // Success, we got a callback interface. // return pDeviceBase; }
DoTraceLevelMessage( pOrigParent->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGOBJECT, "WDFHANDLE %p does not have a callbacks interface in its object tree" "(WDFDEVICE %p)", pOrigParent->GetObjectHandle(), pDeviceBase->GetHandle());
return pDeviceBase;}
FxDeviceBase*FxDeviceBase::_SearchForDevice( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes ){ FxObject* pParentObject; FxDeviceBase* pDeviceBase;
if (Attributes == NULL || Attributes->ParentObject == NULL) { return NULL; }
FxObjectHandleGetPtr(FxDriverGlobals, Attributes->ParentObject, FX_TYPE_OBJECT, (PVOID*) &pParentObject);
pDeviceBase = _SearchForDevice(pParentObject, NULL);
return pDeviceBase;}
_Must_inspect_result_NTSTATUSFxDeviceBase::AllocateTarget( _Out_ FxIoTarget** Target, _In_ BOOLEAN SelfTarget )/*++
Routine Description:
Allocates an IO Target or an Self IO target for the FxDevice.
Arguments:
Target - Out - returns the pointer to the allocated IO target.
SelfTarget - If TRUE allocates an Self IO Target, if FALSE allocates a regular IO target.
Returns:
NTSTATUS
--*/{ FxIoTarget* pTarget; NTSTATUS status;
if (SelfTarget) { pTarget = (FxIoTarget*) new(GetDriverGlobals(), WDF_NO_OBJECT_ATTRIBUTES) FxIoTargetSelf(GetDriverGlobals(), sizeof(FxIoTargetSelf)); } else { pTarget = new(GetDriverGlobals(), WDF_NO_OBJECT_ATTRIBUTES) FxIoTarget(GetDriverGlobals(), sizeof(FxIoTarget)); }
if (pTarget == NULL) { status = STATUS_INSUFFICIENT_RESOURCES;
DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE, "WDFDEVICE %p could not allocate a WDFIOTARGET, %!STATUS!", GetHandle(), status);
goto Done; }
status = AddIoTarget(pTarget); if (!NT_SUCCESS(status)) { DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE, "WDFDEVICE %p failed to initialize (add) a WDFIOTARGET, %!STATUS!", GetHandle(), status);
goto Done; }
status = pTarget->Init(this); if (!NT_SUCCESS(status)) { DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE, "WDFDEVICE %p failed to initialize a WDFIOTARGET, %!STATUS!", GetHandle(), status);
goto Done; }
status = pTarget->Commit(WDF_NO_OBJECT_ATTRIBUTES, NULL, this); if (!NT_SUCCESS(status)) { DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGDEVICE, "WDFDEVICE %p failed to initialize (commit) a WDFIOTARGET, %!STATUS!", GetHandle(), status);
goto Done; }
status = STATUS_SUCCESS;
Done: if (!NT_SUCCESS(status)) { if (pTarget != NULL) { pTarget->DeleteFromFailedCreate(); pTarget = NULL; } }
*Target = pTarget;
return status;}