+++ /dev/null
-/*
- * PROJECT: ReactOS VT100 emulator
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: drivers/base/green/pnp.c
- * PURPOSE: IRP_MJ_PNP operations
- * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
- */
-
-#include "green.h"
-
-#define NDEBUG
-#include <debug.h>
-
-static NTSTATUS
-CreateGreenFdo(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT GreenPdo)
-{
- PGREEN_DRIVER_EXTENSION DriverExtension = NULL;
- PGREEN_DEVICE_EXTENSION DeviceExtension = NULL;
- OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG Fcr;
- HANDLE LocalHandle = 0;
- ACCESS_MASK DesiredAccess = FILE_ANY_ACCESS;
- NTSTATUS Status;
-
- DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
-
- Status = IoCreateDevice(
- DriverObject,
- sizeof(GREEN_DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_TERMSRV,
- FILE_DEVICE_SECURE_OPEN,
- FALSE,
- &DriverExtension->GreenMainDO);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateDevice() failed with status %08lx\n", Status);
- goto cleanup;
- }
-
- DeviceExtension = (PGREEN_DEVICE_EXTENSION)DriverExtension->GreenMainDO->DeviceExtension;
- RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION));
- DeviceExtension->Common.Type = GreenFDO;
- DriverExtension->GreenMainDO->Flags |= DO_POWER_PAGABLE;
- DriverExtension->LowerDevice = IoAttachDeviceToDeviceStack(DriverExtension->GreenMainDO, GreenPdo);
-
- /* Initialize serial port */
- InitializeObjectAttributes(&ObjectAttributes, &DriverExtension->AttachedDeviceName, OBJ_KERNEL_HANDLE, NULL, NULL);
- Status = ObOpenObjectByName(
- &ObjectAttributes,
- *IoFileObjectType,
- KernelMode,
- NULL,
- DesiredAccess,
- NULL,
- &LocalHandle);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ObOpenObjectByName() failed with status %08lx\n", Status);
- goto cleanup;
- }
- Status = ObReferenceObjectByHandle(
- LocalHandle,
- DesiredAccess,
- NULL,
- KernelMode,
- (PVOID*)&DeviceExtension->Serial,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ObReferenceObjectByHandle() failed with status %08lx\n", Status);
- goto cleanup;
- }
- Fcr = 0;
- Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_FIFO_CONTROL,
- &Fcr, sizeof(Fcr), NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
- goto cleanup;
- }
- Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_BAUD_RATE,
- &DriverExtension->SampleRate, sizeof(DriverExtension->SampleRate), NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
- goto cleanup;
- }
- DeviceExtension->LineControl.WordLength = 8;
- DeviceExtension->LineControl.Parity = NO_PARITY;
- DeviceExtension->LineControl.StopBits = STOP_BIT_1;
- Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_LINE_CONTROL,
- &DeviceExtension->LineControl, sizeof(SERIAL_LINE_CONTROL), NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
- goto cleanup;
- }
- RtlZeroMemory(&DeviceExtension->Timeouts, sizeof(SERIAL_TIMEOUTS));
- DeviceExtension->Timeouts.ReadIntervalTimeout = 100;
- Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_TIMEOUTS,
- &DeviceExtension->Timeouts, sizeof(SERIAL_TIMEOUTS), NULL, NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
- goto cleanup;
- }
-
- DriverExtension->GreenMainDO->Flags |= DO_BUFFERED_IO;
- DriverExtension->GreenMainDO->Flags &= ~DO_DEVICE_INITIALIZING;
-
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (LocalHandle != 0)
- ZwClose(LocalHandle);
- if (!NT_SUCCESS(Status))
- {
- if (DeviceExtension && DeviceExtension->Serial)
- ObDereferenceObject(DeviceExtension->Serial);
- if (DriverExtension)
- {
- if (DriverExtension->LowerDevice)
- {
- IoDetachDevice(DriverExtension->LowerDevice);
- DriverExtension->LowerDevice = NULL;
- }
- if (DriverExtension->GreenMainDO)
- {
- IoDeleteDevice(DriverExtension->GreenMainDO);
- DriverExtension->GreenMainDO = NULL;
- }
- }
- }
- return Status;
-}
-
-static NTSTATUS
-ReportGreenPdo(
- IN PDRIVER_OBJECT DriverObject,
- IN PGREEN_DRIVER_EXTENSION DriverExtension)
-{
- PDEVICE_OBJECT GreenPdo = NULL;
- NTSTATUS Status;
-
- /* Create green PDO */
- Status = IoReportDetectedDevice(
- DriverObject,
- InterfaceTypeUndefined, -1, -1,
- NULL, NULL, TRUE,
- &GreenPdo);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoReportDetectedDevice() failed with status 0x%lx\n", Status);
- goto cleanup;
- }
-
- /* Create green FDO */
- Status = CreateGreenFdo(DriverObject, GreenPdo);
-
- IoInvalidateDeviceRelations(GreenPdo, BusRelations);
-
- /* FIXME: Update registry, set "DeviceReported" to 1 */
-
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (!NT_SUCCESS(Status))
- {
- if (DriverExtension->GreenMainDO)
- IoDeleteDevice(DriverExtension->GreenMainDO);
- }
- return Status;
-}
-
-NTSTATUS NTAPI
-GreenAddDevice(
- IN PDRIVER_OBJECT DriverObject,
- IN PDEVICE_OBJECT Pdo)
-{
- PGREEN_DRIVER_EXTENSION DriverExtension;
-
- DPRINT("AddDevice(DriverObject %p, Pdo %p)\n", DriverObject, Pdo);
-
- DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
-
- if (Pdo == NULL)
- {
- if (DriverExtension->DeviceReported)
- /* Green Pdo has already been reported during a previous boot.
- * We will get another AddDevice call soon.
- */
- return STATUS_SUCCESS;
- else
- return ReportGreenPdo(DriverObject, DriverExtension);
- }
- else if (DriverExtension->GreenMainDO == NULL)
- {
- return CreateGreenFdo(DriverObject, Pdo);
- }
- else
- {
- PGREEN_DEVICE_EXTENSION GreenDeviceExtension;
-
- GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DriverExtension->GreenMainDO->DeviceExtension;
- if (Pdo == GreenDeviceExtension->KeyboardPdo)
- return KeyboardAddDevice(DriverObject, Pdo);
- else if (Pdo == GreenDeviceExtension->ScreenPdo)
- return ScreenAddDevice(DriverObject, Pdo);
- else
- /* Strange PDO. We don't know it */
- ASSERT(FALSE);
- return STATUS_UNSUCCESSFUL;
- }
-}
-
-static NTSTATUS
-GreenQueryBusRelations(
- IN PDEVICE_OBJECT DeviceObject,
- OUT PDEVICE_RELATIONS* pDeviceRelations)
-{
- PGREEN_DEVICE_EXTENSION DeviceExtension;
- PDEVICE_RELATIONS DeviceRelations = NULL;
- NTSTATUS Status;
-
- DeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- /* Create PDOs for keyboard and screen */
- if (DeviceExtension->KeyboardPdo == NULL)
- {
- Status = IoCreateDevice(
- DeviceObject->DriverObject,
- sizeof(COMMON_DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_KEYBOARD,
- FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
- FALSE,
- &DeviceExtension->KeyboardPdo);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
- goto cleanup;
- }
- ((PCOMMON_DEVICE_EXTENSION)DeviceExtension->KeyboardPdo->DeviceExtension)->Type = KeyboardPDO;
- DeviceExtension->KeyboardPdo->Flags |= DO_POWER_PAGABLE | DO_BUS_ENUMERATED_DEVICE;
- DeviceExtension->KeyboardPdo->Flags &= ~DO_DEVICE_INITIALIZING;
- }
-
- if (DeviceExtension->ScreenPdo == NULL)
- {
- Status = IoCreateDevice(
- DeviceObject->DriverObject,
- sizeof(COMMON_DEVICE_EXTENSION),
- NULL,
- FILE_DEVICE_SCREEN,
- FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
- FALSE,
- &DeviceExtension->ScreenPdo);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
- goto cleanup;
- }
- ((PCOMMON_DEVICE_EXTENSION)DeviceExtension->ScreenPdo->DeviceExtension)->Type = ScreenPDO;
- DeviceExtension->ScreenPdo->Flags |= DO_POWER_PAGABLE | DO_BUS_ENUMERATED_DEVICE;
- DeviceExtension->ScreenPdo->Flags &= ~DO_DEVICE_INITIALIZING;
- }
-
- /* Allocate return structure */
- DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
- PagedPool,
- FIELD_OFFSET(DEVICE_RELATIONS, Objects) + 2 * sizeof(PDEVICE_OBJECT));
- if (!DeviceRelations)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* Fill return structure */
- DeviceRelations->Count = 2;
- ObReferenceObject(DeviceExtension->KeyboardPdo);
- ObReferenceObject(DeviceExtension->ScreenPdo);
- DeviceRelations->Objects[0] = DeviceExtension->KeyboardPdo;
- DeviceRelations->Objects[1] = DeviceExtension->ScreenPdo;
-
- *pDeviceRelations = DeviceRelations;
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (!NT_SUCCESS(Status))
- {
- if (DeviceRelations)
- {
- ULONG i;
- for (i = 0; i < DeviceRelations->Count; i++)
- ObDereferenceObject(DeviceRelations->Objects[i]);
- ExFreePool(DeviceRelations);
- }
- if (DeviceExtension->KeyboardPdo)
- {
- IoDeleteDevice(DeviceExtension->KeyboardPdo);
- DeviceExtension->KeyboardPdo = NULL;
- }
- if (DeviceExtension->ScreenPdo)
- {
- IoDeleteDevice(DeviceExtension->ScreenPdo);
- DeviceExtension->ScreenPdo = NULL;
- }
- }
- return Status;
-}
-
-static NTSTATUS
-GreenQueryId(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- OUT ULONG_PTR* Information)
-{
- GREEN_DEVICE_TYPE Type;
- ULONG IdType;
- NTSTATUS Status = Irp->IoStatus.Status;
-
- Type = ((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type;
- IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
-
- switch (IdType)
- {
- case BusQueryDeviceID:
- {
- LPCWSTR Source = NULL;
-
- if (Type == ScreenPDO)
- Source = L"GREEN\\SCREEN";
- else if (Type == KeyboardPDO)
- Source = L"GREEN\\KEYBOARD";
- else
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceId / Unknown type 0x%lx\n",
- Type);
- ASSERT(FALSE);
- }
-
- if (Source)
- {
- UNICODE_STRING SourceU, String;
- RtlInitUnicodeString(&SourceU, Source);
- Status = GreenDuplicateUnicodeString(
- RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
- &SourceU,
- &String);
- *Information = (ULONG_PTR)String.Buffer;
- }
- break;
- }
- case BusQueryHardwareIDs:
- {
- UNICODE_STRING SourceU = { 0, };
-
- if (Type == ScreenPDO)
- {
- RtlInitUnicodeString(&SourceU, L"GREEN\\SCREEN\0");
- /* We can add the two \0 that are at the end of the string */
- SourceU.Length = SourceU.MaximumLength = SourceU.Length + 2 * sizeof(WCHAR);
- }
- else if (Type == KeyboardPDO)
- {
- RtlInitUnicodeString(&SourceU, L"GREEN\\KEYBOARD\0");
- /* We can add the two \0 that are at the end of the string */
- SourceU.Length = SourceU.MaximumLength = SourceU.Length + 2 * sizeof(WCHAR);
- }
- else
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs / Unknown type 0x%lx\n",
- Type);
- ASSERT(FALSE);
- }
-
- if (SourceU.Length)
- {
- UNICODE_STRING String;
- Status = GreenDuplicateUnicodeString(
- RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
- &SourceU,
- &String);
- *Information = (ULONG_PTR)String.Buffer;
- }
- break;
- }
- case BusQueryCompatibleIDs:
- {
- /* We don't have any compatible ID */
- break;
- }
- case BusQueryInstanceID:
- {
- /* We don't have any instance ID */
- break;
- }
- default:
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
- }
- }
-
- return Status;
-}
-
-NTSTATUS
-GreenPnp(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp)
-{
- GREEN_DEVICE_TYPE Type;
- PIO_STACK_LOCATION Stack;
- ULONG_PTR Information = Irp->IoStatus.Information;
- NTSTATUS Status = Irp->IoStatus.Status;
-
- Type = ((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type;
- Stack = IoGetCurrentIrpStackLocation(Irp);
-
- switch (Stack->MinorFunction)
- {
- case IRP_MN_START_DEVICE: /* 0x00 */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
- if (Type == GreenFDO || Type == KeyboardPDO || Type == ScreenPDO)
- Status = STATUS_SUCCESS;
- else
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE / Unknown type 0x%lx\n",
- Type);
- ASSERT(FALSE);
- }
- break;
- }
- case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n");
- switch (Stack->Parameters.QueryDeviceRelations.Type)
- {
- case BusRelations:
- {
- if (Type == GreenFDO)
- {
- PDEVICE_RELATIONS DeviceRelations = NULL;
- Status = GreenQueryBusRelations(DeviceObject, &DeviceRelations);
- Information = (ULONG_PTR)DeviceRelations;
- }
- else if (Type == KeyboardPDO || Type == ScreenPDO)
- {
- PDEVICE_RELATIONS DeviceRelations = NULL;
- DeviceRelations = ExAllocatePool(PagedPool, FIELD_OFFSET(DEVICE_RELATIONS, Objects));
- if (!DeviceRelations)
- Status = STATUS_INSUFFICIENT_RESOURCES;
- else
- {
- DeviceRelations->Count = 0;
- Status = STATUS_SUCCESS;
- Information = (ULONG_PTR)DeviceRelations;
- }
- }
- else
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations / Unknown type 0x%lx\n",
- Type);
- ASSERT(FALSE);
- }
- break;
- }
- default:
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
- Stack->Parameters.QueryDeviceRelations.Type);
- break;
- }
- }
- break;
- }
- case IRP_MN_QUERY_RESOURCES: /* 0x0a */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCES\n");
- /* We don't need resources */
- break;
- }
- case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
- /* We don't need resources */
- break;
- }
- case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT\n");
- switch (Stack->Parameters.QueryDeviceText.DeviceTextType)
- {
- case DeviceTextDescription:
- {
- LPCWSTR Description = NULL;
- if (Type == GreenFDO)
- Description = L"Green device";
- else if (Type == ScreenPDO)
- Description = L"Green screen";
- else if (Type == KeyboardPDO)
- Description = L"Green keyboard";
-
- if (Description != NULL)
- {
- LPWSTR Destination = ExAllocatePool(PagedPool, wcslen(Description) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
- if (!Destination)
- Status = STATUS_INSUFFICIENT_RESOURCES;
- else
- {
- wcscpy(Destination, Description);
- Information = (ULONG_PTR)Description;
- Status = STATUS_SUCCESS;
- }
- }
- else
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / DeviceTextDescription / Unknown type 0x%lx\n",
- Type);
- ASSERT(FALSE);
- }
- break;
- }
- case DeviceTextLocationInformation:
- {
- /* We don't have any text location to report,
- * and this query is optional, so ignore it.
- */
- break;
- }
- default:
- {
- DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n",
- Stack->Parameters.QueryDeviceText.DeviceTextType);
- ASSERT(FALSE);
- break;
- }
- }
- break;
- }
- case IRP_MN_QUERY_ID: /* 0x13 */
- {
- DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID\n");
- Status = GreenQueryId(DeviceObject, Irp, &Information);
- break;
- }
- default:
- {
- DPRINT1("IRP_MJ_PNP / unknown minor function 0x%lx\n", Stack->MinorFunction);
- break;
- }
- }
-
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = Information;
- if (Status != STATUS_PENDING)
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return Status;
-}
-
-