Fixed callback calling conventions (part 2).
[reactos.git] / reactos / ntoskrnl / io / pnproot.c
1 /* $Id: pnproot.c,v 1.4 2001/08/27 01:20:50 ekohl Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/pnproot.c
6 * PURPOSE: PnP manager root device
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 16/04/2001 CSH Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16
17 #define NDEBUG
18 #include <internal/debug.h>
19
20 /* GLOBALS *******************************************************************/
21
22 /* DATA **********************************************************************/
23
24 typedef struct _PNPROOT_DEVICE {
25 LIST_ENTRY ListEntry;
26 PDEVICE_OBJECT Pdo;
27 } PNPROOT_DEVICE, *PPNPROOT_DEVICE;
28
29 PDEVICE_OBJECT PnpRootDeviceObject;
30 LIST_ENTRY PnpRootDeviceListHead;
31 ULONG PnpRootDeviceListCount;
32 KSPIN_LOCK PnpRootDeviceListLock;
33
34 /* FUNCTIONS *****************************************************************/
35
36 NTSTATUS
37 PnpRootCreateDevice(
38 PDEVICE_OBJECT *PhysicalDeviceObject)
39 {
40 PPNPROOT_DEVICE Device;
41 NTSTATUS Status;
42
43 DPRINT("Called\n");
44
45 Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
46 if (!Device)
47 return STATUS_INSUFFICIENT_RESOURCES;
48
49 Status = IoCreateDevice(PnpRootDeviceObject->DriverObject, 0,
50 NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
51 if (!NT_SUCCESS(Status))
52 {
53 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
54 ExFreePool(Device);
55 return Status;
56 }
57
58 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
59
60 ObReferenceObject(Device->Pdo);
61
62 ExInterlockedInsertTailList(&PnpRootDeviceListHead,
63 &Device->ListEntry,
64 &PnpRootDeviceListLock);
65
66 *PhysicalDeviceObject = Device->Pdo;
67
68 return STATUS_SUCCESS;
69 }
70
71
72 NTSTATUS
73 PnpRootQueryBusRelations(
74 IN PDEVICE_OBJECT DeviceObject,
75 IN PIRP Irp,
76 IN PIO_STACK_LOCATION IrpSp)
77 {
78 PDEVICE_RELATIONS Relations;
79 PLIST_ENTRY CurrentEntry;
80 PPNPROOT_DEVICE Device;
81 NTSTATUS Status;
82 ULONG Size;
83 ULONG i;
84
85 DPRINT("Called\n");
86
87 Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
88 (PnpRootDeviceListCount - 1);
89 Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
90 if (!Relations)
91 return STATUS_INSUFFICIENT_RESOURCES;
92
93 Relations->Count = PnpRootDeviceListCount;
94
95 i = 0;
96 CurrentEntry = PnpRootDeviceListHead.Flink;
97 while (CurrentEntry != &PnpRootDeviceListHead)
98 {
99 Device = CONTAINING_RECORD(
100 CurrentEntry, PNPROOT_DEVICE, ListEntry);
101
102 if (!Device->Pdo) {
103 /* Create a physical device object for the
104 device as it does not already have one */
105 Status = IoCreateDevice(DeviceObject->DriverObject, 0,
106 NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
107 if (!NT_SUCCESS(Status)) {
108 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
109 ExFreePool(Relations);
110 return Status;
111 }
112
113 Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
114 }
115
116 /* Reference the physical device object. The PnP manager
117 will dereference it again when it is no longer needed */
118 ObReferenceObject(Device->Pdo);
119
120 Relations->Objects[i] = Device->Pdo;
121
122 i++;
123
124 CurrentEntry = CurrentEntry->Flink;
125 }
126
127 Irp->IoStatus.Information = (ULONG)Relations;
128
129 return Status;
130 }
131
132 NTSTATUS
133 PnpRootQueryDeviceRelations(
134 IN PDEVICE_OBJECT DeviceObject,
135 IN PIRP Irp,
136 IN PIO_STACK_LOCATION IrpSp)
137 {
138 NTSTATUS Status;
139
140 DPRINT("Called\n");
141
142 switch (IrpSp->Parameters.QueryDeviceRelations.Type)
143 {
144 case BusRelations:
145 Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
146 break;
147
148 default:
149 Status = STATUS_NOT_IMPLEMENTED;
150 }
151
152 return Status;
153 }
154
155 NTSTATUS
156 STDCALL
157 PnpRootPnpControl(
158 IN PDEVICE_OBJECT DeviceObject,
159 IN PIRP Irp)
160 {
161 PIO_STACK_LOCATION IrpSp;
162 NTSTATUS Status;
163
164 DPRINT("Called\n");
165
166 IrpSp = IoGetCurrentIrpStackLocation(Irp);
167 switch (IrpSp->MinorFunction)
168 {
169 case IRP_MN_QUERY_DEVICE_RELATIONS:
170 Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
171 break;
172
173 case IRP_MN_START_DEVICE:
174 PnpRootDeviceListCount = 0;
175 Status = STATUS_SUCCESS;
176 break;
177
178 case IRP_MN_STOP_DEVICE:
179 /* Root device cannot be stopped */
180 Status = STATUS_UNSUCCESSFUL;
181 break;
182
183 default:
184 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
185 Status = STATUS_NOT_IMPLEMENTED;
186 break;
187 }
188
189 if (Status != STATUS_PENDING)
190 {
191 Irp->IoStatus.Status = Status;
192 IoCompleteRequest(Irp, IO_NO_INCREMENT);
193 }
194
195 DPRINT("Leaving. Status 0x%X\n", Status);
196
197 return Status;
198 }
199
200 NTSTATUS
201 STDCALL
202 PnpRootPowerControl(
203 IN PDEVICE_OBJECT DeviceObject,
204 IN PIRP Irp)
205 {
206 PIO_STACK_LOCATION IrpSp;
207 NTSTATUS Status;
208
209 DPRINT("Called\n");
210
211 IrpSp = IoGetCurrentIrpStackLocation(Irp);
212 switch (IrpSp->MinorFunction)
213 {
214 default:
215 DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
216 Status = STATUS_NOT_IMPLEMENTED;
217 break;
218 }
219
220 if (Status != STATUS_PENDING)
221 {
222 Irp->IoStatus.Status = Status;
223 IoCompleteRequest(Irp, IO_NO_INCREMENT);
224 }
225
226 DPRINT("Leaving. Status 0x%X\n", Status);
227
228 return Status;
229 }
230
231 NTSTATUS
232 STDCALL
233 PnpRootAddDevice(
234 IN PDRIVER_OBJECT DriverObject,
235 IN PDEVICE_OBJECT PhysicalDeviceObject)
236 {
237 PDEVICE_OBJECT Ldo;
238 NTSTATUS Status;
239
240 DPRINT("Called\n");
241
242 Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_BUS_EXTENDER,
243 FILE_DEVICE_SECURE_OPEN, TRUE, &PnpRootDeviceObject);
244 if (!NT_SUCCESS(Status))
245 {
246 DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
247 KeBugCheck(0);
248 return Status;
249 }
250
251 Ldo = IoAttachDeviceToDeviceStack(PnpRootDeviceObject, PhysicalDeviceObject);
252
253 if (!PnpRootDeviceObject)
254 {
255 DbgPrint("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
256 KeBugCheck(0);
257 }
258
259 if (!PhysicalDeviceObject)
260 {
261 DbgPrint("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
262 KeBugCheck(0);
263 }
264
265 InitializeListHead(&PnpRootDeviceListHead);
266 PnpRootDeviceListCount = 0;
267 KeInitializeSpinLock(&PnpRootDeviceListLock);
268
269 PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
270
271 DPRINT("Done\n");
272
273 return STATUS_SUCCESS;
274 }
275
276 NTSTATUS
277 STDCALL
278 PnpRootDriverEntry(
279 IN PDRIVER_OBJECT DriverObject,
280 IN PUNICODE_STRING RegistryPath)
281 {
282 DPRINT("Called\n");
283
284 DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
285 DriverObject->MajorFunction[IRP_MJ_POWER] = PnpRootPowerControl;
286 DriverObject->DriverExtension->AddDevice = PnpRootAddDevice;
287
288 return STATUS_SUCCESS;
289 }
290
291 /* EOF */