Author: ekohl Date: Thu May 14 14:42:05 2015 New Revision: 67713
URL: http://svn.reactos.org/svn/reactos?rev=67713&view=rev Log: [PARPORT] Implement basic funtions of the parallel port driver. It supports Centronics-Mode only. You can print files using: copy <filename> lpt1:
Added: trunk/reactos/drivers/parallel/parport/fdo.c (with props) trunk/reactos/drivers/parallel/parport/misc.c (with props) trunk/reactos/drivers/parallel/parport/pdo.c (with props) Modified: trunk/reactos/drivers/parallel/parport/CMakeLists.txt trunk/reactos/drivers/parallel/parport/parport.c trunk/reactos/drivers/parallel/parport/parport.h
Modified: trunk/reactos/drivers/parallel/parport/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/CM... ============================================================================== --- trunk/reactos/drivers/parallel/parport/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/drivers/parallel/parport/CMakeLists.txt [iso-8859-1] Thu May 14 14:42:05 2015 @@ -1,5 +1,16 @@
-add_library(parport SHARED parport.c parport.rc) +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)
Added: trunk/reactos/drivers/parallel/parport/fdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/fd... ============================================================================== --- trunk/reactos/drivers/parallel/parport/fdo.c (added) +++ trunk/reactos/drivers/parallel/parport/fdo.c [iso-8859-1] Thu May 14 14:42:05 2015 @@ -0,0 +1,572 @@ +/* + * 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" + +/* + * 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 */ + + +/* 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->ParallelPortNumber = IoGetConfigurationInformation()->ParallelCount++; + if (pLptPortNumber == NULL) + DeviceExtension->LptPort = DeviceExtension->ParallelPortNumber + 1; + else + DeviceExtension->LptPort = *pLptPortNumber; + 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; + WCHAR DeviceNameBuffer[32]; + WCHAR LinkNameBuffer[32]; + WCHAR LptPortBuffer[32]; + UNICODE_STRING DeviceName; + UNICODE_STRING LinkName; + UNICODE_STRING LptPort; + ULONG i; +// ULONG Vector = 0; +// KIRQL Dirql = 0; +// KAFFINITY Affinity = 0; +// KINTERRUPT_MODE InterruptMode = Latched; +// BOOLEAN ShareInterrupt = TRUE; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + HANDLE KeyHandle; + NTSTATUS Status; + + 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 < 8) + 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 ressource: \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 + + /* Create link \DosDevices\LPTX -> \Device\ParallelPortX */ + swprintf(DeviceNameBuffer, L"\Device\ParallelPort%lu", DeviceExtension->ParallelPortNumber); + swprintf(LinkNameBuffer, L"\DosDevices\LPT%lu", DeviceExtension->LptPort); + swprintf(LptPortBuffer, L"LPT%lu", DeviceExtension->LptPort); + RtlInitUnicodeString(&DeviceName, DeviceNameBuffer); + RtlInitUnicodeString(&LinkName, LinkNameBuffer); + RtlInitUnicodeString(&LptPort, LptPortBuffer); + Status = IoCreateSymbolicLink(&LinkName, + &DeviceName); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IoCreateSymbolicLink() failed with status 0x%08x\n", Status); + return Status; + } + + + /* 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, + 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); + } + + DeviceExtension->Common.PnpState = dsStarted; + + + /* We don't really care if the call succeeded or not... */ + + 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 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 +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 +FdoWrite(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION DeviceExtension; + PIO_STACK_LOCATION IoStack; + PUCHAR Buffer; + ULONG i; + UCHAR PortStatus; + ULONG ulCount; + + DPRINT("FdoWrite()\n"); + + DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + IoStack = IoGetCurrentIrpStackLocation(Irp); + + Buffer = GetUserBuffer(Irp); + DPRINT("Length: %lu\n", IoStack->Parameters.Write.Length); + DPRINT("Buffer: %p\n", Buffer); + + if (Buffer != NULL) + { + DPRINT("%s\n", Buffer); + } + + for (i = 0; i < IoStack->Parameters.Write.Length; i++) + { + DPRINT("%lu: %c\n", i, Buffer[i]); + + ulCount = 0; + + do + { + KeStallExecutionProcessor(10); + PortStatus = READ_PORT_UCHAR((PUCHAR)(DeviceExtension->BaseAddress + 1)); + ulCount++; + } + while (ulCount < 500000 && !(PortStatus & LP_PBUSY)); + + if (ulCount == 500000) + { + DPRINT1("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)DeviceExtension->BaseAddress, Buffer[i]); + + KeStallExecutionProcessor(10); + + WRITE_PORT_UCHAR((PUCHAR)(DeviceExtension->BaseAddress + 2), (LP_PSELECP | LP_PINITP | LP_PSTROBE)); + + KeStallExecutionProcessor(10); + + WRITE_PORT_UCHAR((PUCHAR)(DeviceExtension->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 +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: + DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + + case RemovalRelations: + DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + + default: + DPRINT1("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 */ + DPRINT1("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); + return ForwardIrpAndForget(DeviceObject, Irp); + + default: + DPRINT1("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) +{ + DPRINT("FdoPower()\n"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +/* EOF */
Propchange: trunk/reactos/drivers/parallel/parport/fdo.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/parallel/parport/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/mi... ============================================================================== --- trunk/reactos/drivers/parallel/parport/misc.c (added) +++ trunk/reactos/drivers/parallel/parport/misc.c [iso-8859-1] Thu May 14 14:42:05 2015 @@ -0,0 +1,83 @@ +/* + * 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; + + LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice; + 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 */
Propchange: trunk/reactos/drivers/parallel/parport/misc.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/drivers/parallel/parport/parport.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/pa... ============================================================================== --- trunk/reactos/drivers/parallel/parport/parport.c [iso-8859-1] (original) +++ trunk/reactos/drivers/parallel/parport/parport.c [iso-8859-1] Thu May 14 14:42:05 2015 @@ -7,7 +7,15 @@ #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 @@ -17,14 +25,109 @@ 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 +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; }
Modified: trunk/reactos/drivers/parallel/parport/parport.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/pa... ============================================================================== --- trunk/reactos/drivers/parallel/parport/parport.h [iso-8859-1] (original) +++ trunk/reactos/drivers/parallel/parport/parport.h [iso-8859-1] Thu May 14 14:42:05 2015 @@ -8,9 +8,131 @@ #define _PARPORT_PCH_
#include <ntddk.h> -#include <ntddser.h> +#include <ndk/haltypes.h> +#include <ntddpar.h> +#include <stdio.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; + + ULONG ParallelPortNumber; + + ULONG LptPort; + ULONG OpenCount; + + ULONG BaseAddress; + PKINTERRUPT Interrupt; + +} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; + +typedef struct _PDO_DEVICE_EXTENSION +{ + COMMON_DEVICE_EXTENSION Common; + +} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION; + + +/* 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 +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 +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_ */
Added: trunk/reactos/drivers/parallel/parport/pdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/parallel/parport/pd... ============================================================================== --- trunk/reactos/drivers/parallel/parport/pdo.c (added) +++ trunk/reactos/drivers/parallel/parport/pdo.c [iso-8859-1] Thu May 14 14:42:05 2015 @@ -0,0 +1,95 @@ +/* + * 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) +{ + DPRINT("PdoCreate()\n"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +PdoClose(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("PdoClose()\n"); + + 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 +PdoWrite(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("PdoWrite()\n"); + + 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) +{ + DPRINT("PdoPnp()\n"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +PdoPower(IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("PdoPower()\n"); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +/* EOF */
Propchange: trunk/reactos/drivers/parallel/parport/pdo.c ------------------------------------------------------------------------------ svn:eol-style = native