hidclass.sys: Implement IRP_MJ_READ for HID Devices.
This commit is contained in:
parent
01aa7a6ec1
commit
1de389ae2b
|
@ -80,6 +80,39 @@ void RingBuffer_Destroy(struct ReportRingBuffer *ring)
|
|||
HeapFree(GetProcessHeap(), 0, ring);
|
||||
}
|
||||
|
||||
UINT RingBuffer_GetBufferSize(struct ReportRingBuffer *ring)
|
||||
{
|
||||
return ring->buffer_size;
|
||||
}
|
||||
|
||||
void RingBuffer_Read(struct ReportRingBuffer *ring, UINT index, void *output, UINT *size)
|
||||
{
|
||||
void *ret = NULL;
|
||||
|
||||
EnterCriticalSection(&ring->lock);
|
||||
if (index >= ring->pointer_alloc || ring->pointers[index] == 0xffffffff)
|
||||
{
|
||||
LeaveCriticalSection(&ring->lock);
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
if (ring->pointers[index] == ring->end)
|
||||
{
|
||||
LeaveCriticalSection(&ring->lock);
|
||||
*size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = &ring->buffer[ring->pointers[index] * ring->buffer_size];
|
||||
memcpy(output, ret, ring->buffer_size);
|
||||
ring->pointers[index]++;
|
||||
if (ring->pointers[index] == ring->size)
|
||||
ring->pointers[index] = 0;
|
||||
LeaveCriticalSection(&ring->lock);
|
||||
*size = ring->buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
UINT RingBuffer_AddPointer(struct ReportRingBuffer *ring)
|
||||
{
|
||||
UINT idx;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "devguid.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(hid);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(hid_report);
|
||||
|
||||
static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e',
|
||||
'\\','H','I','D','#','%','p','&','%','p',0};
|
||||
|
@ -352,6 +353,48 @@ NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp)
|
|||
return rc;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp)
|
||||
{
|
||||
HID_XFER_PACKET *packet;
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer);
|
||||
NTSTATUS rc = STATUS_SUCCESS;
|
||||
int ptr = -1;
|
||||
|
||||
packet = HeapAlloc(GetProcessHeap(), 0, buffer_size);
|
||||
ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext );
|
||||
|
||||
irp->IoStatus.Information = 0;
|
||||
RingBuffer_Read(ext->ring_buffer, ptr, packet, &buffer_size);
|
||||
|
||||
if (buffer_size)
|
||||
{
|
||||
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
|
||||
TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen);
|
||||
if (irpsp->Parameters.Read.Length >= packet->reportBufferLen)
|
||||
{
|
||||
memcpy(irp->AssociatedIrp.SystemBuffer, packet->reportBuffer, packet->reportBufferLen);
|
||||
irp->IoStatus.Information = packet->reportBufferLen;
|
||||
irp->IoStatus.u.Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
irp->IoStatus.Information = 0;
|
||||
irp->IoStatus.u.Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
IoCompleteRequest( irp, IO_NO_INCREMENT );
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_(hid_report)("Queue irp\n");
|
||||
InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.ListEntry);
|
||||
rc = STATUS_PENDING;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, packet);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI HID_Device_create(DEVICE_OBJECT *device, IRP *irp)
|
||||
{
|
||||
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
|
||||
|
|
|
@ -58,6 +58,8 @@ typedef struct _BASE_DEVICE_EXTENSTION {
|
|||
|
||||
UINT RingBuffer_AddPointer(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
|
||||
void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index) DECLSPEC_HIDDEN;
|
||||
void RingBuffer_Read(struct ReportRingBuffer *buffer, UINT index, void *output, UINT *size) DECLSPEC_HIDDEN;
|
||||
UINT RingBuffer_GetBufferSize(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
|
||||
void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
|
||||
struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -81,6 +83,7 @@ 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_read(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;
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ 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_READ] = HID_Device_read;
|
||||
registration->DriverObject->MajorFunction[IRP_MJ_CREATE] = HID_Device_create;
|
||||
registration->DriverObject->MajorFunction[IRP_MJ_CLOSE] = HID_Device_close;
|
||||
|
||||
|
|
Loading…
Reference in New Issue