Properly setup the I/O stack location in IopSecurityFile.
[reactos.git] / reactos / ntoskrnl / io / controller.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/contrller.c
5 * PURPOSE: Implements the controller object
6 *
7 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #include <internal/debug.h>
14
15 /* GLOBALS *******************************************************************/
16
17 POBJECT_TYPE IoControllerObjectType;
18
19 /* FUNCTIONS *****************************************************************/
20
21 /*
22 * @implemented
23 *
24 * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
25 * as soon as the device controller, represented by the given controller
26 * object, is available to carry out an I/O operation for the target device,
27 * represented by the given device object.
28 * ARGUMENTS:
29 * ControllerObject = Driver created controller object
30 * DeviceObject = Target device for the current irp
31 * ExecutionRoutine = Routine to be called when the device is available
32 * Context = Driver supplied context to be passed on to the above routine
33 */
34 VOID
35 STDCALL
36 IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
37 PDEVICE_OBJECT DeviceObject,
38 PDRIVER_CONTROL ExecutionRoutine,
39 PVOID Context)
40 {
41 IO_ALLOCATION_ACTION Result;
42
43 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
44
45 /* Initialize the Wait Context Block */
46 DeviceObject->Queue.Wcb.DeviceContext = Context;
47 DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
48
49 /* Insert the Device Queue */
50 if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,
51 &DeviceObject->Queue.Wcb.WaitQueueEntry));
52 {
53 Result = ExecutionRoutine(DeviceObject,
54 DeviceObject->CurrentIrp,
55 NULL,
56 Context);
57 }
58
59 if (Result == DeallocateObject)
60 {
61 IoFreeController(ControllerObject);
62 }
63 }
64
65 /*
66 * @implemented
67 *
68 * FUNCTION: Allocates memory and initializes a controller object
69 * ARGUMENTS:
70 * Size = Size (in bytes) to be allocated for the controller extension
71 * RETURNS: A pointer to the created object
72 */
73 PCONTROLLER_OBJECT
74 STDCALL
75 IoCreateController(ULONG Size)
76
77 {
78 PCONTROLLER_OBJECT Controller;
79 OBJECT_ATTRIBUTES ObjectAttributes;
80 HANDLE Handle;
81 NTSTATUS Status;
82 ASSERT_IRQL(PASSIVE_LEVEL);
83
84 /* Initialize an empty OBA */
85 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
86
87 /* Create the Object */
88 Status = ObCreateObject(KernelMode,
89 IoControllerObjectType,
90 &ObjectAttributes,
91 KernelMode,
92 NULL,
93 sizeof(CONTROLLER_OBJECT) + Size,
94 0,
95 0,
96 (PVOID*)&Controller);
97 if (!NT_SUCCESS(Status)) return NULL;
98
99 /* Insert it */
100 Status = ObInsertObject(Controller,
101 NULL,
102 FILE_READ_DATA | FILE_WRITE_DATA,
103 0,
104 NULL,
105 &Handle);
106 if (!NT_SUCCESS(Status)) return NULL;
107
108 /* Close the dummy handle */
109 NtClose(Handle);
110
111 /* Zero the Object and set its data */
112 RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
113 Controller->Type = IO_TYPE_CONTROLLER;
114 Controller->Size = sizeof(CONTROLLER_OBJECT) + Size;
115 Controller->ControllerExtension = (Controller + 1);
116
117 /* Initialize its Queue */
118 KeInitializeDeviceQueue(&Controller->DeviceWaitQueue);
119
120 /* Return Controller */
121 return Controller;
122 }
123
124 /*
125 * @implemented
126 *
127 * FUNCTION: Removes a given controller object from the system
128 * ARGUMENTS:
129 * ControllerObject = Controller object to be released
130 */
131 VOID
132 STDCALL
133 IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
134
135 {
136 /* Just Dereference it */
137 ObDereferenceObject(ControllerObject);
138 }
139
140 /*
141 * @implemented
142 *
143 * FUNCTION: Releases a previously allocated controller object when a
144 * device has finished an I/O request
145 * ARGUMENTS:
146 * ControllerObject = Controller object to be released
147 */
148 VOID
149 STDCALL
150 IoFreeController(PCONTROLLER_OBJECT ControllerObject)
151 {
152 PKDEVICE_QUEUE_ENTRY QueueEntry;
153 PDEVICE_OBJECT DeviceObject;
154 IO_ALLOCATION_ACTION Result;
155
156 /* Remove the Queue */
157 if ((QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue)))
158 {
159 /* Get the Device Object */
160 DeviceObject = CONTAINING_RECORD(QueueEntry,
161 DEVICE_OBJECT,
162 Queue.Wcb.WaitQueueEntry);
163 /* Call the routine */
164 Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
165 DeviceObject->CurrentIrp,
166 NULL,
167 DeviceObject->Queue.Wcb.DeviceContext);
168 /* Check the result */
169 if (Result == DeallocateObject)
170 {
171 /* Free it again */
172 IoFreeController(ControllerObject);
173 }
174 }
175 }
176
177
178 /* EOF */