1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * PROJECT: ReactOS Kernel
3*c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory
4*c2c66affSColin Finck * FILE: ntoskrnl/io/iomgr/controller.c
5*c2c66affSColin Finck * PURPOSE: I/O Wrappers (called Controllers) for Kernel Device Queues
6*c2c66affSColin Finck * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7*c2c66affSColin Finck */
8*c2c66affSColin Finck
9*c2c66affSColin Finck /* INCLUDES *****************************************************************/
10*c2c66affSColin Finck
11*c2c66affSColin Finck #include <ntoskrnl.h>
12*c2c66affSColin Finck #include <debug.h>
13*c2c66affSColin Finck
14*c2c66affSColin Finck /* GLOBALS *******************************************************************/
15*c2c66affSColin Finck
16*c2c66affSColin Finck POBJECT_TYPE IoControllerObjectType;
17*c2c66affSColin Finck
18*c2c66affSColin Finck /* FUNCTIONS *****************************************************************/
19*c2c66affSColin Finck
20*c2c66affSColin Finck /*
21*c2c66affSColin Finck * @implemented
22*c2c66affSColin Finck */
23*c2c66affSColin Finck VOID
24*c2c66affSColin Finck NTAPI
IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject,IN PDEVICE_OBJECT DeviceObject,IN PDRIVER_CONTROL ExecutionRoutine,IN PVOID Context)25*c2c66affSColin Finck IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject,
26*c2c66affSColin Finck IN PDEVICE_OBJECT DeviceObject,
27*c2c66affSColin Finck IN PDRIVER_CONTROL ExecutionRoutine,
28*c2c66affSColin Finck IN PVOID Context)
29*c2c66affSColin Finck {
30*c2c66affSColin Finck IO_ALLOCATION_ACTION Result;
31*c2c66affSColin Finck ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
32*c2c66affSColin Finck
33*c2c66affSColin Finck /* Initialize the Wait Context Block */
34*c2c66affSColin Finck DeviceObject->Queue.Wcb.DeviceContext = Context;
35*c2c66affSColin Finck DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
36*c2c66affSColin Finck
37*c2c66affSColin Finck /* Insert the Device Queue */
38*c2c66affSColin Finck if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,
39*c2c66affSColin Finck &DeviceObject->Queue.Wcb.WaitQueueEntry))
40*c2c66affSColin Finck {
41*c2c66affSColin Finck /* Call the execution routine */
42*c2c66affSColin Finck Result = ExecutionRoutine(DeviceObject,
43*c2c66affSColin Finck DeviceObject->CurrentIrp,
44*c2c66affSColin Finck NULL,
45*c2c66affSColin Finck Context);
46*c2c66affSColin Finck
47*c2c66affSColin Finck /* Free the controller if this was requested */
48*c2c66affSColin Finck if (Result == DeallocateObject) IoFreeController(ControllerObject);
49*c2c66affSColin Finck }
50*c2c66affSColin Finck }
51*c2c66affSColin Finck
52*c2c66affSColin Finck /*
53*c2c66affSColin Finck * @implemented
54*c2c66affSColin Finck */
55*c2c66affSColin Finck PCONTROLLER_OBJECT
56*c2c66affSColin Finck NTAPI
IoCreateController(IN ULONG Size)57*c2c66affSColin Finck IoCreateController(IN ULONG Size)
58*c2c66affSColin Finck {
59*c2c66affSColin Finck PCONTROLLER_OBJECT Controller;
60*c2c66affSColin Finck OBJECT_ATTRIBUTES ObjectAttributes;
61*c2c66affSColin Finck HANDLE Handle;
62*c2c66affSColin Finck NTSTATUS Status;
63*c2c66affSColin Finck PAGED_CODE();
64*c2c66affSColin Finck
65*c2c66affSColin Finck /* Initialize an empty OBA */
66*c2c66affSColin Finck InitializeObjectAttributes(&ObjectAttributes,
67*c2c66affSColin Finck NULL,
68*c2c66affSColin Finck OBJ_KERNEL_HANDLE,
69*c2c66affSColin Finck NULL,
70*c2c66affSColin Finck NULL);
71*c2c66affSColin Finck
72*c2c66affSColin Finck /* Create the Object */
73*c2c66affSColin Finck Status = ObCreateObject(KernelMode,
74*c2c66affSColin Finck IoControllerObjectType,
75*c2c66affSColin Finck &ObjectAttributes,
76*c2c66affSColin Finck KernelMode,
77*c2c66affSColin Finck NULL,
78*c2c66affSColin Finck sizeof(CONTROLLER_OBJECT) + Size,
79*c2c66affSColin Finck 0,
80*c2c66affSColin Finck 0,
81*c2c66affSColin Finck (PVOID*)&Controller);
82*c2c66affSColin Finck if (!NT_SUCCESS(Status)) return NULL;
83*c2c66affSColin Finck
84*c2c66affSColin Finck /* Insert it */
85*c2c66affSColin Finck Status = ObInsertObject(Controller,
86*c2c66affSColin Finck NULL,
87*c2c66affSColin Finck FILE_READ_DATA | FILE_WRITE_DATA,
88*c2c66affSColin Finck 1,
89*c2c66affSColin Finck (PVOID*)&Controller,
90*c2c66affSColin Finck &Handle);
91*c2c66affSColin Finck if (!NT_SUCCESS(Status)) return NULL;
92*c2c66affSColin Finck
93*c2c66affSColin Finck /* Close the dummy handle */
94*c2c66affSColin Finck ObCloseHandle(Handle, KernelMode);
95*c2c66affSColin Finck
96*c2c66affSColin Finck /* Zero the Object and set its data */
97*c2c66affSColin Finck RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
98*c2c66affSColin Finck Controller->Type = IO_TYPE_CONTROLLER;
99*c2c66affSColin Finck Controller->Size = sizeof(CONTROLLER_OBJECT) + (CSHORT)Size;
100*c2c66affSColin Finck Controller->ControllerExtension = (Controller + 1);
101*c2c66affSColin Finck
102*c2c66affSColin Finck /* Initialize its Queue */
103*c2c66affSColin Finck KeInitializeDeviceQueue(&Controller->DeviceWaitQueue);
104*c2c66affSColin Finck
105*c2c66affSColin Finck /* Return Controller */
106*c2c66affSColin Finck return Controller;
107*c2c66affSColin Finck }
108*c2c66affSColin Finck
109*c2c66affSColin Finck /*
110*c2c66affSColin Finck * @implemented
111*c2c66affSColin Finck */
112*c2c66affSColin Finck VOID
113*c2c66affSColin Finck NTAPI
IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject)114*c2c66affSColin Finck IoDeleteController(IN PCONTROLLER_OBJECT ControllerObject)
115*c2c66affSColin Finck {
116*c2c66affSColin Finck /* Just Dereference it */
117*c2c66affSColin Finck ObDereferenceObject(ControllerObject);
118*c2c66affSColin Finck }
119*c2c66affSColin Finck
120*c2c66affSColin Finck /*
121*c2c66affSColin Finck * @implemented
122*c2c66affSColin Finck */
123*c2c66affSColin Finck VOID
124*c2c66affSColin Finck NTAPI
IoFreeController(IN PCONTROLLER_OBJECT ControllerObject)125*c2c66affSColin Finck IoFreeController(IN PCONTROLLER_OBJECT ControllerObject)
126*c2c66affSColin Finck {
127*c2c66affSColin Finck PKDEVICE_QUEUE_ENTRY QueueEntry;
128*c2c66affSColin Finck PDEVICE_OBJECT DeviceObject;
129*c2c66affSColin Finck IO_ALLOCATION_ACTION Result;
130*c2c66affSColin Finck
131*c2c66affSColin Finck /* Remove the Queue */
132*c2c66affSColin Finck QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
133*c2c66affSColin Finck if (QueueEntry)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck /* Get the Device Object */
136*c2c66affSColin Finck DeviceObject = CONTAINING_RECORD(QueueEntry,
137*c2c66affSColin Finck DEVICE_OBJECT,
138*c2c66affSColin Finck Queue.Wcb.WaitQueueEntry);
139*c2c66affSColin Finck
140*c2c66affSColin Finck /* Call the routine */
141*c2c66affSColin Finck Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
142*c2c66affSColin Finck DeviceObject->CurrentIrp,
143*c2c66affSColin Finck NULL,
144*c2c66affSColin Finck DeviceObject->
145*c2c66affSColin Finck Queue.Wcb.DeviceContext);
146*c2c66affSColin Finck /* Free the controller if this was requested */
147*c2c66affSColin Finck if (Result == DeallocateObject) IoFreeController(ControllerObject);
148*c2c66affSColin Finck }
149*c2c66affSColin Finck }
150*c2c66affSColin Finck
151*c2c66affSColin Finck /* EOF */
152