Aric Stewart : hidclass.sys: Implement a report ring buffer.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Sep 14 09:44:34 CDT 2015


Module: wine
Branch: master
Commit: 7e2ca70f799c12418178ef08d95ff10445b410b1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7e2ca70f799c12418178ef08d95ff10445b410b1

Author: Aric Stewart <aric at codeweavers.com>
Date:   Fri Sep 11 10:45:54 2015 -0500

hidclass.sys: Implement a report ring buffer.

---

 dlls/hidclass.sys/Makefile.in |  1 +
 dlls/hidclass.sys/buffer.c    | 81 +++++++++++++++++++++++++++++++++++++++++++
 dlls/hidclass.sys/device.c    |  2 ++
 dlls/hidclass.sys/hid.h       |  7 ++++
 dlls/hidclass.sys/pnp.c       |  2 ++
 5 files changed, 93 insertions(+)

diff --git a/dlls/hidclass.sys/Makefile.in b/dlls/hidclass.sys/Makefile.in
index c5c9eb7..8ed51e6 100644
--- a/dlls/hidclass.sys/Makefile.in
+++ b/dlls/hidclass.sys/Makefile.in
@@ -4,6 +4,7 @@ IMPORTS   = ntoskrnl.exe
 DELAYIMPORTS = setupapi hid
 
 C_SRCS = \
+	buffer.c \
 	device.c \
 	main.c \
 	pnp.c
diff --git a/dlls/hidclass.sys/buffer.c b/dlls/hidclass.sys/buffer.c
new file mode 100644
index 0000000..6fbcc0d
--- /dev/null
+++ b/dlls/hidclass.sys/buffer.c
@@ -0,0 +1,81 @@
+/*  Implementation of a ring buffer for reports
+ *
+ * Copyright 2015 CodeWeavers, Aric Stewart
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include <stdarg.h>
+#define NONAMELESSUNION
+#include "hid.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hid);
+
+#define BASE_BUFFER_SIZE 32
+
+struct ReportRingBuffer
+{
+    UINT start, end, size;
+
+    int *pointers;
+    UINT pointer_alloc;
+    UINT buffer_size;
+
+    CRITICAL_SECTION lock;
+
+    BYTE *buffer;
+};
+
+struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size)
+{
+    struct ReportRingBuffer *ring;
+    TRACE("Create Ring Buffer with buffer size %i\n",buffer_size);
+    ring = HeapAlloc(GetProcessHeap(), 0, sizeof(*ring));
+    if (!ring)
+        return NULL;
+    ring->start = ring->end = 0;
+    ring->size = BASE_BUFFER_SIZE;
+    ring->buffer_size = buffer_size;
+    ring->pointer_alloc = 2;
+    ring->pointers = HeapAlloc(GetProcessHeap(), 0, sizeof(int) * ring->pointer_alloc);
+    if (!ring->pointers)
+    {
+        HeapFree(GetProcessHeap(), 0, ring);
+        return NULL;
+    }
+    memset(ring->pointers, 0xff, sizeof(int) * ring->pointer_alloc);
+    ring->buffer = HeapAlloc(GetProcessHeap(), 0, buffer_size * ring->size);
+    if (!ring->buffer)
+    {
+        HeapFree(GetProcessHeap(), 0, ring->pointers);
+        HeapFree(GetProcessHeap(), 0, ring);
+        return NULL;
+    }
+    InitializeCriticalSection(&ring->lock);
+    ring->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": RingBuffer.lock");
+    return ring;
+}
+
+void RingBuffer_Destroy(struct ReportRingBuffer *ring)
+{
+    HeapFree(GetProcessHeap(), 0, ring->buffer);
+    HeapFree(GetProcessHeap(), 0, ring->pointers);
+    ring->lock.DebugInfo->Spare[0] = 0;
+    DeleteCriticalSection(&ring->lock);
+    HeapFree(GetProcessHeap(), 0, ring);
+}
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 384bc8f..e8deb95 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -178,6 +178,8 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
     CloseHandle(ext->halt_event);
 
     HeapFree(GetProcessHeap(), 0, ext->preparseData);
+    if (ext->ring_buffer)
+        RingBuffer_Destroy(ext->ring_buffer);
 
     entry = RemoveHeadList(&ext->irp_queue);
     while(entry != &ext->irp_queue)
diff --git a/dlls/hidclass.sys/hid.h b/dlls/hidclass.sys/hid.h
index efa4712..538942b 100644
--- a/dlls/hidclass.sys/hid.h
+++ b/dlls/hidclass.sys/hid.h
@@ -35,6 +35,9 @@
 
 typedef NTSTATUS (WINAPI *pAddDevice)(DRIVER_OBJECT *DriverObject, DEVICE_OBJECT *PhysicalDeviceObject);
 
+/* Ring buffer functions */
+struct ReportRingBuffer;
+
 typedef struct _BASE_DEVICE_EXTENSTION {
     HID_DEVICE_EXTENSION deviceExtension;
 
@@ -44,6 +47,7 @@ typedef struct _BASE_DEVICE_EXTENSTION {
     ULONG poll_interval;
     WCHAR *device_name;
     WCHAR *link_name;
+    struct ReportRingBuffer *ring_buffer;
     HANDLE halt_event;
     HANDLE thread;
 
@@ -52,6 +56,9 @@ typedef struct _BASE_DEVICE_EXTENSTION {
     /* Minidriver Specific stuff will end up here */
 } BASE_DEVICE_EXTENSION;
 
+void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
+struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
+
 typedef struct _minidriver
 {
     struct list entry;
diff --git a/dlls/hidclass.sys/pnp.c b/dlls/hidclass.sys/pnp.c
index 0fb06a2..43bc449 100644
--- a/dlls/hidclass.sys/pnp.c
+++ b/dlls/hidclass.sys/pnp.c
@@ -126,6 +126,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
     ext->poll_interval = DEFAULT_POLL_INTERVAL;
     InitializeListHead(&ext->irp_queue);
 
+    ext->ring_buffer = RingBuffer_Create(sizeof(HID_XFER_PACKET) + ext->preparseData->caps.InputReportByteLength);
+
     return STATUS_SUCCESS;
 }
 




More information about the wine-cvs mailing list