2005-04-26 14:51:18 +00:00
|
|
|
/*
|
2006-06-30 19:09:39 +00:00
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-10-04 11:54:25 +00:00
|
|
|
* FILE: ntoskrnl/io/iomgr/controller.c
|
2006-06-30 19:09:39 +00:00
|
|
|
* PURPOSE: I/O Wrappers (called Controllers) for Kernel Device Queues
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
2005-04-26 14:51:18 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
2005-04-26 14:51:18 +00:00
|
|
|
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
|
|
|
POBJECT_TYPE IoControllerObjectType;
|
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
2006-06-30 19:09:39 +00:00
|
|
|
NTAPI
|
|
|
|
IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject,
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PDRIVER_CONTROL ExecutionRoutine,
|
|
|
|
IN PVOID Context)
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
|
|
|
IO_ALLOCATION_ACTION Result;
|
2007-01-17 20:44:37 +00:00
|
|
|
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
|
2005-04-26 14:51:18 +00:00
|
|
|
|
|
|
|
/* Initialize the Wait Context Block */
|
|
|
|
DeviceObject->Queue.Wcb.DeviceContext = Context;
|
|
|
|
DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Insert the Device Queue */
|
|
|
|
if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,
|
2008-12-03 17:39:55 +00:00
|
|
|
&DeviceObject->Queue.Wcb.WaitQueueEntry))
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
2006-06-30 19:09:39 +00:00
|
|
|
/* Call the execution routine */
|
2005-04-26 14:51:18 +00:00
|
|
|
Result = ExecutionRoutine(DeviceObject,
|
|
|
|
DeviceObject->CurrentIrp,
|
|
|
|
NULL,
|
2005-05-09 01:38:29 +00:00
|
|
|
Context);
|
|
|
|
|
2006-06-30 19:09:39 +00:00
|
|
|
/* Free the controller if this was requested */
|
|
|
|
if (Result == DeallocateObject) IoFreeController(ControllerObject);
|
2005-04-26 14:51:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
PCONTROLLER_OBJECT
|
2006-06-30 19:09:39 +00:00
|
|
|
NTAPI
|
|
|
|
IoCreateController(IN ULONG Size)
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
2018-12-16 09:30:23 +00:00
|
|
|
PCONTROLLER_OBJECT Controller;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE Handle;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
/* Initialize an empty OBA */
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
NULL,
|
|
|
|
OBJ_KERNEL_HANDLE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* Create the Object */
|
|
|
|
Status = ObCreateObject(KernelMode,
|
|
|
|
IoControllerObjectType,
|
|
|
|
&ObjectAttributes,
|
|
|
|
KernelMode,
|
|
|
|
NULL,
|
|
|
|
sizeof(CONTROLLER_OBJECT) + Size,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
(PVOID*)&Controller);
|
2005-04-26 14:51:18 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return NULL;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Insert it */
|
|
|
|
Status = ObInsertObject(Controller,
|
|
|
|
NULL,
|
|
|
|
FILE_READ_DATA | FILE_WRITE_DATA,
|
2006-06-29 05:05:27 +00:00
|
|
|
1,
|
|
|
|
(PVOID*)&Controller,
|
2005-04-26 14:51:18 +00:00
|
|
|
&Handle);
|
2018-12-16 09:30:23 +00:00
|
|
|
if (!NT_SUCCESS(Status)) return NULL;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Close the dummy handle */
|
2010-11-23 16:32:56 +00:00
|
|
|
ObCloseHandle(Handle, KernelMode);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Zero the Object and set its data */
|
|
|
|
RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
|
|
|
|
Controller->Type = IO_TYPE_CONTROLLER;
|
2007-08-05 11:27:39 +00:00
|
|
|
Controller->Size = sizeof(CONTROLLER_OBJECT) + (CSHORT)Size;
|
2005-04-26 14:51:18 +00:00
|
|
|
Controller->ControllerExtension = (Controller + 1);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Initialize its Queue */
|
|
|
|
KeInitializeDeviceQueue(&Controller->DeviceWaitQueue);
|
|
|
|
|
|
|
|
/* Return Controller */
|
|
|
|
return Controller;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
2006-06-30 19:09:39 +00:00
|
|
|
NTAPI
|
|
|
|
IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject)
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
|
|
|
/* Just Dereference it */
|
|
|
|
ObDereferenceObject(ControllerObject);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
2006-06-30 19:09:39 +00:00
|
|
|
NTAPI
|
|
|
|
IoFreeController(IN PCONTROLLER_OBJECT ControllerObject)
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
|
|
|
PKDEVICE_QUEUE_ENTRY QueueEntry;
|
|
|
|
PDEVICE_OBJECT DeviceObject;
|
|
|
|
IO_ALLOCATION_ACTION Result;
|
|
|
|
|
|
|
|
/* Remove the Queue */
|
2006-06-30 19:09:39 +00:00
|
|
|
QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
|
|
|
|
if (QueueEntry)
|
2005-04-26 14:51:18 +00:00
|
|
|
{
|
|
|
|
/* Get the Device Object */
|
2005-05-09 01:38:29 +00:00
|
|
|
DeviceObject = CONTAINING_RECORD(QueueEntry,
|
|
|
|
DEVICE_OBJECT,
|
2005-04-26 14:51:18 +00:00
|
|
|
Queue.Wcb.WaitQueueEntry);
|
2006-06-30 19:09:39 +00:00
|
|
|
|
2005-04-26 14:51:18 +00:00
|
|
|
/* Call the routine */
|
|
|
|
Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
|
|
|
|
DeviceObject->CurrentIrp,
|
|
|
|
NULL,
|
2006-06-30 19:09:39 +00:00
|
|
|
DeviceObject->
|
|
|
|
Queue.Wcb.DeviceContext);
|
|
|
|
/* Free the controller if this was requested */
|
|
|
|
if (Result == DeallocateObject) IoFreeController(ControllerObject);
|
2005-04-26 14:51:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|