Aric Stewart : hidclass.sys: Implement IOCTL_GET(SET) _NUM_DEVICE_INPUT_BUFFERS.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Oct 14 11:12:51 CDT 2015
Module: wine
Branch: master
Commit: b95027f0481b164cec2fbc45cca2da4c3d1dcb14
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b95027f0481b164cec2fbc45cca2da4c3d1dcb14
Author: Aric Stewart <aric at codeweavers.com>
Date: Thu Oct 8 14:35:27 2015 -0500
hidclass.sys: Implement IOCTL_GET(SET)_NUM_DEVICE_INPUT_BUFFERS.
Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/hidclass.sys/buffer.c | 35 +++++++++++++++++++++++++++++++++++
dlls/hidclass.sys/device.c | 28 ++++++++++++++++++++++++++++
dlls/hidclass.sys/hid.h | 2 ++
3 files changed, 65 insertions(+)
diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c
index d7770f6..23636e0 100644
--- a/dlls/hidclass.sys/buffer.c
+++ b/dlls/hidclass.sys/buffer.c
@@ -27,6 +27,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(hid);
#define BASE_BUFFER_SIZE 32
+#define MIN_BUFFER_SIZE 2
+#define MAX_BUFFER_SIZE 512
struct ReportRingBuffer
{
@@ -85,6 +87,39 @@ UINT RingBuffer_GetBufferSize(struct ReportRingBuffer *ring)
return ring->buffer_size;
}
+UINT RingBuffer_GetSize(struct ReportRingBuffer *ring)
+{
+ return ring->size;
+}
+
+NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *ring, UINT size)
+{
+ BYTE* new_buffer;
+ int i;
+
+ if (size < MIN_BUFFER_SIZE || size > MAX_BUFFER_SIZE || size == ring->size)
+ return STATUS_INVALID_PARAMETER;
+
+ EnterCriticalSection(&ring->lock);
+ ring->start = ring->end = 0;
+ for (i = 0; i < ring->pointer_alloc; i++)
+ {
+ if (ring->pointers[i] != 0xffffffff)
+ ring->pointers[i] = 0;
+ }
+ new_buffer = HeapAlloc(GetProcessHeap(), 0, ring->buffer_size * size);
+ if (!new_buffer)
+ {
+ LeaveCriticalSection(&ring->lock);
+ return STATUS_NO_MEMORY;
+ }
+ HeapFree(GetProcessHeap(), 0, ring->buffer);
+ ring->buffer = new_buffer;
+ ring->size = size;
+ LeaveCriticalSection(&ring->lock);
+ return STATUS_SUCCESS;
+}
+
void RingBuffer_Read(struct ReportRingBuffer *ring, UINT index, void *output, UINT *size)
{
void *ret = NULL;
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index f2f5f06..e7e7e11 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -512,6 +512,34 @@ NTSTATUS WINAPI HID_Device_ioctl(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.u.Status = STATUS_SUCCESS;
break;
}
+ case IOCTL_SET_NUM_DEVICE_INPUT_BUFFERS:
+ {
+ irp->IoStatus.Information = 0;
+
+ if (irpsp->Parameters.DeviceIoControl.InputBufferLength != sizeof(ULONG))
+ {
+ irp->IoStatus.u.Status = rc = STATUS_BUFFER_OVERFLOW;
+ }
+ else
+ {
+ rc = RingBuffer_SetSize(extension->ring_buffer, *(ULONG*)irp->AssociatedIrp.SystemBuffer);
+ irp->IoStatus.u.Status = rc;
+ }
+ break;
+ }
+ case IOCTL_GET_NUM_DEVICE_INPUT_BUFFERS:
+ {
+ if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
+ {
+ irp->IoStatus.u.Status = rc = STATUS_BUFFER_TOO_SMALL;
+ }
+ else
+ {
+ *(ULONG*)irp->AssociatedIrp.SystemBuffer = RingBuffer_GetSize(extension->ring_buffer);
+ rc = irp->IoStatus.u.Status = STATUS_SUCCESS;
+ }
+ break;
+ }
default:
{
ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode;
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index 1fccc5b..0dcc3a6 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -61,8 +61,10 @@ 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;
+UINT RingBuffer_GetSize(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
+NTSTATUS RingBuffer_SetSize(struct ReportRingBuffer *buffer, UINT size) DECLSPEC_HIDDEN;
typedef struct _minidriver
{
More information about the wine-cvs
mailing list