mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 23:43:39 +00:00
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9
Licensed under MIT
This commit is contained in:
parent
545df81502
commit
8a978a179f
475 changed files with 285099 additions and 0 deletions
119
sdk/lib/drivers/wdf/shared/irphandlers/pnp/km/eventqueuekm.cpp
Normal file
119
sdk/lib/drivers/wdf/shared/irphandlers/pnp/km/eventqueuekm.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
EventQueueKm.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
This module implements kernel mode specific functionality of event queue
|
||||
|
||||
This functionality needed to be separated out since the KM portion takes
|
||||
a reference on driver object because KM MxWorkItem::_Free does not wait for
|
||||
callback to return (i.e. rundown synchronously).
|
||||
|
||||
MxWorkItem::_Free in UM currently waits for callback to return (i.e. runs
|
||||
down synchronously) hence does not need a reference on driver/devstack
|
||||
object (see comments on top of MxWorkItemUm.h file).
|
||||
|
||||
In future if UM work-item is made similar to km workitem, UMDF may need to
|
||||
ensure that modules stay loaded, though the mechanism to ensure that would
|
||||
likely be different from a reference on the driver. It would likely be a
|
||||
reference on the devicestack object.
|
||||
|
||||
Environment:
|
||||
|
||||
Kernel mode only
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "pnppriv.hpp"
|
||||
|
||||
VOID
|
||||
FxWorkItemEventQueue::QueueWorkItem(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
//
|
||||
// The work item will take a reference on KMDF itself. This will keep KMDF's
|
||||
// image around (but not necessarily prevent DriverUnload from being called)
|
||||
// so that the code after we set the done event will be in memory and not
|
||||
// unloaded. We must do this because there is no explicit reference between
|
||||
// the client driver and KMDF, so when the io manager calls the client's
|
||||
// DriverUnload, it has no way of managing KMDF's ref count to stay in memory
|
||||
// when the loader unloads KMDF explicitly in response to DriverUnload.
|
||||
//
|
||||
// We manually take a reference on the client so that we provide the same
|
||||
// functionality that IO workitems do. The client driver's image will have
|
||||
// a reference on it after it has returned.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
Mx::MxReferenceObject(m_PkgPnp->GetDriverGlobals()->Driver->GetDriverObject());
|
||||
|
||||
//
|
||||
// Prevent FxDriverGlobals from being deleted until the workitem finishes
|
||||
// its work. In case of a bus driver with a PDO in removed
|
||||
// state, if the bus is removed, the removal of PDO may happen in a workitem
|
||||
// and may result in unload routine being called before the PDO package is
|
||||
// deallocated. Since FxPool deallocation code touches FxDriverGlobals
|
||||
// (a pointer of which is located in the header of each FxPool allocated
|
||||
// object), taking this ref prevents the globals from going away until a
|
||||
// corresponding deref at the end of workitem.
|
||||
//
|
||||
m_PkgPnp->GetDriverGlobals()->ADDREF(_WorkItemCallback);
|
||||
|
||||
m_WorkItem.Enqueue(
|
||||
(PMX_WORKITEM_ROUTINE) _WorkItemCallback,
|
||||
(FxEventQueue*) this);
|
||||
}
|
||||
|
||||
VOID
|
||||
FxWorkItemEventQueue::_WorkItemCallback(
|
||||
__in MdDeviceObject DeviceObject,
|
||||
__in PVOID Context
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This is the work item that attempts to run the machine on a thread
|
||||
separate from the one the caller was using. It implements step 9 above.
|
||||
|
||||
--*/
|
||||
{
|
||||
FxWorkItemEventQueue* This = (FxWorkItemEventQueue*) Context;
|
||||
PFX_DRIVER_GLOBALS pFxDriverGlobals;
|
||||
|
||||
UNREFERENCED_PARAMETER(DeviceObject);
|
||||
|
||||
MdDriverObject pDriverObject;
|
||||
|
||||
pFxDriverGlobals = This->m_PkgPnp->GetDriverGlobals();
|
||||
|
||||
//
|
||||
// Capture the driver object before we call the EventQueueWoker() because
|
||||
// the time it returns, This could be freed.
|
||||
|
||||
|
||||
|
||||
pDriverObject = pFxDriverGlobals->Driver->GetDriverObject();
|
||||
|
||||
This->EventQueueWorker();
|
||||
|
||||
//
|
||||
// Release the ref on FxDriverGlobals taken before queuing this workitem.
|
||||
//
|
||||
pFxDriverGlobals->RELEASE(_WorkItemCallback);
|
||||
|
||||
Mx::MxDereferenceObject(pDriverObject);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue