From 2f99c45433f43e0fd24cb1a8a459837b8eb6393a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 7 Jul 2013 15:15:10 +0000 Subject: [PATCH] [CONDRV] Initial commit of the ReactOS Console Driver. For the moment, it's just able to load/unload, creating a "controller" device and being able to DPRINT1 lots of messages when you try to access to it. svn path=/trunk/; revision=59447 --- reactos/drivers/base/CMakeLists.txt | 1 + reactos/drivers/base/condrv/CMakeLists.txt | 18 ++ reactos/drivers/base/condrv/condrv.c | 172 ++++++++++++++++++ reactos/drivers/base/condrv/condrv.h | 47 +++++ reactos/drivers/base/condrv/condrv.rc | 6 + reactos/drivers/base/condrv/control.c | 88 +++++++++ .../include/reactos/drivers/condrv/ntddcon.h | 145 +++++++++++++++ 7 files changed, 477 insertions(+) create mode 100644 reactos/drivers/base/condrv/CMakeLists.txt create mode 100644 reactos/drivers/base/condrv/condrv.c create mode 100644 reactos/drivers/base/condrv/condrv.h create mode 100644 reactos/drivers/base/condrv/condrv.rc create mode 100644 reactos/drivers/base/condrv/control.c create mode 100644 reactos/include/reactos/drivers/condrv/ntddcon.h diff --git a/reactos/drivers/base/CMakeLists.txt b/reactos/drivers/base/CMakeLists.txt index af805ceb1da..2a539a84aef 100644 --- a/reactos/drivers/base/CMakeLists.txt +++ b/reactos/drivers/base/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(beep) add_subdirectory(bootvid) +add_subdirectory(condrv) if(_WINKD_) add_subdirectory(kdcom) diff --git a/reactos/drivers/base/condrv/CMakeLists.txt b/reactos/drivers/base/condrv/CMakeLists.txt new file mode 100644 index 00000000000..ab53c8ebc5c --- /dev/null +++ b/reactos/drivers/base/condrv/CMakeLists.txt @@ -0,0 +1,18 @@ + +include_directories(${REACTOS_SOURCE_DIR}/include/reactos/drivers) + +## spec2def(condrv.sys condrv.spec ADD_IMPORTLIB) + +add_library(condrv SHARED + condrv.c + control.c + condrv.rc) + # ${CMAKE_CURRENT_BINARY_DIR}/condrv.def) + +add_pch(condrv condrv.h) + +set_module_type(condrv kernelmodedriver) +target_link_libraries(condrv ${PSEH_LIB}) +add_importlibs(condrv ntoskrnl hal) + +add_cd_file(TARGET condrv DESTINATION reactos/system32/drivers NO_CAB FOR all) diff --git a/reactos/drivers/base/condrv/condrv.c b/reactos/drivers/base/condrv/condrv.c new file mode 100644 index 00000000000..b183eac4af1 --- /dev/null +++ b/reactos/drivers/base/condrv/condrv.c @@ -0,0 +1,172 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/condrv.c + * PURPOSE: Console Driver Management Functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "condrv.h" + +#define NDEBUG +#include + + +/* FUNCTIONS ******************************************************************/ + +/* + * Callback functions prototypes + */ +DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD ConDrvUnload; +/* +DRIVER_DISPATCH ConDrvIoControl; +DRIVER_DISPATCH ConDrvCreate; +DRIVER_DISPATCH ConDrvClose; +DRIVER_DISPATCH ConDrvRead; +DRIVER_DISPATCH ConDrvWrite; +DRIVER_DISPATCH ConDrvCleanup; +*/ +DRIVER_DISPATCH ConDrvDispatch; + +NTSTATUS NTAPI +CompleteRequest(IN PIRP Irp, + IN NTSTATUS Status, + IN ULONG_PTR Information) +{ + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = Information; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Irp->IoStatus.Status; +} + +NTSTATUS NTAPI +ConDrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) +{ +#define HANDLE_CTRL_CODE(CtrlCode) \ + case CtrlCode : \ + { \ + DPRINT1("ConDrv: " #CtrlCode ", stack->FileObject = 0x%p\n", stack->FileObject); \ + if (stack->FileObject) \ + { \ + DPRINT1("stack->FileObject->FileName = %wZ\n", &stack->FileObject->FileName); \ + } \ + break; \ + } + + PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); + ULONG ctrlCode = stack->Parameters.DeviceIoControl.IoControlCode; + + /* Just display all the IRP codes for now... */ + switch (ctrlCode) + { + HANDLE_CTRL_CODE(IRP_MJ_CREATE); + HANDLE_CTRL_CODE(IRP_MJ_CREATE_NAMED_PIPE); + HANDLE_CTRL_CODE(IRP_MJ_CLOSE); + HANDLE_CTRL_CODE(IRP_MJ_READ); + HANDLE_CTRL_CODE(IRP_MJ_WRITE); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_SET_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_EA); + HANDLE_CTRL_CODE(IRP_MJ_SET_EA); + HANDLE_CTRL_CODE(IRP_MJ_FLUSH_BUFFERS); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_VOLUME_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_SET_VOLUME_INFORMATION); + HANDLE_CTRL_CODE(IRP_MJ_DIRECTORY_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_FILE_SYSTEM_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_DEVICE_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_INTERNAL_DEVICE_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_SHUTDOWN); + HANDLE_CTRL_CODE(IRP_MJ_LOCK_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_CLEANUP); + HANDLE_CTRL_CODE(IRP_MJ_CREATE_MAILSLOT); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_SECURITY); + HANDLE_CTRL_CODE(IRP_MJ_SET_SECURITY); + HANDLE_CTRL_CODE(IRP_MJ_POWER); + HANDLE_CTRL_CODE(IRP_MJ_SYSTEM_CONTROL); + HANDLE_CTRL_CODE(IRP_MJ_DEVICE_CHANGE); + HANDLE_CTRL_CODE(IRP_MJ_QUERY_QUOTA); + HANDLE_CTRL_CODE(IRP_MJ_SET_QUOTA); + HANDLE_CTRL_CODE(IRP_MJ_PNP); + // case IRP_MJ_PNP_POWER: + // case IRP_MJ_MAXIMUM_FUNCTION: + + default: + { + DPRINT1("Unknown code %lu\n", ctrlCode); + break; + } + } + + return CompleteRequest(Irp, STATUS_SUCCESS, 0); +} + +NTSTATUS NTAPI +DriverEntry(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NTSTATUS Status; + USHORT i; + PCONDRV_DRIVER DriverExtension = NULL; + + DPRINT1("Loading ReactOS Console Driver v0.0.1...\n"); + + DriverObject->DriverUnload = ConDrvUnload; + + /* Initialize the different callback function pointers */ + for (i = 0 ; i <= IRP_MJ_MAXIMUM_FUNCTION ; ++i) + DriverObject->MajorFunction[i] = ConDrvDispatch; + +#if 0 + DriverObject->MajorFunction[IRP_MJ_CREATE] = ConDrvCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = ConDrvClose; + + /* temporary deactivated... + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = ConDrvCleanup; + */ + DriverObject->MajorFunction[IRP_MJ_READ] = ConDrvRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = ConDrvWrite; + + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ConDrvIoControl; +#endif + + Status = IoAllocateDriverObjectExtension(DriverObject, + DriverObject, // Unique ID for the driver object extension ==> gives it its address ! + sizeof(CONDRV_DRIVER), + (PVOID*)&DriverExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoAllocateDriverObjectExtension() failed with status 0x%08lx\n", Status); + return Status; + } + RtlZeroMemory(DriverExtension, sizeof(CONDRV_DRIVER)); + + Status = ConDrvCreateController(DriverObject, RegistryPath); + + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +VOID NTAPI +ConDrvUnload(IN PDRIVER_OBJECT DriverObject) +{ + DPRINT1("Unloading ReactOS Console Driver v0.0.1...\n"); + + /* + * Delete the Controller device. This has as effect + * to delete also all the terminals. + */ + ConDrvDeleteController(DriverObject); + + /* Sanity check: No devices must exist at this point */ + ASSERT(DriverObject->DeviceObject == NULL); + + DPRINT1("Done\n"); + return; +} + + +/* EOF */ diff --git a/reactos/drivers/base/condrv/condrv.h b/reactos/drivers/base/condrv/condrv.h new file mode 100644 index 00000000000..7424a40ace4 --- /dev/null +++ b/reactos/drivers/base/condrv/condrv.h @@ -0,0 +1,47 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/condrv.h + * PURPOSE: Console Driver Management Functions + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#ifndef __CONDRV_H__ +#define __CONDRV_H__ + +/* This is needed for VisualDDK testing */ +#ifdef __USE_VISUALDDK_AT_HOME__ + #include "VisualDDKHelpers.h" +#endif + + +#include +#include + + +#define CONDRV_TAG ' noC' +#define DD_CONDRV_TAG '1noC' +#define CONDRV_CONS_TAG '2noC' + + +// +// Console Driver object extension +// +typedef struct _CONDRV_DRIVER +{ + UNICODE_STRING RegistryPath; + PDEVICE_OBJECT Controller; // The unique Controller device for the driver. +} CONDRV_DRIVER, *PCONDRV_DRIVER; + + + +NTSTATUS NTAPI +ConDrvCreateController(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath); +NTSTATUS NTAPI +ConDrvDeleteController(IN PDRIVER_OBJECT DriverObject); + + +#endif // __CONDRV_H__ + +/* EOF */ diff --git a/reactos/drivers/base/condrv/condrv.rc b/reactos/drivers/base/condrv/condrv.rc new file mode 100644 index 00000000000..5e2148c08be --- /dev/null +++ b/reactos/drivers/base/condrv/condrv.rc @@ -0,0 +1,6 @@ + +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Console Device Driver" +#define REACTOS_STR_INTERNAL_NAME "condrv" +#define REACTOS_STR_ORIGINAL_FILENAME "condrv.sys" +#include diff --git a/reactos/drivers/base/condrv/control.c b/reactos/drivers/base/condrv/control.c new file mode 100644 index 00000000000..802283ec7da --- /dev/null +++ b/reactos/drivers/base/condrv/control.c @@ -0,0 +1,88 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: drivers/base/condrv/control.c + * PURPOSE: Console Driver - Controller Device + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#include "condrv.h" + +#define NDEBUG +#include + + +/* FUNCTIONS ******************************************************************/ + +NTSTATUS NTAPI +ConDrvCreateController(IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + NTSTATUS Status = STATUS_SUCCESS; + UNICODE_STRING DeviceName, SymlinkName; + PCONDRV_DRIVER DriverExtension; + PDEVICE_OBJECT Controller = NULL; + + DPRINT1("Create the Controller device...\n"); + + RtlInitUnicodeString(&DeviceName , DD_CONDRV_CTRL_DEVICE_NAME_U); + RtlInitUnicodeString(&SymlinkName, DD_CONDRV_CTRL_SYMLNK_NAME_U); + + /* Get the driver extension */ + DriverExtension = (PCONDRV_DRIVER)IoGetDriverObjectExtension(DriverObject, + DriverObject); + + /* Create the Controller device, if it doesn't exist */ + Status = IoCreateDevice(DriverObject, + 0, + (PUNICODE_STRING)&DeviceName, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &Controller); + if (!NT_SUCCESS(Status)) goto Done; + + Status = IoCreateSymbolicLink((PUNICODE_STRING)&SymlinkName, + (PUNICODE_STRING)&DeviceName); + if (!NT_SUCCESS(Status)) + { + IoDeleteDevice(Controller); + goto Done; + } + + Controller->Flags &= ~DO_DEVICE_INITIALIZING; + + /* Save the Controller device */ + DriverExtension->Controller = Controller; + +Done: + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +NTSTATUS NTAPI +ConDrvDeleteController(IN PDRIVER_OBJECT DriverObject) +{ + NTSTATUS Status = STATUS_SUCCESS; + PDEVICE_OBJECT Controller; + UNICODE_STRING SymlinkName; + + DPRINT1("Delete the Controller device...\n"); + + /* Retrieve the Controller device */ + Controller = ((PCONDRV_DRIVER)IoGetDriverObjectExtension(DriverObject, DriverObject))->Controller; + if (!Controller) return STATUS_OBJECT_TYPE_MISMATCH; + + RtlInitUnicodeString(&SymlinkName, DD_CONDRV_CTRL_SYMLNK_NAME_U); + IoDeleteSymbolicLink(&SymlinkName); + + /* Delete the controller device itself */ + IoDeleteDevice(Controller); + + DPRINT1("Done, Status = 0x%08lx\n", Status); + return Status; +} + +/* EOF */ diff --git a/reactos/include/reactos/drivers/condrv/ntddcon.h b/reactos/include/reactos/drivers/condrv/ntddcon.h new file mode 100644 index 00000000000..589635091cb --- /dev/null +++ b/reactos/include/reactos/drivers/condrv/ntddcon.h @@ -0,0 +1,145 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Console Driver + * FILE: include/reactos/drivers/condrv/ntddcon.h + * PURPOSE: Console Driver IOCTL Interface + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#if (_MSC_VER >= 1020) +#pragma once +#endif + +#ifndef _NTDDCON_H_ +#define _NTDDCON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// FIXME: Redo all the drawing since this one is quite old... + +/************************************************************************************************ + * Architecture of the Generic Terminal Driver + ************************************************************************************************ + +IN = CONIN$ = stdin +OUT = CONOUT$ = stdout +ERR = stderr + + +------------------------------+ + +-------------+ | +-----------------+ | + | |----- ERR ---->| |------+ | + | Console App |----- OUT ---->| Virtual Console |----+ | | + | 1 |<---- IN -----| 1-1 |--+ | | | + +-------------+ | +-----------------+ | | | | + | | | \ | + +-------------+ | +-----------------+ | | >--X----- ERR ----> + | |----- ERR ---->| |--|-|-/ | + | Console App |----- OUT ---->| Virtual Console |--|-+-----X----- OUT ----> + | 2 |<---- IN -----| 1-2 |--+---\ | + +-------------+ ^ | +-----------------+ \--X<---- IN ----- + | | | ^ + --+ | | . . . | | +\Console +-- \CurrentIn | | | | | + +-- \CurrentOut +----+ | | | + \CurrentErr | | Terminal 1 | | + --+ | | | + +------------------------------+ | + | + +----+----+ + . . . | \Input | + \Output + \Error + +*/ + +/* + * Remarks on the symbolic links : + * + * - \DosDevices\ is an alias to \??\ + * + * - Using "\DosDevices\Global\" allows the driver to ALWAYS + * create the symbolic link in the global object namespace. Indeed, + * under Windows NT-2000, the \DosDevices\ directory was always + * global, but starting with Windows XP, it became local to a session. + * One would then use \GLOBAL??\ to access to the global directory. + * However, this name doesn't exist under Windows NT-2000. + * Therefore, we use the trick to use the 'Global' symbolic link + * defined both under Windows NT-2000 and Windows XP and later, + * which exists in \DosDevices\, to access to \??\ (global) under + * Windows NT-2000, and to \GLOBAL??\ under Windows XP and later. + */ + +// +// Controller device +// +#define DD_CONDRV_CTRL_DEVICE_NAME "\\Device\\ConDrv" +#define DD_CONDRV_CTRL_DEVICE_NAME_U L"\\Device\\ConDrv" +#define DD_CONDRV_CTRL_SYMLNK_NAME "\\DosDevices\\Global\\ConDrv" +#define DD_CONDRV_CTRL_SYMLNK_NAME_U L"\\DosDevices\\Global\\ConDrv" + + +// +// Console +// +#define DD_CONDRV_CONSOLE_DEVICE_NAME "\\Device\\Console" +#define DD_CONDRV_CONSOLE_DEVICE_NAME_U L"\\Device\\Console" +#define DD_CONDRV_CONSOLE_SYMLNK_NAME "\\DosDevices\\Global\\Console" +#define DD_CONDRV_CONSOLE_SYMLNK_NAME_U L"\\DosDevices\\Global\\Console" + + +#ifdef TELETYPE +// +// Virtual files associated with a given console +// +#define CONDRV_CONSOLE_FILE_CURRIN "\\CurrentIn" +#define CONDRV_CONSOLE_FILE_CURRIN_U L"\\CurrentIn" + +#define CONDRV_CONSOLE_FILE_CURROUT "\\CurrentOut" +#define CONDRV_CONSOLE_FILE_CURROUT_U L"\\CurrentOut" + +//#define CONDRV_CONSOLE_FILE_CURRERR "\\CurrentErr" +//#define CONDRV_CONSOLE_FILE_CURRERR_U L"\\CurrentErr" + +#define CONDRV_VC_FILE_SCRBUF "\\ScreenBuffer" +#define CONDRV_VC_FILE_SCRBUF_U L"\\ScreenBuffer" + +/*** Original names from Windows-8 condrv.sys *** + +L"\Connect" +L"\Reference" +L"\Server" +L"\Broker" + +L"\Console" +L"\Display" + +L"\Input" +L"\Output" +L"\CurrentIn" +L"\CurrentOut" +L"\ScreenBuffer" + +***/ + +#endif + + +// +// IO codes +// +#ifndef CTL_CODE + #error "CTL_CODE undefined. Include winioctl.h or wdm.h" +#endif + +#define IOCTL_CONDRV_CREATE_CONSOLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ALL_ACCESS) +#define IOCTL_CONDRV_DELETE_CONSOLE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_WRITE_ACCESS) + +#ifdef __cplusplus +} +#endif + +#endif // _NTDDCON_H_ + +/* EOF */