#include "precomp.h"
+#define NDEBUG
+#include <debug.h>
+
static LPWSTR ClientIdentificationAddress = L"HIDCLASS";
static ULONG HidClassDeviceNumber = 0;
-ULONG
+NTSTATUS
NTAPI
-DllInitialize(ULONG Unknown)
+DllInitialize(
+ IN PUNICODE_STRING RegistryPath)
{
- return 0;
+ return STATUS_SUCCESS;
}
-ULONG
+NTSTATUS
NTAPI
-DllUnload()
+DllUnload(VOID)
{
- return 0;
+ return STATUS_SUCCESS;
}
NTSTATUS
ULONG DeviceExtensionSize;
PHIDCLASS_DRIVER_EXTENSION DriverExtension;
-
/* increment device number */
InterlockedIncrement((PLONG)&HidClassDeviceNumber);
RtlInitUnicodeString(&DeviceName, CharDeviceName);
/* get driver object extension */
- DriverExtension = (PHIDCLASS_DRIVER_EXTENSION) IoGetDriverObjectExtension(DriverObject, ClientIdentificationAddress);
+ DriverExtension = IoGetDriverObjectExtension(DriverObject, ClientIdentificationAddress);
if (!DriverExtension)
{
/* device removed */
}
/* get device extension */
- FDODeviceExtension = (PHIDCLASS_FDO_EXTENSION)NewDeviceObject->DeviceExtension;
+ FDODeviceExtension = NewDeviceObject->DeviceExtension;
/* zero device extension */
RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION));
HidClassDriverUnload(
IN PDRIVER_OBJECT DriverObject)
{
- UNIMPLEMENTED
+ UNIMPLEMENTED;
}
NTSTATUS
//
// get device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
if (CommonDeviceExtension->IsFDO)
{
-#ifndef __REACTOS__
-
//
// only supported for PDO
//
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
-#else
- //
- // ReactOS PnP manager [...]
- //
- DPRINT1("[HIDCLASS] PnP HACK\n");
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-#endif
}
//
//
// get device extension
//
- PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)CommonDeviceExtension;
+ PDODeviceExtension = DeviceObject->DeviceExtension;
//
// get stack location
//
// allocate context
//
- Context = (PHIDCLASS_FILEOP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_FILEOP_CONTEXT));
+ Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(HIDCLASS_FILEOP_CONTEXT), HIDCLASS_TAG);
if (!Context)
{
//
KeInitializeSpinLock(&Context->Lock);
InitializeListHead(&Context->ReadPendingIrpListHead);
InitializeListHead(&Context->IrpCompletedListHead);
+ KeInitializeEvent(&Context->IrpReadComplete, NotificationEvent, FALSE);
//
// store context
//
ASSERT(IoStack->FileObject);
- IoStack->FileObject->FsContext = (PVOID)Context;
+ IoStack->FileObject->FsContext = Context;
//
// done
{
PIO_STACK_LOCATION IoStack;
PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
- PHIDCLASS_IRP_CONTEXT IrpContext;
+ PHIDCLASS_FILEOP_CONTEXT IrpContext;
+ BOOLEAN IsRequestPending = FALSE;
+ KIRQL OldLevel;
+ PLIST_ENTRY Entry;
+ PIRP ListIrp;
//
// get device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
//
// is it a FDO request
//
// get irp context
//
- IrpContext = (PHIDCLASS_IRP_CONTEXT)IoStack->FileObject->FsContext;
+ IrpContext = IoStack->FileObject->FsContext;
+ ASSERT(IrpContext);
//
- // cancel pending irps
+ // acquire lock
//
- UNIMPLEMENTED
+ KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
+
+ if (!IsListEmpty(&IrpContext->ReadPendingIrpListHead))
+ {
+ //
+ // FIXME cancel irp
+ //
+ IsRequestPending = TRUE;
+ }
//
- // remove context
+ // signal stop
//
- IoStack->FileObject->FsContext = NULL;
+ IrpContext->StopInProgress = TRUE;
//
- // free context
+ // release lock
//
- ExFreePool(IrpContext);
+ KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+ if (IsRequestPending)
+ {
+ //
+ // wait for request to complete
+ //
+ DPRINT1("[HIDCLASS] Waiting for read irp completion...\n");
+ KeWaitForSingleObject(&IrpContext->IrpReadComplete, Executive, KernelMode, FALSE, NULL);
+ }
//
- // complete request
+ // acquire lock
//
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-}
+ KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
-PVOID
-HidClass_GetSystemAddress(
- IN PMDL ReportMDL)
-{
//
// sanity check
//
- ASSERT(ReportMDL);
+ ASSERT(IsListEmpty(&IrpContext->ReadPendingIrpListHead));
- if (ReportMDL->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL | MDL_MAPPED_TO_SYSTEM_VA))
- {
- //
- // buffer is non paged pool
- //
- return ReportMDL->MappedSystemVa;
- }
- else
+ //
+ // now free all irps
+ //
+ while (!IsListEmpty(&IrpContext->IrpCompletedListHead))
{
- //
- // map mdl
- //
- return MmMapLockedPages(ReportMDL, KernelMode);
+ //
+ // remove head irp
+ //
+ Entry = RemoveHeadList(&IrpContext->IrpCompletedListHead);
+
+ //
+ // get irp
+ //
+ ListIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
+
+ //
+ // free the irp
+ //
+ IoFreeIrp(ListIrp);
}
+
+ //
+ // release lock
+ //
+ KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+ //
+ // remove context
+ //
+ IoStack->FileObject->FsContext = NULL;
+
+ //
+ // free context
+ //
+ ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
+
+ //
+ // complete request
+ //
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
}
NTSTATUS
ULONG Offset;
PHIDP_COLLECTION_DESC CollectionDescription;
PHIDP_REPORT_IDS ReportDescription;
+ BOOLEAN IsEmpty;
//
// get irp context
//
- IrpContext = (PHIDCLASS_IRP_CONTEXT)Ctx;
+ IrpContext = Ctx;
DPRINT("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql());
DPRINT("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status);
//
// get address
//
- Address = (PUCHAR)HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress);
+ Address = MmGetSystemAddressForMdlSafe(IrpContext->OriginalIrp->MdlAddress, NormalPagePriority);
if (Address)
{
//
//
// get collection description
//
- CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+ CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+ IrpContext->FileOp->DeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
//
// get report description
//
- ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+ ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+ IrpContext->FileOp->DeviceExtension->CollectionNumber);
ASSERT(ReportDescription);
if (CollectionDescription && ReportDescription)
// copy result status
//
IrpContext->OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
- Irp->IoStatus.Information = Irp->IoStatus.Information;
+ IrpContext->OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
//
// free input report buffer
//
- ExFreePool(IrpContext->InputReportBuffer);
+ ExFreePoolWithTag(IrpContext->InputReportBuffer, HIDCLASS_TAG);
//
// remove us from pending list
//
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ //
+ // is list empty
+ //
+ IsEmpty = IsListEmpty(&IrpContext->FileOp->ReadPendingIrpListHead);
+
//
// insert into completed list
//
//
IoCompleteRequest(IrpContext->OriginalIrp, IO_NO_INCREMENT);
+
+ DPRINT("StopInProgress %x IsEmpty %x\n", IrpContext->FileOp->StopInProgress, IsEmpty);
+ if (IrpContext->FileOp->StopInProgress && IsEmpty)
+ {
+ //
+ // last pending irp
+ //
+ DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
+ KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
+ }
+
+ if (IrpContext->FileOp->StopInProgress && IsEmpty)
+ {
+ //
+ // last pending irp
+ //
+ DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
+ KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
+ }
+
//
// free irp context
//
- ExFreePool(IrpContext);
+ ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
//
// done
//
// get irp
//
- Irp = (PIRP)CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
+ Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
}
//
//
// allocate completion context
//
- IrpContext = (PHIDCLASS_IRP_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(HIDCLASS_IRP_CONTEXT));
+ IrpContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(HIDCLASS_IRP_CONTEXT), HIDCLASS_TAG);
if (!IrpContext)
{
//
//
// get device extension
//
- PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ PDODeviceExtension = DeviceObject->DeviceExtension;
ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
//
//
// get collection description
//
- CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+ CollectionDescription = HidClassPDO_GetCollectionDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+ IrpContext->FileOp->DeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
//
// get report description
//
- ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription, IrpContext->FileOp->DeviceExtension->CollectionNumber);
+ ReportDescription = HidClassPDO_GetReportDescription(&IrpContext->FileOp->DeviceExtension->Common.DeviceDescription,
+ IrpContext->FileOp->DeviceExtension->CollectionNumber);
ASSERT(ReportDescription);
//
//
ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
+ if (Context->StopInProgress)
+ {
+ //
+ // stop in progress
+ //
+ DPRINT1("[HIDCLASS] Stop In Progress\n");
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CANCELLED;
+
+ }
+
//
// store report length
//
//
// allocate buffer
//
- IrpContext->InputReportBuffer = ExAllocatePool(NonPagedPool, IrpContext->InputReportBufferLength);
+ IrpContext->InputReportBuffer = ExAllocatePoolWithTag(NonPagedPool, IrpContext->InputReportBufferLength, HIDCLASS_TAG);
if (!IrpContext->InputReportBuffer)
{
//
// no memory
//
IoFreeIrp(Irp);
- ExFreePool(IrpContext);
+ ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;
}
-
NTSTATUS
NTAPI
HidClass_Read(
//
// get device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
ASSERT(CommonDeviceExtension->IsFDO == FALSE);
//
//
// get context
//
- Context = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext;
+ Context = IoStack->FileObject->FsContext;
ASSERT(Context);
//
//
ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);
+ if (Context->StopInProgress)
+ {
+ //
+ // stop in progress
+ //
+ DPRINT1("[HIDCLASS] Stop In Progress\n");
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CANCELLED;
+ }
+
//
// build irp request
//
- Status = HidClass_BuildIrp(DeviceObject, Irp, Context, IOCTL_HID_READ_REPORT, IoStack->Parameters.Read.Length, &NewIrp, &NewIrpContext);
+ Status = HidClass_BuildIrp(DeviceObject,
+ Irp,
+ Context,
+ IOCTL_HID_READ_REPORT,
+ IoStack->Parameters.Read.Length,
+ &NewIrp,
+ &NewIrpContext);
if (!NT_SUCCESS(Status))
{
//
IoMarkIrpPending(Irp);
//
- // lets dispatch the request
+ // let's dispatch the request
//
ASSERT(Context->DeviceExtension);
Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](Context->DeviceExtension->FDODeviceObject, NewIrp);
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- UNIMPLEMENTED
+ UNIMPLEMENTED;
ASSERT(FALSE);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//
// get device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
//
// only PDO are supported
// invalid request
//
DPRINT1("[HIDCLASS] DeviceControl Irp for FDO arrived\n");
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER_1;
}
//
// get pdo device extension
//
- PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ PDODeviceExtension = DeviceObject->DeviceExtension;
//
// get stack location
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
- switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
+ switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HID_GET_COLLECTION_INFORMATION:
{
//
// get output buffer
//
- CollectionInformation = (PHID_COLLECTION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
+ CollectionInformation = Irp->AssociatedIrp.SystemBuffer;
ASSERT(CollectionInformation);
//
// get collection description
//
- CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
+ CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
+ PDODeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
//
//
// get collection description
//
- CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription, PDODeviceExtension->CollectionNumber);
+ CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
+ PDODeviceExtension->CollectionNumber);
ASSERT(CollectionDescription);
//
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- UNIMPLEMENTED
+ UNIMPLEMENTED;
ASSERT(FALSE);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
}
-
NTSTATUS
NTAPI
HidClass_Power(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
+ PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
+
+ if (CommonDeviceExtension->IsFDO)
+ {
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ return HidClassFDO_DispatchRequest(DeviceObject, Irp);
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ PoStartNextPowerIrp(Irp);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
}
NTSTATUS
//
// get common device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
//
// check type of device object
//
// get common device extension
//
- CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ CommonDeviceExtension = DeviceObject->DeviceExtension;
//
// FIXME: support PDO
return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp);
}
-
NTSTATUS
NTAPI
HidClassDispatch(
//
// dispatch request based on major function
//
- switch(IoStack->MajorFunction)
+ switch (IoStack->MajorFunction)
{
case IRP_MJ_CREATE:
return HidClass_Create(DeviceObject, Irp);
}
/* now allocate the driver object extension */
- Status = IoAllocateDriverObjectExtension(MinidriverRegistration->DriverObject, (PVOID)ClientIdentificationAddress, sizeof(HIDCLASS_DRIVER_EXTENSION), (PVOID*)&DriverExtension);
+ Status = IoAllocateDriverObjectExtension(MinidriverRegistration->DriverObject,
+ ClientIdentificationAddress,
+ sizeof(HIDCLASS_DRIVER_EXTENSION),
+ (PVOID *)&DriverExtension);
if (!NT_SUCCESS(Status))
{
/* failed to allocate driver extension */
DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload;
/* copy driver dispatch routines */
- RtlCopyMemory(DriverExtension->MajorFunction, MinidriverRegistration->DriverObject->MajorFunction, sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION+1));
+ RtlCopyMemory(DriverExtension->MajorFunction,
+ MinidriverRegistration->DriverObject->MajorFunction,
+ sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1));
/* initialize lock */
KeInitializeSpinLock(&DriverExtension->Lock);