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