- 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:
Alex Ionescu 2006-11-12 22:39:09 +00:00
parent 1c3d0f91a1
commit b66b8bdcea
2 changed files with 58 additions and 3 deletions

View file

@ -229,6 +229,16 @@ typedef struct _IO_COMPLETION_PACKET
IO_STATUS_BLOCK IoStatus;
} 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
//

View file

@ -33,6 +33,32 @@ static const INFORMATION_CLASS_INFO IoCompletionInfoClass[] =
/* 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
NTAPI
IopFreeIoCompletionPacket(PIO_COMPLETION_PACKET Packet)
@ -187,7 +213,7 @@ IoSetIoCompletion(IN PVOID IoCompletion,
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI
@ -199,8 +225,27 @@ IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN InvokeOnError,
IN BOOLEAN InvokeOnCancel)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PIO_UNLOAD_SAFE_COMPLETION_CONTEXT UnloadContext;
/* 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