[ISAPNP] Make the driver pageable

This commit is contained in:
Dmitry Borisov 2021-03-04 18:43:44 +06:00
parent 66c195755c
commit 70ba96f164
5 changed files with 137 additions and 36 deletions

View file

@ -11,8 +11,9 @@
#define NDEBUG
#include <debug.h>
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaFdoStartDevice(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
@ -21,26 +22,31 @@ IsaFdoStartDevice(
UNREFERENCED_PARAMETER(Irp);
UNREFERENCED_PARAMETER(IrpSp);
PAGED_CODE();
FdoExt->Common.State = dsStarted;
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaFdoQueryDeviceRelations(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
return Irp->IoStatus.Status;
return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE);
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaFdoPnp(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
@ -48,6 +54,8 @@ IsaFdoPnp(
{
NTSTATUS Status = Irp->IoStatus.Status;
PAGED_CODE();
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE:

View file

@ -250,12 +250,15 @@ SendKey(VOID)
}
static
CODE_SEG("PAGE")
USHORT
PeekByte(
_In_ PUCHAR ReadDataPort)
{
USHORT i;
PAGED_CODE();
for (i = 0; i < 20; i++)
{
if (ReadStatus(ReadDataPort) & 0x01)
@ -268,6 +271,7 @@ PeekByte(
}
static
CODE_SEG("PAGE")
VOID
Peek(
_In_ PUCHAR ReadDataPort,
@ -276,6 +280,8 @@ Peek(
{
USHORT i, Byte;
PAGED_CODE();
for (i = 0; i < Length; i++)
{
Byte = PeekByte(ReadDataPort);
@ -285,12 +291,15 @@ Peek(
}
static
CODE_SEG("PAGE")
USHORT
IsaPnpChecksum(
_In_ PISAPNP_IDENTIFIER Identifier)
{
UCHAR i, j, Lfsr;
PAGED_CODE();
Lfsr = ISAPNP_LFSR_SEED;
for (i = 0; i < FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum); i++)
{
@ -307,6 +316,7 @@ IsaPnpChecksum(
}
static
CODE_SEG("PAGE")
BOOLEAN
ReadTags(
_In_ PUCHAR ReadDataPort,
@ -318,6 +328,8 @@ ReadTags(
USHORT Tag, TagLen, MaxLen;
ULONG NumberOfIo = 0, NumberOfIrq = 0, NumberOfDma = 0;
PAGED_CODE();
LogDev += 1;
while (TRUE)
@ -391,6 +403,7 @@ ReadTags(
}
static
CODE_SEG("PAGE")
INT
TryIsolate(
_In_ PUCHAR ReadDataPort)
@ -401,6 +414,8 @@ TryIsolate(
INT Csn = 0;
USHORT Byte, Data;
PAGED_CODE();
DPRINT("Setting read data port: 0x%p\n", ReadDataPort);
WaitForKey();
@ -496,6 +511,7 @@ TryIsolate(
return Csn;
}
static
VOID
DeviceActivation(
_In_ PISAPNP_LOGICAL_DEVICE IsaDevice,
@ -515,6 +531,8 @@ DeviceActivation(
WaitForKey();
}
static
CODE_SEG("PAGE")
NTSTATUS
ProbeIsaPnpBus(
_In_ PISAPNP_FDO_EXTENSION FdoExt)
@ -525,6 +543,7 @@ ProbeIsaPnpBus(
USHORT LogDev;
ULONG i;
PAGED_CODE();
ASSERT(FdoExt->ReadDataPort);
for (Csn = 1; Csn <= 0xFF; Csn++)
@ -585,16 +604,18 @@ ProbeIsaPnpBus(
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaHwTryReadDataPort(
_In_ PUCHAR ReadDataPort)
{
PAGED_CODE();
return TryIsolate(ReadDataPort) > 0 ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
NTAPI
IsaHwActivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice)
{
@ -604,8 +625,8 @@ IsaHwActivateDevice(
return STATUS_SUCCESS;
}
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
NTAPI
IsaHwDeactivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice)
{
@ -615,10 +636,12 @@ IsaHwDeactivateDevice(
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaHwFillDeviceList(
_In_ PISAPNP_FDO_EXTENSION FdoExt)
{
PAGED_CODE();
return ProbeIsaPnpBus(FdoExt);
}

View file

@ -138,8 +138,8 @@ IsaFdoCreateDeviceIDs(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpCreateLogicalDeviceRequirements(
_In_ PISAPNP_PDO_EXTENSION PdoExt)
{
@ -154,6 +154,8 @@ IsaPnpCreateLogicalDeviceRequirements(
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
PIO_RESOURCE_DESCRIPTOR Descriptor;
PAGED_CODE();
/* Count number of requirements */
for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
{
@ -307,8 +309,8 @@ IsaPnpCreateLogicalDeviceRequirements(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpCreateLogicalDeviceResources(
_In_ PISAPNP_PDO_EXTENSION PdoExt)
{
@ -318,6 +320,8 @@ IsaPnpCreateLogicalDeviceResources(
PCM_RESOURCE_LIST ResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
PAGED_CODE();
/* Count number of required resources */
for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
{
@ -421,8 +425,8 @@ IsaPnpCreateLogicalDeviceResources(
return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpFillDeviceRelations(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
@ -435,6 +439,8 @@ IsaPnpFillDeviceRelations(
PDEVICE_RELATIONS DeviceRelations;
ULONG i = 0;
PAGED_CODE();
DeviceRelations = ExAllocatePool(NonPagedPool,
sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * FdoExt->DeviceCount);
if (!DeviceRelations)
@ -555,15 +561,18 @@ IsaForwardIrpSynchronous(
_Dispatch_type_(IRP_MJ_CREATE)
_Dispatch_type_(IRP_MJ_CLOSE)
static DRIVER_DISPATCH IsaCreateClose;
static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose;
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaCreateClose(
_In_ PDEVICE_OBJECT DeviceObject,
_Inout_ PIRP Irp)
{
PAGED_CODE();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
@ -622,8 +631,8 @@ IsaReadWrite(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpCreateReadPortDORequirements(
_In_ PISAPNP_PDO_EXTENSION PdoExt)
{
@ -633,6 +642,8 @@ IsaPnpCreateReadPortDORequirements(
const ULONG Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS,
0x274, 0x3E4, 0x204, 0x2E4, 0x354, 0x2F4 };
PAGED_CODE();
ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
+ 2 * RTL_NUMBER_OF(Ports) * sizeof(IO_RESOURCE_DESCRIPTOR);
RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
@ -672,8 +683,8 @@ IsaPnpCreateReadPortDORequirements(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpCreateReadPortDOResources(
_In_ PISAPNP_PDO_EXTENSION PdoExt)
{
@ -682,6 +693,8 @@ IsaPnpCreateReadPortDOResources(
PCM_RESOURCE_LIST ResourceList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
PAGED_CODE();
ListSize = sizeof(CM_RESOURCE_LIST) +
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (RTL_NUMBER_OF(Ports) - 1);
ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
@ -710,8 +723,8 @@ IsaPnpCreateReadPortDOResources(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpCreateReadPortDO(
_In_ PISAPNP_FDO_EXTENSION FdoExt)
{
@ -722,6 +735,8 @@ IsaPnpCreateReadPortDO(
PISAPNP_PDO_EXTENSION PdoExt;
NTSTATUS Status;
PAGED_CODE();
Status = IoCreateDevice(FdoExt->DriverObject,
sizeof(ISAPNP_PDO_EXTENSION),
NULL,
@ -774,7 +789,10 @@ IsaPnpCreateReadPortDO(
return Status;
}
static CODE_SEG("PAGE") DRIVER_ADD_DEVICE IsaAddDevice;
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaAddDevice(
@ -785,6 +803,8 @@ IsaAddDevice(
PISAPNP_FDO_EXTENSION FdoExt;
NTSTATUS Status;
PAGED_CODE();
DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject);
Status = IoCreateDevice(DriverObject,
@ -812,7 +832,7 @@ IsaAddDevice(
PhysicalDeviceObject);
InitializeListHead(&FdoExt->DeviceListHead);
KeInitializeSpinLock(&FdoExt->Lock);
KeInitializeEvent(&FdoExt->DeviceSyncEvent, SynchronizationEvent, TRUE);
Status = IsaPnpCreateReadPortDO(FdoExt);
if (!NT_SUCCESS(Status))
@ -825,8 +845,9 @@ IsaAddDevice(
}
_Dispatch_type_(IRP_MJ_POWER)
DRIVER_DISPATCH IsaPower;
static DRIVER_DISPATCH_RAISED IsaPower;
static
NTSTATUS
NTAPI
IsaPower(
@ -849,9 +870,10 @@ IsaPower(
}
_Dispatch_type_(IRP_MJ_PNP)
static DRIVER_DISPATCH IsaPnp;
static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaPnp;
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnp(
@ -861,6 +883,8 @@ IsaPnp(
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
PAGED_CODE();
DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
if (DevExt->IsFdo)
@ -869,6 +893,7 @@ IsaPnp(
return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt, Irp, IrpSp);
}
CODE_SEG("INIT")
NTSTATUS
NTAPI
DriverEntry(

View file

@ -11,6 +11,7 @@
#include <wdm.h>
#include <ntstrsafe.h>
#include <section_attribs.h>
#include "isapnphw.h"
#ifdef __cplusplus
@ -72,11 +73,11 @@ typedef struct _ISAPNP_FDO_EXTENSION
PDEVICE_OBJECT Ldo;
PDEVICE_OBJECT Pdo;
PDEVICE_OBJECT ReadPortPdo;
KEVENT DeviceSyncEvent;
LIST_ENTRY DeviceListHead;
ULONG DeviceCount;
PDRIVER_OBJECT DriverObject;
PUCHAR ReadDataPort;
KSPIN_LOCK Lock;
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
typedef struct _ISAPNP_PDO_EXTENSION
@ -93,6 +94,25 @@ typedef struct _ISAPNP_PDO_EXTENSION
ULONG ResourceListSize;
} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
_Requires_lock_not_held_(FdoExt->DeviceSyncEvent)
_Acquires_lock_(FdoExt->DeviceSyncEvent)
FORCEINLINE
VOID
IsaPnpAcquireDeviceDataLock(
_In_ PISAPNP_FDO_EXTENSION FdoExt)
{
KeWaitForSingleObject(&FdoExt->DeviceSyncEvent, Executive, KernelMode, FALSE, NULL);
}
_Releases_lock_(FdoExt->DeviceSyncEvent)
FORCEINLINE
VOID
IsaPnpReleaseDeviceDataLock(
_In_ PISAPNP_FDO_EXTENSION FdoExt)
{
KeSetEvent(&FdoExt->DeviceSyncEvent, IO_NO_INCREMENT, FALSE);
}
/* isapnp.c */
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE 1
@ -105,13 +125,14 @@ IsaPnpDuplicateUnicodeString(
IN PCUNICODE_STRING SourceString,
OUT PUNICODE_STRING DestinationString);
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPnpFillDeviceRelations(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
_In_ BOOLEAN IncludeDataPort);
CODE_SEG("INIT")
DRIVER_INITIALIZE DriverEntry;
NTSTATUS
@ -121,39 +142,39 @@ IsaForwardIrpSynchronous(
_Inout_ PIRP Irp);
/* fdo.c */
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaFdoPnp(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp);
/* pdo.c */
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoPnp(
_In_ PISAPNP_PDO_EXTENSION PdoDeviceExtension,
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp);
/* hardware.c */
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaHwTryReadDataPort(
_In_ PUCHAR ReadDataPort);
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaHwFillDeviceList(
_In_ PISAPNP_FDO_EXTENSION FdoExt);
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
NTAPI
IsaHwDeactivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice);
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS
NTAPI
IsaHwActivateDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice);

View file

@ -11,8 +11,9 @@
#define NDEBUG
#include <debug.h>
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryDeviceRelations(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -20,6 +21,8 @@ IsaPdoQueryDeviceRelations(
{
PDEVICE_RELATIONS DeviceRelations;
PAGED_CODE();
if (IrpSp->Parameters.QueryDeviceRelations.Type == RemovalRelations &&
PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo)
{
@ -41,8 +44,9 @@ IsaPdoQueryDeviceRelations(
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryCapabilities(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -52,6 +56,8 @@ IsaPdoQueryCapabilities(
PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
ULONG i;
PAGED_CODE();
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
if (DeviceCapabilities->Version != 1)
return STATUS_REVISION_MISMATCH;
@ -75,19 +81,23 @@ IsaPdoQueryCapabilities(
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryPnpDeviceState(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
_In_ PIO_STACK_LOCATION IrpSp)
{
PAGED_CODE();
Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryId(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -96,6 +106,8 @@ IsaPdoQueryId(
PUNICODE_STRING Source;
PWCHAR Buffer;
PAGED_CODE();
switch (IrpSp->Parameters.QueryId.IdType)
{
case BusQueryDeviceID:
@ -136,8 +148,9 @@ IsaPdoQueryId(
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryResources(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -146,6 +159,8 @@ IsaPdoQueryResources(
ULONG ListSize;
PCM_RESOURCE_LIST ResourceList;
PAGED_CODE();
if (!PdoExt->ResourceList)
return Irp->IoStatus.Status;
@ -159,8 +174,9 @@ IsaPdoQueryResources(
return STATUS_SUCCESS;
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoQueryResourceRequirements(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -169,6 +185,8 @@ IsaPdoQueryResourceRequirements(
ULONG ListSize;
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
PAGED_CODE();
if (!PdoExt->RequirementsList)
return Irp->IoStatus.Status;
@ -183,17 +201,18 @@ IsaPdoQueryResourceRequirements(
}
static
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoStartReadPort(
_In_ PISAPNP_FDO_EXTENSION FdoExt,
_In_ PIO_STACK_LOCATION IrpSp)
{
PCM_RESOURCE_LIST ResourceList = IrpSp->Parameters.StartDevice.AllocatedResources;
NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
KIRQL OldIrql;
ULONG i;
PAGED_CODE();
if (!ResourceList || ResourceList->Count != 1)
{
DPRINT1("No resource list (%p) or bad count (%d)\n",
@ -222,10 +241,13 @@ IsaPdoStartReadPort(
if (NT_SUCCESS(IsaHwTryReadDataPort(ReadDataPort)))
{
/* We detected some ISAPNP cards */
FdoExt->ReadDataPort = ReadDataPort;
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
IsaPnpAcquireDeviceDataLock(FdoExt);
Status = IsaHwFillDeviceList(FdoExt);
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
IsaPnpReleaseDeviceDataLock(FdoExt);
if (FdoExt->DeviceCount > 0)
{
IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations);
@ -301,8 +323,8 @@ IsaPdoRepeatRequest(
return STATUS_PENDING;
}
CODE_SEG("PAGE")
NTSTATUS
NTAPI
IsaPdoPnp(
_In_ PISAPNP_PDO_EXTENSION PdoExt,
_Inout_ PIRP Irp,
@ -310,6 +332,8 @@ IsaPdoPnp(
{
NTSTATUS Status = Irp->IoStatus.Status;
PAGED_CODE();
switch (IrpSp->MinorFunction)
{
case IRP_MN_START_DEVICE: