From: Aric Stewart Subject: [5/5](retry)hidclass: Implment IRP_MJ_CREATE and IRP_MJ_CLOSE for HID Devices Message-Id: <55F04E3C.4000308@codeweavers.com> Date: Wed, 9 Sep 2015 10:20:28 -0500 --- dlls/hidclass.sys/buffer.c | 28 ++++++++++++++++++++++++++++ dlls/hidclass.sys/device.c | 22 ++++++++++++++++++++++ dlls/hidclass.sys/hid.h | 4 ++++ dlls/hidclass.sys/main.c | 2 ++ 4 files changed, 56 insertions(+) diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c index 8c9a775..2561235 100644 --- a/dlls/hidclass.sys/buffer.c +++ b/dlls/hidclass.sys/buffer.c @@ -79,3 +79,31 @@ void RingBuffer_Destroy(struct ReportRingBuffer *ring) DeleteCriticalSection(&ring->lock); HeapFree(GetProcessHeap(), 0, ring); } + +UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring) +{ + UINT idx; + EnterCriticalSection(&ring->lock); + for (idx = 0; idx < ring->pointer_alloc; idx++) + if (ring->pointers[idx] == -1) + break; + if (idx >= ring->pointer_alloc) + { + int count = idx = ring->pointer_alloc; + ring->pointer_alloc *= 2; + ring->pointers = HeapReAlloc(GetProcessHeap(), 0, ring->pointers, sizeof(int) * ring->pointer_alloc); + for( ;count < ring->pointer_alloc; count++) + ring->pointers[count] = -1; + } + ring->pointers[idx] = ring->start; + LeaveCriticalSection(&ring->lock); + return idx; +} + +void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index) +{ + EnterCriticalSection(&ring->lock); + if (index < ring->pointer_alloc) + ring->pointers[index] = 0xffffffff; + LeaveCriticalSection(&ring->lock); +} diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 004ad1d..87589d6 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -352,3 +352,25 @@ NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp) return rc; } + +NTSTATUS WINAPI HID_Device_create(DEVICE_OBJECT *device, IRP *irp) +{ + BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + + TRACE("Open handle on device %p\n", device); + irp->Tail.Overlay.OriginalFileObject->FsContext = (void*)RingBuffer_AddPointer(ext->ring_buffer); + irp->IoStatus.u.Status = STATUS_SUCCESS; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_SUCCESS; +} + +NTSTATUS WINAPI HID_Device_close(DEVICE_OBJECT *device, IRP *irp) +{ + BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; + int ptr = (int)irp->Tail.Overlay.OriginalFileObject->FsContext; + TRACE("Close handle on device %p\n", device); + RingBuffer_RemovePointer(ext->ring_buffer, ptr); + irp->IoStatus.u.Status = STATUS_SUCCESS; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_SUCCESS; +} diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h index f3a5465..1db4fc6 100644 --- a/dlls/hidclass.sys/hid.h +++ b/dlls/hidclass.sys/hid.h @@ -56,6 +56,8 @@ typedef struct _BASE_DEVICE_EXTENSTION { /* Minidriver Specific stuff will end up here */ } BASE_DEVICE_EXTENSION; +UINT RingBuffer_AddPointer(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN; +void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index) DECLSPEC_HIDDEN; void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN; struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN; @@ -79,6 +81,8 @@ NTSTATUS HID_LinkDevice(DEVICE_OBJECT *device, LPCWSTR serial, LPCWSTR index) DE void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device) DECLSPEC_HIDDEN; NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; +NTSTATUS WINAPI HID_Device_create(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; +NTSTATUS WINAPI HID_Device_close(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN; /* Pseudo-Plug and Play support*/ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT* PDO) DECLSPEC_HIDDEN; diff --git a/dlls/hidclass.sys/main.c b/dlls/hidclass.sys/main.c index f11d7b4..1e0e802 100644 --- a/dlls/hidclass.sys/main.c +++ b/dlls/hidclass.sys/main.c @@ -69,6 +69,8 @@ NTSTATUS WINAPI HidRegisterMinidriver(HID_MINIDRIVER_REGISTRATION *registration) registration->DriverObject->DriverUnload = UnloadDriver; registration->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HID_Device_ioctl; + registration->DriverObject->MajorFunction[IRP_MJ_CREATE] = HID_Device_create; + registration->DriverObject->MajorFunction[IRP_MJ_CLOSE] = HID_Device_close; driver->AddDevice = registration->DriverObject->DriverExtension->AddDevice; registration->DriverObject->DriverExtension->AddDevice = PNP_AddDevice;