2020-09-24 20:51:15 +00:00
/*++
Copyright ( c ) Microsoft Corporation
Module Name :
FxIoTargetRemote . cpp
Abstract :
Author :
Environment :
Both kernel and user mode
Revision History :
- - */
2020-10-16 03:30:51 +00:00
# include "../fxtargetsshared.hpp"
2020-09-24 20:51:15 +00:00
extern " C " {
2020-10-16 03:30:51 +00:00
// #include "FxIoTargetRemote.tmh"
2020-09-24 20:51:15 +00:00
}
# include <initguid.h>
# include "wdmguid.h"
FxIoTargetRemote : : FxIoTargetRemote (
__in PFX_DRIVER_GLOBALS FxDriverGlobals
) :
FxIoTarget ( FxDriverGlobals , sizeof ( FxIoTargetRemote ) ) ,
m_EvtQueryRemove ( FxDriverGlobals ) ,
m_EvtRemoveCanceled ( FxDriverGlobals ) ,
m_EvtRemoveComplete ( FxDriverGlobals )
{
//
// No automatic state changes based on the pnp state changes of our own
// device stack. The one exception is remove where we need to shut
// everything down.
//
m_InStack = FALSE ;
m_ClearedPointers = NULL ;
m_OpenState = FxIoTargetRemoteOpenStateClosed ;
m_TargetHandle = NULL ;
m_EvtQueryRemove . m_Method = NULL ;
m_EvtRemoveCanceled . m_Method = NULL ;
m_EvtRemoveComplete . m_Method = NULL ;
# if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
m_TargetNotifyHandle = NULL ;
2020-10-16 03:30:51 +00:00
# elif (FX_CORE_MODE == FX_CORE_USER_MODE)
2020-09-24 20:51:15 +00:00
m_TargetNotifyHandle = WUDF_TARGET_CONTEXT_INVALID ;
m_pIoDispatcher = NULL ;
m_pRemoteDispatcher = NULL ;
m_NotificationCallback = NULL ;
# endif
}
FxIoTargetRemote : : ~ FxIoTargetRemote ( )
{
}
_Must_inspect_result_
NTSTATUS
FxIoTargetRemote : : _Create (
__in PFX_DRIVER_GLOBALS FxDriverGlobals ,
__in PWDF_OBJECT_ATTRIBUTES Attributes ,
__in CfxDeviceBase * Device ,
__out FxIoTargetRemote * * Target
)
{
FxIoTargetRemote * pTarget ;
FxObject * pParent ;
WDFOBJECT hTarget ;
NTSTATUS status ;
* Target = NULL ;
if ( Attributes = = NULL | | Attributes - > ParentObject = = NULL ) {
pParent = Device ;
}
else {
CfxDeviceBase * pSearchDevice ;
FxObjectHandleGetPtr ( FxDriverGlobals ,
Attributes - > ParentObject ,
FX_TYPE_OBJECT ,
( PVOID * ) & pParent ) ;
pSearchDevice = FxDeviceBase : : _SearchForDevice ( pParent , NULL ) ;
if ( pSearchDevice = = NULL ) {
status = STATUS_INVALID_DEVICE_REQUEST ;
DoTraceLevelMessage (
FxDriverGlobals , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Attributes->ParentObject 0x%p must have WDFDEVICE as an "
" eventual ancestor, %!STATUS! " ,
Attributes - > ParentObject , status ) ;
return status ;
}
else if ( pSearchDevice ! = Device ) {
status = STATUS_INVALID_DEVICE_REQUEST ;
DoTraceLevelMessage (
FxDriverGlobals , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but "
" not the same WDFDEVICE 0x%p passed to WdfIoTargetCreate, "
" %!STATUS! " ,
Attributes - > ParentObject , pSearchDevice - > GetHandle ( ) ,
Device - > GetHandle ( ) , status ) ;
return status ;
}
}
pTarget = new ( FxDriverGlobals , Attributes )
FxIoTargetRemote ( FxDriverGlobals ) ;
if ( pTarget = = NULL ) {
status = STATUS_INSUFFICIENT_RESOURCES ;
DoTraceLevelMessage (
FxDriverGlobals , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Could not allocate memory for target, %!STATUS! " , status ) ;
return status ;
}
//
// initialize the new target
//
status = pTarget - > InitRemote ( Device ) ;
if ( ! NT_SUCCESS ( status ) ) {
return status ;
}
//
// Commit and apply the attributes
//
status = pTarget - > Commit ( Attributes , & hTarget , pParent ) ;
if ( NT_SUCCESS ( status ) ) {
* Target = pTarget ;
}
else {
//
// This will properly clean up the target's state and free it
//
DoTraceLevelMessage (
FxDriverGlobals , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Commit failed for target, %!STATUS! " , status ) ;
pTarget - > DeleteFromFailedCreate ( ) ;
}
return status ;
}
NTSTATUS
FxIoTargetRemote : : InitRemote (
__in FxDeviceBase * Device
)
{
NTSTATUS status ;
//
// do the base class mode-specific initialization
//
2020-10-16 03:30:51 +00:00
status = FxIoTarget : : InitModeSpecific ( Device ) ; // __super call
2020-09-24 20:51:15 +00:00
if ( ! NT_SUCCESS ( status ) ) {
return status ;
}
//
// Do mode-specific initilialization
//
status = InitRemoteModeSpecific ( Device ) ;
if ( ! NT_SUCCESS ( status ) ) {
return status ;
}
m_Driver = Device - > GetDriver ( ) ;
SetDeviceBase ( Device ) ;
m_InStackDevice = Device - > GetDeviceObject ( ) ;
( void ) Device - > AddIoTarget ( this ) ;
return STATUS_SUCCESS ;
}
_Must_inspect_result_
NTSTATUS
FxIoTargetRemote : : Open (
__in PWDF_IO_TARGET_OPEN_PARAMS OpenParams
)
{
FxIoTargetRemoveOpenParams params , * pParams ;
UNICODE_STRING name ;
LIST_ENTRY pended ;
WDF_IO_TARGET_OPEN_TYPE type ;
NTSTATUS status ;
BOOLEAN close , reopen ;
PVOID pEa ;
ULONG eaLength ;
KIRQL irql ;
RtlZeroMemory ( & name , sizeof ( name ) ) ;
close = FALSE ;
reopen = OpenParams - > Type = = WdfIoTargetOpenReopen ? TRUE : FALSE ;
pEa = NULL ;
eaLength = 0 ;
//
// We only support reopening using stored settings when we open by name
//
if ( reopen & & m_OpenParams . OpenType ! = WdfIoTargetOpenByName ) {
status = STATUS_INVALID_DEVICE_REQUEST ;
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Reopen only supported if the open type is WdfIoTargetOpenByName WDFIOTARGET %p %!STATUS! " ,
GetObjectHandle ( ) , status ) ;
return status ;
}
//
// Must preallocate all settings now
//
if ( reopen ) {
//
// convert the type into the type used for the previous open
//
type = m_OpenParams . OpenType ;
pParams = & m_OpenParams ;
}
else {
type = OpenParams - > Type ;
pParams = & params ;
if ( OpenParams - > Type = = WdfIoTargetOpenByName ) {
status = FxDuplicateUnicodeString ( GetDriverGlobals ( ) ,
& OpenParams - > TargetDeviceName ,
& name ) ;
if ( ! NT_SUCCESS ( status ) ) {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Could not allocate memory for target name for WDFIOTARGET %p " ,
GetObjectHandle ( ) ) ;
goto Done ;
}
if ( OpenParams - > EaBuffer ! = NULL & & OpenParams - > EaBufferLength > 0 ) {
pEa = FxPoolAllocate ( GetDriverGlobals ( ) ,
PagedPool ,
OpenParams - > EaBufferLength ) ;
if ( pEa = = NULL ) {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Could not allocate memory for target name "
" for WDFIOTARGET %p " , GetObjectHandle ( ) ) ;
status = STATUS_INSUFFICIENT_RESOURCES ;
goto Done ;
}
else {
eaLength = OpenParams - > EaBufferLength ;
RtlCopyMemory ( pEa , OpenParams - > EaBuffer , eaLength ) ;
}
}
}
}
Lock ( & irql ) ;
if ( m_State = = WdfIoTargetDeleted ) {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Opening WDFIOTARGET %p which is removed, state %d " ,
GetObjectHandle ( ) , m_State ) ;
status = STATUS_INVALID_DEVICE_STATE ;
}
else if ( m_OpenState ! = FxIoTargetRemoteOpenStateClosed ) {
//
// We are either open or are opening
//
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_ERROR , TRACINGIOTARGET ,
" Opening an already open WDFIOTARGET %p, open state %d " ,
GetObjectHandle ( ) , m_OpenState ) ;
status = STATUS_INVALID_DEVICE_STATE ;
}
else {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Opening WDFIOTARGET %p " , GetObjectHandle ( ) ) ;
//
// Clear the event so that if something is waiting on the state
// transition, they will block until we are done.
//
m_OpenedEvent . Clear ( ) ;
m_OpenState = FxIoTargetRemoteOpenStateOpening ;
status = STATUS_SUCCESS ;
}
Unlock ( irql ) ;
if ( ! NT_SUCCESS ( status ) ) {
goto Done ;
}
ASSERT ( m_TargetFileObject = = NULL ) ;
ASSERT ( m_TargetDevice = = NULL ) ;
ASSERT ( m_TargetPdo = = NULL ) ;
ASSERT ( m_TargetHandle = = NULL ) ;
//
// m_TargetNotifyHandle can be a valid value if the caller has previously
// opened the target, received a query remove, then a cancel remove, and
// is now reopening the target.
//
UnregisterForPnpNotification ( m_TargetNotifyHandle ) ;
ResetTargetNotifyHandle ( ) ;
//
// Only clear the open parameters if we are not attempting a reopen.
//
if ( reopen = = FALSE ) {
m_OpenParams . Clear ( ) ;
}
switch ( type ) {
case WdfIoTargetOpenUseExistingDevice :
KMDF_ONLY_CODE_PATH_ASSERT ( ) ;
//
// OpenParams must be non NULL b/c we can't reopen a target with a
// previous device object.
//
ASSERT ( OpenParams - > Type = = WdfIoTargetOpenUseExistingDevice ) ;
m_TargetDevice = ( MdDeviceObject ) OpenParams - > TargetDeviceObject ;
m_TargetFileObject = ( MdFileObject ) OpenParams - > TargetFileObject ;
m_TargetHandle = NULL ;
//
// By taking a manual reference here, we simplify the code in
// FxIoTargetRemote::Close where we can assume there is an outstanding
// reference on the PFILE_OBJECT at all times as long as we have a non
// NULL pointer.
//
if ( m_TargetFileObject ! = NULL ) {
Mx : : MxReferenceObject ( m_TargetFileObject ) ;
}
status = STATUS_SUCCESS ;
break ;
case WdfIoTargetOpenLocalTargetByFile :
UMDF_ONLY_CODE_PATH_ASSERT ( ) ;
status = OpenLocalTargetByFile ( OpenParams ) ;
break ;
case WdfIoTargetOpenByName :
//
// Only capture the open parameters if we are not reopening.
//
if ( reopen = = FALSE ) {
pParams - > Set ( OpenParams , & name , pEa , eaLength ) ;
}
status = OpenTargetHandle ( OpenParams , pParams ) ;
if ( NT_SUCCESS ( status ) ) {
if ( reopen = = FALSE ) {
m_OpenParams . Set ( OpenParams , & name , pEa , eaLength ) ;
//
// Setting pEa to NULL stops it from being freed later.
// Zeroing out name stops it from being freed later.
//
pEa = NULL ;
RtlZeroMemory ( & name , sizeof ( name ) ) ;
}
}
else {
close = TRUE ;
}
break ;
}
InitializeListHead ( & pended ) ;
//
// Get Target file object for KMDF. Noop for UMDF.
//
if ( NT_SUCCESS ( status ) ) {
status = GetTargetDeviceRelations ( & close ) ;
}
if ( NT_SUCCESS ( status ) & & CanRegisterForPnpNotification ( ) ) {
if ( reopen = = FALSE ) {
//
// Set the values before the register so that if a notification
// comes in before the register returns, we have a function to call.
//
m_EvtQueryRemove . m_Method = OpenParams - > EvtIoTargetQueryRemove ;
m_EvtRemoveCanceled . m_Method = OpenParams - > EvtIoTargetRemoveCanceled ;
m_EvtRemoveComplete . m_Method = OpenParams - > EvtIoTargetRemoveComplete ;
}
status = RegisterForPnpNotification ( ) ;
//
// Even if we can't register, we still are successful in opening
// up the device and we will proceed from there.
//
if ( ! NT_SUCCESS ( status ) ) {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" WDFIOTARGET %p, could not register pnp notification, %!STATUS! not "
" treated as an error " , GetObjectHandle ( ) , status ) ;
m_EvtQueryRemove . m_Method = NULL ;
m_EvtRemoveCanceled . m_Method = NULL ;
m_EvtRemoveComplete . m_Method = NULL ;
status = STATUS_SUCCESS ;
}
}
//
// UMDF only. Bind handle to remote dispatcher.
//
# if (FX_CORE_MODE == FX_CORE_USER_MODE)
if ( NT_SUCCESS ( status ) & & type ! = WdfIoTargetOpenLocalTargetByFile ) {
status = BindToHandle ( ) ;
if ( ! NT_SUCCESS ( status ) ) {
close = TRUE ;
}
}
# endif
Lock ( & irql ) ;
if ( NT_SUCCESS ( status ) ) {
# if (FX_CORE_MODE == FX_CORE_KERNEL_MODE)
m_TargetStackSize = m_TargetDevice - > StackSize ;
m_TargetIoType = GetTargetIoType ( ) ;
# endif
m_OpenState = FxIoTargetRemoteOpenStateOpen ;
//
// Set our state to started. This will also resend any pended requests
// due to a query remove.
//
status = GotoStartState ( & pended , FALSE ) ;
//
// We could not successfully start, close back down
//
if ( ! NT_SUCCESS ( status ) ) {
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" WDFIOTARGET %p could not transition to started state, %!STATUS! " ,
GetObjectHandle ( ) , status ) ;
close = TRUE ;
}
}
else {
m_OpenState = FxIoTargetRemoteOpenStateClosed ;
}
//
// No matter what, indicate to any waiters that our state change has
// completed.
//
m_OpenedEvent . Set ( ) ;
Unlock ( irql ) ;
Done :
//
// Resubmit any reads that were pended until now.
//
if ( NT_SUCCESS ( status ) ) {
SubmitPendedRequests ( & pended ) ;
}
else if ( close ) {
Close ( FxIoTargetRemoteCloseReasonPlainClose ) ;
}
if ( name . Buffer ! = NULL ) {
FxPoolFree ( name . Buffer ) ;
}
if ( pEa ! = NULL ) {
FxPoolFree ( pEa ) ;
}
return status ;
}
VOID
FxIoTargetRemote : : Close (
__in FxIoTargetRemoteCloseReason Reason
)
{
FxIoTargetClearedPointers pointers ;
MdTargetNotifyHandle pNotifyHandle ;
SINGLE_LIST_ENTRY sent ;
LIST_ENTRY pended ;
WDF_IO_TARGET_STATE removeState ;
KIRQL irql ;
BOOLEAN wait ;
PFX_DRIVER_GLOBALS pFxDriverGlobals ;
pFxDriverGlobals = GetDriverGlobals ( ) ;
DoTraceLevelMessage ( pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" enter: WDFIOTARGET %p, reason %d " , GetObjectHandle ( ) , Reason ) ;
RtlZeroMemory ( & pointers , sizeof ( pointers ) ) ;
pNotifyHandle = NULL ;
sent . Next = NULL ;
InitializeListHead ( & pended ) ;
wait = FALSE ;
//
// Pick a value that is not used anywhere in the function and make sure that
// we have changed it, before we go to the Remove state
//
# pragma prefast(suppress: __WARNING_UNUSED_SCALAR_ASSIGNMENT, "PFD is warning that the following assignement is unused. Suppress it to prevent changing any logic.")
removeState = WdfIoTargetStarted ;
CheckState :
Lock ( & irql ) ;
//
// If we are in the process of opening the target, wait for that to finish.
//
if ( m_OpenState = = FxIoTargetRemoteOpenStateOpening ) {
Unlock ( irql ) ;
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Closing WDFIOTARGET %p which is opening, waiting on event %p " ,
GetObjectHandle ( ) , m_OpenedEvent . GetEvent ( ) ) ;
m_OpenedEvent . EnterCRAndWaitAndLeave ( ) ;
//
// Jump back to the top and recheck
//
goto CheckState ;
}
if ( Reason = = FxIoTargetRemoteCloseReasonDelete ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Closing WDFIOTARGET %p, reason: delete " , GetObjectHandle ( ) ) ;
removeState = WdfIoTargetDeleted ;
}
else if ( m_OpenState = = FxIoTargetRemoteOpenStateOpen ) {
if ( Reason = = FxIoTargetRemoteCloseReasonQueryRemove ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Closing WDFIOTARGET %p, reason: query remove " ,
GetObjectHandle ( ) ) ;
//
// Not really being removed, but that is what the API name is...
//
removeState = WdfIoTargetClosedForQueryRemove ;
}
else {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Closing WDFIOTARGET %p, reason: close " , GetObjectHandle ( ) ) ;
if ( pFxDriverGlobals - > IsVersionGreaterThanOrEqualTo ( 1 , 9 ) ) {
removeState = WdfIoTargetClosed ;
}
else {
removeState = WdfIoTargetClosedForQueryRemove ;
}
}
//
// Either way, we are no longer open for business
//
m_OpenState = FxIoTargetRemoteOpenStateClosed ;
}
else {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" Closing WDFIOTARGET %p which is not open " , GetObjectHandle ( ) ) ;
//
// We are not opened, so treat this as a cleanup
//
removeState = WdfIoTargetClosed ;
}
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" WDFIOTARGET %p: fileobj %p, devobj %p, handle %p, notify handle %I64d " ,
GetObjectHandle ( ) , m_TargetFileObject ,
m_TargetDevice , m_TargetHandle , ( UINT64 ) m_TargetNotifyHandle ) ;
if ( Reason ! = FxIoTargetRemoteCloseReasonQueryRemove ) {
//
// If we are closing for a query remove, we want to keep the handle
// around so that we can be notified of the final close or if the close
// was canceled.
//
pNotifyHandle = m_TargetNotifyHandle ;
ResetTargetNotifyHandle ( ) ;
}
ASSERT ( removeState ! = WdfIoTargetStarted ) ;
m_ClearedPointers = & pointers ;
GotoRemoveState ( removeState , & pended , & sent , FALSE , & wait ) ;
Unlock ( irql ) ;
UnregisterForPnpNotification ( pNotifyHandle ) ;
//
// Complete any requests we might have pulled off of our lists
//
CompletePendedRequestList ( & pended ) ;
_CancelSentRequests ( & sent ) ;
//
// We were just removed, wait for any I/O to complete back if necessary.
//
if ( wait ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_VERBOSE , TRACINGIOTARGET ,
" WDFIOTARGET %p, waiting for stop to complete " , GetObjectHandle ( ) ) ;
WaitForSentIoToComplete ( ) ;
}
switch ( Reason ) {
case FxIoTargetRemoteCloseReasonQueryRemove :
//
// m_OpenParams is needed for reopen on canceled query remove
//
DO_NOTHING ( ) ;
break ;
case FxIoTargetRemoteCloseReasonDelete :
m_OpenParams . Clear ( ) ;
break ;
default :
//
// If this object is not about to be deleted, we need to revert some
// of the state that just changed.
//
m_SentIoEvent . Clear ( ) ;
break ;
}
if ( removeState = = WdfIoTargetDeleted ) {
WaitForDisposeEvent ( ) ;
}
//
// Finally, close down our handle and pointers
//
if ( pointers . TargetPdo ! = NULL ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_INFORMATION , TRACINGIOTARGET ,
" WDFIOTARGET %p derefing PDO %p on close " ,
GetObjectHandle ( ) , pointers . TargetPdo ) ;
Mx : : MxDereferenceObject ( pointers . TargetPdo ) ;
}
if ( pointers . TargetFileObject ! = NULL ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_INFORMATION , TRACINGIOTARGET ,
" WDFIOTARGET %p derefing FileObj %p on close " ,
GetObjectHandle ( ) , pointers . TargetFileObject ) ;
Mx : : MxDereferenceObject ( pointers . TargetFileObject ) ;
# if (FX_CORE_MODE == FX_CORE_USER_MODE)
CloseWdfFileObject ( pointers . TargetFileObject ) ;
# endif
}
# if (FX_CORE_MODE == FX_CORE_USER_MODE)
UnbindHandle ( & pointers ) ;
# endif
if ( pointers . TargetHandle ! = NULL ) {
DoTraceLevelMessage (
pFxDriverGlobals , TRACE_LEVEL_INFORMATION , TRACINGIOTARGET ,
" WDFIOTARGET %p closing handle %p on close " ,
GetObjectHandle ( ) , pointers . TargetHandle ) ;
Mx : : MxClose ( pointers . TargetHandle ) ;
}
}
VOID
FxIoTargetRemote : : ClearTargetPointers (
VOID
)
{
DoTraceLevelMessage (
GetDriverGlobals ( ) , TRACE_LEVEL_INFORMATION , TRACINGIOTARGET ,
" WDFIOTARGET %p cleared pointers %p state %!WDF_IO_TARGET_STATE!, "
" open state %d, pdo %p, fileobj %p, handle %p " ,
GetObjectHandle ( ) , m_ClearedPointers , m_State , m_OpenState , m_TargetPdo ,
m_TargetFileObject , m_TargetHandle ) ;
//
// Check to see if the caller who is changing state wants these pointer
// values before they being cleared out.
//
if ( m_ClearedPointers ! = NULL ) {
m_ClearedPointers - > TargetPdo = m_TargetPdo ;
m_ClearedPointers - > TargetFileObject = m_TargetFileObject ;
m_ClearedPointers - > TargetHandle = m_TargetHandle ;
m_ClearedPointers = NULL ;
}
//
// m_TargetHandle is only an FxIoTargetRemote field, clear it now
//
m_TargetHandle = NULL ;
//
// m_TargetPdo and m_TargetFileObject will be cleared in the following call.
//
// m_TargetNotifyHandle is not cleared in the following call and is left
// valid because we want to receive the notification about query remove being
// canceled or completing. When we receive either of those notifications,
// m_TargetNotifyHandle will be freed then.
//
2020-10-16 03:30:51 +00:00
FxIoTarget : : ClearTargetPointers ( ) ; // __super call
2020-09-24 20:51:15 +00:00
}
VOID
FxIoTargetRemote : : Remove (
VOID
)
{
//
// Close is the same as remove in this object
//
Close ( FxIoTargetRemoteCloseReasonDelete ) ;
//
// Do mode-specific work
//
RemoveModeSpecific ( ) ;
return ;
}
VOID
FxIoTargetRemoveOpenParams : : Clear (
VOID
)
{
if ( EaBuffer ! = NULL ) {
FxPoolFree ( EaBuffer ) ;
}
if ( TargetDeviceName . Buffer ! = NULL ) {
FxPoolFree ( TargetDeviceName . Buffer ) ;
}
RtlZeroMemory ( this , sizeof ( FxIoTargetRemoveOpenParams ) ) ;
}
VOID
FxIoTargetRemoveOpenParams : : Set (
__in PWDF_IO_TARGET_OPEN_PARAMS OpenParams ,
__in PUNICODE_STRING Name ,
__in PVOID Ea ,
__in ULONG EaLength
)
{
OpenType = WdfIoTargetOpenByName ;
EaBuffer = Ea ;
EaBufferLength = EaLength ;
RtlCopyMemory ( & TargetDeviceName , Name , sizeof ( UNICODE_STRING ) ) ;
DesiredAccess = OpenParams - > DesiredAccess ;
FileAttributes = OpenParams - > FileAttributes ;
ShareAccess = OpenParams - > ShareAccess ;
CreateDisposition = OpenParams - > CreateDisposition ;
CreateOptions = OpenParams - > CreateOptions ;
if ( OpenParams - > AllocationSize ! = NULL ) {
AllocationSize . QuadPart = * ( OpenParams - > AllocationSize ) ;
AllocationSizePointer = & AllocationSize ;
}
else {
AllocationSizePointer = NULL ;
}
}