From c8a90f769b135fa84cfa92edb77e8966cf08c9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 19 Feb 2006 18:05:01 +0000 Subject: [PATCH] Major update of Green driver: - Add PnP support (stack over the serial port, and enumerate 2 attached devices: a screen and a keyboard) - Read some parameters from registry (buffer size is still not configurable) svn path=/trunk/; revision=21165 --- reactos/drivers/base/green/createclose.c | 21 +- reactos/drivers/base/green/dispatch.c | 58 ++- reactos/drivers/base/green/green.c | 59 ++- reactos/drivers/base/green/green.h | 80 +++- reactos/drivers/base/green/green.inf | 96 ++++ reactos/drivers/base/green/green.rbuild | 3 +- reactos/drivers/base/green/keyboard.c | 78 +-- reactos/drivers/base/green/misc.c | 75 ++- reactos/drivers/base/green/pnp.c | 582 ++++++++++++++++++++--- reactos/drivers/base/green/power.c | 58 +++ reactos/drivers/base/green/screen.c | 239 ++++++---- 11 files changed, 1065 insertions(+), 284 deletions(-) create mode 100644 reactos/drivers/base/green/green.inf create mode 100644 reactos/drivers/base/green/power.c diff --git a/reactos/drivers/base/green/createclose.c b/reactos/drivers/base/green/createclose.c index 0d63f2b8a7f..c1dc2ecc002 100644 --- a/reactos/drivers/base/green/createclose.c +++ b/reactos/drivers/base/green/createclose.c @@ -1,23 +1,22 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/createclose.c - * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLOSE and IRP_MJ_CLEANUP operations - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/createclose.c + * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLOSE and IRP_MJ_CLEANUP operations + * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ -//#define NDEBUG -#include - #include "green.h" +#define NDEBUG +#include + NTSTATUS NTAPI GreenCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Green: IRP_MJ_CREATE\n"); + DPRINT("IRP_MJ_CREATE\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; @@ -30,7 +29,7 @@ GreenClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("Green: IRP_MJ_CLOSE\n"); + DPRINT("IRP_MJ_CLOSE\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; diff --git a/reactos/drivers/base/green/dispatch.c b/reactos/drivers/base/green/dispatch.c index 0d10708b3ec..57f2b900071 100644 --- a/reactos/drivers/base/green/dispatch.c +++ b/reactos/drivers/base/green/dispatch.c @@ -1,17 +1,16 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/dispatch.c - * PURPOSE: Dispatch routines - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/dispatch.c + * PURPOSE: Dispatch routines + * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ +#include "green.h" + #define NDEBUG #include -#include "green.h" - NTSTATUS NTAPI GreenDispatch( IN PDEVICE_OBJECT DeviceObject, @@ -28,35 +27,56 @@ GreenDispatch( Information = Irp->IoStatus.Information; Status = Irp->IoStatus.Status; - DPRINT("Green: Dispatching major function 0x%lx, DeviceType %d\n", + DPRINT("Dispatching major function 0x%lx, DeviceType %u\n", MajorFunction, DeviceType); - if (MajorFunction == IRP_MJ_CREATE && DeviceType == Green) + if (DeviceType == PassThroughFDO) + { + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(((PCOMMON_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp); + } + else if (MajorFunction == IRP_MJ_CREATE && (DeviceType == GreenFDO || DeviceType == KeyboardPDO || DeviceType == ScreenPDO)) return GreenCreate(DeviceObject, Irp); - else if (MajorFunction == IRP_MJ_CLOSE && DeviceType == Green) + else if (MajorFunction == IRP_MJ_CLOSE && (DeviceType == GreenFDO || DeviceType == KeyboardPDO || DeviceType == ScreenPDO)) return GreenClose(DeviceObject, Irp); - else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == Green) + else if ((MajorFunction == IRP_MJ_CREATE || MajorFunction == IRP_MJ_CLOSE || MajorFunction == IRP_MJ_CLEANUP) + && (DeviceType == KeyboardFDO || DeviceType == ScreenFDO)) + { + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(((PCOMMON_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp); + } + else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == GreenFDO) { return KeyboardInternalDeviceControl( - ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Keyboard, + ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->KeyboardFdo, Irp); } - else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == Keyboard) + else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == KeyboardFDO) return KeyboardInternalDeviceControl(DeviceObject, Irp); - else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Green) + else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == GreenFDO) { return ScreenDeviceControl( - ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Screen, + ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ScreenFdo, Irp); } - else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Screen) + else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == ScreenFDO) return ScreenDeviceControl(DeviceObject, Irp); - else if (MajorFunction == IRP_MJ_WRITE && DeviceType == Screen) + else if (MajorFunction == IRP_MJ_WRITE && DeviceType == ScreenFDO) return ScreenWrite(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_PNP && (DeviceType == KeyboardFDO || DeviceType == ScreenFDO)) + { + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(((PCOMMON_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp); + } + else if (MajorFunction == IRP_MJ_PNP && (DeviceType == GreenFDO || DeviceType == KeyboardPDO || DeviceType == ScreenPDO)) + return GreenPnp(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_POWER && DeviceType == GreenFDO) + return GreenPower(DeviceObject, Irp); else { - DPRINT1("Green: unknown combination: MajorFunction 0x%lx, DeviceType %d\n", + DPRINT1("Unknown combination: MajorFunction 0x%lx, DeviceType %d\n", MajorFunction, DeviceType); + ASSERT(FALSE); } Irp->IoStatus.Information = Information; diff --git a/reactos/drivers/base/green/green.c b/reactos/drivers/base/green/green.c index a30ab3e022b..5834f3bfcb0 100644 --- a/reactos/drivers/base/green/green.c +++ b/reactos/drivers/base/green/green.c @@ -1,17 +1,16 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/green.c - * PURPOSE: Driver entry point - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/green.c + * PURPOSE: Driver entry point + * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ -//#define NDEBUG -#include - #include "green.h" +#define NDEBUG +#include + VOID NTAPI DriverUnload(IN PDRIVER_OBJECT DriverObject) { @@ -24,22 +23,46 @@ DriverUnload(IN PDRIVER_OBJECT DriverObject) NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, - IN PUNICODE_STRING RegPath) + IN PUNICODE_STRING RegistryPath) { + PGREEN_DRIVER_EXTENSION DriverExtension; ULONG i; + NTSTATUS Status; + + Status = IoAllocateDriverObjectExtension( + DriverObject, + DriverObject, + sizeof(GREEN_DRIVER_EXTENSION), + (PVOID*)&DriverExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); + return Status; + } + RtlZeroMemory(DriverExtension, sizeof(GREEN_DRIVER_EXTENSION)); + + Status = RtlDuplicateUnicodeString( + 0, + RegistryPath, + &DriverExtension->RegistryPath); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlDuplicateUnicodeString() failed with status 0x%08lx\n", Status); + return Status; + } + + Status = ReadRegistryEntries(RegistryPath, DriverExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT("ReadRegistryEntries() failed with status 0x%08lx\n", Status); + return Status; + } DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = GreenAddDevice; - for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i] = GreenDispatch; - /* keyboard only */ - //DriverObject->DriverStartIo = GreenStartIo; - - /* keyboard and screen */ - DriverObject->MajorFunction[IRP_MJ_CREATE] = GreenCreate; - DriverObject->MajorFunction[IRP_MJ_CLOSE] = GreenClose; - return STATUS_SUCCESS; } diff --git a/reactos/drivers/base/green/green.h b/reactos/drivers/base/green/green.h index 0915ee78fd3..1b8a27ccb16 100644 --- a/reactos/drivers/base/green/green.h +++ b/reactos/drivers/base/green/green.h @@ -9,14 +9,28 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES; #include #include +NTSYSAPI +NTSTATUS +NTAPI +RtlDuplicateUnicodeString( + IN ULONG Flags, + IN PCUNICODE_STRING SourceString, + OUT PUNICODE_STRING DestinationString +); +#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE 1 + #define INFINITE -1 #define KEYBOARD_BUFFER_SIZE 100 typedef enum { - Green, - Screen, - Keyboard + GreenPDO, + ScreenPDO, + KeyboardPDO, + GreenFDO, + ScreenFDO, + KeyboardFDO, + PassThroughFDO, } GREEN_DEVICE_TYPE; typedef struct _COMMON_DEVICE_EXTENSION @@ -24,9 +38,17 @@ typedef struct _COMMON_DEVICE_EXTENSION GREEN_DEVICE_TYPE Type; } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; +/* For PassThroughFDO devices */ +typedef struct _COMMON_FDO_DEVICE_EXTENSION +{ + GREEN_DEVICE_TYPE Type; + PDEVICE_OBJECT LowerDevice; +} COMMON_FDO_DEVICE_EXTENSION, *PCOMMON_FDO_DEVICE_EXTENSION; + +/* For KeyboardFDO devices */ typedef struct _KEYBOARD_DEVICE_EXTENSION { - COMMON_DEVICE_EXTENSION Common; + COMMON_FDO_DEVICE_EXTENSION Common; PDEVICE_OBJECT Green; CONNECT_DATA ClassInformation; @@ -38,9 +60,10 @@ typedef struct _KEYBOARD_DEVICE_EXTENSION KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE]; } KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION; +/* For ScreenFDO devices */ typedef struct _SCREEN_DEVICE_EXTENSION { - COMMON_DEVICE_EXTENSION Common; + COMMON_FDO_DEVICE_EXTENSION Common; PDEVICE_OBJECT Green; PUCHAR VideoMemory; /* Pointer to video memory */ @@ -58,20 +81,32 @@ typedef struct _SCREEN_DEVICE_EXTENSION PDEVICE_OBJECT PreviousBlue; } SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION; +/* For GreenFDO devices */ typedef struct _GREEN_DEVICE_EXTENSION { - COMMON_DEVICE_EXTENSION Common; + COMMON_FDO_DEVICE_EXTENSION Common; PDEVICE_OBJECT Serial; - PDEVICE_OBJECT LowerDevice; - ULONG BaudRate; SERIAL_LINE_CONTROL LineControl; SERIAL_TIMEOUTS Timeouts; - PDEVICE_OBJECT Keyboard; - PDEVICE_OBJECT Screen; + PDEVICE_OBJECT KeyboardPdo; + PDEVICE_OBJECT ScreenPdo; + PDEVICE_OBJECT KeyboardFdo; + PDEVICE_OBJECT ScreenFdo; } GREEN_DEVICE_EXTENSION, *PGREEN_DEVICE_EXTENSION; +typedef struct _GREEN_DRIVER_EXTENSION +{ + UNICODE_STRING RegistryPath; + + UNICODE_STRING AttachedDeviceName; + ULONG DeviceReported; + ULONG SampleRate; + + PDEVICE_OBJECT GreenMainDO; +} GREEN_DRIVER_EXTENSION, *PGREEN_DRIVER_EXTENSION; + /************************************ createclose.c */ NTSTATUS NTAPI @@ -94,9 +129,9 @@ GreenDispatch( /************************************ keyboard.c */ NTSTATUS -KeyboardInitialize( +KeyboardAddDevice( IN PDRIVER_OBJECT DriverObject, - OUT PDEVICE_OBJECT* KeyboardFdo); + IN PDEVICE_OBJECT Pdo); NTSTATUS KeyboardInternalDeviceControl( @@ -114,6 +149,11 @@ GreenDeviceIoControl( IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG OutputBufferSize); +NTSTATUS +ReadRegistryEntries( + IN PUNICODE_STRING RegistryPath, + IN PGREEN_DRIVER_EXTENSION DriverExtension); + /************************************ pnp.c */ NTSTATUS NTAPI @@ -121,12 +161,24 @@ GreenAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo); +NTSTATUS +GreenPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/************************************ power.c */ + +NTSTATUS +GreenPower( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + /************************************ screen.c */ NTSTATUS -ScreenInitialize( +ScreenAddDevice( IN PDRIVER_OBJECT DriverObject, - OUT PDEVICE_OBJECT* ScreenFdo); + IN PDEVICE_OBJECT Pdo); NTSTATUS ScreenWrite( diff --git a/reactos/drivers/base/green/green.inf b/reactos/drivers/base/green/green.inf new file mode 100644 index 00000000000..b7a37542ca3 --- /dev/null +++ b/reactos/drivers/base/green/green.inf @@ -0,0 +1,96 @@ +; GREEN.INF + +; Installation file for Green (VT100 server emulator) driver + +[Version] +Signature = "$Windows NT$" +;Signature = "$ReactOS$" +LayoutFile = layout.inf +Class = System +ClassGUID = {4D36E97D-E325-11CE-BFC1-08002BE10318} +Provider = %ReactOS% +DriverVer = 12/7/2005,1.00 + +[DestinationDirs] +DefaultDestDir = 12 + +[Manufacturer] +%ReactOSMfg% = ReactOSMfg + +[ReactOSMfg] +%KEYBOARD.DeviceDesc% = Keyboard_Inst,GREEN\KEYBOARD +%SCREEN.DeviceDesc% = Screen_Inst,GREEN\SCREEN + +;----------------------------- GREEN DRIVER ----------------------------- + +[DefaultInstall.NT] +CopyFiles = Green_CopyFiles.NT +AddReg = Green_AddReg.NT + +[Green_CopyFiles.NT] +green.sys + +[DefaultInstall.NT.Services] +AddService = green, 0x00000002, green_Service_Inst + +[green_Service_Inst] +ServiceType = 1 +StartType = 1 +ErrorControl = 0 +ServiceBinary = %12%\green.sys +LoadOrderGroup = Video Init +Description = %GREEN.DriverDesc% +Dependencies = blue + +[Green_AddReg.NT] +HKLM,"SYSTEM\CurrentControlSet\Services\green\Parameters","AttachedDevice",0x00000000,"\Device\Serial1" + +[DefaultUninstall.NT] +DelFiles = Green_DelFiles.NT +DelReg = Green_DelReg.NT + +[DefaultUninstall.NT.Services] +DelService = green, 0x00000200 + +[Green_DelFiles.NT] +green.sys,,,0x00000001 + +[Green_DelReg.NT] +HKLM,"SYSTEM\CurrentControlSet\Services\green\Parameters" + +;---------------------------- KEYBOARD DEVICE --------------------------- + +[Keyboard_Inst.NT] +CopyFiles = Green_CopyFiles.NT +Include = keyboard.inf +Needs = STANDARD_Inst + +[Keyboard_Inst.NT.HW] +AddReg = Keyboard_AddReg.NT + +[Keyboard_AddReg.NT] +HKR, , "UpperFilters", 0x00010000, "kbdclass" + +[Keyboard_Inst.NT.Services] +AddService = green, 0x00000002, green_Service_Inst +Include = msmouse.inf +Needs = PS2_Inst.Services + +;----------------------------- SCREEN DEVICE ---------------------------- + +[Screen_Inst.NT] +CopyFiles = Green_CopyFiles.NT + +[Screen_Inst.NT.Services] +AddService = green, 0x00000002, green_Service_Inst + +;-------------------------------- STRINGS ------------------------------- + +[Strings] +ReactOS = "ReactOS Team" + +GREEN.DriverDesc = "VT100 server emulator" + +ReactOSMfg = "(ReactOS Team)" +KEYBOARD.DeviceDesc = "Keyboard for remote console" +SCREEN.DeviceDesc = "Screen for remote console" diff --git a/reactos/drivers/base/green/green.rbuild b/reactos/drivers/base/green/green.rbuild index 39f0e6623d7..1c0b6a8edb9 100644 --- a/reactos/drivers/base/green/green.rbuild +++ b/reactos/drivers/base/green/green.rbuild @@ -1,6 +1,6 @@ - + ntoskrnl hal createclose.c @@ -9,6 +9,7 @@ keyboard.c misc.c pnp.c + power.c screen.c green.rc green.h diff --git a/reactos/drivers/base/green/keyboard.c b/reactos/drivers/base/green/keyboard.c index 16c86cd3650..0a4b1950154 100644 --- a/reactos/drivers/base/green/keyboard.c +++ b/reactos/drivers/base/green/keyboard.c @@ -1,17 +1,16 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/keyboard.c - * PURPOSE: Keyboard part of green management - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/dd/green/keyboard.c + * PURPOSE: Keyboard part of green management + * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ +#include "green.h" + #define NDEBUG #include -#include "green.h" - static BOOLEAN TranslateCharToScanCodes( IN PUCHAR InputBuffer, @@ -100,27 +99,26 @@ TranslateCharToScanCodes( } /* Consume strange character by ignoring it */ - DPRINT1("Green: strange byte received 0x%02x ('%c')\n", + DPRINT1("Strange byte received 0x%02x ('%c')\n", *InputBuffer, *InputBuffer >= 32 ? *InputBuffer : '.'); *BytesConsumed = 1; return TRUE; } NTSTATUS -KeyboardInitialize( +KeyboardAddDevice( IN PDRIVER_OBJECT DriverObject, - OUT PDEVICE_OBJECT* KeyboardFdo) + IN PDEVICE_OBJECT Pdo) { PDEVICE_OBJECT Fdo; PKEYBOARD_DEVICE_EXTENSION DeviceExtension; - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass1"); NTSTATUS Status; - DPRINT("Green: KeyboardInitialize() called\n"); + DPRINT("KeyboardInitialize() called\n"); Status = IoCreateDevice(DriverObject, sizeof(KEYBOARD_DEVICE_EXTENSION), - &DeviceName, /* FIXME: don't hardcode string */ + NULL, FILE_DEVICE_KEYBOARD, FILE_DEVICE_SECURE_OPEN, TRUE, @@ -130,12 +128,13 @@ KeyboardInitialize( DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION)); - DeviceExtension->Common.Type = Keyboard; + DeviceExtension->Common.Type = KeyboardFDO; + DeviceExtension->Common.LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); + DeviceExtension->Green = ((PGREEN_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject))->GreenMainDO; + ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->KeyboardFdo = Fdo; Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - *KeyboardFdo = Fdo; - return STATUS_SUCCESS; } @@ -157,11 +156,12 @@ KeyboardDpcSendData( (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.ClassService)( DeviceExtension->ClassInformation.ClassDeviceObject, DeviceExtension->KeyboardInputData[Queue], - &DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCount[Queue]], + DeviceExtension->KeyboardInputData[Queue] + DeviceExtension->InputDataCount[Queue], &InputDataConsumed); DeviceExtension->InputDataCount[Queue] = 0; } + static VOID NTAPI KeyboardDeviceWorker( PVOID Context) @@ -172,6 +172,7 @@ KeyboardDeviceWorker( PDEVICE_OBJECT LowerDevice; UCHAR Buffer[16]; /* Arbitrary size */ ULONG BufferSize; + LARGE_INTEGER Zero; PIRP Irp; IO_STATUS_BLOCK ioStatus; KEVENT event; @@ -182,13 +183,14 @@ KeyboardDeviceWorker( PKEYBOARD_INPUT_DATA Input; NTSTATUS Status; - DPRINT("Green: KeyboardDeviceWorker() called\n"); + DPRINT("KeyboardDeviceWorker() called\n"); DeviceObject = (PDEVICE_OBJECT)Context; DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension; LowerDevice = GreenDeviceExtension->Serial; BufferSize = sizeof(Buffer); + Zero.QuadPart = 0; /* Initialize device extension */ DeviceExtension->ActiveQueue = 0; @@ -205,7 +207,7 @@ KeyboardDeviceWorker( IRP_MJ_READ, LowerDevice, Buffer, BufferSize, - 0, + &Zero, &event, &ioStatus); if (!Irp) @@ -242,7 +244,7 @@ KeyboardDeviceWorker( &SpaceInQueue, /* output buffer size */ &BytesConsumed)) /* bytes consumed in input buffer */ { - DPRINT1("Green: got char 0x%02x (%c)\n", Buffer[i], Buffer[i] >= 32 ? Buffer[i] : ' '); + DPRINT("Got char 0x%02x (%c)\n", Buffer[i], Buffer[i] >= 32 ? Buffer[i] : ' '); DeviceExtension->InputDataCount[Queue] += BytesConsumed; /* Send the data to the keyboard class driver */ @@ -274,25 +276,17 @@ KeyboardInternalDeviceControl( { PIO_STACK_LOCATION Stack; PKEYBOARD_DEVICE_EXTENSION DeviceExtension; - PGREEN_DEVICE_EXTENSION GreenDeviceExtension; - OBJECT_ATTRIBUTES objectAttributes; - PDEVICE_OBJECT LowerDevice; NTSTATUS Status; Stack = IoGetCurrentIrpStackLocation(Irp); Irp->IoStatus.Information = 0; DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension; - LowerDevice = GreenDeviceExtension->Serial; - DPRINT1("Green: LowerDevice %p\n", LowerDevice); switch (Stack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_INTERNAL_KEYBOARD_CONNECT: { - ULONG Fcr; - - DPRINT("Green: IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) { Status = STATUS_INVALID_PARAMETER; @@ -302,31 +296,11 @@ KeyboardInternalDeviceControl( DeviceExtension->ClassInformation = *((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); - /* Initialize serial port */ - Fcr = 0; - Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL, - &Fcr, sizeof(Fcr), NULL, NULL); - if (!NT_SUCCESS(Status)) break; - /* Set serial port speed */ - Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE, - &GreenDeviceExtension->BaudRate, sizeof(GreenDeviceExtension->BaudRate), NULL, NULL); - if (!NT_SUCCESS(Status)) break; - /* Set LCR */ - Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL, - &GreenDeviceExtension->LineControl, sizeof(GreenDeviceExtension->LineControl), NULL, NULL); - if (!NT_SUCCESS(Status)) break; - - /* Set timeouts */ - Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS, - &GreenDeviceExtension->Timeouts, sizeof(GreenDeviceExtension->Timeouts), NULL, NULL); - if (!NT_SUCCESS(Status)) break; - /* Start read loop */ - InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); Status = PsCreateSystemThread( &DeviceExtension->WorkerThreadHandle, (ACCESS_MASK)0L, - &objectAttributes, + NULL, NULL, NULL, KeyboardDeviceWorker, @@ -335,7 +309,7 @@ KeyboardInternalDeviceControl( } default: { - DPRINT("Green: IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode); Status = STATUS_INVALID_DEVICE_REQUEST; } diff --git a/reactos/drivers/base/green/misc.c b/reactos/drivers/base/green/misc.c index de9bdd0ec76..b467146a742 100644 --- a/reactos/drivers/base/green/misc.c +++ b/reactos/drivers/base/green/misc.c @@ -1,17 +1,16 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/misc.c - * PURPOSE: Misceallenous operations - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/misc.c + * PURPOSE: Misceallenous operations + * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ -//#define NDEBUG -#include - #include "green.h" +#define NDEBUG +#include + NTSTATUS GreenDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, @@ -39,7 +38,7 @@ GreenDeviceIoControl( &IoStatus); if (Irp == NULL) { - DPRINT("Green: IoBuildDeviceIoControlRequest() failed\n"); + DPRINT("IoBuildDeviceIoControlRequest() failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } @@ -47,7 +46,7 @@ GreenDeviceIoControl( if (Status == STATUS_PENDING) { - DPRINT("Green: Operation pending\n"); + DPRINT("Operation pending\n"); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); Status = IoStatus.Status; } @@ -59,3 +58,57 @@ GreenDeviceIoControl( return Status; } + +NTSTATUS +ReadRegistryEntries( + IN PUNICODE_STRING RegistryPath, + IN PGREEN_DRIVER_EXTENSION DriverExtension) +{ + UNICODE_STRING ParametersRegistryKey; + RTL_QUERY_REGISTRY_TABLE Parameters[4]; + NTSTATUS Status; + + ULONG DefaultDeviceReported = 0; + ULONG DefaultSampleRate = 1200; + + ParametersRegistryKey.Length = 0; + ParametersRegistryKey.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters") + sizeof(UNICODE_NULL); + ParametersRegistryKey.Buffer = ExAllocatePool(PagedPool, ParametersRegistryKey.MaximumLength); + if (!ParametersRegistryKey.Buffer) + { + DPRINT("ExAllocatePool() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlCopyUnicodeString(&ParametersRegistryKey, RegistryPath); + RtlAppendUnicodeToString(&ParametersRegistryKey, L"\\Parameters"); + ParametersRegistryKey.Buffer[ParametersRegistryKey.Length / sizeof(WCHAR)] = UNICODE_NULL; + + RtlZeroMemory(Parameters, sizeof(Parameters)); + + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[0].Name = L"AttachedDevice"; + Parameters[0].EntryContext = &DriverExtension->AttachedDeviceName; + + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[1].Name = L"DeviceReported"; + Parameters[1].EntryContext = &DriverExtension->DeviceReported; + Parameters[1].DefaultType = REG_DWORD; + Parameters[1].DefaultData = &DefaultDeviceReported; + Parameters[1].DefaultLength = sizeof(ULONG); + + Parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_REGISTRY_OPTIONAL; + Parameters[2].Name = L"SampleRate"; + Parameters[2].EntryContext = &DriverExtension->SampleRate; + Parameters[2].DefaultType = REG_DWORD; + Parameters[2].DefaultData = &DefaultSampleRate; + Parameters[2].DefaultLength = sizeof(ULONG); + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + ParametersRegistryKey.Buffer, + Parameters, + NULL, + NULL); + + return Status; +} diff --git a/reactos/drivers/base/green/pnp.c b/reactos/drivers/base/green/pnp.c index 2cd884e627f..c4e462fb06a 100644 --- a/reactos/drivers/base/green/pnp.c +++ b/reactos/drivers/base/green/pnp.c @@ -1,95 +1,547 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/pnp.c - * PURPOSE: IRP_MJ_PNP operations - * - * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + * 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 -#include "green.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 = 0; /* FIXME */ + 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; + IoAttachDeviceToDeviceStack(DriverExtension->GreenMainDO, GreenPdo); + + /* Initialize serial port */ + InitializeObjectAttributes(&ObjectAttributes, &DriverExtension->AttachedDeviceName, OBJ_KERNEL_HANDLE, NULL, NULL); + Status = ObOpenObjectByName( + &ObjectAttributes, + IoDeviceObjectType, + NULL, + KernelMode, + 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 && 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) { - PDEVICE_OBJECT Fdo = NULL; + 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; - UNICODE_STRING serialPortName; + PDEVICE_RELATIONS DeviceRelations = NULL; NTSTATUS Status; - DPRINT("Green: AddDevice(DriverObject %p, Pdo %p)\n", DriverObject, Pdo); + DeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - /* Create green FDO */ - Status = IoCreateDevice(DriverObject, - sizeof(GREEN_DEVICE_EXTENSION), + /* Create PDOs for keyboard and screen */ + Status = IoCreateDevice( + DeviceObject->DriverObject, + sizeof(COMMON_DEVICE_EXTENSION), NULL, - FILE_DEVICE_UNKNOWN, - FILE_DEVICE_SECURE_OPEN, - TRUE, - &Fdo); - + FILE_DEVICE_KEYBOARD, + FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, + FALSE, + &DeviceExtension->KeyboardPdo); if (!NT_SUCCESS(Status)) { - DPRINT1("Status = %08lx\n", Status); - return 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; - DeviceExtension = (PGREEN_DEVICE_EXTENSION)Fdo->DeviceExtension; - RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION)); - DeviceExtension->Common.Type = Green; - - Status = KeyboardInitialize(DriverObject, &DeviceExtension->Keyboard); + 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)) { - IoDeleteDevice(Fdo); - DPRINT1("Status = %08lx\n", Status); - return Status; + DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status); + goto cleanup; } - ((PKEYBOARD_DEVICE_EXTENSION)DeviceExtension->Keyboard->DeviceExtension)->Green = Fdo; + ((PCOMMON_DEVICE_EXTENSION)DeviceExtension->ScreenPdo->DeviceExtension)->Type = ScreenPDO; + DeviceExtension->ScreenPdo->Flags |= DO_POWER_PAGABLE | DO_BUS_ENUMERATED_DEVICE; + DeviceExtension->ScreenPdo->Flags &= ~DO_DEVICE_INITIALIZING; - Status = ScreenInitialize(DriverObject, &DeviceExtension->Screen); + /* 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)) { - IoDeleteDevice(DeviceExtension->Keyboard); - IoDeleteDevice(Fdo); - DPRINT1("Status = %08lx\n", Status); - return 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; + } } - ((PSCREEN_DEVICE_EXTENSION)DeviceExtension->Screen->DeviceExtension)->Green = Fdo; - - /* initialize green Fdo */ - DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); - DeviceExtension->LineControl.WordLength = 8; - DeviceExtension->LineControl.Parity = NO_PARITY; - DeviceExtension->LineControl.StopBits = STOP_BIT_1; - DeviceExtension->BaudRate = SERIAL_BAUD_38400; - DeviceExtension->Timeouts.ReadTotalTimeoutConstant = 1; /* not null */ - DeviceExtension->Timeouts.ReadIntervalTimeout = INFINITE; - DeviceExtension->Timeouts.ReadTotalTimeoutMultiplier = INFINITE; - DeviceExtension->Timeouts.WriteTotalTimeoutMultiplier = 0; /* FIXME */ - DeviceExtension->Timeouts.WriteTotalTimeoutConstant = 0; /* FIXME */ - - /* open associated serial port */ - RtlInitUnicodeString(&serialPortName, L"\\Device\\Serial1"); /* FIXME: don't hardcode string */ - Status = ObReferenceObjectByName( - &serialPortName, - OBJ_EXCLUSIVE | OBJ_KERNEL_HANDLE, - NULL, - (ACCESS_MASK)0, - IoDeviceObjectType, - KernelMode, - NULL, - (PVOID*)&DeviceExtension->Serial); - /* FIXME: we never ObDereferenceObject */ - - Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; - Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - - DPRINT("Status = %08lx\n", Status); 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 = RtlDuplicateUnicodeString( + 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 = RtlDuplicateUnicodeString( + 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; +} + diff --git a/reactos/drivers/base/green/power.c b/reactos/drivers/base/green/power.c new file mode 100644 index 00000000000..b4a7cb5b182 --- /dev/null +++ b/reactos/drivers/base/green/power.c @@ -0,0 +1,58 @@ +/* + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/power.c + * PURPOSE: IRP_MJ_POWER operations + * PROGRAMMERS: Copyright 2006 Hervé Poussineau (hpoussin@reactos.org) + */ + +#include "green.h" + +#define NDEBUG +#include + +NTSTATUS +GreenPower( + 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_SET_POWER: /* 0x02 */ + { + DPRINT("IRP_MJ_POWER / IRP_MN_SET_POWER\n"); + if (Type == GreenFDO) + { + PoStartNextPowerIrp(Irp); + Status = STATUS_SUCCESS; + } + else + { + DPRINT1("IRP_MJ_POWER / IRP_MN_SET_POWER / Unknown type 0x%lx\n", + Type); + ASSERT(FALSE); + } + break; + } + default: + { + DPRINT1("IRP_MJ_POWER / 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; +} diff --git a/reactos/drivers/base/green/screen.c b/reactos/drivers/base/green/screen.c index 1f620e00744..6851442d45b 100644 --- a/reactos/drivers/base/green/screen.c +++ b/reactos/drivers/base/green/screen.c @@ -1,19 +1,18 @@ /* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS VT100 emulator - * FILE: drivers/dd/green/screen.c - * PURPOSE: Screen part of green management - * - * PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de) - * Art Yerkes - * Hervé Poussineau (hpoussin@reactos.org) + * PROJECT: ReactOS VT100 emulator + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/base/green/screen.c + * PURPOSE: IRP_MJ_PNP operations + * PROGRAMMERS: Copyright 2005 Eric Kohl (ekohl@abo.rhein-zeitung.de) + * Copyright 2005 Art Yerkes + * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org) */ +#include "green.h" + #define NDEBUG #include -#include "green.h" - #define ESC ((UCHAR)0x1b) /* Force a move of the cursor on each printer char. @@ -38,9 +37,9 @@ AddToSendBuffer( int CurrentInt; UCHAR CurrentChar; NTSTATUS Status; - LARGE_INTEGER ZeroOffset; + LARGE_INTEGER ZeroOffset; - ZeroOffset.QuadPart = 0; + ZeroOffset.QuadPart = 0; SizeLeft = sizeof(DeviceExtension->SendBuffer) - DeviceExtension->SendBufferPosition; if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0) @@ -50,12 +49,12 @@ AddToSendBuffer( IRP_MJ_WRITE, SerialDevice, DeviceExtension->SendBuffer, DeviceExtension->SendBufferPosition, - &ZeroOffset, + &ZeroOffset, NULL, /* Event */ &ioStatus); if (!Irp) { - DPRINT1("Green: IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n"); + DPRINT1("IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n"); return; } @@ -63,7 +62,7 @@ AddToSendBuffer( if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) { - DPRINT1("Green: IoCallDriver() failed. Status = 0x%08lx\n", Status); + DPRINT1("IoCallDriver() failed. Status = 0x%08lx\n", Status); return; } DeviceExtension->SendBufferPosition = 0; @@ -109,73 +108,113 @@ AddToSendBuffer( } NTSTATUS -ScreenInitialize( +ScreenAddDevice( IN PDRIVER_OBJECT DriverObject, - OUT PDEVICE_OBJECT* ScreenFdo) + IN PDEVICE_OBJECT Pdo) { - PDEVICE_OBJECT Fdo, PreviousBlue = NULL; - PSCREEN_DEVICE_EXTENSION DeviceExtension; - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen"); + /* We want to be an upper filter of Blue, if it is existing. + * We also *have to* create a Fdo on top of the given Pdo. + * Hence, we have 2 cases: + * - Blue doesn't exist -> Create a unique Fdo (named Blue) at + * the top of the given Pdo + * - Blue does exist -> Create a Fdo at the top of the existing + * DO, and create a "pass to Green" FDO at the top of the Pdo + */ + PDEVICE_OBJECT Fdo = NULL; + PDEVICE_OBJECT PassThroughFdo = NULL; + PDEVICE_OBJECT LowerDevice = NULL; + PDEVICE_OBJECT PreviousBlue = NULL; + PSCREEN_DEVICE_EXTENSION DeviceExtension = NULL; + UNICODE_STRING BlueScreenName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen"); NTSTATUS Status; - DPRINT("Green: ScreenInitialize() called\n"); + DPRINT("ScreenInitialize() called\n"); - Status = IoCreateDevice(DriverObject, + /* Try to create a unique Fdo */ + Status = IoCreateDevice( + DriverObject, sizeof(SCREEN_DEVICE_EXTENSION), - &DeviceName, /* FIXME: don't hardcode string */ + &BlueScreenName, FILE_DEVICE_SCREEN, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); - if (Status == STATUS_OBJECT_NAME_COLLISION) - { - DPRINT("Green: Attaching to old blue\n"); + if (Status == STATUS_OBJECT_NAME_COLLISION) + { + DPRINT("Attaching to old blue\n"); /* Suggested by hpoussin .. Hide previous blue device * This makes us able to coexist with blue, and install * when loaded */ - Status = IoCreateDevice(DriverObject, + Status = IoCreateDevice( + DriverObject, sizeof(SCREEN_DEVICE_EXTENSION), NULL, FILE_DEVICE_SCREEN, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo); - if (!NT_SUCCESS(Status)) - return Status; + { + DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); + goto cleanup; + } + /* Initialize some fields, as IoAttachDevice will trigger the + * sending of IRP_MJ_CLEANUP/IRP_MJ_CLOSE. We have to know where to + * dispatch these IRPs... */ + ((PSCREEN_DEVICE_EXTENSION)Fdo->DeviceExtension)->Common.Type = ScreenPDO; Status = IoAttachDevice( Fdo, - &DeviceName, /* FIXME: don't hardcode string */ - &PreviousBlue); - - if (!NT_SUCCESS(Status)) { - IoDeleteDevice(Fdo); - return Status; + &BlueScreenName, + &LowerDevice); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoAttachDevice() failed with status 0x%08lx\n", Status); + goto cleanup; } - } - else if (!NT_SUCCESS(Status)) - return Status; + PreviousBlue = LowerDevice; - /* We definately have a device object. PreviousBlue may or may + /* Attach a faked FDO to PDO */ + Status = IoCreateDevice( + DriverObject, + sizeof(COMMON_FDO_DEVICE_EXTENSION), + NULL, + FILE_DEVICE_SCREEN, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &PassThroughFdo); + if (!NT_SUCCESS(Status)) + { + DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); + goto cleanup; + } + ((PCOMMON_FDO_DEVICE_EXTENSION)PassThroughFdo->DeviceExtension)->Type = PassThroughFDO; + ((PCOMMON_FDO_DEVICE_EXTENSION)PassThroughFdo->DeviceExtension)->LowerDevice = Fdo; + PassThroughFdo->StackSize = Fdo->StackSize + 1; + } + else if (NT_SUCCESS(Status)) + { + /* Attach the named Fdo on top of Pdo */ + LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); + } + else + { + DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status); + return Status; + } + + /* We definately have a device object. PreviousBlue may or may * not be null */ - DeviceExtension = (PSCREEN_DEVICE_EXTENSION)Fdo->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(SCREEN_DEVICE_EXTENSION)); - DeviceExtension->Common.Type = Screen; + DeviceExtension->Common.Type = ScreenFDO; + DeviceExtension->Common.LowerDevice = LowerDevice; + DeviceExtension->Green = ((PGREEN_DRIVER_EXTENSION)IoGetDriverObjectExtension(DriverObject, DriverObject))->GreenMainDO; + ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->ScreenFdo = Fdo; DeviceExtension->PreviousBlue = PreviousBlue; - - if (!NT_SUCCESS(Status)) - { - /* If a device was attached, detach it first */ - if (DeviceExtension->PreviousBlue) - IoDetachDevice(DeviceExtension->PreviousBlue); - - IoDeleteDevice(Fdo); - return Status; - } + IoAttachDeviceToDeviceStack(PassThroughFdo ? PassThroughFdo : Fdo, Pdo); /* initialize screen */ DeviceExtension->Columns = 80; @@ -186,12 +225,9 @@ ScreenInitialize( 2 * DeviceExtension->Columns * DeviceExtension->Rows * sizeof(UCHAR)); if (!DeviceExtension->VideoMemory) { - /* If a device was attached, detach it first */ - if (DeviceExtension->PreviousBlue) - IoDetachDevice(DeviceExtension->PreviousBlue); - - IoDeleteDevice(Fdo); - return STATUS_INSUFFICIENT_RESOURCES; + DPRINT("ExAllocatePool() failed\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; } DeviceExtension->TabWidth = 8; @@ -207,9 +243,22 @@ ScreenInitialize( Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags &= ~DO_DEVICE_INITIALIZING; - *ScreenFdo = Fdo; + Status = STATUS_SUCCESS; - return STATUS_SUCCESS; +cleanup: + if (!NT_SUCCESS(Status)) + { + if (DeviceExtension) + ExFreePool(DeviceExtension->VideoMemory); + if (LowerDevice) + IoDetachDevice(LowerDevice); + if (Fdo) + IoDeleteDevice(Fdo); + if (PassThroughFdo) + IoDeleteDevice(PassThroughFdo); + } + + return Status; } NTSTATUS @@ -227,9 +276,8 @@ ScreenWrite( ULONG Columns, Rows; ULONG CursorX, CursorY; ULONG i, j; - NTSTATUS Status; - DPRINT("Green: IRP_MJ_WRITE\n"); + DPRINT("ScreenWrite() called\n"); Stack = IoGetCurrentIrpStackLocation (Irp); Buffer = Irp->UserBuffer; @@ -250,14 +298,6 @@ ScreenWrite( CursorY = (DeviceExtension->LogicalOffset / 2) / Columns + 1; VideoMemorySize = Columns * Rows * 2 * sizeof(UCHAR); -#if DBG - DPRINT("Y: %lu\n", CursorY); - DPRINT("Buffer ="); - for (i = 0; i < Stack->Parameters.Write.Length; i++) - DbgPrint(" 0x%02x", Buffer[i]); - DbgPrint("\n"); -#endif - if (!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT)) { /* raw output mode */ @@ -358,11 +398,9 @@ ScreenWrite( /* flush output buffer */ AddToSendBuffer(DeviceExtension, 0); - Status = STATUS_SUCCESS; - Irp->IoStatus.Status = Status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - - return Status; + /* Call lower driver */ + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp); } NTSTATUS @@ -377,7 +415,6 @@ ScreenDeviceControl( Stack = IoGetCurrentIrpStackLocation(Irp); DeviceExtension = (PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial; if (!SerialDevice) { @@ -388,10 +425,11 @@ ScreenDeviceControl( switch (Stack->Parameters.DeviceIoControl.IoControlCode) { +#if 0 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO: { PCONSOLE_SCREEN_BUFFER_INFO pcsbi; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO\n"); pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer; @@ -418,7 +456,7 @@ ScreenDeviceControl( case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO: { PCONSOLE_SCREEN_BUFFER_INFO pcsbi; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO\n"); pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer; /* FIXME: remove */ { pcsbi->dwCursorPosition.X++; } @@ -447,7 +485,7 @@ ScreenDeviceControl( case IOCTL_CONSOLE_GET_CURSOR_INFO: { PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_CURSOR_INFO\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_CURSOR_INFO\n"); pcci->dwSize = 1; pcci->bVisible = TRUE; @@ -459,7 +497,7 @@ ScreenDeviceControl( case IOCTL_CONSOLE_GET_MODE: { PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_MODE\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_MODE\n"); pcm->dwMode = DeviceExtension->Mode; @@ -470,7 +508,7 @@ ScreenDeviceControl( case IOCTL_CONSOLE_SET_MODE: { PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_MODE\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_MODE\n"); DeviceExtension->Mode = pcm->dwMode; @@ -480,25 +518,25 @@ ScreenDeviceControl( } case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE */ break; } case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE */ break; } case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE */ break; } case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE: { - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE\n"); DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer; Irp->IoStatus.Information = 0; @@ -507,19 +545,19 @@ ScreenDeviceControl( } case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME:IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER */ break; } case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_CHARACTER\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_CHARACTER\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_CHARACTER */ break; } case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER: { - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER\n"); + DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER\n"); Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER */ break; } @@ -529,7 +567,7 @@ ScreenDeviceControl( PUCHAR Video; ULONG x, y; BOOLEAN DoOptimization = FALSE; - DPRINT("Green: IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_DRAW\n"); + DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_DRAW\n"); ConsoleDraw = (PCONSOLE_DRAW)MmGetSystemAddressForMdl(Irp->MdlAddress); /* FIXME: remove */ { ConsoleDraw->X++; ConsoleDraw->CursorX++; } @@ -609,13 +647,28 @@ ScreenDeviceControl( Status = STATUS_SUCCESS; break; } +#endif default: - DPRINT1("Green: IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + { + DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_IMPLEMENTED; + /* Call lower driver */ + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp); + } } - Irp->IoStatus.Status = Status; - IoCompleteRequest (Irp, IO_NO_INCREMENT); - return Status; + if (!NT_SUCCESS(Status)) + { + /* Don't call blue (if any), as we encountered an error */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + else + { + /* Call lower driver */ + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp); + } }