Module: wine Branch: master Commit: 7e2ca70f799c12418178ef08d95ff10445b410b1 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7e2ca70f799c12418178ef08d9...
Author: Aric Stewart aric@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; }