2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/io/controller.c
5 * PURPOSE: I/O Wrappers (called Controllers) for Kernel Device Queues
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* GLOBALS *******************************************************************/
16 POBJECT_TYPE IoControllerObjectType
;
18 /* FUNCTIONS *****************************************************************/
25 IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject
,
26 IN PDEVICE_OBJECT DeviceObject
,
27 IN PDRIVER_CONTROL ExecutionRoutine
,
30 IO_ALLOCATION_ACTION Result
;
31 ASSERT_IRQL_EQUAL(DISPATCH_LEVEL
);
33 /* Initialize the Wait Context Block */
34 DeviceObject
->Queue
.Wcb
.DeviceContext
= Context
;
35 DeviceObject
->Queue
.Wcb
.DeviceRoutine
= ExecutionRoutine
;
37 /* Insert the Device Queue */
38 if (!KeInsertDeviceQueue(&ControllerObject
->DeviceWaitQueue
,
39 &DeviceObject
->Queue
.Wcb
.WaitQueueEntry
))
41 /* Call the execution routine */
42 Result
= ExecutionRoutine(DeviceObject
,
43 DeviceObject
->CurrentIrp
,
47 /* Free the controller if this was requested */
48 if (Result
== DeallocateObject
) IoFreeController(ControllerObject
);
57 IoCreateController(IN ULONG Size
)
59 PCONTROLLER_OBJECT Controller
;
60 OBJECT_ATTRIBUTES ObjectAttributes
;
65 /* Initialize an empty OBA */
66 InitializeObjectAttributes(&ObjectAttributes
, NULL
, 0, NULL
, NULL
);
68 /* Create the Object */
69 Status
= ObCreateObject(KernelMode
,
70 IoControllerObjectType
,
74 sizeof(CONTROLLER_OBJECT
) + Size
,
78 if (!NT_SUCCESS(Status
)) return NULL
;
81 Status
= ObInsertObject(Controller
,
83 FILE_READ_DATA
| FILE_WRITE_DATA
,
87 if (!NT_SUCCESS(Status
)) return NULL
;
89 /* Close the dummy handle */
92 /* Zero the Object and set its data */
93 RtlZeroMemory(Controller
, sizeof(CONTROLLER_OBJECT
) + Size
);
94 Controller
->Type
= IO_TYPE_CONTROLLER
;
95 Controller
->Size
= sizeof(CONTROLLER_OBJECT
) + (CSHORT
)Size
;
96 Controller
->ControllerExtension
= (Controller
+ 1);
98 /* Initialize its Queue */
99 KeInitializeDeviceQueue(&Controller
->DeviceWaitQueue
);
101 /* Return Controller */
110 IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject
)
112 /* Just Dereference it */
113 ObDereferenceObject(ControllerObject
);
121 IoFreeController(IN PCONTROLLER_OBJECT ControllerObject
)
123 PKDEVICE_QUEUE_ENTRY QueueEntry
;
124 PDEVICE_OBJECT DeviceObject
;
125 IO_ALLOCATION_ACTION Result
;
127 /* Remove the Queue */
128 QueueEntry
= KeRemoveDeviceQueue(&ControllerObject
->DeviceWaitQueue
);
131 /* Get the Device Object */
132 DeviceObject
= CONTAINING_RECORD(QueueEntry
,
134 Queue
.Wcb
.WaitQueueEntry
);
136 /* Call the routine */
137 Result
= DeviceObject
->Queue
.Wcb
.DeviceRoutine(DeviceObject
,
138 DeviceObject
->CurrentIrp
,
141 Queue
.Wcb
.DeviceContext
);
142 /* Free the controller if this was requested */
143 if (Result
== DeallocateObject
) IoFreeController(ControllerObject
);