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
,
72 /* Create the Object */
73 Status
= ObCreateObject(KernelMode
,
74 IoControllerObjectType
,
78 sizeof(CONTROLLER_OBJECT
) + Size
,
82 if (!NT_SUCCESS(Status
)) return NULL
;
85 Status
= ObInsertObject(Controller
,
87 FILE_READ_DATA
| FILE_WRITE_DATA
,
91 if (!NT_SUCCESS(Status
)) return NULL
;
93 /* Close the dummy handle */
94 ObCloseHandle(Handle
, KernelMode
);
96 /* Zero the Object and set its data */
97 RtlZeroMemory(Controller
, sizeof(CONTROLLER_OBJECT
) + Size
);
98 Controller
->Type
= IO_TYPE_CONTROLLER
;
99 Controller
->Size
= sizeof(CONTROLLER_OBJECT
) + (CSHORT
)Size
;
100 Controller
->ControllerExtension
= (Controller
+ 1);
102 /* Initialize its Queue */
103 KeInitializeDeviceQueue(&Controller
->DeviceWaitQueue
);
105 /* Return Controller */
114 IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject
)
116 /* Just Dereference it */
117 ObDereferenceObject(ControllerObject
);
125 IoFreeController(IN PCONTROLLER_OBJECT ControllerObject
)
127 PKDEVICE_QUEUE_ENTRY QueueEntry
;
128 PDEVICE_OBJECT DeviceObject
;
129 IO_ALLOCATION_ACTION Result
;
131 /* Remove the Queue */
132 QueueEntry
= KeRemoveDeviceQueue(&ControllerObject
->DeviceWaitQueue
);
135 /* Get the Device Object */
136 DeviceObject
= CONTAINING_RECORD(QueueEntry
,
138 Queue
.Wcb
.WaitQueueEntry
);
140 /* Call the routine */
141 Result
= DeviceObject
->Queue
.Wcb
.DeviceRoutine(DeviceObject
,
142 DeviceObject
->CurrentIrp
,
145 Queue
.Wcb
.DeviceContext
);
146 /* Free the controller if this was requested */
147 if (Result
== DeallocateObject
) IoFreeController(ControllerObject
);