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