2 * PROJECT: ReactOS VT100 emulator
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/base/green/pnp.c
5 * PURPOSE: IRP_MJ_PNP operations
6 * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
16 IN PDRIVER_OBJECT DriverObject
,
17 IN PDEVICE_OBJECT GreenPdo
)
19 PGREEN_DRIVER_EXTENSION DriverExtension
= NULL
;
20 PGREEN_DEVICE_EXTENSION DeviceExtension
= NULL
;
21 OBJECT_ATTRIBUTES ObjectAttributes
;
23 HANDLE LocalHandle
= 0;
24 ACCESS_MASK DesiredAccess
= 0; /* FIXME */
27 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
29 Status
= IoCreateDevice(
31 sizeof(GREEN_DEVICE_EXTENSION
),
34 FILE_DEVICE_SECURE_OPEN
,
36 &DriverExtension
->GreenMainDO
);
37 if (!NT_SUCCESS(Status
))
39 DPRINT("IoCreateDevice() failed with status %08lx\n", Status
);
43 DeviceExtension
= (PGREEN_DEVICE_EXTENSION
)DriverExtension
->GreenMainDO
->DeviceExtension
;
44 RtlZeroMemory(DeviceExtension
, sizeof(GREEN_DEVICE_EXTENSION
));
45 DeviceExtension
->Common
.Type
= GreenFDO
;
46 DriverExtension
->GreenMainDO
->Flags
|= DO_POWER_PAGABLE
;
47 DriverExtension
->LowerDevice
= IoAttachDeviceToDeviceStack(DriverExtension
->GreenMainDO
, GreenPdo
);
49 /* Initialize serial port */
50 InitializeObjectAttributes(&ObjectAttributes
, &DriverExtension
->AttachedDeviceName
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
51 Status
= ObOpenObjectByName(
59 if (!NT_SUCCESS(Status
))
61 DPRINT("ObOpenObjectByName() failed with status %08lx\n", Status
);
64 Status
= ObReferenceObjectByHandle(
69 (PVOID
*)&DeviceExtension
->Serial
,
71 if (!NT_SUCCESS(Status
))
73 DPRINT("ObReferenceObjectByHandle() failed with status %08lx\n", Status
);
77 Status
= GreenDeviceIoControl(DeviceExtension
->Serial
, IOCTL_SERIAL_SET_FIFO_CONTROL
,
78 &Fcr
, sizeof(Fcr
), NULL
, NULL
);
79 if (!NT_SUCCESS(Status
))
81 DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status
);
84 Status
= GreenDeviceIoControl(DeviceExtension
->Serial
, IOCTL_SERIAL_SET_BAUD_RATE
,
85 &DriverExtension
->SampleRate
, sizeof(DriverExtension
->SampleRate
), NULL
, NULL
);
86 if (!NT_SUCCESS(Status
))
88 DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status
);
91 DeviceExtension
->LineControl
.WordLength
= 8;
92 DeviceExtension
->LineControl
.Parity
= NO_PARITY
;
93 DeviceExtension
->LineControl
.StopBits
= STOP_BIT_1
;
94 Status
= GreenDeviceIoControl(DeviceExtension
->Serial
, IOCTL_SERIAL_SET_LINE_CONTROL
,
95 &DeviceExtension
->LineControl
, sizeof(SERIAL_LINE_CONTROL
), NULL
, NULL
);
96 if (!NT_SUCCESS(Status
))
98 DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status
);
101 RtlZeroMemory(&DeviceExtension
->Timeouts
, sizeof(SERIAL_TIMEOUTS
));
102 DeviceExtension
->Timeouts
.ReadIntervalTimeout
= 100;
103 Status
= GreenDeviceIoControl(DeviceExtension
->Serial
, IOCTL_SERIAL_SET_TIMEOUTS
,
104 &DeviceExtension
->Timeouts
, sizeof(SERIAL_TIMEOUTS
), NULL
, NULL
);
105 if (!NT_SUCCESS(Status
))
107 DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status
);
111 DriverExtension
->GreenMainDO
->Flags
|= DO_BUFFERED_IO
;
112 DriverExtension
->GreenMainDO
->Flags
&= ~DO_DEVICE_INITIALIZING
;
114 Status
= STATUS_SUCCESS
;
117 if (LocalHandle
!= 0)
118 ZwClose(LocalHandle
);
119 if (!NT_SUCCESS(Status
))
121 if (DeviceExtension
&& DeviceExtension
->Serial
)
122 ObDereferenceObject(DeviceExtension
->Serial
);
125 if (DriverExtension
->LowerDevice
)
127 IoDetachDevice(DriverExtension
->LowerDevice
);
128 DriverExtension
->LowerDevice
= NULL
;
130 if (DriverExtension
->GreenMainDO
)
132 IoDeleteDevice(DriverExtension
->GreenMainDO
);
133 DriverExtension
->GreenMainDO
= NULL
;
142 IN PDRIVER_OBJECT DriverObject
,
143 IN PGREEN_DRIVER_EXTENSION DriverExtension
)
145 PDEVICE_OBJECT GreenPdo
= NULL
;
148 /* Create green PDO */
149 Status
= IoReportDetectedDevice(
151 InterfaceTypeUndefined
, -1, -1,
154 if (!NT_SUCCESS(Status
))
156 DPRINT("IoReportDetectedDevice() failed with status 0x%lx\n", Status
);
160 /* Create green FDO */
161 Status
= CreateGreenFdo(DriverObject
, GreenPdo
);
163 IoInvalidateDeviceRelations(GreenPdo
, BusRelations
);
165 /* FIXME: Update registry, set "DeviceReported" to 1 */
167 Status
= STATUS_SUCCESS
;
170 if (!NT_SUCCESS(Status
))
172 if (DriverExtension
->GreenMainDO
)
173 IoDeleteDevice(DriverExtension
->GreenMainDO
);
180 IN PDRIVER_OBJECT DriverObject
,
181 IN PDEVICE_OBJECT Pdo
)
183 PGREEN_DRIVER_EXTENSION DriverExtension
;
185 DPRINT("AddDevice(DriverObject %p, Pdo %p)\n", DriverObject
, Pdo
);
187 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
191 if (DriverExtension
->DeviceReported
)
192 /* Green Pdo has already been reported during a previous boot.
193 * We will get another AddDevice call soon.
195 return STATUS_SUCCESS
;
197 return ReportGreenPdo(DriverObject
, DriverExtension
);
199 else if (DriverExtension
->GreenMainDO
== NULL
)
201 return CreateGreenFdo(DriverObject
, Pdo
);
205 PGREEN_DEVICE_EXTENSION GreenDeviceExtension
;
207 GreenDeviceExtension
= (PGREEN_DEVICE_EXTENSION
)DriverExtension
->GreenMainDO
->DeviceExtension
;
208 if (Pdo
== GreenDeviceExtension
->KeyboardPdo
)
209 return KeyboardAddDevice(DriverObject
, Pdo
);
210 else if (Pdo
== GreenDeviceExtension
->ScreenPdo
)
211 return ScreenAddDevice(DriverObject
, Pdo
);
213 /* Strange PDO. We don't know it */
215 return STATUS_UNSUCCESSFUL
;
220 GreenQueryBusRelations(
221 IN PDEVICE_OBJECT DeviceObject
,
222 OUT PDEVICE_RELATIONS
* pDeviceRelations
)
224 PGREEN_DEVICE_EXTENSION DeviceExtension
;
225 PDEVICE_RELATIONS DeviceRelations
= NULL
;
228 DeviceExtension
= (PGREEN_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
230 /* Create PDOs for keyboard and screen */
231 if (DeviceExtension
->KeyboardPdo
== NULL
)
233 Status
= IoCreateDevice(
234 DeviceObject
->DriverObject
,
235 sizeof(COMMON_DEVICE_EXTENSION
),
237 FILE_DEVICE_KEYBOARD
,
238 FILE_AUTOGENERATED_DEVICE_NAME
| FILE_DEVICE_SECURE_OPEN
,
240 &DeviceExtension
->KeyboardPdo
);
241 if (!NT_SUCCESS(Status
))
243 DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status
);
246 ((PCOMMON_DEVICE_EXTENSION
)DeviceExtension
->KeyboardPdo
->DeviceExtension
)->Type
= KeyboardPDO
;
247 DeviceExtension
->KeyboardPdo
->Flags
|= DO_POWER_PAGABLE
| DO_BUS_ENUMERATED_DEVICE
;
248 DeviceExtension
->KeyboardPdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
251 if (DeviceExtension
->ScreenPdo
== NULL
)
253 Status
= IoCreateDevice(
254 DeviceObject
->DriverObject
,
255 sizeof(COMMON_DEVICE_EXTENSION
),
258 FILE_AUTOGENERATED_DEVICE_NAME
| FILE_DEVICE_SECURE_OPEN
,
260 &DeviceExtension
->ScreenPdo
);
261 if (!NT_SUCCESS(Status
))
263 DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status
);
266 ((PCOMMON_DEVICE_EXTENSION
)DeviceExtension
->ScreenPdo
->DeviceExtension
)->Type
= ScreenPDO
;
267 DeviceExtension
->ScreenPdo
->Flags
|= DO_POWER_PAGABLE
| DO_BUS_ENUMERATED_DEVICE
;
268 DeviceExtension
->ScreenPdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
271 /* Allocate return structure */
272 DeviceRelations
= (PDEVICE_RELATIONS
)ExAllocatePool(
274 FIELD_OFFSET(DEVICE_RELATIONS
, Objects
) + 2 * sizeof(PDEVICE_OBJECT
));
275 if (!DeviceRelations
)
276 return STATUS_INSUFFICIENT_RESOURCES
;
278 /* Fill return structure */
279 DeviceRelations
->Count
= 2;
280 ObReferenceObject(DeviceExtension
->KeyboardPdo
);
281 ObReferenceObject(DeviceExtension
->ScreenPdo
);
282 DeviceRelations
->Objects
[0] = DeviceExtension
->KeyboardPdo
;
283 DeviceRelations
->Objects
[1] = DeviceExtension
->ScreenPdo
;
285 *pDeviceRelations
= DeviceRelations
;
286 Status
= STATUS_SUCCESS
;
289 if (!NT_SUCCESS(Status
))
294 for (i
= 0; i
< DeviceRelations
->Count
; i
++)
295 ObDereferenceObject(DeviceRelations
->Objects
[i
]);
296 ExFreePool(DeviceRelations
);
298 if (DeviceExtension
->KeyboardPdo
)
300 IoDeleteDevice(DeviceExtension
->KeyboardPdo
);
301 DeviceExtension
->KeyboardPdo
= NULL
;
303 if (DeviceExtension
->ScreenPdo
)
305 IoDeleteDevice(DeviceExtension
->ScreenPdo
);
306 DeviceExtension
->ScreenPdo
= NULL
;
314 IN PDEVICE_OBJECT DeviceObject
,
316 OUT ULONG_PTR
* Information
)
318 GREEN_DEVICE_TYPE Type
;
320 NTSTATUS Status
= Irp
->IoStatus
.Status
;
322 Type
= ((PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->Type
;
323 IdType
= IoGetCurrentIrpStackLocation(Irp
)->Parameters
.QueryId
.IdType
;
327 case BusQueryDeviceID
:
329 LPCWSTR Source
= NULL
;
331 if (Type
== ScreenPDO
)
332 Source
= L
"GREEN\\SCREEN";
333 else if (Type
== KeyboardPDO
)
334 Source
= L
"GREEN\\KEYBOARD";
337 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceId / Unknown type 0x%lx\n",
344 UNICODE_STRING SourceU
, String
;
345 RtlInitUnicodeString(&SourceU
, Source
);
346 Status
= RtlDuplicateUnicodeString(
347 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
350 *Information
= (ULONG_PTR
)String
.Buffer
;
354 case BusQueryHardwareIDs
:
356 UNICODE_STRING SourceU
= { 0, };
358 if (Type
== ScreenPDO
)
360 RtlInitUnicodeString(&SourceU
, L
"GREEN\\SCREEN\0");
361 /* We can add the two \0 that are at the end of the string */
362 SourceU
.Length
= SourceU
.MaximumLength
= SourceU
.Length
+ 2 * sizeof(WCHAR
);
364 else if (Type
== KeyboardPDO
)
366 RtlInitUnicodeString(&SourceU
, L
"GREEN\\KEYBOARD\0");
367 /* We can add the two \0 that are at the end of the string */
368 SourceU
.Length
= SourceU
.MaximumLength
= SourceU
.Length
+ 2 * sizeof(WCHAR
);
372 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs / Unknown type 0x%lx\n",
379 UNICODE_STRING String
;
380 Status
= RtlDuplicateUnicodeString(
381 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
,
384 *Information
= (ULONG_PTR
)String
.Buffer
;
388 case BusQueryCompatibleIDs
:
390 /* We don't have any compatible ID */
393 case BusQueryInstanceID
:
395 /* We don't have any instance ID */
400 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType
);
409 IN PDEVICE_OBJECT DeviceObject
,
412 GREEN_DEVICE_TYPE Type
;
413 PIO_STACK_LOCATION Stack
;
414 ULONG_PTR Information
= Irp
->IoStatus
.Information
;
415 NTSTATUS Status
= Irp
->IoStatus
.Status
;
417 Type
= ((PCOMMON_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
)->Type
;
418 Stack
= IoGetCurrentIrpStackLocation(Irp
);
420 switch (Stack
->MinorFunction
)
422 case IRP_MN_START_DEVICE
: /* 0x00 */
424 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
425 if (Type
== GreenFDO
|| Type
== KeyboardPDO
|| Type
== ScreenPDO
)
426 Status
= STATUS_SUCCESS
;
429 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE / Unknown type 0x%lx\n",
435 case IRP_MN_QUERY_DEVICE_RELATIONS
: /* 0x07 */
437 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
438 switch (Stack
->Parameters
.QueryDeviceRelations
.Type
)
442 if (Type
== GreenFDO
)
444 PDEVICE_RELATIONS DeviceRelations
= NULL
;
445 Status
= GreenQueryBusRelations(DeviceObject
, &DeviceRelations
);
446 Information
= (ULONG_PTR
)DeviceRelations
;
448 else if (Type
== KeyboardPDO
|| Type
== ScreenPDO
)
450 PDEVICE_RELATIONS DeviceRelations
= NULL
;
451 DeviceRelations
= ExAllocatePool(PagedPool
, FIELD_OFFSET(DEVICE_RELATIONS
, Objects
));
452 if (!DeviceRelations
)
453 Status
= STATUS_INSUFFICIENT_RESOURCES
;
456 DeviceRelations
->Count
= 0;
457 Status
= STATUS_SUCCESS
;
458 Information
= (ULONG_PTR
)DeviceRelations
;
463 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations / Unknown type 0x%lx\n",
471 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
472 Stack
->Parameters
.QueryDeviceRelations
.Type
);
478 case IRP_MN_QUERY_RESOURCES
: /* 0x0a */
480 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
481 /* We don't need resources */
484 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
: /* 0x0b */
486 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
487 /* We don't need resources */
490 case IRP_MN_QUERY_DEVICE_TEXT
: /* 0x0c */
492 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT\n");
493 switch (Stack
->Parameters
.QueryDeviceText
.DeviceTextType
)
495 case DeviceTextDescription
:
497 LPCWSTR Description
= NULL
;
498 if (Type
== GreenFDO
)
499 Description
= L
"Green device";
500 else if (Type
== ScreenPDO
)
501 Description
= L
"Green screen";
502 else if (Type
== KeyboardPDO
)
503 Description
= L
"Green keyboard";
505 if (Description
!= NULL
)
507 LPWSTR Destination
= ExAllocatePool(PagedPool
, wcslen(Description
) * sizeof(WCHAR
) + sizeof(UNICODE_NULL
));
509 Status
= STATUS_INSUFFICIENT_RESOURCES
;
512 wcscpy(Destination
, Description
);
513 Information
= (ULONG_PTR
)Description
;
514 Status
= STATUS_SUCCESS
;
519 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription / Unknown type 0x%lx\n",
525 case DeviceTextLocationInformation
:
527 /* We don't have any text location to report,
528 * and this query is optional, so ignore it.
534 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
535 Stack
->Parameters
.QueryDeviceText
.DeviceTextType
);
542 case IRP_MN_QUERY_ID
: /* 0x13 */
544 DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID\n");
545 Status
= GreenQueryId(DeviceObject
, Irp
, &Information
);
550 DPRINT1("IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack
->MinorFunction
);
555 Irp
->IoStatus
.Status
= Status
;
556 Irp
->IoStatus
.Information
= Information
;
557 if (Status
!= STATUS_PENDING
)
558 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);