mirror of
https://github.com/reactos/reactos.git
synced 2025-08-11 13:15:39 +00:00
- Gather drivers in a special "drivers" subdirectory.
- Remove legacy _USE_W32API from those drivers. svn path=/trunk/; revision=32964
This commit is contained in:
parent
dcced82d09
commit
f7f8963f3a
31 changed files with 2 additions and 12 deletions
7
rosapps/drivers/avtest/avtest.rbuild
Executable file
7
rosapps/drivers/avtest/avtest.rbuild
Executable file
|
@ -0,0 +1,7 @@
|
|||
<module name="avtest" type="kernelmodedriver" installbase="system32/drivers" installname="avtest.sys">
|
||||
<include base="avtest">.</include>
|
||||
<define name="_NTDDK_" />
|
||||
<library>ks</library>
|
||||
<library>ntoskrnl</library>
|
||||
<file>entry.c</file>
|
||||
</module>
|
84
rosapps/drivers/avtest/entry.c
Executable file
84
rosapps/drivers/avtest/entry.c
Executable file
|
@ -0,0 +1,84 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <debug.h>
|
||||
#include <ks.h>
|
||||
|
||||
/* Where do we go? */
|
||||
#ifndef SIZEOF_ARRAY
|
||||
#define SIZEOF_ARRAY(array) \
|
||||
(sizeof(array) / sizeof(array[0]))
|
||||
#endif
|
||||
|
||||
/* Not in the DDK but hey! */
|
||||
#define DEFINE_KSFILTER_DISPATCH(name) \
|
||||
const KSFILTER_DISPATCH name =
|
||||
|
||||
/* To be put in KS.H */
|
||||
#define DEFINE_KSFILTER_DESCRIPTOR(name) \
|
||||
const KSFILTER_DESCRIPTOR name =
|
||||
|
||||
#define DEFINE_KSFILTER_DESCRIPTOR_TABLE(name) \
|
||||
const KSFILTER_DESCRIPTOR* const name[] =
|
||||
|
||||
|
||||
|
||||
NTSTATUS FilterCreate(
|
||||
IN OUT PKSFILTER Filter,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FilterClose(
|
||||
IN OUT PKSFILTER Filter,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS Process(
|
||||
IN PKSFILTER Filter,
|
||||
IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_KSFILTER_DISPATCH(FilterDispatch)
|
||||
{
|
||||
FilterCreate,
|
||||
FilterClose,
|
||||
Process,
|
||||
NULL // Reset
|
||||
};
|
||||
|
||||
DEFINE_KSFILTER_DESCRIPTOR(FilterDesc)
|
||||
{
|
||||
};
|
||||
|
||||
DEFINE_KSFILTER_DESCRIPTOR_TABLE(FilterDescs)
|
||||
{
|
||||
&FilterDesc
|
||||
};
|
||||
|
||||
|
||||
|
||||
const KSDEVICE_DESCRIPTOR DeviceDescriptor =
|
||||
{
|
||||
NULL,
|
||||
SIZEOF_ARRAY(FilterDescs),
|
||||
FilterDescs
|
||||
};
|
||||
|
||||
|
||||
/* Funcs */
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPathName)
|
||||
{
|
||||
DPRINT1("AVStream test component loaded!\n");
|
||||
|
||||
return KsInitializeDriver(DriverObject, RegistryPathName,
|
||||
&DeviceDescriptor);
|
||||
}
|
38
rosapps/drivers/green/createclose.c
Normal file
38
rosapps/drivers/green/createclose.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include "green.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NTSTATUS
|
||||
GreenCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("IRP_MJ_CREATE\n");
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GreenClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("IRP_MJ_CLOSE\n");
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
105
rosapps/drivers/green/dispatch.c
Normal file
105
rosapps/drivers/green/dispatch.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 <debug.h>
|
||||
|
||||
NTSTATUS NTAPI
|
||||
GreenDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG MajorFunction;
|
||||
GREEN_DEVICE_TYPE DeviceType;
|
||||
ULONG_PTR Information;
|
||||
NTSTATUS Status;
|
||||
|
||||
MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction;
|
||||
DeviceType = ((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type;
|
||||
|
||||
Information = Irp->IoStatus.Information;
|
||||
Status = Irp->IoStatus.Status;
|
||||
|
||||
DPRINT("Dispatching major function 0x%lx, DeviceType %u\n",
|
||||
MajorFunction, DeviceType);
|
||||
|
||||
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 == GreenFDO || DeviceType == KeyboardPDO || DeviceType == ScreenPDO))
|
||||
return GreenClose(DeviceObject, Irp);
|
||||
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)->KeyboardFdo,
|
||||
Irp);
|
||||
}
|
||||
else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == KeyboardFDO)
|
||||
return KeyboardInternalDeviceControl(DeviceObject, Irp);
|
||||
else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == GreenFDO)
|
||||
{
|
||||
return ScreenDeviceControl(
|
||||
((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->ScreenFdo,
|
||||
Irp);
|
||||
}
|
||||
else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == ScreenFDO)
|
||||
return ScreenDeviceControl(DeviceObject, Irp);
|
||||
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("Unknown combination: MajorFunction 0x%lx, DeviceType %d\n",
|
||||
MajorFunction, DeviceType);
|
||||
switch (DeviceType)
|
||||
{
|
||||
case KeyboardFDO:
|
||||
case ScreenFDO:
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(((PCOMMON_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice, Irp);
|
||||
}
|
||||
case GreenFDO:
|
||||
{
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PGREEN_DRIVER_EXTENSION DriverExtension;
|
||||
DriverObject = DeviceObject->DriverObject;
|
||||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DriverExtension->LowerDevice, Irp);
|
||||
}
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
68
rosapps/drivers/green/green.c
Normal file
68
rosapps/drivers/green/green.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include "green.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
VOID NTAPI
|
||||
DriverUnload(IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
// nothing to do here yet
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard DriverEntry method.
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
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++)
|
||||
DriverObject->MajorFunction[i] = GreenDispatch;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
192
rosapps/drivers/green/green.h
Normal file
192
rosapps/drivers/green/green.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
#include <stdarg.h>
|
||||
#include <ntddk.h>
|
||||
#include <ndk/iotypes.h>
|
||||
#include <windef.h>
|
||||
#define WINBASEAPI
|
||||
typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
|
||||
#include <ntddser.h>
|
||||
#include <kbdmou.h>
|
||||
#include <wincon.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 KEYBOARD_BUFFER_SIZE 100
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GreenPDO,
|
||||
ScreenPDO,
|
||||
KeyboardPDO,
|
||||
GreenFDO,
|
||||
ScreenFDO,
|
||||
KeyboardFDO,
|
||||
PassThroughFDO,
|
||||
} GREEN_DEVICE_TYPE;
|
||||
|
||||
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_FDO_DEVICE_EXTENSION Common;
|
||||
PDEVICE_OBJECT Green;
|
||||
|
||||
CONNECT_DATA ClassInformation;
|
||||
HANDLE WorkerThreadHandle;
|
||||
KDPC KeyboardDpc;
|
||||
|
||||
ULONG ActiveQueue;
|
||||
ULONG InputDataCount[2];
|
||||
KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE];
|
||||
} KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION;
|
||||
|
||||
/* For ScreenFDO devices */
|
||||
typedef struct _SCREEN_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_FDO_DEVICE_EXTENSION Common;
|
||||
PDEVICE_OBJECT Green;
|
||||
|
||||
PUCHAR VideoMemory; /* Pointer to video memory */
|
||||
USHORT CharAttribute; /* Current color attribute */
|
||||
ULONG Mode;
|
||||
UCHAR ScanLines; /* Height of a text line */
|
||||
UCHAR Rows; /* Number of rows */
|
||||
UCHAR Columns; /* Number of columns */
|
||||
UCHAR TabWidth;
|
||||
|
||||
ULONG LogicalOffset; /* Position of the cursor */
|
||||
|
||||
UCHAR SendBuffer[1024];
|
||||
ULONG SendBufferPosition;
|
||||
PDEVICE_OBJECT PreviousBlue;
|
||||
} SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION;
|
||||
|
||||
/* For GreenFDO devices */
|
||||
typedef struct _GREEN_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_FDO_DEVICE_EXTENSION Common;
|
||||
PDEVICE_OBJECT Serial;
|
||||
|
||||
SERIAL_LINE_CONTROL LineControl;
|
||||
SERIAL_TIMEOUTS Timeouts;
|
||||
|
||||
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;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
} GREEN_DRIVER_EXTENSION, *PGREEN_DRIVER_EXTENSION;
|
||||
|
||||
/************************************ createclose.c */
|
||||
|
||||
NTSTATUS
|
||||
GreenCreate(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
GreenClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ dispatch.c */
|
||||
|
||||
NTSTATUS NTAPI
|
||||
GreenDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ keyboard.c */
|
||||
|
||||
NTSTATUS
|
||||
KeyboardAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo);
|
||||
|
||||
NTSTATUS
|
||||
KeyboardInternalDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
/************************************ misc.c */
|
||||
|
||||
NTSTATUS
|
||||
GreenDeviceIoControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG CtlCode,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferSize,
|
||||
IN OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN OUT PULONG OutputBufferSize);
|
||||
|
||||
NTSTATUS
|
||||
ReadRegistryEntries(
|
||||
IN PUNICODE_STRING RegistryPath,
|
||||
IN PGREEN_DRIVER_EXTENSION DriverExtension);
|
||||
|
||||
/************************************ pnp.c */
|
||||
|
||||
NTSTATUS NTAPI
|
||||
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
|
||||
ScreenAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo);
|
||||
|
||||
NTSTATUS
|
||||
ScreenWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
ScreenDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
96
rosapps/drivers/green/green.inf
Normal file
96
rosapps/drivers/green/green.inf
Normal 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 = Extended base
|
||||
Description = %GREEN.DriverDesc%
|
||||
Dependencies = blue, serial
|
||||
|
||||
[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"
|
15
rosapps/drivers/green/green.rbuild
Normal file
15
rosapps/drivers/green/green.rbuild
Normal file
|
@ -0,0 +1,15 @@
|
|||
<module name="green" type="kernelmodedriver" installbase="system32/drivers" installname="green.sys">
|
||||
<bootstrap installbase="reactos" />
|
||||
<library>ntoskrnl</library>
|
||||
<library>hal</library>
|
||||
<file>createclose.c</file>
|
||||
<file>dispatch.c</file>
|
||||
<file>green.c</file>
|
||||
<file>keyboard.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>pnp.c</file>
|
||||
<file>power.c</file>
|
||||
<file>screen.c</file>
|
||||
<file>green.rc</file>
|
||||
<pch>green.h</pch>
|
||||
</module>
|
5
rosapps/drivers/green/green.rc
Normal file
5
rosapps/drivers/green/green.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "VT100 Server Driver\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "green\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "green.sys\0"
|
||||
#include <reactos/version.rc>
|
321
rosapps/drivers/green/keyboard.c
Normal file
321
rosapps/drivers/green/keyboard.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* 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 <debug.h>
|
||||
|
||||
static BOOLEAN
|
||||
TranslateCharToScanCodes(
|
||||
IN PUCHAR InputBuffer,
|
||||
IN ULONG InputBufferSize,
|
||||
OUT KEYBOARD_INPUT_DATA* OutputBuffer,
|
||||
OUT PULONG OutputBufferSize,
|
||||
OUT PULONG BytesConsumed)
|
||||
{
|
||||
BOOLEAN NormalKey = FALSE;
|
||||
USHORT MakeCode;
|
||||
|
||||
if (InputBufferSize == 0)
|
||||
return FALSE;
|
||||
|
||||
switch (*InputBuffer)
|
||||
{
|
||||
case 0x1b: MakeCode = 0x01; NormalKey = TRUE; break; /* ESC */
|
||||
|
||||
case '1': MakeCode = 0x02; NormalKey = TRUE; break;
|
||||
case '2': MakeCode = 0x03; NormalKey = TRUE; break;
|
||||
case '3': MakeCode = 0x04; NormalKey = TRUE; break;
|
||||
case '4': MakeCode = 0x05; NormalKey = TRUE; break;
|
||||
case '5': MakeCode = 0x06; NormalKey = TRUE; break;
|
||||
case '6': MakeCode = 0x07; NormalKey = TRUE; break;
|
||||
case '7': MakeCode = 0x08; NormalKey = TRUE; break;
|
||||
case '8': MakeCode = 0x09; NormalKey = TRUE; break;
|
||||
case '9': MakeCode = 0x0a; NormalKey = TRUE; break;
|
||||
case '0': MakeCode = 0x0b; NormalKey = TRUE; break;
|
||||
case '-': MakeCode = 0x0c; NormalKey = TRUE; break;
|
||||
case '=': MakeCode = 0x0d; NormalKey = TRUE; break;
|
||||
case '\b': MakeCode = 0x0e; NormalKey = TRUE; break;
|
||||
|
||||
case '\t': MakeCode = 0x0f; NormalKey = TRUE; break;
|
||||
case 'q': MakeCode = 0x10; NormalKey = TRUE; break;
|
||||
case 'w': MakeCode = 0x11; NormalKey = TRUE; break;
|
||||
case 'e': MakeCode = 0x12; NormalKey = TRUE; break;
|
||||
case 'r': MakeCode = 0x13; NormalKey = TRUE; break;
|
||||
case 't': MakeCode = 0x14; NormalKey = TRUE; break;
|
||||
case 'y': MakeCode = 0x15; NormalKey = TRUE; break;
|
||||
case 'u': MakeCode = 0x16; NormalKey = TRUE; break;
|
||||
case 'i': MakeCode = 0x17; NormalKey = TRUE; break;
|
||||
case 'o': MakeCode = 0x18; NormalKey = TRUE; break;
|
||||
case 'p': MakeCode = 0x19; NormalKey = TRUE; break;
|
||||
case '[': MakeCode = 0x1a; NormalKey = TRUE; break;
|
||||
case ']': MakeCode = 0x1b; NormalKey = TRUE; break;
|
||||
|
||||
case '\r': MakeCode = 0x1c; NormalKey = TRUE; break;
|
||||
|
||||
case 'a': MakeCode = 0x1e; NormalKey = TRUE; break;
|
||||
case 's': MakeCode = 0x1f; NormalKey = TRUE; break;
|
||||
case 'd': MakeCode = 0x20; NormalKey = TRUE; break;
|
||||
case 'f': MakeCode = 0x21; NormalKey = TRUE; break;
|
||||
case 'g': MakeCode = 0x22; NormalKey = TRUE; break;
|
||||
case 'h': MakeCode = 0x23; NormalKey = TRUE; break;
|
||||
case 'j': MakeCode = 0x24; NormalKey = TRUE; break;
|
||||
case 'k': MakeCode = 0x25; NormalKey = TRUE; break;
|
||||
case 'l': MakeCode = 0x26; NormalKey = TRUE; break;
|
||||
case ';': MakeCode = 0x27; NormalKey = TRUE; break;
|
||||
case '\'': MakeCode = 0x28; NormalKey = TRUE; break;
|
||||
|
||||
case '`': MakeCode = 0x29; NormalKey = TRUE; break;
|
||||
|
||||
case '\\': MakeCode = 0x2b; NormalKey = TRUE; break;
|
||||
|
||||
case 'z': MakeCode = 0x2c; NormalKey = TRUE; break;
|
||||
case 'x': MakeCode = 0x2d; NormalKey = TRUE; break;
|
||||
case 'c': MakeCode = 0x2e; NormalKey = TRUE; break;
|
||||
case 'v': MakeCode = 0x2f; NormalKey = TRUE; break;
|
||||
case 'b': MakeCode = 0x30; NormalKey = TRUE; break;
|
||||
case 'n': MakeCode = 0x31; NormalKey = TRUE; break;
|
||||
case 'm': MakeCode = 0x32; NormalKey = TRUE; break;
|
||||
case ',': MakeCode = 0x33; NormalKey = TRUE; break;
|
||||
case '.': MakeCode = 0x34; NormalKey = TRUE; break;
|
||||
case '/': MakeCode = 0x35; NormalKey = TRUE; break;
|
||||
|
||||
case ' ': MakeCode = 0x39; NormalKey = TRUE; break;
|
||||
}
|
||||
if (NormalKey && *OutputBufferSize >= 2)
|
||||
{
|
||||
OutputBuffer[0].MakeCode = MakeCode;
|
||||
OutputBuffer[0].Flags = KEY_MAKE;
|
||||
OutputBuffer[1].MakeCode = MakeCode;
|
||||
OutputBuffer[1].Flags = KEY_BREAK;
|
||||
*BytesConsumed = 2;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Consume strange character by ignoring it */
|
||||
DPRINT1("Strange byte received 0x%02x ('%c')\n",
|
||||
*InputBuffer, *InputBuffer >= 32 ? *InputBuffer : '.');
|
||||
*BytesConsumed = 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
KeyboardAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
PDEVICE_OBJECT Fdo;
|
||||
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("KeyboardInitialize() called\n");
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(KEYBOARD_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
TRUE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION));
|
||||
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;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
KeyboardDpcSendData(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID pDeviceExtension, /* real type PKEYBOARD_DEVICE_EXTENSION */
|
||||
IN PVOID Unused1,
|
||||
IN PVOID Unused2)
|
||||
{
|
||||
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Queue;
|
||||
ULONG InputDataConsumed;
|
||||
|
||||
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)pDeviceExtension;
|
||||
|
||||
Queue = DeviceExtension->ActiveQueue % 2;
|
||||
InterlockedIncrement((PLONG)&DeviceExtension->ActiveQueue);
|
||||
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.ClassService)(
|
||||
DeviceExtension->ClassInformation.ClassDeviceObject,
|
||||
DeviceExtension->KeyboardInputData[Queue],
|
||||
DeviceExtension->KeyboardInputData[Queue] + DeviceExtension->InputDataCount[Queue],
|
||||
&InputDataConsumed);
|
||||
|
||||
DeviceExtension->InputDataCount[Queue] = 0;
|
||||
}
|
||||
|
||||
static VOID NTAPI
|
||||
KeyboardDeviceWorker(
|
||||
PVOID Context)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
|
||||
PGREEN_DEVICE_EXTENSION GreenDeviceExtension;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
UCHAR Buffer[16]; /* Arbitrary size */
|
||||
ULONG BufferSize;
|
||||
LARGE_INTEGER Zero;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
KEVENT event;
|
||||
KIRQL OldIrql;
|
||||
ULONG i, Queue;
|
||||
ULONG SpaceInQueue;
|
||||
ULONG BytesConsumed = 0;
|
||||
PKEYBOARD_INPUT_DATA Input;
|
||||
NTSTATUS Status;
|
||||
|
||||
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;
|
||||
DeviceExtension->InputDataCount[0] = 0;
|
||||
DeviceExtension->InputDataCount[1] = 0;
|
||||
KeInitializeDpc(&DeviceExtension->KeyboardDpc, KeyboardDpcSendData, DeviceExtension);
|
||||
RtlZeroMemory(&DeviceExtension->KeyboardInputData, sizeof(DeviceExtension->KeyboardInputData));
|
||||
|
||||
/* main read loop */
|
||||
while (TRUE)
|
||||
{
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildSynchronousFsdRequest(
|
||||
IRP_MJ_READ,
|
||||
LowerDevice,
|
||||
Buffer, BufferSize,
|
||||
&Zero,
|
||||
&event,
|
||||
&ioStatus);
|
||||
if (!Irp)
|
||||
{
|
||||
/* no memory actually, try later */
|
||||
CHECKPOINT;
|
||||
KeStallExecutionProcessor(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
|
||||
Status = ioStatus.Status;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
continue;
|
||||
|
||||
/* Read all available data and process */
|
||||
i = 0;
|
||||
while (i < ioStatus.Information)
|
||||
{
|
||||
Queue = DeviceExtension->ActiveQueue % 2;
|
||||
|
||||
Input = &DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCount[Queue]];
|
||||
|
||||
/* Translate current chars to scan codes */
|
||||
SpaceInQueue = KEYBOARD_BUFFER_SIZE - DeviceExtension->InputDataCount[Queue];
|
||||
if (TranslateCharToScanCodes(
|
||||
&Buffer[i], /* input buffer */
|
||||
ioStatus.Information - i, /* input buffer size */
|
||||
Input, /* output buffer */
|
||||
&SpaceInQueue, /* output buffer size */
|
||||
&BytesConsumed)) /* bytes consumed in input buffer */
|
||||
{
|
||||
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 */
|
||||
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
||||
KeInsertQueueDpc(&DeviceExtension->KeyboardDpc, NULL, NULL);
|
||||
KeLowerIrql(OldIrql);
|
||||
i += BytesConsumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TranslateCharToScanCodes failed. Possible reasons:
|
||||
* - not enough bytes in input buffer (escape control code; wait next received bytes)
|
||||
* - not enough room in output buffer (wait for the Dpc to empty it)
|
||||
*
|
||||
* The best way to resolve this is to try later.
|
||||
*/
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
KeyboardInternalDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PKEYBOARD_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
Irp->IoStatus.Information = 0;
|
||||
DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_INTERNAL_KEYBOARD_CONNECT:
|
||||
{
|
||||
DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
|
||||
if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
DeviceExtension->ClassInformation =
|
||||
*((PCONNECT_DATA)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
|
||||
|
||||
/* Start read loop */
|
||||
Status = PsCreateSystemThread(
|
||||
&DeviceExtension->WorkerThreadHandle,
|
||||
(ACCESS_MASK)0L,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
KeyboardDeviceWorker,
|
||||
DeviceObject);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DPRINT("IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
|
||||
Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
114
rosapps/drivers/green/misc.c
Normal file
114
rosapps/drivers/green/misc.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include "green.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NTSTATUS
|
||||
GreenDeviceIoControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG CtlCode,
|
||||
IN PVOID InputBuffer OPTIONAL,
|
||||
IN ULONG InputBufferSize,
|
||||
IN OUT PVOID OutputBuffer OPTIONAL,
|
||||
IN OUT PULONG OutputBufferSize)
|
||||
{
|
||||
KEVENT Event;
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
KeInitializeEvent (&Event, NotificationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(CtlCode,
|
||||
DeviceObject,
|
||||
InputBuffer,
|
||||
InputBufferSize,
|
||||
OutputBuffer,
|
||||
(OutputBufferSize) ? *OutputBufferSize : 0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Operation pending\n");
|
||||
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
if (OutputBufferSize)
|
||||
{
|
||||
*OutputBufferSize = IoStatus.Information;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
562
rosapps/drivers/green/pnp.c
Normal file
562
rosapps/drivers/green/pnp.c
Normal file
|
@ -0,0 +1,562 @@
|
|||
/*
|
||||
* PROJECT: ReactOS VT100 emulator
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/base/green/pnp.c
|
||||
* PURPOSE: IRP_MJ_PNP operations
|
||||
* PROGRAMMERS: Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
#include "green.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static NTSTATUS
|
||||
CreateGreenFdo(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT GreenPdo)
|
||||
{
|
||||
PGREEN_DRIVER_EXTENSION DriverExtension = NULL;
|
||||
PGREEN_DEVICE_EXTENSION DeviceExtension = NULL;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
ULONG Fcr;
|
||||
HANDLE LocalHandle = 0;
|
||||
ACCESS_MASK DesiredAccess = FILE_ANY_ACCESS;
|
||||
NTSTATUS Status;
|
||||
|
||||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
|
||||
Status = IoCreateDevice(
|
||||
DriverObject,
|
||||
sizeof(GREEN_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_TERMSRV,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DriverExtension->GreenMainDO);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DeviceExtension = (PGREEN_DEVICE_EXTENSION)DriverExtension->GreenMainDO->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION));
|
||||
DeviceExtension->Common.Type = GreenFDO;
|
||||
DriverExtension->GreenMainDO->Flags |= DO_POWER_PAGABLE;
|
||||
DriverExtension->LowerDevice = IoAttachDeviceToDeviceStack(DriverExtension->GreenMainDO, GreenPdo);
|
||||
|
||||
/* Initialize serial port */
|
||||
InitializeObjectAttributes(&ObjectAttributes, &DriverExtension->AttachedDeviceName, OBJ_KERNEL_HANDLE, NULL, NULL);
|
||||
Status = ObOpenObjectByName(
|
||||
&ObjectAttributes,
|
||||
IoFileObjectType,
|
||||
KernelMode,
|
||||
NULL,
|
||||
DesiredAccess,
|
||||
NULL,
|
||||
&LocalHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ObOpenObjectByName() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
Status = ObReferenceObjectByHandle(
|
||||
LocalHandle,
|
||||
DesiredAccess,
|
||||
NULL,
|
||||
KernelMode,
|
||||
(PVOID*)&DeviceExtension->Serial,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("ObReferenceObjectByHandle() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
Fcr = 0;
|
||||
Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_FIFO_CONTROL,
|
||||
&Fcr, sizeof(Fcr), NULL, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_BAUD_RATE,
|
||||
&DriverExtension->SampleRate, sizeof(DriverExtension->SampleRate), NULL, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
DeviceExtension->LineControl.WordLength = 8;
|
||||
DeviceExtension->LineControl.Parity = NO_PARITY;
|
||||
DeviceExtension->LineControl.StopBits = STOP_BIT_1;
|
||||
Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_LINE_CONTROL,
|
||||
&DeviceExtension->LineControl, sizeof(SERIAL_LINE_CONTROL), NULL, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
RtlZeroMemory(&DeviceExtension->Timeouts, sizeof(SERIAL_TIMEOUTS));
|
||||
DeviceExtension->Timeouts.ReadIntervalTimeout = 100;
|
||||
Status = GreenDeviceIoControl(DeviceExtension->Serial, IOCTL_SERIAL_SET_TIMEOUTS,
|
||||
&DeviceExtension->Timeouts, sizeof(SERIAL_TIMEOUTS), NULL, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("GreenDeviceIoControl() failed with status %08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DriverExtension->GreenMainDO->Flags |= DO_BUFFERED_IO;
|
||||
DriverExtension->GreenMainDO->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (LocalHandle != 0)
|
||||
ZwClose(LocalHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (DeviceExtension && DeviceExtension->Serial)
|
||||
ObDereferenceObject(DeviceExtension->Serial);
|
||||
if (DriverExtension)
|
||||
{
|
||||
if (DriverExtension->LowerDevice)
|
||||
{
|
||||
IoDetachDevice(DriverExtension->LowerDevice);
|
||||
DriverExtension->LowerDevice = NULL;
|
||||
}
|
||||
if (DriverExtension->GreenMainDO)
|
||||
{
|
||||
IoDeleteDevice(DriverExtension->GreenMainDO);
|
||||
DriverExtension->GreenMainDO = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
ReportGreenPdo(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PGREEN_DRIVER_EXTENSION DriverExtension)
|
||||
{
|
||||
PDEVICE_OBJECT GreenPdo = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Create green PDO */
|
||||
Status = IoReportDetectedDevice(
|
||||
DriverObject,
|
||||
InterfaceTypeUndefined, -1, -1,
|
||||
NULL, NULL, TRUE,
|
||||
&GreenPdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoReportDetectedDevice() failed with status 0x%lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Create green FDO */
|
||||
Status = CreateGreenFdo(DriverObject, GreenPdo);
|
||||
|
||||
IoInvalidateDeviceRelations(GreenPdo, BusRelations);
|
||||
|
||||
/* FIXME: Update registry, set "DeviceReported" to 1 */
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (DriverExtension->GreenMainDO)
|
||||
IoDeleteDevice(DriverExtension->GreenMainDO);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
GreenAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
PGREEN_DRIVER_EXTENSION DriverExtension;
|
||||
|
||||
DPRINT("AddDevice(DriverObject %p, Pdo %p)\n", DriverObject, Pdo);
|
||||
|
||||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
|
||||
if (Pdo == NULL)
|
||||
{
|
||||
if (DriverExtension->DeviceReported)
|
||||
/* Green Pdo has already been reported during a previous boot.
|
||||
* We will get another AddDevice call soon.
|
||||
*/
|
||||
return STATUS_SUCCESS;
|
||||
else
|
||||
return ReportGreenPdo(DriverObject, DriverExtension);
|
||||
}
|
||||
else if (DriverExtension->GreenMainDO == NULL)
|
||||
{
|
||||
return CreateGreenFdo(DriverObject, Pdo);
|
||||
}
|
||||
else
|
||||
{
|
||||
PGREEN_DEVICE_EXTENSION GreenDeviceExtension;
|
||||
|
||||
GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DriverExtension->GreenMainDO->DeviceExtension;
|
||||
if (Pdo == GreenDeviceExtension->KeyboardPdo)
|
||||
return KeyboardAddDevice(DriverObject, Pdo);
|
||||
else if (Pdo == GreenDeviceExtension->ScreenPdo)
|
||||
return ScreenAddDevice(DriverObject, Pdo);
|
||||
else
|
||||
/* Strange PDO. We don't know it */
|
||||
ASSERT(FALSE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
GreenQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
||||
{
|
||||
PGREEN_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS DeviceRelations = NULL;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* Create PDOs for keyboard and screen */
|
||||
if (DeviceExtension->KeyboardPdo == NULL)
|
||||
{
|
||||
Status = IoCreateDevice(
|
||||
DeviceObject->DriverObject,
|
||||
sizeof(COMMON_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DeviceExtension->KeyboardPdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
((PCOMMON_DEVICE_EXTENSION)DeviceExtension->KeyboardPdo->DeviceExtension)->Type = KeyboardPDO;
|
||||
DeviceExtension->KeyboardPdo->Flags |= DO_POWER_PAGABLE | DO_BUS_ENUMERATED_DEVICE;
|
||||
DeviceExtension->KeyboardPdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
}
|
||||
|
||||
if (DeviceExtension->ScreenPdo == NULL)
|
||||
{
|
||||
Status = IoCreateDevice(
|
||||
DeviceObject->DriverObject,
|
||||
sizeof(COMMON_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_SCREEN,
|
||||
FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DeviceExtension->ScreenPdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoCreateDevice() failed with status 0x%lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
((PCOMMON_DEVICE_EXTENSION)DeviceExtension->ScreenPdo->DeviceExtension)->Type = ScreenPDO;
|
||||
DeviceExtension->ScreenPdo->Flags |= DO_POWER_PAGABLE | DO_BUS_ENUMERATED_DEVICE;
|
||||
DeviceExtension->ScreenPdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
}
|
||||
|
||||
/* Allocate return structure */
|
||||
DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
|
||||
PagedPool,
|
||||
FIELD_OFFSET(DEVICE_RELATIONS, Objects) + 2 * sizeof(PDEVICE_OBJECT));
|
||||
if (!DeviceRelations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Fill return structure */
|
||||
DeviceRelations->Count = 2;
|
||||
ObReferenceObject(DeviceExtension->KeyboardPdo);
|
||||
ObReferenceObject(DeviceExtension->ScreenPdo);
|
||||
DeviceRelations->Objects[0] = DeviceExtension->KeyboardPdo;
|
||||
DeviceRelations->Objects[1] = DeviceExtension->ScreenPdo;
|
||||
|
||||
*pDeviceRelations = DeviceRelations;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (DeviceRelations)
|
||||
{
|
||||
ULONG i;
|
||||
for (i = 0; i < DeviceRelations->Count; i++)
|
||||
ObDereferenceObject(DeviceRelations->Objects[i]);
|
||||
ExFreePool(DeviceRelations);
|
||||
}
|
||||
if (DeviceExtension->KeyboardPdo)
|
||||
{
|
||||
IoDeleteDevice(DeviceExtension->KeyboardPdo);
|
||||
DeviceExtension->KeyboardPdo = NULL;
|
||||
}
|
||||
if (DeviceExtension->ScreenPdo)
|
||||
{
|
||||
IoDeleteDevice(DeviceExtension->ScreenPdo);
|
||||
DeviceExtension->ScreenPdo = NULL;
|
||||
}
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
GreenQueryId(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
OUT ULONG_PTR* Information)
|
||||
{
|
||||
GREEN_DEVICE_TYPE Type;
|
||||
ULONG IdType;
|
||||
NTSTATUS Status = Irp->IoStatus.Status;
|
||||
|
||||
Type = ((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type;
|
||||
IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
|
||||
|
||||
switch (IdType)
|
||||
{
|
||||
case BusQueryDeviceID:
|
||||
{
|
||||
LPCWSTR Source = NULL;
|
||||
|
||||
if (Type == ScreenPDO)
|
||||
Source = L"GREEN\\SCREEN";
|
||||
else if (Type == KeyboardPDO)
|
||||
Source = L"GREEN\\KEYBOARD";
|
||||
else
|
||||
{
|
||||
DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceId / Unknown type 0x%lx\n",
|
||||
Type);
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if (Source)
|
||||
{
|
||||
UNICODE_STRING SourceU, String;
|
||||
RtlInitUnicodeString(&SourceU, Source);
|
||||
Status = 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;
|
||||
}
|
||||
|
58
rosapps/drivers/green/power.c
Normal file
58
rosapps/drivers/green/power.c
Normal 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;
|
||||
}
|
674
rosapps/drivers/green/screen.c
Normal file
674
rosapps/drivers/green/screen.c
Normal file
|
@ -0,0 +1,674 @@
|
|||
/*
|
||||
* 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 <debug.h>
|
||||
|
||||
#define ESC ((UCHAR)0x1b)
|
||||
|
||||
/* Force a move of the cursor on each printer char.
|
||||
* Very useful for debug, but it is very slow...
|
||||
*/
|
||||
//#define FORCE_POSITION
|
||||
|
||||
/* UCHAR is promoted to int when passed through '...',
|
||||
* so we get int with va_arg and cast them back to UCHAR.
|
||||
*/
|
||||
static VOID
|
||||
AddToSendBuffer(
|
||||
IN PSCREEN_DEVICE_EXTENSION DeviceExtension,
|
||||
IN ULONG NumberOfChars,
|
||||
... /* IN int */)
|
||||
{
|
||||
PIRP Irp;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
va_list args;
|
||||
PDEVICE_OBJECT SerialDevice;
|
||||
ULONG SizeLeft;
|
||||
int CurrentInt;
|
||||
UCHAR CurrentChar;
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER ZeroOffset;
|
||||
|
||||
ZeroOffset.QuadPart = 0;
|
||||
|
||||
SizeLeft = sizeof(DeviceExtension->SendBuffer) - DeviceExtension->SendBufferPosition;
|
||||
if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0)
|
||||
{
|
||||
SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial;
|
||||
Irp = IoBuildSynchronousFsdRequest(
|
||||
IRP_MJ_WRITE,
|
||||
SerialDevice,
|
||||
DeviceExtension->SendBuffer, DeviceExtension->SendBufferPosition,
|
||||
&ZeroOffset,
|
||||
NULL, /* Event */
|
||||
&ioStatus);
|
||||
if (!Irp)
|
||||
{
|
||||
DPRINT1("IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(SerialDevice, Irp);
|
||||
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
|
||||
{
|
||||
DPRINT1("IoCallDriver() failed. Status = 0x%08lx\n", Status);
|
||||
return;
|
||||
}
|
||||
DeviceExtension->SendBufferPosition = 0;
|
||||
SizeLeft = sizeof(DeviceExtension->SendBuffer);
|
||||
}
|
||||
|
||||
va_start(args, NumberOfChars);
|
||||
while (NumberOfChars-- > 0)
|
||||
{
|
||||
CurrentInt = va_arg(args, int);
|
||||
|
||||
if (CurrentInt > 0)
|
||||
{
|
||||
CurrentChar = (UCHAR)CurrentInt;
|
||||
|
||||
/* Why 0xff chars are printed on a 'dir' ? */
|
||||
if (CurrentChar == 0xff) CurrentChar = ' ';
|
||||
|
||||
DeviceExtension->SendBuffer[DeviceExtension->SendBufferPosition++] = CurrentChar;
|
||||
SizeLeft--;
|
||||
}
|
||||
else if (CurrentInt == 0)
|
||||
{
|
||||
DeviceExtension->SendBuffer[DeviceExtension->SendBufferPosition++] = '0';
|
||||
SizeLeft--;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentInt = -CurrentInt;
|
||||
ASSERT(CurrentInt < 100);
|
||||
if (CurrentInt >= 10)
|
||||
{
|
||||
DeviceExtension->SendBuffer[DeviceExtension->SendBufferPosition++] =
|
||||
(CurrentInt / 10) % 10 + '0';
|
||||
SizeLeft--;
|
||||
}
|
||||
DeviceExtension->SendBuffer[DeviceExtension->SendBufferPosition++] =
|
||||
CurrentInt % 10 + '0';
|
||||
SizeLeft--;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ScreenAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
/* 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("ScreenInitialize() called\n");
|
||||
|
||||
/* Try to create a unique Fdo */
|
||||
Status = IoCreateDevice(
|
||||
DriverObject,
|
||||
sizeof(SCREEN_DEVICE_EXTENSION),
|
||||
&BlueScreenName,
|
||||
FILE_DEVICE_SCREEN,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
TRUE,
|
||||
&Fdo);
|
||||
|
||||
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,
|
||||
sizeof(SCREEN_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_SCREEN,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
TRUE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(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,
|
||||
&BlueScreenName,
|
||||
&LowerDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("IoAttachDevice() failed with status 0x%08lx\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
PreviousBlue = LowerDevice;
|
||||
|
||||
/* 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 = 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;
|
||||
IoAttachDeviceToDeviceStack(PassThroughFdo ? PassThroughFdo : Fdo, Pdo);
|
||||
|
||||
/* initialize screen */
|
||||
DeviceExtension->Columns = 80;
|
||||
DeviceExtension->Rows = 25;
|
||||
DeviceExtension->ScanLines = 16;
|
||||
DeviceExtension->VideoMemory = (PUCHAR)ExAllocatePool(
|
||||
PagedPool,
|
||||
2 * DeviceExtension->Columns * DeviceExtension->Rows * sizeof(UCHAR));
|
||||
if (!DeviceExtension->VideoMemory)
|
||||
{
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
DeviceExtension->TabWidth = 8;
|
||||
|
||||
/* more initialization */
|
||||
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
|
||||
ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
|
||||
/* initialize screen at next write */
|
||||
AddToSendBuffer(DeviceExtension, 2, ESC, 'c'); /* reset device */
|
||||
AddToSendBuffer(DeviceExtension, 4, ESC, '[', '7', 'l'); /* disable line wrap */
|
||||
AddToSendBuffer(DeviceExtension, 4, ESC, '[', '3', 'g'); /* clear all tabs */
|
||||
|
||||
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
Status = 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
|
||||
ScreenWrite(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PUCHAR Buffer;
|
||||
PSCREEN_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT SerialDevice;
|
||||
PUCHAR VideoMemory; /* FIXME: is it useful? */
|
||||
ULONG VideoMemorySize; /* FIXME: is it useful? */
|
||||
|
||||
ULONG Columns, Rows;
|
||||
ULONG CursorX, CursorY;
|
||||
ULONG i, j;
|
||||
|
||||
DPRINT("ScreenWrite() called\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
Buffer = Irp->UserBuffer;
|
||||
DeviceExtension = (PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
VideoMemory = DeviceExtension->VideoMemory;
|
||||
|
||||
SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial;
|
||||
if (!SerialDevice)
|
||||
{
|
||||
DPRINT1("Calling blue\n");
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceExtension->PreviousBlue, Irp);
|
||||
}
|
||||
|
||||
Columns = DeviceExtension->Columns;
|
||||
Rows = DeviceExtension->Rows;
|
||||
CursorX = (DeviceExtension->LogicalOffset / 2) % Columns + 1;
|
||||
CursorY = (DeviceExtension->LogicalOffset / 2) / Columns + 1;
|
||||
VideoMemorySize = Columns * Rows * 2 * sizeof(UCHAR);
|
||||
|
||||
if (!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT))
|
||||
{
|
||||
/* raw output mode */
|
||||
CHECKPOINT;
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < Stack->Parameters.Write.Length; i++, Buffer++)
|
||||
{
|
||||
switch (*Buffer)
|
||||
{
|
||||
case '\b':
|
||||
{
|
||||
if (CursorX > 1)
|
||||
{
|
||||
CursorX--;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
AddToSendBuffer(DeviceExtension, 1, ' ');
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
}
|
||||
else if (CursorY > 1)
|
||||
{
|
||||
CursorX = Columns;
|
||||
CursorY--;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '\n':
|
||||
{
|
||||
CursorY++;
|
||||
CursorX = 1;
|
||||
AddToSendBuffer(DeviceExtension, 1, '\n');
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', '1', 'H');
|
||||
break;
|
||||
}
|
||||
case '\r':
|
||||
{
|
||||
if (CursorX > 1)
|
||||
{
|
||||
AddToSendBuffer(DeviceExtension, 4, ESC, '[', -(int)(CursorX-1), 'D');
|
||||
CursorX = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '\t':
|
||||
{
|
||||
ULONG Offset = DeviceExtension->TabWidth - (CursorX % DeviceExtension->TabWidth);
|
||||
for (j = 0; j < Offset; j++)
|
||||
{
|
||||
#ifdef FORCE_POSITION
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
#endif
|
||||
AddToSendBuffer(DeviceExtension, 1, ' ');
|
||||
CursorX++;
|
||||
if (CursorX > Columns)
|
||||
{
|
||||
CursorX = 1;
|
||||
CursorY++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
#ifdef FORCE_POSITION
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
#endif
|
||||
AddToSendBuffer(DeviceExtension, 1, *Buffer);
|
||||
CursorX++;
|
||||
if (CursorX > Columns)
|
||||
{
|
||||
CursorX = 1;
|
||||
DPRINT("Y: %lu -> %lu\n", CursorY, CursorY + 1);
|
||||
CursorY++;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', '1', 'H');
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CursorY >= Rows)
|
||||
{
|
||||
DPRINT("Y: %lu -> %lu\n", CursorY, CursorY - 1);
|
||||
CursorY--;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)1, ';', -(int)(Rows), 'r');
|
||||
AddToSendBuffer(DeviceExtension, 2, ESC, 'D');
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';', -(int)CursorX, 'H');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeviceExtension->LogicalOffset = ((CursorX-1) + (CursorY-1) * Columns) * 2;
|
||||
|
||||
/* flush output buffer */
|
||||
AddToSendBuffer(DeviceExtension, 0);
|
||||
|
||||
/* Call lower driver */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ScreenDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PSCREEN_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT SerialDevice;
|
||||
NTSTATUS Status;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExtension = (PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Serial;
|
||||
if (!SerialDevice)
|
||||
{
|
||||
DPRINT1("Calling blue\n");
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceExtension->PreviousBlue, Irp);
|
||||
}
|
||||
|
||||
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
#if 0
|
||||
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi;
|
||||
DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO\n");
|
||||
|
||||
pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
pcsbi->dwSize.X = DeviceExtension->Columns;
|
||||
pcsbi->dwSize.Y = DeviceExtension->Rows;
|
||||
|
||||
pcsbi->dwCursorPosition.X = (SHORT)(DeviceExtension->LogicalOffset % DeviceExtension->Columns);
|
||||
pcsbi->dwCursorPosition.Y = (SHORT)(DeviceExtension->LogicalOffset / DeviceExtension->Columns);
|
||||
|
||||
pcsbi->wAttributes = DeviceExtension->CharAttribute;
|
||||
|
||||
pcsbi->srWindow.Left = 1;
|
||||
pcsbi->srWindow.Right = DeviceExtension->Columns;
|
||||
pcsbi->srWindow.Top = 1;
|
||||
pcsbi->srWindow.Bottom = DeviceExtension->Rows;
|
||||
|
||||
pcsbi->dwMaximumWindowSize.X = DeviceExtension->Columns;
|
||||
pcsbi->dwMaximumWindowSize.Y = DeviceExtension->Rows;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(CONSOLE_SCREEN_BUFFER_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi;
|
||||
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++; }
|
||||
/* FIXME: remove */ { pcsbi->dwCursorPosition.Y++; }
|
||||
ASSERT(pcsbi->dwCursorPosition.X >= 1);
|
||||
ASSERT(pcsbi->dwCursorPosition.Y >= 1);
|
||||
ASSERT(pcsbi->dwCursorPosition.X <= DeviceExtension->Columns);
|
||||
ASSERT(pcsbi->dwCursorPosition.Y <= DeviceExtension->Rows);
|
||||
|
||||
DeviceExtension->LogicalOffset = (
|
||||
(pcsbi->dwCursorPosition.Y-1) * DeviceExtension->Columns +
|
||||
(pcsbi->dwCursorPosition.X-1)) * 2;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[',
|
||||
-(int)pcsbi->dwCursorPosition.Y, ';',
|
||||
-(int)pcsbi->dwCursorPosition.X, 'H');
|
||||
|
||||
/* flush buffer */
|
||||
AddToSendBuffer(DeviceExtension, 0);
|
||||
|
||||
DeviceExtension->CharAttribute = pcsbi->wAttributes;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_GET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_CURSOR_INFO\n");
|
||||
|
||||
pcci->dwSize = 1;
|
||||
pcci->bVisible = TRUE;
|
||||
|
||||
Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_GET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_MODE\n");
|
||||
|
||||
pcm->dwMode = DeviceExtension->Mode;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_SET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_MODE\n");
|
||||
|
||||
DeviceExtension->Mode = pcm->dwMode;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
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("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("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("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE\n");
|
||||
|
||||
DeviceExtension->CharAttribute = (WORD)*(PWORD)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
|
||||
{
|
||||
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("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("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER */
|
||||
break;
|
||||
}
|
||||
case IOCTL_CONSOLE_DRAW:
|
||||
{
|
||||
PCONSOLE_DRAW ConsoleDraw;
|
||||
PUCHAR Video;
|
||||
ULONG x, y;
|
||||
BOOLEAN DoOptimization = FALSE;
|
||||
DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_DRAW\n");
|
||||
|
||||
ConsoleDraw = (PCONSOLE_DRAW)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
/* FIXME: remove */ { ConsoleDraw->X++; ConsoleDraw->CursorX++; }
|
||||
/* FIXME: remove */ { ConsoleDraw->Y++; ConsoleDraw->CursorY++; }
|
||||
DPRINT1("%lu %lu %lu %lu\n",
|
||||
ConsoleDraw->X, ConsoleDraw->Y,
|
||||
ConsoleDraw->SizeX, ConsoleDraw->SizeY);
|
||||
ASSERT(ConsoleDraw->X >= 1);
|
||||
ASSERT(ConsoleDraw->Y >= 1);
|
||||
ASSERT(ConsoleDraw->X <= DeviceExtension->Columns);
|
||||
ASSERT(ConsoleDraw->Y <= DeviceExtension->Rows);
|
||||
ASSERT(ConsoleDraw->X + ConsoleDraw->SizeX >= 1);
|
||||
ASSERT(ConsoleDraw->Y + ConsoleDraw->SizeY >= 1);
|
||||
ASSERT(ConsoleDraw->X + ConsoleDraw->SizeX - 1 <= DeviceExtension->Columns);
|
||||
ASSERT(ConsoleDraw->Y + ConsoleDraw->SizeY - 1 <= DeviceExtension->Rows);
|
||||
ASSERT(ConsoleDraw->CursorX >= 1);
|
||||
ASSERT(ConsoleDraw->CursorY >= 1);
|
||||
ASSERT(ConsoleDraw->CursorX <= DeviceExtension->Columns);
|
||||
ASSERT(ConsoleDraw->CursorY <= DeviceExtension->Rows);
|
||||
|
||||
#if 0
|
||||
if (ConsoleDraw->X == 1
|
||||
&& ConsoleDraw->Y == 1
|
||||
&& ConsoleDraw->SizeX == DeviceExtension->Columns
|
||||
&& ConsoleDraw->SizeY == DeviceExtension->Rows)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
/* search if we need to clear all screen */
|
||||
DoOptimization = TRUE;
|
||||
Video = (PUCHAR)(ConsoleDraw + 1);
|
||||
x = 0;
|
||||
while (DoOptimization && x < DeviceExtension->Columns * DeviceExtension->Rows)
|
||||
{
|
||||
if (Video[x++] != ' ')
|
||||
{
|
||||
CHECKPOINT1;
|
||||
DoOptimization = FALSE;
|
||||
}
|
||||
/*if (Video[x++] != DeviceExtension->CharAttribute) DoOptimization = FALSE; */
|
||||
}
|
||||
if (DoOptimization)
|
||||
{
|
||||
CHECKPOINT1;
|
||||
AddToSendBuffer(DeviceExtension, 4, ESC, '[', '2', 'J');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* add here more optimizations if needed */
|
||||
|
||||
if (!DoOptimization)
|
||||
{
|
||||
for (y = 0; y < ConsoleDraw->SizeY; y++)
|
||||
{
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[',
|
||||
-(int)(ConsoleDraw->Y + y), ';',
|
||||
-(int)(ConsoleDraw->X), 'H');
|
||||
Video = (PUCHAR)(ConsoleDraw + 1);
|
||||
Video = &Video[((ConsoleDraw->Y + y) * /*DeviceExtension->Columns +*/ ConsoleDraw->X) * 2];
|
||||
for (x = 0; x < ConsoleDraw->SizeX; x++)
|
||||
{
|
||||
AddToSendBuffer(DeviceExtension, 1, Video[x * 2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeviceExtension->LogicalOffset = (
|
||||
(ConsoleDraw->CursorY-1) * DeviceExtension->Columns +
|
||||
(ConsoleDraw->CursorX-1)) * 2;
|
||||
AddToSendBuffer(DeviceExtension, 6, ESC, '[',
|
||||
-(int)(ConsoleDraw->CursorY), ';',
|
||||
-(int)(ConsoleDraw->CursorX), 'H');
|
||||
|
||||
/* flush buffer */
|
||||
AddToSendBuffer(DeviceExtension, 0);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
|
||||
Stack->Parameters.DeviceIoControl.IoControlCode);
|
||||
/* Call lower driver */
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(DeviceExtension->Common.LowerDevice, Irp);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
203
rosapps/drivers/ramdrv/minix/bitops.c
Normal file
203
rosapps/drivers/ramdrv/minix/bitops.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* Copyright 1992, Linus Torvalds.
|
||||
*/
|
||||
/*
|
||||
* These have to be done with inline assembly: that way the bit-setting
|
||||
* is guaranteed to be atomic. All bit operations return 0 if the bit
|
||||
* was cleared before the operation and != 0 if it was not.
|
||||
*
|
||||
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
|
||||
*/
|
||||
|
||||
#ifdef __SMP__
|
||||
#define LOCK_PREFIX "lock ; "
|
||||
#else
|
||||
#define LOCK_PREFIX ""
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Function prototypes to keep gcc -Wall happy
|
||||
*/
|
||||
extern void set_bit(int nr, volatile void * addr);
|
||||
extern void clear_bit(int nr, volatile void * addr);
|
||||
extern void change_bit(int nr, volatile void * addr);
|
||||
extern int test_and_set_bit(int nr, volatile void * addr);
|
||||
extern int test_and_clear_bit(int nr, volatile void * addr);
|
||||
extern int test_and_change_bit(int nr, volatile void * addr);
|
||||
extern int __constant_test_bit(int nr, const volatile void * addr);
|
||||
extern int __test_bit(int nr, volatile void * addr);
|
||||
extern int find_first_zero_bit(void * addr, unsigned size);
|
||||
extern int find_next_zero_bit (void * addr, int size, int offset);
|
||||
extern unsigned long ffz(unsigned long word);
|
||||
|
||||
/*
|
||||
* Some hacks to defeat gcc over-optimizations..
|
||||
*/
|
||||
struct __dummy { unsigned long a[100]; };
|
||||
#define ADDR (*(volatile struct __dummy *) addr)
|
||||
#define CONST_ADDR (*(volatile const struct __dummy *) addr)
|
||||
|
||||
void set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btsl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
void clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btrl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
void change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btcl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
int test_and_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btsl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit),"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
int test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btrl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit),"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
int test_and_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btcl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit),"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine doesn't need to be atomic.
|
||||
*/
|
||||
int __constant_test_bit(int nr, const volatile void * addr)
|
||||
{
|
||||
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
|
||||
}
|
||||
|
||||
int test_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"btl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit)
|
||||
:"m" (ADDR),"Ir" (nr));
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#define test_bit(nr,addr) \
|
||||
(__builtin_constant_p(nr) ? \
|
||||
__constant_test_bit((nr),(addr)) : \
|
||||
__test_bit((nr),(addr)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find-bit routines..
|
||||
*/
|
||||
int find_first_zero_bit(void * addr, unsigned size)
|
||||
{
|
||||
int d0, d1, d2;
|
||||
int res;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
__asm__("cld\n\t"
|
||||
"movl $-1,%%eax\n\t"
|
||||
"xorl %%edx,%%edx\n\t"
|
||||
"repe; scasl\n\t"
|
||||
"je 1f\n\t"
|
||||
"xorl -4(%%edi),%%eax\n\t"
|
||||
"subl $4,%%edi\n\t"
|
||||
"bsfl %%eax,%%edx\n"
|
||||
"1:\tsubl %%ebx,%%edi\n\t"
|
||||
"shll $3,%%edi\n\t"
|
||||
"addl %%edi,%%edx"
|
||||
:"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
|
||||
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
|
||||
return res;
|
||||
}
|
||||
|
||||
int find_next_zero_bit (void * addr, int size, int offset)
|
||||
{
|
||||
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
|
||||
int set = 0, bit = offset & 31, res;
|
||||
|
||||
if (bit) {
|
||||
/*
|
||||
* Look for zero in first byte
|
||||
*/
|
||||
__asm__("bsfl %1,%0\n\t"
|
||||
"jne 1f\n\t"
|
||||
"movl $32, %0\n"
|
||||
"1:"
|
||||
: "=r" (set)
|
||||
: "r" (~(*p >> bit)));
|
||||
if (set < (32 - bit))
|
||||
return set + offset;
|
||||
set = 32 - bit;
|
||||
p++;
|
||||
}
|
||||
/*
|
||||
* No zero yet, search remaining full bytes for a zero
|
||||
*/
|
||||
res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
|
||||
return (offset + set + res);
|
||||
}
|
||||
|
||||
/*
|
||||
* ffz = Find First Zero in word. Undefined if no zero exists,
|
||||
* so code should check against ~0UL first..
|
||||
*/
|
||||
unsigned long ffz(unsigned long word)
|
||||
{
|
||||
__asm__("bsfl %1,%0"
|
||||
:"=r" (word)
|
||||
:"r" (~word));
|
||||
return word;
|
||||
}
|
30
rosapps/drivers/ramdrv/minix/bitops.h
Normal file
30
rosapps/drivers/ramdrv/minix/bitops.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef _I386_BITOPS_H
|
||||
#define _I386_BITOPS_H
|
||||
|
||||
/*
|
||||
* Copyright 1992, Linus Torvalds.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These have to be done with inline assembly: that way the bit-setting
|
||||
* is guaranteed to be atomic. All bit operations return 0 if the bit
|
||||
* was cleared before the operation and != 0 if it was not.
|
||||
*
|
||||
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function prototypes to keep gcc -Wall happy
|
||||
*/
|
||||
extern void set_bit(int nr, volatile void * addr);
|
||||
extern void clear_bit(int nr, volatile void * addr);
|
||||
extern void change_bit(int nr, volatile void * addr);
|
||||
extern int test_and_set_bit(int nr, volatile void * addr);
|
||||
extern int test_and_clear_bit(int nr, volatile void * addr);
|
||||
extern int test_and_change_bit(int nr, volatile void * addr);
|
||||
extern int test_bit(int nr, volatile void * addr);
|
||||
extern int find_first_zero_bit(void * addr, unsigned size);
|
||||
extern int find_next_zero_bit (void * addr, int size, int offset);
|
||||
extern unsigned long ffz(unsigned long word);
|
||||
|
||||
#endif /* _I386_BITOPS_H */
|
109
rosapps/drivers/ramdrv/minix/block.c
Normal file
109
rosapps/drivers/ramdrv/minix/block.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/minix.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static unsigned int MinixGetBlock(PDEVICE_OBJECT DeviceObject,
|
||||
PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||
struct minix_inode* inode,
|
||||
ULONG FileOffset)
|
||||
{
|
||||
int block;
|
||||
PVOID BaseAddress;
|
||||
ULONG blk;
|
||||
|
||||
blk = FileOffset / BLOCKSIZE;
|
||||
|
||||
DPRINT("MinixGetBlock(inode %x, blk %d)\n",inode,blk);
|
||||
|
||||
/*
|
||||
* The first few blocks are available in the inode
|
||||
*/
|
||||
if (blk < 7)
|
||||
{
|
||||
block = inode->i_zone[blk];
|
||||
return(block);
|
||||
}
|
||||
blk = blk - 7;
|
||||
|
||||
/*
|
||||
* Retrieve a single-indirect block
|
||||
*/
|
||||
if (blk < 512)
|
||||
{
|
||||
block = inode->i_zone[7];
|
||||
|
||||
BaseAddress = ExAllocatePool(NonPagedPool, 512);
|
||||
|
||||
MinixReadSector(DeviceObject,
|
||||
block,
|
||||
BaseAddress);
|
||||
|
||||
block = ((PUSHORT)(BaseAddress))[blk];
|
||||
|
||||
ExFreePool(BaseAddress);
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a double indirect block
|
||||
*/
|
||||
blk = blk - 512;
|
||||
block = inode->i_zone[8];
|
||||
|
||||
BaseAddress = ExAllocatePool(NonPagedPool, 512);
|
||||
|
||||
MinixReadSector(DeviceObject,
|
||||
block,
|
||||
BaseAddress);
|
||||
|
||||
block = ((PUSHORT)BaseAddress)[(blk>>9)&511];
|
||||
|
||||
ExFreePool(BaseAddress);
|
||||
|
||||
|
||||
BaseAddress = ExAllocatePool(NonPagedPool, 512);
|
||||
|
||||
MinixReadSector(DeviceObject,
|
||||
block,
|
||||
BaseAddress);
|
||||
|
||||
block = ((PUSHORT)BaseAddress)[blk&512];
|
||||
|
||||
ExFreePool(BaseAddress);
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
||||
NTSTATUS MinixReadBlock(PDEVICE_OBJECT DeviceObject,
|
||||
PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||
struct minix_inode* inode,
|
||||
ULONG FileOffset,
|
||||
PULONG DiskOffset)
|
||||
{
|
||||
unsigned int block;
|
||||
|
||||
DPRINT("MinixReadBlock()\n");
|
||||
|
||||
block = MinixGetBlock(DeviceObject, DeviceExt,inode, FileOffset);
|
||||
|
||||
(*DiskOffset) = block * BLOCKSIZE;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
154
rosapps/drivers/ramdrv/minix/blockdev.c
Normal file
154
rosapps/drivers/ramdrv/minix/blockdev.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/minix.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
BOOLEAN MinixReadPage(PDEVICE_OBJECT DeviceObject,
|
||||
ULONG Offset,
|
||||
PVOID Buffer)
|
||||
{
|
||||
ULONG i;
|
||||
BOOLEAN Result;
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
Result = MinixReadSector(DeviceObject,
|
||||
(Offset + (i * PAGE_SIZE)) / BLOCKSIZE,
|
||||
(Buffer + (i * PAGE_SIZE)));
|
||||
if (!Result)
|
||||
{
|
||||
return(Result);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
LARGE_INTEGER sectorNumber;
|
||||
PIRP irp;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
KEVENT event;
|
||||
NTSTATUS status;
|
||||
ULONG sectorSize;
|
||||
PULONG mbr;
|
||||
|
||||
DPRINT("MinixReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||
pDeviceObject,DiskSector,Buffer);
|
||||
|
||||
sectorNumber.u.HighPart = 0;
|
||||
sectorNumber.u.LowPart = DiskSector * BLOCKSIZE;
|
||||
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
|
||||
sectorSize = BLOCKSIZE;
|
||||
|
||||
mbr = ExAllocatePool(NonPagedPool, sectorSize);
|
||||
|
||||
if (!mbr) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
||||
pDeviceObject,
|
||||
mbr,
|
||||
sectorSize,
|
||||
§orNumber,
|
||||
&event,
|
||||
&ioStatus );
|
||||
|
||||
if (!irp) {
|
||||
ExFreePool(mbr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
status = IoCallDriver(pDeviceObject,
|
||||
irp);
|
||||
|
||||
if (status == STATUS_PENDING) {
|
||||
KeWaitForSingleObject(&event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
status = ioStatus.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
ExFreePool(mbr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Buffer,mbr,sectorSize);
|
||||
|
||||
ExFreePool(mbr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN MinixWriteSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
LARGE_INTEGER sectorNumber;
|
||||
PIRP irp;
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
KEVENT event;
|
||||
NTSTATUS status;
|
||||
ULONG sectorSize;
|
||||
|
||||
DPRINT("MinixWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||
pDeviceObject,DiskSector,Buffer);
|
||||
|
||||
sectorNumber.u.HighPart = 0;
|
||||
sectorNumber.u.LowPart = DiskSector * BLOCKSIZE;
|
||||
|
||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
||||
|
||||
sectorSize = BLOCKSIZE;
|
||||
|
||||
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
||||
pDeviceObject,
|
||||
Buffer,
|
||||
sectorSize,
|
||||
§orNumber,
|
||||
&event,
|
||||
&ioStatus );
|
||||
|
||||
|
||||
status = IoCallDriver(pDeviceObject,
|
||||
irp);
|
||||
|
||||
if (status == STATUS_PENDING) {
|
||||
KeWaitForSingleObject(&event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
status = ioStatus.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
45
rosapps/drivers/ramdrv/minix/cache.c
Normal file
45
rosapps/drivers/ramdrv/minix/cache.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/cache.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <ntifs.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS MinixRequestCacheBlock(PDEVICE_OBJECT DeviceObject,
|
||||
PBCB Bcb,
|
||||
ULONG FileOffset,
|
||||
PVOID* BaseAddress,
|
||||
PCACHE_SEGMENT* CacheSeg)
|
||||
{
|
||||
BOOLEAN UptoDate;
|
||||
|
||||
CcRosRequestCacheSegment(Bcb,
|
||||
FileOffset,
|
||||
BaseAddress,
|
||||
&UptoDate,
|
||||
CacheSeg);
|
||||
if (!UptoDate)
|
||||
{
|
||||
MinixReadPage(DeviceObject,
|
||||
PAGE_ROUND_DOWN(FileOffset),
|
||||
BaseAddress);
|
||||
}
|
||||
BaseAddress = BaseAddress + (FileOffset % PAGE_SIZE);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
234
rosapps/drivers/ramdrv/minix/dir.c
Normal file
234
rosapps/drivers/ramdrv/minix/dir.c
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/minix.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
BOOLEAN MinixCompareUnicodeStringToAnsi(PCH AnsiStr,
|
||||
PWCHAR UnicodeStr,
|
||||
ULONG MaxLen)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
while (i<MaxLen)
|
||||
{
|
||||
if ((*AnsiStr)!=(*UnicodeStr))
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
if ((*AnsiStr)==0 && (*UnicodeStr)==0)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
AnsiStr++;
|
||||
UnicodeStr++;
|
||||
i++;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
#define ENTRIES_PER_BLOCK (BLOCKSIZE / MINIX_DIR_ENTRY_SIZE)
|
||||
|
||||
ULONG MinixDirLookup(PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
struct minix_inode* dir,
|
||||
PWCHAR Name)
|
||||
{
|
||||
struct minix_dir_entry* current_entry = NULL;
|
||||
unsigned int offset;
|
||||
unsigned int i;
|
||||
unsigned int inode;
|
||||
PVOID Block;
|
||||
ULONG DiskOffset;
|
||||
|
||||
DPRINT("MinixDirLookup(DeviceExt %x, dir %x, Name %S)\n",DeviceExt,dir,
|
||||
Name);
|
||||
|
||||
Block = ExAllocatePool(NonPagedPool, 512);
|
||||
|
||||
for (i=0;i<(dir->i_size/MINIX_DIR_ENTRY_SIZE);i++)
|
||||
{
|
||||
CHECKPOINT;
|
||||
offset = i*MINIX_DIR_ENTRY_SIZE;
|
||||
if ((offset%BLOCKSIZE)==0)
|
||||
{
|
||||
MinixReadBlock(DeviceObject,
|
||||
DeviceExt,
|
||||
dir,
|
||||
offset/BLOCKSIZE,
|
||||
&DiskOffset);
|
||||
MinixReadSector(DeviceObject,
|
||||
DiskOffset,
|
||||
Block);
|
||||
}
|
||||
current_entry = (struct minix_dir_entry *)
|
||||
(Block+offset%BLOCKSIZE);
|
||||
DPRINT("Inode %x Name %.30s\n",current_entry->inode,
|
||||
current_entry->name);
|
||||
if (MinixCompareUnicodeStringToAnsi(current_entry->name,
|
||||
Name,30))
|
||||
{
|
||||
inode = current_entry->inode;
|
||||
ExFreePool(Block);
|
||||
DPRINT("MinixDirLookup() = %d\n",inode);
|
||||
return(inode);
|
||||
}
|
||||
}
|
||||
CHECKPOINT;
|
||||
ExFreePool(Block);
|
||||
DPRINT("MinixDirLookup() = %d\n",0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
NTSTATUS MinixOpen(PDEVICE_OBJECT DeviceObject,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
PFILE_OBJECT FileObject,
|
||||
PMINIX_FSCONTEXT result,
|
||||
PULONG Information)
|
||||
{
|
||||
PWSTR current;
|
||||
PWSTR next;
|
||||
PWSTR string;
|
||||
struct minix_inode current_dir;
|
||||
unsigned int current_ino;
|
||||
|
||||
string = ExAllocatePool(NonPagedPool,
|
||||
2*(wcslen(FileObject->FileName.Buffer)+1));
|
||||
wcscpy(string, FileObject->FileName.Buffer);
|
||||
|
||||
DbgPrint("MinixOpen(DeviceObject %x, DeviceName %S, result %x)\n",
|
||||
DeviceObject,string,result);
|
||||
|
||||
|
||||
next = &string[0];
|
||||
current = next+1;
|
||||
|
||||
current_ino = MINIX_ROOT_INO;
|
||||
|
||||
while (next != NULL && current_ino != 0)
|
||||
{
|
||||
MinixReadInode(DeviceObject,DeviceExt,current_ino,¤t_dir);
|
||||
|
||||
DPRINT("current %S next %x\n",current,next);
|
||||
|
||||
*next = '\\';
|
||||
current = next+1;
|
||||
next = wcschr(next+1,'\\');
|
||||
if (next!=NULL)
|
||||
{
|
||||
*next=0;
|
||||
}
|
||||
|
||||
current_ino = MinixDirLookup(DeviceExt,
|
||||
DeviceObject,
|
||||
¤t_dir,
|
||||
current);
|
||||
}
|
||||
if (next == NULL && current_ino != 0)
|
||||
{
|
||||
MinixReadInode(DeviceObject,DeviceExt,current_ino,¤t_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*Information) = FILE_DOES_NOT_EXIST;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
result = ExAllocatePool(NonPagedPool, sizeof(MINIX_FSCONTEXT));
|
||||
memcpy(&result->inode,¤t_dir,sizeof(struct minix_inode));
|
||||
|
||||
DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixClose(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
|
||||
DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
ExFreePool(FileObject->FsContext);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixDirectoryControl(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
// PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
|
||||
if (Stack->MinorFunction != IRP_MN_QUERY_DIRECTORY)
|
||||
{
|
||||
return(STATUS_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixCreate(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
NTSTATUS Status;
|
||||
PMINIX_FSCONTEXT result;
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt;
|
||||
|
||||
DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||
DPRINT("Opening file %x %S\n",FileObject->FileName.Buffer,
|
||||
FileObject->FileName.Buffer);
|
||||
DPRINT("FileObject->FileName.Buffer %x\n",
|
||||
FileObject->FileName.Buffer);
|
||||
|
||||
DeviceExt = (MINIX_DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
|
||||
result = ExAllocatePool(NonPagedPool,sizeof(struct minix_inode));
|
||||
DPRINT("result %x\n",result);
|
||||
Status = MinixOpen(DeviceExt->AttachedDevice,
|
||||
DeviceExt,
|
||||
FileObject,
|
||||
result,
|
||||
&Irp->IoStatus.Information);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
FileObject->FsContext = result;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
DPRINT("Finished MinixCreate()\n");
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(Status);
|
||||
}
|
||||
|
136
rosapps/drivers/ramdrv/minix/inode.c
Normal file
136
rosapps/drivers/ramdrv/minix/inode.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/minix.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <string.h>
|
||||
#include "bitops.h"
|
||||
#include <ntifs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino)
|
||||
{
|
||||
PULONG Buffer;
|
||||
ULONG off;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
MinixReadSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
|
||||
off = ino % 8192;
|
||||
clear_bit(off%32,&Buffer[off/32]);
|
||||
MinixWriteSector(Volume, (ino / 8192)+2, (PVOID)Buffer);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
static ULONG MinixAllocateInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt)
|
||||
{
|
||||
ULONG i;
|
||||
PULONG Buffer;
|
||||
ULONG ino;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
for (i=0; i<DeviceExt->sb->s_imap_blocks; i++)
|
||||
{
|
||||
MinixReadSector(Volume,i + 2,Buffer);
|
||||
ino = find_first_zero_bit(Buffer,8192);
|
||||
if (ino < 8192)
|
||||
{
|
||||
set_bit(ino%32,&Buffer[32]);
|
||||
MinixWriteSector(Volume,i + 2,Buffer);
|
||||
ExFreePool(Buffer);
|
||||
return(ino + (i*8192));
|
||||
}
|
||||
}
|
||||
ExFreePool(Buffer);
|
||||
return(0);
|
||||
}
|
||||
|
||||
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
struct minix_inode* new_inode)
|
||||
{
|
||||
ULONG ino;
|
||||
|
||||
ino = MinixAllocateInode(Volume,DeviceExt);
|
||||
if (ino == 0)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
MinixWriteInode(Volume,DeviceExt,ino,new_inode);
|
||||
return(ino);
|
||||
}
|
||||
|
||||
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino,
|
||||
struct minix_inode* result)
|
||||
{
|
||||
int block;
|
||||
char* buffer;
|
||||
struct minix_inode* inodes;
|
||||
|
||||
DPRINT("MinixWriteInode(ino %x, result %x)\n",ino,result);
|
||||
|
||||
buffer = ExAllocatePool(NonPagedPool,1024);
|
||||
inodes = (struct minix_inode *)buffer;
|
||||
|
||||
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
|
||||
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
|
||||
MinixReadSector(Volume,block,buffer);
|
||||
memcpy(&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],result,
|
||||
sizeof(struct minix_inode));
|
||||
MinixWriteSector(Volume,block,buffer);
|
||||
|
||||
ExFreePool(buffer);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino,
|
||||
struct minix_inode* result)
|
||||
{
|
||||
int block;
|
||||
struct minix_inode* inodes;
|
||||
PVOID BaseAddress;
|
||||
|
||||
DPRINT("MinixReadInode(ino %x, result %x)\n",ino,result);
|
||||
|
||||
block = 2 + DeviceExt->sb->s_imap_blocks + DeviceExt->sb->s_zmap_blocks
|
||||
+ ((ino-1) / MINIX_INODES_PER_BLOCK);
|
||||
DPRINT("Reading block %x offset %x\n",block,block*BLOCKSIZE);
|
||||
DPRINT("Index %x\n",(ino-1)%MINIX_INODES_PER_BLOCK);
|
||||
|
||||
BaseAddress = ExAllocatePool(NonPagedPool, PAGE_SIZE);
|
||||
|
||||
MinixReadPage(DeviceObject,
|
||||
block,
|
||||
BaseAddress);
|
||||
|
||||
inodes = (struct minix_inode *)(BaseAddress + ((block % 4) * 512));
|
||||
|
||||
memcpy(result,
|
||||
&inodes[(ino-1)%MINIX_INODES_PER_BLOCK],
|
||||
sizeof(struct minix_inode));
|
||||
DPRINT("result->i_uid %x\n",result->i_uid);
|
||||
DPRINT("result->i_size %x\n",result->i_size);
|
||||
|
||||
ExFreePool(BaseAddress);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
133
rosapps/drivers/ramdrv/minix/minix.h
Normal file
133
rosapps/drivers/ramdrv/minix/minix.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
#include <ntddk.h>
|
||||
#include <ntifs.h>
|
||||
|
||||
#define MINIX_ROOT_INO 1
|
||||
|
||||
/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
|
||||
#define MINIX_LINK_MAX 250
|
||||
|
||||
#define MINIX_I_MAP_SLOTS 8
|
||||
#define MINIX_Z_MAP_SLOTS 64
|
||||
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
|
||||
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
|
||||
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
|
||||
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
|
||||
#define MINIX_VALID_FS 0x0001 /* Clean fs. */
|
||||
#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
|
||||
|
||||
#define MINIX_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix_inode)))
|
||||
#define MINIX2_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix2_inode)))
|
||||
|
||||
#define MINIX_V1 0x0001 /* original minix fs */
|
||||
#define MINIX_V2 0x0002 /* minix V2 fs */
|
||||
|
||||
|
||||
/*
|
||||
* This is the original minix inode layout on disk.
|
||||
* Note the 8-bit gid and atime and ctime.
|
||||
*/
|
||||
struct minix_inode {
|
||||
unsigned short int i_mode;
|
||||
unsigned short int i_uid;
|
||||
unsigned long i_size;
|
||||
unsigned long i_time;
|
||||
unsigned char i_gid;
|
||||
unsigned char i_nlinks;
|
||||
unsigned short int i_zone[9];
|
||||
};
|
||||
|
||||
/*
|
||||
* The new minix inode has all the time entries, as well as
|
||||
* long block numbers and a third indirect block (7+1+1+1
|
||||
* instead of 7+1+1). Also, some previously 8-bit values are
|
||||
* now 16-bit. The inode is now 64 bytes instead of 32.
|
||||
*/
|
||||
struct minix2_inode {
|
||||
unsigned short int i_mode;
|
||||
unsigned short int i_nlinks;
|
||||
unsigned short int i_uid;
|
||||
unsigned short int i_gid;
|
||||
unsigned long i_size;
|
||||
unsigned long i_atime;
|
||||
unsigned long i_mtime;
|
||||
unsigned long i_ctime;
|
||||
unsigned long i_zone[10];
|
||||
};
|
||||
|
||||
/*
|
||||
* minix super-block data on disk
|
||||
*/
|
||||
struct minix_super_block {
|
||||
unsigned short int s_ninodes;
|
||||
unsigned short int s_nzones;
|
||||
unsigned short int s_imap_blocks;
|
||||
unsigned short int s_zmap_blocks;
|
||||
unsigned short int s_firstdatazone;
|
||||
unsigned short int s_log_zone_size;
|
||||
unsigned long s_max_size;
|
||||
unsigned short int s_magic;
|
||||
unsigned short int s_state;
|
||||
unsigned long s_zones;
|
||||
};
|
||||
|
||||
struct minix_dir_entry {
|
||||
unsigned short int inode;
|
||||
char name[0];
|
||||
};
|
||||
#define MINIX_DIR_ENTRY_SIZE (sizeof(struct minix_dir_entry)+30)
|
||||
|
||||
BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN PVOID Buffer);
|
||||
BOOLEAN MinixWriteSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN PVOID Buffer);
|
||||
|
||||
#define BLOCKSIZE (1024)
|
||||
|
||||
//extern PDRIVER_OBJECT DriverObject;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PDEVICE_OBJECT AttachedDevice;
|
||||
struct minix_inode root_inode;
|
||||
char superblock_buf[BLOCKSIZE];
|
||||
struct minix_super_block* sb;
|
||||
PFILE_OBJECT FileObject;
|
||||
} MINIX_DEVICE_EXTENSION, *PMINIX_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct minix_inode inode;
|
||||
} MINIX_FSCONTEXT, *PMINIX_FSCONTEXT;
|
||||
|
||||
NTSTATUS STDCALL MinixCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL MinixClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL MinixDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
||||
ULONG MinixNewInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
struct minix_inode* new_inode);
|
||||
NTSTATUS MinixWriteInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino,
|
||||
struct minix_inode* result);
|
||||
NTSTATUS MinixReadInode(PDEVICE_OBJECT DeviceObject,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino,
|
||||
struct minix_inode* result);
|
||||
NTSTATUS MinixDeleteInode(PDEVICE_OBJECT Volume,
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt,
|
||||
ULONG ino);
|
||||
|
||||
NTSTATUS MinixReadBlock(PDEVICE_OBJECT DeviceObject,
|
||||
PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||
struct minix_inode* inode,
|
||||
ULONG FileOffset,
|
||||
PULONG DiskOffset);
|
||||
|
||||
BOOLEAN MinixReadPage(PDEVICE_OBJECT DeviceObject,
|
||||
ULONG Offset,
|
||||
PVOID Buffer);
|
7
rosapps/drivers/ramdrv/minix/minix.rc
Normal file
7
rosapps/drivers/ramdrv/minix/minix.rc
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* $Id$ */
|
||||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Minix IFS Driver\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "minix\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "minix.sys\0"
|
||||
#include <reactos/version.rc>
|
80
rosapps/drivers/ramdrv/minix/minix_fs.h
Normal file
80
rosapps/drivers/ramdrv/minix/minix_fs.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
#define MINIX_ROOT_INO 1
|
||||
|
||||
/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
|
||||
#define MINIX_LINK_MAX 250
|
||||
|
||||
#define MINIX_I_MAP_SLOTS 8
|
||||
#define MINIX_Z_MAP_SLOTS 64
|
||||
#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
|
||||
#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
|
||||
#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
|
||||
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
|
||||
#define MINIX_VALID_FS 0x0001 /* Clean fs. */
|
||||
#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
|
||||
|
||||
#define MINIX_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix_inode)))
|
||||
#define MINIX2_INODES_PER_BLOCK ((BLOCKSIZE)/(sizeof (struct minix2_inode)))
|
||||
|
||||
#define MINIX_V1 0x0001 /* original minix fs */
|
||||
#define MINIX_V2 0x0002 /* minix V2 fs */
|
||||
|
||||
|
||||
/*
|
||||
* This is the original minix inode layout on disk.
|
||||
* Note the 8-bit gid and atime and ctime.
|
||||
*/
|
||||
struct minix_inode {
|
||||
unsigned short int i_mode;
|
||||
unsigned short int i_uid;
|
||||
unsigned long i_size;
|
||||
unsigned long i_time;
|
||||
unsigned char i_gid;
|
||||
unsigned char i_nlinks;
|
||||
unsigned short int i_zone[9];
|
||||
};
|
||||
|
||||
/*
|
||||
* The new minix inode has all the time entries, as well as
|
||||
* long block numbers and a third indirect block (7+1+1+1
|
||||
* instead of 7+1+1). Also, some previously 8-bit values are
|
||||
* now 16-bit. The inode is now 64 bytes instead of 32.
|
||||
*/
|
||||
struct minix2_inode {
|
||||
unsigned short int i_mode;
|
||||
unsigned short int i_nlinks;
|
||||
unsigned short int i_uid;
|
||||
unsigned short int i_gid;
|
||||
unsigned long i_size;
|
||||
unsigned long i_atime;
|
||||
unsigned long i_mtime;
|
||||
unsigned long i_ctime;
|
||||
unsigned long i_zone[10];
|
||||
};
|
||||
|
||||
/*
|
||||
* minix super-block data on disk
|
||||
*/
|
||||
struct minix_super_block {
|
||||
unsigned short int s_ninodes;
|
||||
unsigned short int s_nzones;
|
||||
unsigned short int s_imap_blocks;
|
||||
unsigned short int s_zmap_blocks;
|
||||
unsigned short int s_firstdatazone;
|
||||
unsigned short int s_log_zone_size;
|
||||
unsigned long s_max_size;
|
||||
unsigned short int s_magic;
|
||||
unsigned short int s_state;
|
||||
unsigned long s_zones;
|
||||
};
|
||||
|
||||
struct minix_dir_entry {
|
||||
unsigned short int inode;
|
||||
char name[0];
|
||||
};
|
||||
#define MINIX_DIR_ENTRY_SIZE (sizeof(struct minix_dir_entry)+30)
|
||||
|
||||
BOOLEAN MinixReadSector(IN PDEVICE_OBJECT pDeviceObject,
|
||||
IN ULONG DiskSector,
|
||||
IN UCHAR* Buffer);
|
||||
|
||||
#define BLOCKSIZE (1024)
|
160
rosapps/drivers/ramdrv/minix/mount.c
Normal file
160
rosapps/drivers/ramdrv/minix/mount.c
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2000 David Welch <welch@cwcom.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/minix.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <ntifs.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static PDRIVER_OBJECT DriverObject;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
VOID MinixMount(PDEVICE_OBJECT DeviceToMount)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt;
|
||||
|
||||
IoCreateDevice(DriverObject,
|
||||
sizeof(MINIX_DEVICE_EXTENSION),
|
||||
NULL,
|
||||
FILE_DEVICE_FILE_SYSTEM,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||
DeviceExt = DeviceObject->DeviceExtension;
|
||||
|
||||
MinixReadSector(DeviceToMount,1,DeviceExt->superblock_buf);
|
||||
DeviceExt->sb = (struct minix_super_block *)(DeviceExt->superblock_buf);
|
||||
|
||||
DeviceExt->StorageDevice = DeviceToMount;
|
||||
DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
|
||||
DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
|
||||
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
|
||||
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
|
||||
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
DeviceExt->FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||
NTSTATUS Status;
|
||||
char* superblock_buf;
|
||||
struct minix_super_block* sb;
|
||||
|
||||
DbgPrint("MinixFileSystemControl(DeviceObject %x, Irp %x)\n",DeviceObject,
|
||||
Irp);
|
||||
DPRINT("DeviceToMount %x\n",DeviceToMount);
|
||||
|
||||
superblock_buf = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
||||
|
||||
DPRINT("MinixReadSector %x\n",MinixReadSector);
|
||||
MinixReadSector(DeviceToMount,1,superblock_buf);
|
||||
sb = (struct minix_super_block *)superblock_buf;
|
||||
DPRINT("Magic %x\n",sb->s_magic);
|
||||
DPRINT("Imap blocks %x\n",sb->s_imap_blocks);
|
||||
DPRINT("Zmap blocks %x\n",sb->s_zmap_blocks);
|
||||
if (sb->s_magic==MINIX_SUPER_MAGIC2)
|
||||
{
|
||||
DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__);
|
||||
MinixMount(DeviceToMount);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("%s() = STATUS_UNRECOGNIZED_VOLUME\n",__FUNCTION__);
|
||||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initalize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
NTSTATUS ret;
|
||||
UNICODE_STRING DeviceName;
|
||||
|
||||
DbgPrint("Minix FSD 0.0.1\n");
|
||||
|
||||
DriverObject = _DriverObject;
|
||||
|
||||
RtlInitUnicodeString(&DeviceName,
|
||||
L"\\Device\\Minix");
|
||||
ret = IoCreateDevice(DriverObject,
|
||||
0,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_FILE_SYSTEM,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(ret))
|
||||
{
|
||||
return(ret);
|
||||
}
|
||||
|
||||
DeviceObject->Flags = 0;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MinixClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = MinixCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = MinixRead;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = MinixWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||
MinixFileSystemControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||
MinixDirectoryControl;
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
IoRegisterFileSystem(DeviceObject);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
162
rosapps/drivers/ramdrv/minix/rw.c
Normal file
162
rosapps/drivers/ramdrv/minix/rw.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/fs/minix/rw.c
|
||||
* PURPOSE: Minix FSD
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <string.h>
|
||||
#include <ntos/minmax.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "minix.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
DPRINT("MinixWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
static NTSTATUS MinixReadFilePage(PDEVICE_OBJECT DeviceObject,
|
||||
PMINIX_DEVICE_EXTENSION DeviceExt,
|
||||
PMINIX_FSCONTEXT FsContext,
|
||||
ULONG Offset,
|
||||
PVOID* Buffer)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
ULONG DiskOffset;
|
||||
|
||||
*Buffer = ExAllocatePool(NonPagedPool, 4096);
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
Status = MinixReadBlock(DeviceObject,
|
||||
DeviceExt,
|
||||
&FsContext->inode,
|
||||
Offset + (i * BLOCKSIZE),
|
||||
&DiskOffset);
|
||||
MinixReadSector(DeviceObject,
|
||||
DiskOffset / BLOCKSIZE,
|
||||
(*Buffer) + (i * BLOCKSIZE));
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
MinixRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG Offset;
|
||||
ULONG CurrentOffset;
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||
MINIX_DEVICE_EXTENSION* DeviceExt = DeviceObject->DeviceExtension;
|
||||
PMINIX_FSCONTEXT FsContext = (PMINIX_FSCONTEXT)FileObject->FsContext;
|
||||
unsigned int i;
|
||||
PVOID DiskBuffer;
|
||||
|
||||
DPRINT("MinixRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
Length = Stack->Parameters.Read.Length;
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
|
||||
|
||||
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
|
||||
|
||||
CurrentOffset=Offset;
|
||||
|
||||
DPRINT("inode->i_size %d\n",inode->i_size);
|
||||
|
||||
if (Offset > FsContext->inode.i_size)
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if ((Offset+Length) > FsContext->inode.i_size)
|
||||
{
|
||||
Length = FsContext->inode.i_size - Offset;
|
||||
}
|
||||
|
||||
if ((Offset%PAGE_SIZE)!=0)
|
||||
{
|
||||
CurrentOffset = Offset - (Offset%PAGE_SIZE);
|
||||
|
||||
MinixReadFilePage(DeviceObject,
|
||||
DeviceExt,
|
||||
FsContext,
|
||||
CurrentOffset,
|
||||
&DiskBuffer);
|
||||
|
||||
memcpy(Buffer,
|
||||
DiskBuffer+(Offset%PAGE_SIZE),
|
||||
min(PAGE_SIZE - (Offset%PAGE_SIZE),Length));
|
||||
|
||||
ExFreePool(DiskBuffer);
|
||||
|
||||
DPRINT("(BLOCKSIZE - (Offset%BLOCKSIZE)) %d\n",
|
||||
(BLOCKSIZE - (Offset%BLOCKSIZE)));
|
||||
DPRINT("Length %d\n",Length);
|
||||
CurrentOffset = CurrentOffset + PAGE_SIZE;
|
||||
Buffer = Buffer + PAGE_SIZE - (Offset%PAGE_SIZE);
|
||||
Length = Length - min(PAGE_SIZE - (Offset%PAGE_SIZE),Length);
|
||||
DPRINT("CurrentOffset %d Buffer %x Length %d\n",CurrentOffset,Buffer,
|
||||
Length);
|
||||
}
|
||||
for (i=0;i<(Length/PAGE_SIZE);i++)
|
||||
{
|
||||
CHECKPOINT;
|
||||
|
||||
DPRINT("Length %d\n",Length);
|
||||
|
||||
MinixReadFilePage(DeviceObject,
|
||||
DeviceExt,
|
||||
FsContext,
|
||||
CurrentOffset,
|
||||
&DiskBuffer);
|
||||
memcpy(Buffer, DiskBuffer, PAGE_SIZE);
|
||||
|
||||
ExFreePool(DiskBuffer);
|
||||
|
||||
CurrentOffset = CurrentOffset + PAGE_SIZE;
|
||||
Buffer = Buffer + PAGE_SIZE;
|
||||
}
|
||||
if ((Length%PAGE_SIZE) > 0)
|
||||
{
|
||||
CHECKPOINT;
|
||||
|
||||
DPRINT("Length %x Buffer %x\n",(Length%PAGE_SIZE),Buffer);
|
||||
|
||||
MinixReadFilePage(DeviceObject,
|
||||
DeviceExt,
|
||||
FsContext,
|
||||
CurrentOffset,
|
||||
&DiskBuffer);
|
||||
|
||||
memcpy(Buffer, DiskBuffer, (Length%PAGE_SIZE));
|
||||
|
||||
ExFreePool(DiskBuffer);
|
||||
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = Length;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
242
rosapps/drivers/ramdrv/ramdrv.c
Normal file
242
rosapps/drivers/ramdrv/ramdrv.c
Normal file
|
@ -0,0 +1,242 @@
|
|||
#include <ntddk.h>
|
||||
#include <ntdddisk.h>
|
||||
#include "ramdrv.h"
|
||||
#include <debug.h>
|
||||
#include "bzlib.h"
|
||||
|
||||
static NTSTATUS STDCALL RamdrvDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IrpStack;
|
||||
ULONG ControlCode, InputLength, OutputLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("RamdrvDispatchDeviceControl\n");
|
||||
|
||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
|
||||
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
|
||||
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
switch (ControlCode)
|
||||
{
|
||||
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||||
if (OutputLength < sizeof(DISK_GEOMETRY))
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
PDISK_GEOMETRY Geometry = Irp->AssociatedIrp.SystemBuffer;
|
||||
Geometry->MediaType = F3_1Pt44_512;
|
||||
Geometry->Cylinders.QuadPart = 80;
|
||||
Geometry->TracksPerCylinder = 2 * 18;
|
||||
Geometry->SectorsPerTrack = 18;
|
||||
Geometry->BytesPerSector = 512;
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
}
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS STDCALL RamdrvDispatchReadWrite(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PRAMDRV_DEVICE_EXTENSION devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION Stk = IoGetCurrentIrpStackLocation( Irp );
|
||||
|
||||
if( Stk->Parameters.Read.ByteOffset.u.HighPart ||
|
||||
Stk->Parameters.Read.ByteOffset.u.LowPart >= devext->Size )
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_END_OF_FILE;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest( Irp, 0 );
|
||||
return STATUS_END_OF_FILE;
|
||||
}
|
||||
if( (Stk->Parameters.Read.ByteOffset.u.LowPart + Stk->Parameters.Read.Length) > devext->Size )
|
||||
Stk->Parameters.Read.Length = devext->Size - Stk->Parameters.Read.ByteOffset.u.LowPart;
|
||||
if( Stk->MajorFunction == IRP_MJ_READ )
|
||||
RtlCopyMemory( MmGetSystemAddressForMdl( Irp->MdlAddress ),
|
||||
(PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
|
||||
Stk->Parameters.Read.Length );
|
||||
else RtlCopyMemory( (PVOID)((ULONG_PTR)devext->Buffer + Stk->Parameters.Read.ByteOffset.u.LowPart),
|
||||
MmGetSystemAddressForMdl( Irp->MdlAddress ),
|
||||
Stk->Parameters.Read.Length );
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = Stk->Parameters.Read.Length;
|
||||
IoCompleteRequest( Irp, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS STDCALL RamdrvDispatchOpenClose(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
DPRINT("RamdrvDispatchOpenClose\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Ramdisk");
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PRAMDRV_DEVICE_EXTENSION devext;
|
||||
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\??\\Z:");
|
||||
UNICODE_STRING ImageName = RTL_CONSTANT_STRING(L"\\Device\\Floppy0\\ramdisk.bz2");
|
||||
HANDLE file;
|
||||
OBJECT_ATTRIBUTES objattr;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
LARGE_INTEGER allocsize;
|
||||
HANDLE event;
|
||||
void *tbuff;
|
||||
unsigned int dstlen = 1024 * 1440;
|
||||
FILE_STANDARD_INFORMATION finfo;
|
||||
ULONG err;
|
||||
|
||||
DPRINT("Ramdisk driver\n");
|
||||
|
||||
/* Export other driver entry points... */
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = RamdrvDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = RamdrvDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = RamdrvDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = RamdrvDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RamdrvDispatchDeviceControl;
|
||||
|
||||
|
||||
// create device and symbolic link
|
||||
Status = IoCreateDevice( DriverObject,
|
||||
sizeof( RAMDRV_DEVICE_EXTENSION ),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_DISK,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject );
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
return Status;
|
||||
DeviceObject->Flags |= DO_DIRECT_IO;
|
||||
devext = (PRAMDRV_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
devext->Size = 1440 * 1024;
|
||||
devext->Buffer = ExAllocatePool( PagedPool, devext->Size );
|
||||
if( !devext->Buffer )
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleandevice;
|
||||
}
|
||||
IoCreateSymbolicLink( &LinkName, &DeviceName );
|
||||
|
||||
InitializeObjectAttributes( &objattr,
|
||||
&ImageName,
|
||||
0,
|
||||
0,
|
||||
0 );
|
||||
allocsize.u.LowPart = allocsize.u.HighPart = 0;
|
||||
|
||||
Status = ZwOpenFile( &file,
|
||||
GENERIC_READ,
|
||||
&objattr,
|
||||
&iosb,
|
||||
FILE_SHARE_READ,
|
||||
FILE_NO_INTERMEDIATE_BUFFERING );
|
||||
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DPRINT( "Failed to open floppy\n" );
|
||||
goto cleanbuffer;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes( &objattr,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0 );
|
||||
Status = ZwCreateEvent( &event,
|
||||
0,
|
||||
&objattr,
|
||||
NotificationEvent,
|
||||
FALSE );
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DPRINT( "Failed to create event\n" );
|
||||
goto cleanfile;
|
||||
}
|
||||
|
||||
Status = ZwQueryInformationFile( file,
|
||||
&iosb,
|
||||
&finfo,
|
||||
sizeof( finfo ),
|
||||
FileStandardInformation );
|
||||
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DPRINT1( "Failed to query file information\n" );
|
||||
goto cleanevent;
|
||||
}
|
||||
tbuff = ExAllocatePool( PagedPool, finfo.EndOfFile.u.LowPart );
|
||||
if( !tbuff )
|
||||
{
|
||||
DPRINT1( "Failed to allocate buffer of size %d\n", finfo.EndOfFile.u.LowPart );
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanevent;
|
||||
}
|
||||
|
||||
Status = ZwReadFile( file,
|
||||
event,
|
||||
0,
|
||||
0,
|
||||
&iosb,
|
||||
tbuff,
|
||||
finfo.EndOfFile.u.LowPart,
|
||||
&allocsize,
|
||||
0 );
|
||||
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DPRINT( "Failed to read floppy\n" );
|
||||
goto cleantbuff;
|
||||
}
|
||||
Status = ZwWaitForSingleObject( event, FALSE, 0 );
|
||||
if( Status != STATUS_WAIT_0 || !NT_SUCCESS( iosb.Status ) )
|
||||
{
|
||||
DPRINT( "Failed to read floppy\n" );
|
||||
goto cleantbuff;
|
||||
}
|
||||
DPRINT( "RAMDRV: Read in %d bytes, decompressing now\n", iosb.Information );
|
||||
err = BZ2_bzBuffToBuffDecompress( devext->Buffer,
|
||||
&dstlen,
|
||||
tbuff,
|
||||
iosb.Information,
|
||||
1,
|
||||
0 );
|
||||
if( err == 0 )
|
||||
{
|
||||
DPRINT( "RAMDRV: Image Decompressed\n");
|
||||
}
|
||||
else DbgPrint( "RAMDRV: Failed to decomparess image, error: %d\n", err );
|
||||
ExFreePool( tbuff );
|
||||
ZwClose( file );
|
||||
ZwClose( event );
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
cleantbuff:
|
||||
ExFreePool( tbuff );
|
||||
cleanevent:
|
||||
ZwClose( event );
|
||||
cleanfile:
|
||||
ZwClose( file );
|
||||
cleanbuffer:
|
||||
ExFreePool( devext->Buffer );
|
||||
|
||||
cleandevice:
|
||||
IoDeleteDevice( DeviceObject );
|
||||
for(;;);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
8
rosapps/drivers/ramdrv/ramdrv.h
Normal file
8
rosapps/drivers/ramdrv/ramdrv.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
typedef struct _RAMDRV_DEVICE_EXTENSION {
|
||||
void *Buffer;
|
||||
unsigned long Size;
|
||||
} RAMDRV_DEVICE_EXTENSION, *PRAMDRV_DEVICE_EXTENSION;
|
||||
|
||||
NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath);
|
||||
|
9
rosapps/drivers/ramdrv/ramdrv.rbuild
Normal file
9
rosapps/drivers/ramdrv/ramdrv.rbuild
Normal file
|
@ -0,0 +1,9 @@
|
|||
<module name="ramdrv" type="kernelmodedriver">
|
||||
<include base="ramdrv">.</include>
|
||||
<include base="bzip2">.</include>
|
||||
<library>ntoskrnl</library>
|
||||
<library>hal</library>
|
||||
<library>bzip2</library>
|
||||
<file>ramdrv.c</file>
|
||||
<file>ramdrv.rc</file>
|
||||
</module>
|
5
rosapps/drivers/ramdrv/ramdrv.rc
Normal file
5
rosapps/drivers/ramdrv/ramdrv.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "RAM Disk Device Driver\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "ramdrv\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "ramdrv.sys\0"
|
||||
#include <reactos/version.rc>
|
Loading…
Add table
Add a link
Reference in a new issue