mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 07:13:23 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
2
drivers/parallel/CMakeLists.txt
Normal file
2
drivers/parallel/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
add_subdirectory(parport)
|
4
drivers/parallel/parallel/CMakeLists.txt
Normal file
4
drivers/parallel/parallel/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
add_library(parallel SHARED parallel.c parallel.rc)
|
||||
set_module_type(parallel kernelmodedriver)
|
||||
add_importlibs(parallel ntoskrnl hal)
|
159
drivers/parallel/parallel/parallel.c
Normal file
159
drivers/parallel/parallel/parallel.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/parallel/parallel.c
|
||||
* PURPOSE: Parallel port driver
|
||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||
* UPDATE HISTORY:
|
||||
* ??/??/??: Created
|
||||
* 18/06/98: Made more NT like
|
||||
*/
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
#include <wdm.h>
|
||||
|
||||
#include "parallel.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#define LP_B (0x378)
|
||||
#define LP_S (READ_PORT_UCHAR((PUCHAR)(LP_B+1)))
|
||||
#define LP_C (LP_B+2)
|
||||
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
|
||||
|
||||
static void Parallel_Reset(void)
|
||||
/*
|
||||
* FUNCTION: Resets the device attached to the parallel port
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)LP_C,0);
|
||||
for (i=0;i<LP_DELAY;i++);
|
||||
WRITE_PORT_UCHAR((PUCHAR)LP_C,LP_PSELECP | LP_PINITP);
|
||||
}
|
||||
|
||||
static void Parallel_putchar(unsigned char ch)
|
||||
/*
|
||||
* FUNCTION: Writes a character to the parallel port
|
||||
* ARGUMENTS:
|
||||
* ch = character to write
|
||||
*/
|
||||
{
|
||||
|
||||
int count=0;
|
||||
int status;
|
||||
int wait=0;
|
||||
|
||||
do
|
||||
{
|
||||
status=LP_S;
|
||||
count++;
|
||||
}
|
||||
while ( count < 500000 && !(status & LP_PBUSY) );
|
||||
|
||||
if (count==500000)
|
||||
{
|
||||
DPRINT("printer_putchar(): timed out\n");
|
||||
return;
|
||||
}
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)LP_B,ch);
|
||||
while (wait != 10000) { wait++; }
|
||||
WRITE_PORT_UCHAR((PUCHAR)LP_C, (LP_PSELECP | LP_PINITP | LP_PSTROBE ));
|
||||
while (wait) { wait--; }
|
||||
WRITE_PORT_UCHAR((PUCHAR)LP_C, LP_PSELECP | LP_PINITP);
|
||||
}
|
||||
|
||||
static DRIVER_DISPATCH Dispatch;
|
||||
static NTSTATUS NTAPI
|
||||
Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS status;
|
||||
ULONG i;
|
||||
|
||||
switch (Stack->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
DPRINT("(Parallel Port Driver) Creating\n");
|
||||
Parallel_Reset();
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_WRITE:
|
||||
DPRINT("(Parallel Port Driver) Writing %d bytes\n",
|
||||
Stack->Parameters.Write.Length);
|
||||
for (i=0;i<Stack->Parameters.Write.Length;i++)
|
||||
{
|
||||
Parallel_putchar(((char *)Irp->UserBuffer)[i]);
|
||||
}
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return(status);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initialize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Parallel");
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Parallel Port Driver 0.0.1\n");
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
0,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_PARALLEL_PORT,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DeviceObject->Flags=0;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
|
||||
DriverObject->DriverUnload = NULL;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
134
drivers/parallel/parallel/parallel.h
Normal file
134
drivers/parallel/parallel/parallel.h
Normal file
|
@ -0,0 +1,134 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
* usr/include/linux/lp.h c.1991-1992 James Wiegand
|
||||
* many modifications copyright (C) 1992 Michael K. Johnson
|
||||
* Interrupt support added 1993 Nigel Gamble
|
||||
*/
|
||||
|
||||
/*
|
||||
* Per POSIX guidelines, this module reserves the LP and lp prefixes
|
||||
* These are the lp_table[minor].flags flags...
|
||||
*/
|
||||
#define LP_EXIST 0x0001
|
||||
#define LP_SELEC 0x0002
|
||||
#define LP_BUSY 0x0004
|
||||
#define LP_OFFL 0x0008
|
||||
#define LP_NOPA 0x0010
|
||||
#define LP_ERR 0x0020
|
||||
#define LP_ABORT 0x0040
|
||||
#define LP_CAREFUL 0x0080
|
||||
#define LP_ABORTOPEN 0x0100
|
||||
|
||||
/* timeout for each character. This is relative to bus cycles -- it
|
||||
* is the count in a busy loop. THIS IS THE VALUE TO CHANGE if you
|
||||
* have extremely slow printing, or if the machine seems to slow down
|
||||
* a lot when you print. If you have slow printing, increase this
|
||||
* number and recompile, and if your system gets bogged down, decrease
|
||||
* this number. This can be changed with the tunelp(8) command as well.
|
||||
*/
|
||||
|
||||
#define LP_INIT_CHAR 1000
|
||||
|
||||
/* The parallel port specs apparently say that there needs to be
|
||||
* a .5usec wait before and after the strobe. Since there are wildly
|
||||
* different computers running linux, I can't come up with a perfect
|
||||
* value, but since it worked well on most printers before without,
|
||||
* I'll initialize it to 0.
|
||||
*/
|
||||
|
||||
#define LP_INIT_WAIT 0
|
||||
|
||||
/* This is the amount of time that the driver waits for the printer to
|
||||
* catch up when the printer's buffer appears to be filled. If you
|
||||
* want to tune this and have a fast printer (i.e. HPIIIP), decrease
|
||||
* this number, and if you have a slow printer, increase this number.
|
||||
* This is in hundredths of a second, the default 2 being .05 second.
|
||||
* Or use the tunelp(8) command, which is especially nice if you want
|
||||
* change back and forth between character and graphics printing, which
|
||||
* are wildly different...
|
||||
*/
|
||||
|
||||
#define LP_INIT_TIME 2
|
||||
|
||||
/* IOCTL numbers */
|
||||
#define LPCHAR 0x0601 /* corresponds to LP_INIT_CHAR */
|
||||
#define LPTIME 0x0602 /* corresponds to LP_INIT_TIME */
|
||||
#define LPABORT 0x0604 /* call with TRUE arg to abort on error,
|
||||
FALSE to retry. Default is retry. */
|
||||
#define LPSETIRQ 0x0605 /* call with new IRQ number,
|
||||
or 0 for polling (no IRQ) */
|
||||
#define LPGETIRQ 0x0606 /* get the current IRQ number */
|
||||
#define LPWAIT 0x0608 /* corresponds to LP_INIT_WAIT */
|
||||
#define LPCAREFUL 0x0609 /* call with TRUE arg to require out-of-paper, off-
|
||||
line, and error indicators good on all writes,
|
||||
FALSE to ignore them. Default is ignore. */
|
||||
#define LPABORTOPEN 0x060a /* call with TRUE arg to abort open() on error,
|
||||
FALSE to ignore error. Default is ignore. */
|
||||
#define LPGETSTATUS 0x060b /* return LP_S(minor) */
|
||||
#define LPRESET 0x060c /* reset printer */
|
||||
|
||||
/* timeout for printing a timeout, in jiffies (100ths of a second).
|
||||
This is also used for re-checking error conditions if LP_ABORT is
|
||||
not set. This is the default behavior. */
|
||||
|
||||
#define LP_TIMEOUT_INTERRUPT (60 * HZ)
|
||||
#define LP_TIMEOUT_POLLED (10 * HZ)
|
||||
|
||||
#if 0
|
||||
#define LP_B(minor) lp_table[(minor)].base /* IO address */
|
||||
#define LP_F(minor) lp_table[(minor)].flags /* flags for busy, etc. */
|
||||
#define LP_S(minor) inb_p(LP_B((minor)) + 1) /* status port */
|
||||
#define LP_C(minor) (lp_table[(minor)].base + 2) /* control port */
|
||||
#define LP_CHAR(minor) lp_table[(minor)].chars /* busy timeout */
|
||||
#define LP_TIME(minor) lp_table[(minor)].time /* wait time */
|
||||
#define LP_WAIT(minor) lp_table[(minor)].wait /* strobe wait */
|
||||
#define LP_IRQ(minor) lp_table[(minor)].irq /* interrupt # */
|
||||
/* 0 means polled */
|
||||
#endif
|
||||
|
||||
#define LP_BUFFER_SIZE 256
|
||||
|
||||
|
||||
/*
|
||||
* The following constants describe the various signals of the printer port
|
||||
* hardware. Note that the hardware inverts some signals and that some
|
||||
* signals are active low. An example is LP_STROBE, which must be programmed
|
||||
* with 1 for being active and 0 for being inactive, because the strobe signal
|
||||
* gets inverted, but it is also active low.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bit defines for 8255 status port
|
||||
* base + 1
|
||||
* accessed with LP_S(minor), which gets the byte...
|
||||
*/
|
||||
#define LP_PBUSY 0x80 /* inverted input, active high */
|
||||
#define LP_PACK 0x40 /* unchanged input, active low */
|
||||
#define LP_POUTPA 0x20 /* unchanged input, active high */
|
||||
#define LP_PSELECD 0x10 /* unchanged input, active high */
|
||||
#define LP_PERRORP 0x08 /* unchanged input, active low */
|
||||
|
||||
/*
|
||||
* defines for 8255 control port
|
||||
* base + 2
|
||||
* accessed with LP_C(minor)
|
||||
*/
|
||||
#define LP_PINTEN 0x10
|
||||
#define LP_PSELECP 0x08 /* inverted output, active low */
|
||||
#define LP_PINITP 0x04 /* unchanged output, active low */
|
||||
#define LP_PAUTOLF 0x02 /* inverted output, active low */
|
||||
#define LP_PSTROBE 0x01 /* inverted output, active low */
|
||||
|
||||
/*
|
||||
* the value written to ports to test existence. PC-style ports will
|
||||
* return the value written. AT-style ports will return 0. so why not
|
||||
* make them the same ?
|
||||
*/
|
||||
#define LP_DUMMY 0x00
|
||||
|
||||
/*
|
||||
* This is the port delay time. Your mileage may vary.
|
||||
* It is used only in the lp_init() routine.
|
||||
*/
|
||||
#define LP_DELAY 150000
|
5
drivers/parallel/parallel/parallel.rc
Normal file
5
drivers/parallel/parallel/parallel.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Parallel Port Device Driver"
|
||||
#define REACTOS_STR_INTERNAL_NAME "parallel"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "parallel.sys"
|
||||
#include <reactos/version.rc>
|
0
drivers/parallel/parclass/.gitignore
vendored
Normal file
0
drivers/parallel/parclass/.gitignore
vendored
Normal file
0
drivers/parallel/parport/.gitignore
vendored
Normal file
0
drivers/parallel/parport/.gitignore
vendored
Normal file
16
drivers/parallel/parport/CMakeLists.txt
Normal file
16
drivers/parallel/parport/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
fdo.c
|
||||
misc.c
|
||||
pdo.c
|
||||
parport.c
|
||||
parport.h)
|
||||
|
||||
add_library(parport SHARED
|
||||
${SOURCE}
|
||||
parport.rc)
|
||||
|
||||
set_module_type(parport kernelmodedriver)
|
||||
add_pch(parport parport.h SOURCE)
|
||||
add_importlibs(parport ntoskrnl hal)
|
||||
add_cd_file(TARGET parport DESTINATION reactos/system32/drivers FOR all)
|
613
drivers/parallel/parport/fdo.c
Normal file
613
drivers/parallel/parport/fdo.c
Normal file
|
@ -0,0 +1,613 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* FILE: drivers/parallel/parport/fdo.c
|
||||
* PURPOSE: FDO functions
|
||||
*/
|
||||
|
||||
#include "parport.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
AddDeviceInternal(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo,
|
||||
IN PULONG pLptPortNumber OPTIONAL,
|
||||
OUT PDEVICE_OBJECT* pFdo OPTIONAL)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension = NULL;
|
||||
PDEVICE_OBJECT Fdo = NULL;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("AddDeviceInternal()\n");
|
||||
|
||||
ASSERT(DriverObject);
|
||||
ASSERT(Pdo);
|
||||
|
||||
/* Create new device object */
|
||||
swprintf(DeviceNameBuffer,
|
||||
L"\\Device\\ParallelPort%lu",
|
||||
IoGetConfigurationInformation()->ParallelCount);
|
||||
RtlInitUnicodeString(&DeviceName,
|
||||
DeviceNameBuffer);
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(FDO_DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_PARALLEL_PORT,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoCreateDevice() failed (Status 0x%08lx)\n", Status);
|
||||
Fdo = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
|
||||
RtlZeroMemory(DeviceExtension,
|
||||
sizeof(FDO_DEVICE_EXTENSION));
|
||||
|
||||
DeviceExtension->Common.IsFDO = TRUE;
|
||||
DeviceExtension->Common.PnpState = dsStopped;
|
||||
|
||||
DeviceExtension->PortNumber = IoGetConfigurationInformation()->ParallelCount++;
|
||||
DeviceExtension->Pdo = Pdo;
|
||||
|
||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo,
|
||||
Pdo,
|
||||
&DeviceExtension->LowerDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoAttachDeviceToDeviceStackSafe() failed (Status 0x%08lx)\n", Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (DeviceExtension->LowerDevice->Flags & DO_POWER_PAGABLE)
|
||||
Fdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
if (DeviceExtension->LowerDevice->Flags & DO_BUFFERED_IO)
|
||||
Fdo->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
if (DeviceExtension->LowerDevice->Flags & DO_DIRECT_IO)
|
||||
Fdo->Flags |= DO_DIRECT_IO;
|
||||
|
||||
/* Choose default strategy */
|
||||
if ((Fdo->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO)) == 0)
|
||||
Fdo->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
if (pFdo)
|
||||
{
|
||||
*pFdo = Fdo;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
done:
|
||||
if (Fdo)
|
||||
{
|
||||
IoDeleteDevice(Fdo);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoStartDevice(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PCM_RESOURCE_LIST ResourceList,
|
||||
IN PCM_RESOURCE_LIST ResourceListTranslated)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG i;
|
||||
// ULONG Vector = 0;
|
||||
// KIRQL Dirql = 0;
|
||||
// KAFFINITY Affinity = 0;
|
||||
// KINTERRUPT_MODE InterruptMode = Latched;
|
||||
// BOOLEAN ShareInterrupt = TRUE;
|
||||
|
||||
DPRINT("FdoStartDevice ()\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
ASSERT(DeviceExtension);
|
||||
ASSERT(DeviceExtension->Common.IsFDO == TRUE);
|
||||
|
||||
if (!ResourceList)
|
||||
{
|
||||
DPRINT1("No allocated resources sent to driver\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if (ResourceList->Count != 1)
|
||||
{
|
||||
DPRINT1("Wrong number of allocated resources sent to driver\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
if ((ResourceList->List[0].PartialResourceList.Version != 1) ||
|
||||
(ResourceList->List[0].PartialResourceList.Revision != 1) ||
|
||||
(ResourceListTranslated->List[0].PartialResourceList.Version != 1) ||
|
||||
(ResourceListTranslated->List[0].PartialResourceList.Revision != 1))
|
||||
{
|
||||
DPRINT1("Revision mismatch: %u.%u != 1.1 or %u.%u != 1.1\n",
|
||||
ResourceList->List[0].PartialResourceList.Version,
|
||||
ResourceList->List[0].PartialResourceList.Revision,
|
||||
ResourceListTranslated->List[0].PartialResourceList.Version,
|
||||
ResourceListTranslated->List[0].PartialResourceList.Revision);
|
||||
return STATUS_REVISION_MISMATCH;
|
||||
}
|
||||
|
||||
DeviceExtension->BaseAddress = 0;
|
||||
|
||||
for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptorTranslated = &ResourceListTranslated->List[0].PartialResourceList.PartialDescriptors[i];
|
||||
|
||||
switch (PartialDescriptor->Type)
|
||||
{
|
||||
case CmResourceTypePort:
|
||||
DPRINT("Port: BaseAddress 0x%lx Length %lu\n",
|
||||
PartialDescriptor->u.Port.Start.u.LowPart,
|
||||
PartialDescriptor->u.Port.Length);
|
||||
|
||||
if (DeviceExtension->BaseAddress == 0)
|
||||
{
|
||||
if (PartialDescriptor->u.Port.Length < 4)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
DeviceExtension->BaseAddress = PartialDescriptor->u.Port.Start.u.LowPart;
|
||||
}
|
||||
break;
|
||||
|
||||
case CmResourceTypeInterrupt:
|
||||
DPRINT("Interrupt: Level %lu Vector %lu\n",
|
||||
PartialDescriptorTranslated->u.Interrupt.Level,
|
||||
PartialDescriptorTranslated->u.Interrupt.Vector);
|
||||
|
||||
// Dirql = (KIRQL)PartialDescriptorTranslated->u.Interrupt.Level;
|
||||
// Vector = PartialDescriptorTranslated->u.Interrupt.Vector;
|
||||
// Affinity = PartialDescriptorTranslated->u.Interrupt.Affinity;
|
||||
|
||||
// if (PartialDescriptorTranslated->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
|
||||
// InterruptMode = Latched;
|
||||
// else
|
||||
// InterruptMode = LevelSensitive;
|
||||
|
||||
// ShareInterrupt = (PartialDescriptorTranslated->ShareDisposition == CmResourceShareShared);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT1("Other resource: \n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("New LPT port: Base 0x%lx\n",
|
||||
DeviceExtension->BaseAddress);
|
||||
|
||||
if (!DeviceExtension->BaseAddress)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
#if 0
|
||||
if (!Dirql)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
#endif
|
||||
|
||||
DeviceExtension->Common.PnpState = dsStarted;
|
||||
|
||||
|
||||
/* We don't really care if the call succeeded or not... */
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
FdoCreateRawParallelPdo(
|
||||
IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension = NULL;
|
||||
PDEVICE_OBJECT Pdo = NULL;
|
||||
WCHAR DeviceNameBuffer[32];
|
||||
WCHAR LinkNameBuffer[32];
|
||||
WCHAR LptPortBuffer[32];
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING LinkName;
|
||||
UNICODE_STRING LptPort;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("FdoCreateRawParallelPdo()\n");
|
||||
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
/* Create new device object */
|
||||
swprintf(DeviceNameBuffer,
|
||||
L"\\Device\\Parallel%lu",
|
||||
FdoDeviceExtension->PortNumber);
|
||||
RtlInitUnicodeString(&DeviceName,
|
||||
DeviceNameBuffer);
|
||||
|
||||
Status = IoCreateDevice(DeviceObject->DriverObject,
|
||||
sizeof(PDO_DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
0,
|
||||
FALSE,
|
||||
&Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoCreateDevice() failed with status 0x%08x\n", Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||
Pdo->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
|
||||
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
|
||||
|
||||
PdoDeviceExtension->Common.IsFDO = FALSE;
|
||||
PdoDeviceExtension->Common.PnpState = dsStopped;
|
||||
|
||||
Pdo->StackSize = DeviceObject->StackSize + 1;
|
||||
|
||||
FdoDeviceExtension->AttachedRawPdo = Pdo;
|
||||
PdoDeviceExtension->AttachedFdo = DeviceObject;
|
||||
|
||||
PdoDeviceExtension->PortNumber = FdoDeviceExtension->PortNumber;
|
||||
PdoDeviceExtension->LptPort = PdoDeviceExtension->PortNumber + 1;
|
||||
|
||||
|
||||
/* Create link \DosDevices\LPTX -> \Device\ParallelY */
|
||||
swprintf(LinkNameBuffer, L"\\DosDevices\\LPT%lu", PdoDeviceExtension->LptPort);
|
||||
RtlInitUnicodeString(&LinkName, LinkNameBuffer);
|
||||
Status = IoCreateSymbolicLink(&LinkName,
|
||||
&DeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("IoCreateSymbolicLink() failed with status 0x%08x\n", Status);
|
||||
goto done;
|
||||
}
|
||||
|
||||
swprintf(LptPortBuffer, L"LPT%lu", PdoDeviceExtension->LptPort);
|
||||
RtlInitUnicodeString(&LptPort, LptPortBuffer);
|
||||
|
||||
/* Write an entry value under HKLM\HARDWARE\DeviceMap\PARALLEL PORTS. */
|
||||
/* This step is not mandatory, so do not exit in case of error. */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\HARDWARE\\DeviceMap\\PARALLEL PORTS");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ZwCreateKey(&KeyHandle,
|
||||
KEY_SET_VALUE,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_VOLATILE,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Key = \Device\Parallelx, Value = LPTx */
|
||||
ZwSetValueKey(KeyHandle,
|
||||
&DeviceName,
|
||||
0,
|
||||
REG_SZ,
|
||||
LptPortBuffer,
|
||||
LptPort.Length + sizeof(WCHAR));
|
||||
ZwClose(KeyHandle);
|
||||
}
|
||||
|
||||
Pdo->Flags |= DO_BUFFERED_IO;
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
done:
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Pdo)
|
||||
{
|
||||
ASSERT(PdoDeviceExtension);
|
||||
IoDeleteDevice(Pdo);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
FdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
ULONG Size;
|
||||
ULONG i;
|
||||
ULONG PdoCount = 0;
|
||||
NTSTATUS Status;
|
||||
|
||||
UNREFERENCED_PARAMETER(IrpSp);
|
||||
|
||||
DPRINT("FdoQueryBusRelations()\n");
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension->Common.IsFDO);
|
||||
|
||||
/* TODO: Enumerate parallel devices and create their PDOs */
|
||||
|
||||
Status = FdoCreateRawParallelPdo(DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
PdoCount++;
|
||||
|
||||
/* Allocate a buffer for the device relations */
|
||||
Size = sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (PdoCount - 1);
|
||||
DeviceRelations = ExAllocatePoolWithTag(PagedPool, Size, PARPORT_TAG);
|
||||
if (DeviceRelations == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Fill the buffer */
|
||||
i = 0;
|
||||
ObReferenceObject(DeviceExtension->AttachedRawPdo);
|
||||
DeviceRelations->Objects[i] = DeviceExtension->AttachedRawPdo;
|
||||
DeviceRelations->Count = 1;
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
|
||||
DPRINT("Done\n");
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* PUBLIC FUNCTIONS *********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
AddDevice(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
DPRINT("AddDevice(%p %p)\n", DriverObject, Pdo);
|
||||
|
||||
/* Serial.sys is a legacy driver. AddDevice is called once
|
||||
* with a NULL Pdo just after the driver initialization.
|
||||
* Detect this case and return success.
|
||||
*/
|
||||
if (Pdo == NULL)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* We have here a PDO not null. It represents a real serial
|
||||
* port. So call the internal AddDevice function.
|
||||
*/
|
||||
return AddDeviceInternal(DriverObject, Pdo, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("FdoCreate()\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
DPRINT1("Not a directory\n");
|
||||
Status = STATUS_NOT_A_DIRECTORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
DPRINT("Open parallel port %lu: successful\n", DeviceExtension->PortNumber);
|
||||
DeviceExtension->OpenCount++;
|
||||
|
||||
done:
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION pDeviceExtension;
|
||||
|
||||
DPRINT("FdoClose()\n");
|
||||
|
||||
pDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
pDeviceExtension->OpenCount--;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("FdoCleanup()\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("FdoRead()\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("FdoWrite()\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoPnp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = 0;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("FdoPnp()\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
/* FIXME: do all these minor functions
|
||||
IRP_MN_QUERY_REMOVE_DEVICE 0x1
|
||||
IRP_MN_REMOVE_DEVICE 0x2
|
||||
{
|
||||
TRACE_(SERIAL, "IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
|
||||
IoAcquireRemoveLock
|
||||
IoReleaseRemoveLockAndWait
|
||||
pass request to DeviceExtension-LowerDriver
|
||||
disable interface
|
||||
IoDeleteDevice(Fdo) and/or IoDetachDevice
|
||||
break;
|
||||
}
|
||||
IRP_MN_CANCEL_REMOVE_DEVICE 0x3
|
||||
IRP_MN_STOP_DEVICE 0x4
|
||||
IRP_MN_QUERY_STOP_DEVICE 0x5
|
||||
IRP_MN_CANCEL_STOP_DEVICE 0x6
|
||||
IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations (optional) 0x7
|
||||
IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations (optional) 0x7
|
||||
IRP_MN_QUERY_INTERFACE (optional) 0x8
|
||||
IRP_MN_QUERY_CAPABILITIES (optional) 0x9
|
||||
IRP_MN_FILTER_RESOURCE_REQUIREMENTS (optional) 0xd
|
||||
IRP_MN_QUERY_PNP_DEVICE_STATE (optional) 0x14
|
||||
IRP_MN_DEVICE_USAGE_NOTIFICATION (required or optional) 0x16
|
||||
IRP_MN_SURPRISE_REMOVAL 0x17
|
||||
*/
|
||||
case IRP_MN_START_DEVICE: /* 0x0 */
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
|
||||
ASSERT(((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.PnpState == dsStopped);
|
||||
|
||||
/* Call lower driver */
|
||||
Status = ForwardIrpAndWait(DeviceObject, Irp);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = FdoStartDevice(DeviceObject,
|
||||
Stack->Parameters.StartDevice.AllocatedResources,
|
||||
Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
}
|
||||
break;
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
|
||||
switch (Stack->Parameters.QueryDeviceRelations.Type)
|
||||
{
|
||||
case BusRelations:
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
|
||||
Status = FdoQueryBusRelations(DeviceObject, Irp, Stack);
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
|
||||
case RemovalRelations:
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
|
||||
default:
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
|
||||
Stack->Parameters.QueryDeviceRelations.Type);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
break;
|
||||
|
||||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0xd */
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
|
||||
default:
|
||||
DPRINT("Unknown minor function 0x%x\n", MinorFunction);
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = Information;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoPower(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
|
||||
DPRINT("FdoPower()\n");
|
||||
|
||||
LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(LowerDevice, Irp);
|
||||
}
|
||||
|
||||
/* EOF */
|
41
drivers/parallel/parport/hardware.h
Normal file
41
drivers/parallel/parport/hardware.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* FILE: drivers/parallel/parport/hardware.h
|
||||
* PURPOSE: Hardware definitions
|
||||
*/
|
||||
|
||||
#ifndef _HARDWARE_H_
|
||||
#define _HARDWARE_H_
|
||||
|
||||
/*
|
||||
* The following constants describe the various signals of the printer port
|
||||
* hardware. Note that the hardware inverts some signals and that some
|
||||
* signals are active low. An example is LP_STROBE, which must be programmed
|
||||
* with 1 for being active and 0 for being inactive, because the strobe signal
|
||||
* gets inverted, but it is also active low.
|
||||
*/
|
||||
|
||||
/*
|
||||
* bit defines for 8255 status port
|
||||
* base + 1
|
||||
* accessed with LP_S(minor), which gets the byte...
|
||||
*/
|
||||
#define LP_PBUSY 0x80 /* inverted input, active high */
|
||||
#define LP_PACK 0x40 /* unchanged input, active low */
|
||||
#define LP_POUTPA 0x20 /* unchanged input, active high */
|
||||
#define LP_PSELECD 0x10 /* unchanged input, active high */
|
||||
#define LP_PERRORP 0x08 /* unchanged input, active low */
|
||||
|
||||
/*
|
||||
* defines for 8255 control port
|
||||
* base + 2
|
||||
* accessed with LP_C(minor)
|
||||
*/
|
||||
#define LP_PINTEN 0x10
|
||||
#define LP_PSELECP 0x08 /* inverted output, active low */
|
||||
#define LP_PINITP 0x04 /* unchanged output, active low */
|
||||
#define LP_PAUTOLF 0x02 /* inverted output, active low */
|
||||
#define LP_PSTROBE 0x01 /* inverted output, active low */
|
||||
|
||||
#endif /* _HARDWARE_H_ */
|
86
drivers/parallel/parport/misc.c
Normal file
86
drivers/parallel/parport/misc.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* FILE: drivers/parallel/parport/misc.c
|
||||
* PURPOSE: Miscellaneous functions
|
||||
*/
|
||||
|
||||
#include "parport.h"
|
||||
|
||||
|
||||
static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ForwardIrpAndWaitCompletion(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PVOID Context)
|
||||
{
|
||||
if (Irp->PendingReturned)
|
||||
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
|
||||
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
|
||||
LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
ASSERT(LowerDevice);
|
||||
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
IoCopyCurrentIrpStackLocationToNext(Irp);
|
||||
|
||||
DPRINT("Calling lower device %p\n", LowerDevice);
|
||||
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
|
||||
|
||||
Status = IoCallDriver(LowerDevice, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = Irp->IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ForwardIrpAndForget(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
else
|
||||
LowerDevice = ((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedFdo;
|
||||
ASSERT(LowerDevice);
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(LowerDevice, Irp);
|
||||
}
|
||||
|
||||
|
||||
PVOID
|
||||
GetUserBuffer(IN PIRP Irp)
|
||||
{
|
||||
ASSERT(Irp);
|
||||
|
||||
if (Irp->MdlAddress)
|
||||
return Irp->MdlAddress;
|
||||
else
|
||||
return Irp->AssociatedIrp.SystemBuffer;
|
||||
}
|
||||
|
||||
/* EOF */
|
146
drivers/parallel/parport/parport.c
Normal file
146
drivers/parallel/parport/parport.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* PURPOSE: Parport driver loading/unloading
|
||||
*/
|
||||
|
||||
#include "parport.h"
|
||||
|
||||
static DRIVER_UNLOAD DriverUnload;
|
||||
static DRIVER_DISPATCH DispatchCreate;
|
||||
static DRIVER_DISPATCH DispatchClose;
|
||||
static DRIVER_DISPATCH DispatchCleanup;
|
||||
static DRIVER_DISPATCH DispatchPnp;
|
||||
static DRIVER_DISPATCH DispatchPower;
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static
|
||||
VOID
|
||||
NTAPI
|
||||
DriverUnload(IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
DPRINT("Parport DriverUnload\n");
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoCreate(DeviceObject, Irp);
|
||||
else
|
||||
return PdoCreate(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoClose(DeviceObject, Irp);
|
||||
else
|
||||
return PdoClose(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoCleanup(DeviceObject, Irp);
|
||||
else
|
||||
return PdoCleanup(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoRead(DeviceObject, Irp);
|
||||
else
|
||||
return PdoRead(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoWrite(DeviceObject, Irp);
|
||||
else
|
||||
return PdoWrite(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchPnp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoPnp(DeviceObject, Irp);
|
||||
else
|
||||
return PdoPnp(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchPower(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
if (((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
|
||||
return FdoPower(DeviceObject, Irp);
|
||||
else
|
||||
return PdoPower(DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegPath)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
DPRINT("Parport DriverEntry\n");
|
||||
|
||||
DriverObject->DriverUnload = DriverUnload;
|
||||
DriverObject->DriverExtension->AddDevice = AddDevice;
|
||||
|
||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||
DriverObject->MajorFunction[i] = ForwardIrpAndForget;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
|
||||
// DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
|
||||
// DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = DispatchQueryInformation;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
161
drivers/parallel/parport/parport.h
Normal file
161
drivers/parallel/parport/parport.h
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* FILE: drivers/parallel/parport/parport.h
|
||||
* PURPOSE: Parport driver header
|
||||
*/
|
||||
|
||||
#ifndef _PARPORT_PCH_
|
||||
#define _PARPORT_PCH_
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <ndk/haltypes.h>
|
||||
#include <ntddpar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
dsStopped,
|
||||
dsStarted,
|
||||
dsPaused,
|
||||
dsRemoved,
|
||||
dsSurpriseRemoved
|
||||
} DEVICE_STATE;
|
||||
|
||||
typedef struct _COMMON_DEVICE_EXTENSION
|
||||
{
|
||||
BOOLEAN IsFDO;
|
||||
DEVICE_STATE PnpState;
|
||||
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _FDO_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
|
||||
PDEVICE_OBJECT AttachedRawPdo;
|
||||
PDEVICE_OBJECT AttachedPdo[2];
|
||||
|
||||
ULONG PortNumber;
|
||||
|
||||
ULONG OpenCount;
|
||||
|
||||
ULONG BaseAddress;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _PDO_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
|
||||
PDEVICE_OBJECT AttachedFdo;
|
||||
|
||||
ULONG PortNumber;
|
||||
ULONG LptPort;
|
||||
|
||||
ULONG OpenCount;
|
||||
|
||||
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
#define PARPORT_TAG 'trpP'
|
||||
|
||||
/* fdo.c */
|
||||
|
||||
DRIVER_ADD_DEVICE AddDevice;
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoPnp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
FdoPower(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
|
||||
/* misc.c */
|
||||
|
||||
NTSTATUS
|
||||
ForwardIrpAndWait(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
DRIVER_DISPATCH ForwardIrpAndForget;
|
||||
|
||||
PVOID
|
||||
GetUserBuffer(IN PIRP Irp);
|
||||
|
||||
//KSERVICE_ROUTINE ParportInterruptService;
|
||||
|
||||
|
||||
/* pdo.c */
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoPnp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoPower(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
|
||||
#endif /* _PARPORT_PCH_ */
|
5
drivers/parallel/parport/parport.rc
Normal file
5
drivers/parallel/parport/parport.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "Parallel Port Function Driver"
|
||||
#define REACTOS_STR_INTERNAL_NAME "parport"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "parport.sys"
|
||||
#include <reactos/version.rc>
|
199
drivers/parallel/parport/pdo.c
Normal file
199
drivers/parallel/parport/pdo.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Parallel Port Function Driver
|
||||
* FILE: drivers/parallel/parport/pdo.c
|
||||
* PURPOSE: PDO functions
|
||||
*/
|
||||
|
||||
#include "parport.h"
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoCreate(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("PdoCreate()\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
|
||||
if (Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
|
||||
{
|
||||
DPRINT1("Not a directory\n");
|
||||
Status = STATUS_NOT_A_DIRECTORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
DPRINT("Open LPT%lu: successful\n", DeviceExtension->LptPort);
|
||||
DeviceExtension->OpenCount++;
|
||||
|
||||
done:
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoClose(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION pDeviceExtension;
|
||||
|
||||
DPRINT("PdoClose()\n");
|
||||
|
||||
pDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
pDeviceExtension->OpenCount--;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoCleanup(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("PdoCleanup()\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoRead(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
DPRINT("PdoRead()\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoWrite(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PUCHAR Buffer;
|
||||
ULONG i;
|
||||
UCHAR PortStatus;
|
||||
ULONG ulCount;
|
||||
|
||||
DPRINT("PdoWrite()\n");
|
||||
|
||||
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->AttachedFdo->DeviceExtension;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Buffer = GetUserBuffer(Irp);
|
||||
DPRINT("Length: %lu\n", IoStack->Parameters.Write.Length);
|
||||
DPRINT("Buffer: %p\n", Buffer);
|
||||
|
||||
for (i = 0; i < IoStack->Parameters.Write.Length; i++)
|
||||
{
|
||||
ulCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
KeStallExecutionProcessor(10);
|
||||
PortStatus = READ_PORT_UCHAR((PUCHAR)(FdoDeviceExtension->BaseAddress + 1));
|
||||
ulCount++;
|
||||
}
|
||||
while (ulCount < 500000 && !(PortStatus & LP_PBUSY));
|
||||
|
||||
if (ulCount == 500000)
|
||||
{
|
||||
DPRINT("Timed out\n");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_TIMEOUT;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return STATUS_TIMEOUT;
|
||||
}
|
||||
|
||||
/* Write character */
|
||||
WRITE_PORT_UCHAR((PUCHAR)FdoDeviceExtension->BaseAddress, Buffer[i]);
|
||||
|
||||
KeStallExecutionProcessor(10);
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)(FdoDeviceExtension->BaseAddress + 2), (LP_PSELECP | LP_PINITP | LP_PSTROBE));
|
||||
|
||||
KeStallExecutionProcessor(10);
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)(FdoDeviceExtension->BaseAddress + 2), (LP_PSELECP | LP_PINITP));
|
||||
}
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoPnp(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
DPRINT("PdoPnp()\n");
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PdoPower(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
DPRINT("PdoPower()\n");
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_SET_POWER:
|
||||
case IRP_MN_QUERY_POWER:
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
Status = Irp->IoStatus.Status;
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue