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