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
This commit is contained in:
Hervé Poussineau 2006-02-19 18:05:01 +00:00
parent 11c3ca9f05
commit c8a90f769b
11 changed files with 1065 additions and 284 deletions

View file

@ -1,23 +1,22 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/createclose.c * FILE: drivers/base/green/createclose.c
* PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLOSE and IRP_MJ_CLEANUP operations * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLOSE and IRP_MJ_CLEANUP operations
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
//#define NDEBUG
#include <debug.h>
#include "green.h" #include "green.h"
#define NDEBUG
#include <debug.h>
NTSTATUS NTAPI NTSTATUS NTAPI
GreenCreate( GreenCreate(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
DPRINT("Green: IRP_MJ_CREATE\n"); DPRINT("IRP_MJ_CREATE\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -30,7 +29,7 @@ GreenClose(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
DPRINT("Green: IRP_MJ_CLOSE\n"); DPRINT("IRP_MJ_CLOSE\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;

View file

@ -1,17 +1,16 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/dispatch.c * FILE: drivers/base/green/dispatch.c
* PURPOSE: Dispatch routines * PURPOSE: Dispatch routines
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
#include "green.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "green.h"
NTSTATUS NTAPI NTSTATUS NTAPI
GreenDispatch( GreenDispatch(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -28,35 +27,56 @@ GreenDispatch(
Information = Irp->IoStatus.Information; Information = Irp->IoStatus.Information;
Status = Irp->IoStatus.Status; 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); 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); 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); 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( return KeyboardInternalDeviceControl(
((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Keyboard, ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->KeyboardFdo,
Irp); 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); return KeyboardInternalDeviceControl(DeviceObject, Irp);
else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Green) else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == GreenFDO)
{ {
return ScreenDeviceControl( return ScreenDeviceControl(
((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Screen, ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ScreenFdo,
Irp); Irp);
} }
else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Screen) else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == ScreenFDO)
return ScreenDeviceControl(DeviceObject, Irp); return ScreenDeviceControl(DeviceObject, Irp);
else if (MajorFunction == IRP_MJ_WRITE && DeviceType == Screen) else if (MajorFunction == IRP_MJ_WRITE && DeviceType == ScreenFDO)
return ScreenWrite(DeviceObject, Irp); 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 else
{ {
DPRINT1("Green: unknown combination: MajorFunction 0x%lx, DeviceType %d\n", DPRINT1("Unknown combination: MajorFunction 0x%lx, DeviceType %d\n",
MajorFunction, DeviceType); MajorFunction, DeviceType);
ASSERT(FALSE);
} }
Irp->IoStatus.Information = Information; Irp->IoStatus.Information = Information;

View file

@ -1,17 +1,16 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/green.c * FILE: drivers/base/green/green.c
* PURPOSE: Driver entry point * PURPOSE: Driver entry point
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
//#define NDEBUG
#include <debug.h>
#include "green.h" #include "green.h"
#define NDEBUG
#include <debug.h>
VOID NTAPI VOID NTAPI
DriverUnload(IN PDRIVER_OBJECT DriverObject) DriverUnload(IN PDRIVER_OBJECT DriverObject)
{ {
@ -24,22 +23,46 @@ DriverUnload(IN PDRIVER_OBJECT DriverObject)
NTSTATUS NTAPI NTSTATUS NTAPI
DriverEntry( DriverEntry(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegPath) IN PUNICODE_STRING RegistryPath)
{ {
PGREEN_DRIVER_EXTENSION DriverExtension;
ULONG i; 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->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = GreenAddDevice; 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; 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; return STATUS_SUCCESS;
} }

View file

@ -9,14 +9,28 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
#include <wincon.h> #include <wincon.h>
#include <drivers/blue/ntddblue.h> #include <drivers/blue/ntddblue.h>
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 INFINITE -1
#define KEYBOARD_BUFFER_SIZE 100 #define KEYBOARD_BUFFER_SIZE 100
typedef enum typedef enum
{ {
Green, GreenPDO,
Screen, ScreenPDO,
Keyboard KeyboardPDO,
GreenFDO,
ScreenFDO,
KeyboardFDO,
PassThroughFDO,
} GREEN_DEVICE_TYPE; } GREEN_DEVICE_TYPE;
typedef struct _COMMON_DEVICE_EXTENSION typedef struct _COMMON_DEVICE_EXTENSION
@ -24,9 +38,17 @@ typedef struct _COMMON_DEVICE_EXTENSION
GREEN_DEVICE_TYPE Type; GREEN_DEVICE_TYPE Type;
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; } 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 typedef struct _KEYBOARD_DEVICE_EXTENSION
{ {
COMMON_DEVICE_EXTENSION Common; COMMON_FDO_DEVICE_EXTENSION Common;
PDEVICE_OBJECT Green; PDEVICE_OBJECT Green;
CONNECT_DATA ClassInformation; CONNECT_DATA ClassInformation;
@ -38,9 +60,10 @@ typedef struct _KEYBOARD_DEVICE_EXTENSION
KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE]; KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE];
} KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION; } KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION;
/* For ScreenFDO devices */
typedef struct _SCREEN_DEVICE_EXTENSION typedef struct _SCREEN_DEVICE_EXTENSION
{ {
COMMON_DEVICE_EXTENSION Common; COMMON_FDO_DEVICE_EXTENSION Common;
PDEVICE_OBJECT Green; PDEVICE_OBJECT Green;
PUCHAR VideoMemory; /* Pointer to video memory */ PUCHAR VideoMemory; /* Pointer to video memory */
@ -58,20 +81,32 @@ typedef struct _SCREEN_DEVICE_EXTENSION
PDEVICE_OBJECT PreviousBlue; PDEVICE_OBJECT PreviousBlue;
} SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION; } SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION;
/* For GreenFDO devices */
typedef struct _GREEN_DEVICE_EXTENSION typedef struct _GREEN_DEVICE_EXTENSION
{ {
COMMON_DEVICE_EXTENSION Common; COMMON_FDO_DEVICE_EXTENSION Common;
PDEVICE_OBJECT Serial; PDEVICE_OBJECT Serial;
PDEVICE_OBJECT LowerDevice;
ULONG BaudRate;
SERIAL_LINE_CONTROL LineControl; SERIAL_LINE_CONTROL LineControl;
SERIAL_TIMEOUTS Timeouts; SERIAL_TIMEOUTS Timeouts;
PDEVICE_OBJECT Keyboard; PDEVICE_OBJECT KeyboardPdo;
PDEVICE_OBJECT Screen; PDEVICE_OBJECT ScreenPdo;
PDEVICE_OBJECT KeyboardFdo;
PDEVICE_OBJECT ScreenFdo;
} GREEN_DEVICE_EXTENSION, *PGREEN_DEVICE_EXTENSION; } 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 */ /************************************ createclose.c */
NTSTATUS NTAPI NTSTATUS NTAPI
@ -94,9 +129,9 @@ GreenDispatch(
/************************************ keyboard.c */ /************************************ keyboard.c */
NTSTATUS NTSTATUS
KeyboardInitialize( KeyboardAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT* KeyboardFdo); IN PDEVICE_OBJECT Pdo);
NTSTATUS NTSTATUS
KeyboardInternalDeviceControl( KeyboardInternalDeviceControl(
@ -114,6 +149,11 @@ GreenDeviceIoControl(
IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PVOID OutputBuffer OPTIONAL,
IN OUT PULONG OutputBufferSize); IN OUT PULONG OutputBufferSize);
NTSTATUS
ReadRegistryEntries(
IN PUNICODE_STRING RegistryPath,
IN PGREEN_DRIVER_EXTENSION DriverExtension);
/************************************ pnp.c */ /************************************ pnp.c */
NTSTATUS NTAPI NTSTATUS NTAPI
@ -121,12 +161,24 @@ GreenAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo); 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 */ /************************************ screen.c */
NTSTATUS NTSTATUS
ScreenInitialize( ScreenAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT* ScreenFdo); IN PDEVICE_OBJECT Pdo);
NTSTATUS NTSTATUS
ScreenWrite( ScreenWrite(

View file

@ -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"

View file

@ -1,6 +1,6 @@
<module name="green" type="kernelmodedriver" installbase="system32/drivers" installname="green.sys"> <module name="green" type="kernelmodedriver" installbase="system32/drivers" installname="green.sys">
<bootstrap base="reactos" /> <bootstrap base="reactos" />
<define name="__USE_W32API" /> <define name="__USE_W32API" />
<library>ntoskrnl</library> <library>ntoskrnl</library>
<library>hal</library> <library>hal</library>
<file>createclose.c</file> <file>createclose.c</file>
@ -9,6 +9,7 @@
<file>keyboard.c</file> <file>keyboard.c</file>
<file>misc.c</file> <file>misc.c</file>
<file>pnp.c</file> <file>pnp.c</file>
<file>power.c</file>
<file>screen.c</file> <file>screen.c</file>
<file>green.rc</file> <file>green.rc</file>
<pch>green.h</pch> <pch>green.h</pch>

View file

@ -1,17 +1,16 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/keyboard.c * FILE: drivers/dd/green/keyboard.c
* PURPOSE: Keyboard part of green management * PURPOSE: Keyboard part of green management
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
#include "green.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "green.h"
static BOOLEAN static BOOLEAN
TranslateCharToScanCodes( TranslateCharToScanCodes(
IN PUCHAR InputBuffer, IN PUCHAR InputBuffer,
@ -100,27 +99,26 @@ TranslateCharToScanCodes(
} }
/* Consume strange character by ignoring it */ /* 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 : '.'); *InputBuffer, *InputBuffer >= 32 ? *InputBuffer : '.');
*BytesConsumed = 1; *BytesConsumed = 1;
return TRUE; return TRUE;
} }
NTSTATUS NTSTATUS
KeyboardInitialize( KeyboardAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT* KeyboardFdo) IN PDEVICE_OBJECT Pdo)
{ {
PDEVICE_OBJECT Fdo; PDEVICE_OBJECT Fdo;
PKEYBOARD_DEVICE_EXTENSION DeviceExtension; PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass1");
NTSTATUS Status; NTSTATUS Status;
DPRINT("Green: KeyboardInitialize() called\n"); DPRINT("KeyboardInitialize() called\n");
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(DriverObject,
sizeof(KEYBOARD_DEVICE_EXTENSION), sizeof(KEYBOARD_DEVICE_EXTENSION),
&DeviceName, /* FIXME: don't hardcode string */ NULL,
FILE_DEVICE_KEYBOARD, FILE_DEVICE_KEYBOARD,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
TRUE, TRUE,
@ -130,12 +128,13 @@ KeyboardInitialize(
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION)); 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_POWER_PAGABLE | DO_BUFFERED_IO;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
*KeyboardFdo = Fdo;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -157,11 +156,12 @@ KeyboardDpcSendData(
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.ClassService)( (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.ClassService)(
DeviceExtension->ClassInformation.ClassDeviceObject, DeviceExtension->ClassInformation.ClassDeviceObject,
DeviceExtension->KeyboardInputData[Queue], DeviceExtension->KeyboardInputData[Queue],
&DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCount[Queue]], DeviceExtension->KeyboardInputData[Queue] + DeviceExtension->InputDataCount[Queue],
&InputDataConsumed); &InputDataConsumed);
DeviceExtension->InputDataCount[Queue] = 0; DeviceExtension->InputDataCount[Queue] = 0;
} }
static VOID NTAPI static VOID NTAPI
KeyboardDeviceWorker( KeyboardDeviceWorker(
PVOID Context) PVOID Context)
@ -172,6 +172,7 @@ KeyboardDeviceWorker(
PDEVICE_OBJECT LowerDevice; PDEVICE_OBJECT LowerDevice;
UCHAR Buffer[16]; /* Arbitrary size */ UCHAR Buffer[16]; /* Arbitrary size */
ULONG BufferSize; ULONG BufferSize;
LARGE_INTEGER Zero;
PIRP Irp; PIRP Irp;
IO_STATUS_BLOCK ioStatus; IO_STATUS_BLOCK ioStatus;
KEVENT event; KEVENT event;
@ -182,13 +183,14 @@ KeyboardDeviceWorker(
PKEYBOARD_INPUT_DATA Input; PKEYBOARD_INPUT_DATA Input;
NTSTATUS Status; NTSTATUS Status;
DPRINT("Green: KeyboardDeviceWorker() called\n"); DPRINT("KeyboardDeviceWorker() called\n");
DeviceObject = (PDEVICE_OBJECT)Context; DeviceObject = (PDEVICE_OBJECT)Context;
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension; GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension;
LowerDevice = GreenDeviceExtension->Serial; LowerDevice = GreenDeviceExtension->Serial;
BufferSize = sizeof(Buffer); BufferSize = sizeof(Buffer);
Zero.QuadPart = 0;
/* Initialize device extension */ /* Initialize device extension */
DeviceExtension->ActiveQueue = 0; DeviceExtension->ActiveQueue = 0;
@ -205,7 +207,7 @@ KeyboardDeviceWorker(
IRP_MJ_READ, IRP_MJ_READ,
LowerDevice, LowerDevice,
Buffer, BufferSize, Buffer, BufferSize,
0, &Zero,
&event, &event,
&ioStatus); &ioStatus);
if (!Irp) if (!Irp)
@ -242,7 +244,7 @@ KeyboardDeviceWorker(
&SpaceInQueue, /* output buffer size */ &SpaceInQueue, /* output buffer size */
&BytesConsumed)) /* bytes consumed in input buffer */ &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; DeviceExtension->InputDataCount[Queue] += BytesConsumed;
/* Send the data to the keyboard class driver */ /* Send the data to the keyboard class driver */
@ -274,25 +276,17 @@ KeyboardInternalDeviceControl(
{ {
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
PKEYBOARD_DEVICE_EXTENSION DeviceExtension; PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
PGREEN_DEVICE_EXTENSION GreenDeviceExtension;
OBJECT_ATTRIBUTES objectAttributes;
PDEVICE_OBJECT LowerDevice;
NTSTATUS Status; NTSTATUS Status;
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 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) switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{ {
case IOCTL_INTERNAL_KEYBOARD_CONNECT: case IOCTL_INTERNAL_KEYBOARD_CONNECT:
{ {
ULONG Fcr; DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
DPRINT("Green: IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
{ {
Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
@ -302,31 +296,11 @@ KeyboardInternalDeviceControl(
DeviceExtension->ClassInformation = DeviceExtension->ClassInformation =
*((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer); *((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 */ /* Start read loop */
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
Status = PsCreateSystemThread( Status = PsCreateSystemThread(
&DeviceExtension->WorkerThreadHandle, &DeviceExtension->WorkerThreadHandle,
(ACCESS_MASK)0L, (ACCESS_MASK)0L,
&objectAttributes, NULL,
NULL, NULL,
NULL, NULL,
KeyboardDeviceWorker, KeyboardDeviceWorker,
@ -335,7 +309,7 @@ KeyboardInternalDeviceControl(
} }
default: 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); Stack->Parameters.DeviceIoControl.IoControlCode);
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
} }

View file

@ -1,17 +1,16 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/misc.c * FILE: drivers/base/green/misc.c
* PURPOSE: Misceallenous operations * PURPOSE: Misceallenous operations
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
//#define NDEBUG
#include <debug.h>
#include "green.h" #include "green.h"
#define NDEBUG
#include <debug.h>
NTSTATUS NTSTATUS
GreenDeviceIoControl( GreenDeviceIoControl(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
@ -39,7 +38,7 @@ GreenDeviceIoControl(
&IoStatus); &IoStatus);
if (Irp == NULL) if (Irp == NULL)
{ {
DPRINT("Green: IoBuildDeviceIoControlRequest() failed\n"); DPRINT("IoBuildDeviceIoControlRequest() failed\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -47,7 +46,7 @@ GreenDeviceIoControl(
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
DPRINT("Green: Operation pending\n"); DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
Status = IoStatus.Status; Status = IoStatus.Status;
} }
@ -59,3 +58,57 @@ GreenDeviceIoControl(
return Status; 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;
}

View file

@ -1,95 +1,547 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/pnp.c * FILE: drivers/base/green/pnp.c
* PURPOSE: IRP_MJ_PNP operations * PURPOSE: IRP_MJ_PNP operations
* * PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
*/ */
#include "green.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#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 NTSTATUS NTAPI
GreenAddDevice( GreenAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT Pdo) 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; PGREEN_DEVICE_EXTENSION DeviceExtension;
UNICODE_STRING serialPortName; PDEVICE_RELATIONS DeviceRelations = NULL;
NTSTATUS Status; NTSTATUS Status;
DPRINT("Green: AddDevice(DriverObject %p, Pdo %p)\n", DriverObject, Pdo); DeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* Create green FDO */ /* Create PDOs for keyboard and screen */
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(
sizeof(GREEN_DEVICE_EXTENSION), DeviceObject->DriverObject,
sizeof(COMMON_DEVICE_EXTENSION),
NULL, NULL,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_KEYBOARD,
FILE_DEVICE_SECURE_OPEN, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
TRUE, FALSE,
&Fdo); &DeviceExtension->KeyboardPdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Status = %08lx\n", Status); DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
return 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; Status = IoCreateDevice(
RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION)); DeviceObject->DriverObject,
DeviceExtension->Common.Type = Green; sizeof(COMMON_DEVICE_EXTENSION),
NULL,
Status = KeyboardInitialize(DriverObject, &DeviceExtension->Keyboard); FILE_DEVICE_SCREEN,
FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceExtension->ScreenPdo);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
IoDeleteDevice(Fdo); DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
DPRINT1("Status = %08lx\n", Status); goto cleanup;
return Status;
} }
((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)) if (!NT_SUCCESS(Status))
{ {
IoDeleteDevice(DeviceExtension->Keyboard); if (DeviceRelations)
IoDeleteDevice(Fdo); {
DPRINT1("Status = %08lx\n", Status); ULONG i;
return Status; 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; 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;
}

View file

@ -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 <debug.h>
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;
}

View file

@ -1,19 +1,18 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS VT100 emulator
* PROJECT: ReactOS VT100 emulator * LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/dd/green/screen.c * FILE: drivers/base/green/screen.c
* PURPOSE: Screen part of green management * PURPOSE: IRP_MJ_PNP operations
* * PROGRAMMERS: Copyright 2005 Eric Kohl (ekohl@abo.rhein-zeitung.de)
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de) * Copyright 2005 Art Yerkes
* Art Yerkes * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
* Hervé Poussineau (hpoussin@reactos.org)
*/ */
#include "green.h"
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
#include "green.h"
#define ESC ((UCHAR)0x1b) #define ESC ((UCHAR)0x1b)
/* Force a move of the cursor on each printer char. /* Force a move of the cursor on each printer char.
@ -38,9 +37,9 @@ AddToSendBuffer(
int CurrentInt; int CurrentInt;
UCHAR CurrentChar; UCHAR CurrentChar;
NTSTATUS Status; NTSTATUS Status;
LARGE_INTEGER ZeroOffset; LARGE_INTEGER ZeroOffset;
ZeroOffset.QuadPart = 0; ZeroOffset.QuadPart = 0;
SizeLeft = sizeof(DeviceExtension->SendBuffer) - DeviceExtension->SendBufferPosition; SizeLeft = sizeof(DeviceExtension->SendBuffer) - DeviceExtension->SendBufferPosition;
if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0) if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0)
@ -50,12 +49,12 @@ AddToSendBuffer(
IRP_MJ_WRITE, IRP_MJ_WRITE,
SerialDevice, SerialDevice,
DeviceExtension->SendBuffer, DeviceExtension->SendBufferPosition, DeviceExtension->SendBuffer, DeviceExtension->SendBufferPosition,
&ZeroOffset, &ZeroOffset,
NULL, /* Event */ NULL, /* Event */
&ioStatus); &ioStatus);
if (!Irp) if (!Irp)
{ {
DPRINT1("Green: IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n"); DPRINT1("IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n");
return; return;
} }
@ -63,7 +62,7 @@ AddToSendBuffer(
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) 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; return;
} }
DeviceExtension->SendBufferPosition = 0; DeviceExtension->SendBufferPosition = 0;
@ -109,73 +108,113 @@ AddToSendBuffer(
} }
NTSTATUS NTSTATUS
ScreenInitialize( ScreenAddDevice(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT* ScreenFdo) IN PDEVICE_OBJECT Pdo)
{ {
PDEVICE_OBJECT Fdo, PreviousBlue = NULL; /* We want to be an upper filter of Blue, if it is existing.
PSCREEN_DEVICE_EXTENSION DeviceExtension; * We also *have to* create a Fdo on top of the given Pdo.
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BlueScreen"); * 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; 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), sizeof(SCREEN_DEVICE_EXTENSION),
&DeviceName, /* FIXME: don't hardcode string */ &BlueScreenName,
FILE_DEVICE_SCREEN, FILE_DEVICE_SCREEN,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
TRUE, TRUE,
&Fdo); &Fdo);
if (Status == STATUS_OBJECT_NAME_COLLISION) if (Status == STATUS_OBJECT_NAME_COLLISION)
{ {
DPRINT("Green: Attaching to old blue\n"); DPRINT("Attaching to old blue\n");
/* Suggested by hpoussin .. Hide previous blue device /* Suggested by hpoussin .. Hide previous blue device
* This makes us able to coexist with blue, and install * This makes us able to coexist with blue, and install
* when loaded */ * when loaded */
Status = IoCreateDevice(DriverObject, Status = IoCreateDevice(
DriverObject,
sizeof(SCREEN_DEVICE_EXTENSION), sizeof(SCREEN_DEVICE_EXTENSION),
NULL, NULL,
FILE_DEVICE_SCREEN, FILE_DEVICE_SCREEN,
FILE_DEVICE_SECURE_OPEN, FILE_DEVICE_SECURE_OPEN,
TRUE, TRUE,
&Fdo); &Fdo);
if (!NT_SUCCESS(Status)) 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( Status = IoAttachDevice(
Fdo, Fdo,
&DeviceName, /* FIXME: don't hardcode string */ &BlueScreenName,
&PreviousBlue); &LowerDevice);
if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) { {
IoDeleteDevice(Fdo); DPRINT("IoAttachDevice() failed with status 0x%08lx\n", Status);
return Status; goto cleanup;
} }
} PreviousBlue = LowerDevice;
else if (!NT_SUCCESS(Status))
return Status;
/* 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 */ * not be null */
DeviceExtension = (PSCREEN_DEVICE_EXTENSION)Fdo->DeviceExtension; DeviceExtension = (PSCREEN_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(SCREEN_DEVICE_EXTENSION)); 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; DeviceExtension->PreviousBlue = PreviousBlue;
IoAttachDeviceToDeviceStack(PassThroughFdo ? PassThroughFdo : Fdo, Pdo);
if (!NT_SUCCESS(Status))
{
/* If a device was attached, detach it first */
if (DeviceExtension->PreviousBlue)
IoDetachDevice(DeviceExtension->PreviousBlue);
IoDeleteDevice(Fdo);
return Status;
}
/* initialize screen */ /* initialize screen */
DeviceExtension->Columns = 80; DeviceExtension->Columns = 80;
@ -186,12 +225,9 @@ ScreenInitialize(
2 * DeviceExtension->Columns * DeviceExtension->Rows * sizeof(UCHAR)); 2 * DeviceExtension->Columns * DeviceExtension->Rows * sizeof(UCHAR));
if (!DeviceExtension->VideoMemory) if (!DeviceExtension->VideoMemory)
{ {
/* If a device was attached, detach it first */ DPRINT("ExAllocatePool() failed\n");
if (DeviceExtension->PreviousBlue) Status = STATUS_INSUFFICIENT_RESOURCES;
IoDetachDevice(DeviceExtension->PreviousBlue); goto cleanup;
IoDeleteDevice(Fdo);
return STATUS_INSUFFICIENT_RESOURCES;
} }
DeviceExtension->TabWidth = 8; DeviceExtension->TabWidth = 8;
@ -207,9 +243,22 @@ ScreenInitialize(
Fdo->Flags |= DO_POWER_PAGABLE; Fdo->Flags |= DO_POWER_PAGABLE;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING; 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 NTSTATUS
@ -227,9 +276,8 @@ ScreenWrite(
ULONG Columns, Rows; ULONG Columns, Rows;
ULONG CursorX, CursorY; ULONG CursorX, CursorY;
ULONG i, j; ULONG i, j;
NTSTATUS Status;
DPRINT("Green: IRP_MJ_WRITE\n"); DPRINT("ScreenWrite() called\n");
Stack = IoGetCurrentIrpStackLocation (Irp); Stack = IoGetCurrentIrpStackLocation (Irp);
Buffer = Irp->UserBuffer; Buffer = Irp->UserBuffer;
@ -250,14 +298,6 @@ ScreenWrite(
CursorY = (DeviceExtension->LogicalOffset / 2) / Columns + 1; CursorY = (DeviceExtension->LogicalOffset / 2) / Columns + 1;
VideoMemorySize = Columns * Rows * 2 * sizeof(UCHAR); 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)) if (!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT))
{ {
/* raw output mode */ /* raw output mode */
@ -358,11 +398,9 @@ ScreenWrite(
/* flush output buffer */ /* flush output buffer */
AddToSendBuffer(DeviceExtension, 0); AddToSendBuffer(DeviceExtension, 0);
Status = STATUS_SUCCESS; /* Call lower driver */
Irp->IoStatus.Status = Status; IoSkipCurrentIrpStackLocation(Irp);
IoCompleteRequest (Irp, IO_NO_INCREMENT); return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp);
return Status;
} }
NTSTATUS NTSTATUS
@ -377,7 +415,6 @@ ScreenDeviceControl(
Stack = IoGetCurrentIrpStackLocation(Irp); Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension = (PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial; SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial;
if (!SerialDevice) if (!SerialDevice)
{ {
@ -388,10 +425,11 @@ ScreenDeviceControl(
switch (Stack->Parameters.DeviceIoControl.IoControlCode) switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{ {
#if 0
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO: case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
{ {
PCONSOLE_SCREEN_BUFFER_INFO pcsbi; 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; pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
@ -418,7 +456,7 @@ ScreenDeviceControl(
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO: case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
{ {
PCONSOLE_SCREEN_BUFFER_INFO pcsbi; 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; pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
/* FIXME: remove */ { pcsbi->dwCursorPosition.X++; } /* FIXME: remove */ { pcsbi->dwCursorPosition.X++; }
@ -447,7 +485,7 @@ ScreenDeviceControl(
case IOCTL_CONSOLE_GET_CURSOR_INFO: case IOCTL_CONSOLE_GET_CURSOR_INFO:
{ {
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer; 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->dwSize = 1;
pcci->bVisible = TRUE; pcci->bVisible = TRUE;
@ -459,7 +497,7 @@ ScreenDeviceControl(
case IOCTL_CONSOLE_GET_MODE: case IOCTL_CONSOLE_GET_MODE:
{ {
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; 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; pcm->dwMode = DeviceExtension->Mode;
@ -470,7 +508,7 @@ ScreenDeviceControl(
case IOCTL_CONSOLE_SET_MODE: case IOCTL_CONSOLE_SET_MODE:
{ {
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer; 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; DeviceExtension->Mode = pcm->dwMode;
@ -480,25 +518,25 @@ ScreenDeviceControl(
} }
case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE */
break; break;
} }
case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE */
break; break;
} }
case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE */
break; break;
} }
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE: 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; DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -507,19 +545,19 @@ ScreenDeviceControl(
} }
case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME:IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER */
break; break;
} }
case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_CHARACTER */
break; break;
} }
case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER: 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 */ Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER */
break; break;
} }
@ -529,7 +567,7 @@ ScreenDeviceControl(
PUCHAR Video; PUCHAR Video;
ULONG x, y; ULONG x, y;
BOOLEAN DoOptimization = FALSE; 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); ConsoleDraw = (PCONSOLE_DRAW)MmGetSystemAddressForMdl(Irp->MdlAddress);
/* FIXME: remove */ { ConsoleDraw->X++; ConsoleDraw->CursorX++; } /* FIXME: remove */ { ConsoleDraw->X++; ConsoleDraw->CursorX++; }
@ -609,13 +647,28 @@ ScreenDeviceControl(
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
} }
#endif
default: 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); Stack->Parameters.DeviceIoControl.IoControlCode);
Status = STATUS_NOT_IMPLEMENTED; /* Call lower driver */
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp);
}
} }
Irp->IoStatus.Status = Status; if (!NT_SUCCESS(Status))
IoCompleteRequest (Irp, IO_NO_INCREMENT); {
return 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);
}
} }