xref: /reactos/ntoskrnl/io/iomgr/controller.c (revision e8d16d0a)
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