mirror of
https://github.com/reactos/reactos.git
synced 2024-08-19 09:59:44 +00:00
- Implement IoSetCompletionRoutineEx, which is a safe way to set completion routines that almost all newer drivers will be using (XP+).
svn path=/trunk/; revision=24735
This commit is contained in:
parent
1c3d0f91a1
commit
b66b8bdcea
|
@ -229,6 +229,16 @@ typedef struct _IO_COMPLETION_PACKET
|
||||||
IO_STATUS_BLOCK IoStatus;
|
IO_STATUS_BLOCK IoStatus;
|
||||||
} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;
|
} IO_COMPLETION_PACKET, *PIO_COMPLETION_PACKET;
|
||||||
|
|
||||||
|
//
|
||||||
|
// I/O Completion Context for IoSetIoCompletionRoutineEx
|
||||||
|
//
|
||||||
|
typedef struct _IO_UNLOAD_SAFE_COMPLETION_CONTEXT
|
||||||
|
{
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
PVOID Context;
|
||||||
|
PIO_COMPLETION_ROUTINE CompletionRoutine;
|
||||||
|
} IO_UNLOAD_SAFE_COMPLETION_CONTEXT, *PIO_UNLOAD_SAFE_COMPLETION_CONTEXT;
|
||||||
|
|
||||||
//
|
//
|
||||||
// I/O Wrapper around the Executive Work Item
|
// I/O Wrapper around the Executive Work Item
|
||||||
//
|
//
|
||||||
|
|
|
@ -33,6 +33,32 @@ static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] =
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IopUnloadSafeCompletion(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIO_UNLOAD_SAFE_COMPLETION_CONTEXT UnsafeContext =
|
||||||
|
(PIO_UNLOAD_SAFE_COMPLETION_CONTEXT)Context;
|
||||||
|
|
||||||
|
/* Reference the device object */
|
||||||
|
ObReferenceObject(UnsafeContext->DeviceObject);
|
||||||
|
|
||||||
|
/* Call the completion routine */
|
||||||
|
Status= UnsafeContext->CompletionRoutine(DeviceObject,
|
||||||
|
Irp,
|
||||||
|
UnsafeContext->Context);
|
||||||
|
|
||||||
|
/* Dereference the device object */
|
||||||
|
ObDereferenceObject(UnsafeContext->DeviceObject);
|
||||||
|
|
||||||
|
/* Free our context */
|
||||||
|
ExFreePool(UnsafeContext);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
|
||||||
|
@ -187,7 +213,7 @@ IoSetIoCompletion(IN PVOID IoCompletion,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -199,8 +225,27 @@ IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN BOOLEAN InvokeOnError,
|
IN BOOLEAN InvokeOnError,
|
||||||
IN BOOLEAN InvokeOnCancel)
|
IN BOOLEAN InvokeOnCancel)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PIO_UNLOAD_SAFE_COMPLETION_CONTEXT UnloadContext;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
|
/* Allocate the context */
|
||||||
|
UnloadContext = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
|
sizeof(*UnloadContext),
|
||||||
|
TAG('I', 'o', 'U', 's'));
|
||||||
|
if (!UnloadContext) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Set up the context */
|
||||||
|
UnloadContext->DeviceObject = DeviceObject;
|
||||||
|
UnloadContext->Context = Context;
|
||||||
|
UnloadContext->CompletionRoutine = CompletionRoutine;
|
||||||
|
|
||||||
|
/* Now set the completion routine */
|
||||||
|
IoSetCompletionRoutine(Irp,
|
||||||
|
IopUnloadSafeCompletion,
|
||||||
|
UnloadContext,
|
||||||
|
InvokeOnSuccess,
|
||||||
|
InvokeOnError,
|
||||||
|
InvokeOnCancel);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue