Commit 7e2ca70f authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

hidclass.sys: Implement a report ring buffer.

parent a833aaa5
...@@ -4,6 +4,7 @@ IMPORTS = ntoskrnl.exe ...@@ -4,6 +4,7 @@ IMPORTS = ntoskrnl.exe
DELAYIMPORTS = setupapi hid DELAYIMPORTS = setupapi hid
C_SRCS = \ C_SRCS = \
buffer.c \
device.c \ device.c \
main.c \ main.c \
pnp.c pnp.c
/* 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);
}
...@@ -178,6 +178,8 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device ...@@ -178,6 +178,8 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
CloseHandle(ext->halt_event); CloseHandle(ext->halt_event);
HeapFree(GetProcessHeap(), 0, ext->preparseData); HeapFree(GetProcessHeap(), 0, ext->preparseData);
if (ext->ring_buffer)
RingBuffer_Destroy(ext->ring_buffer);
entry = RemoveHeadList(&ext->irp_queue); entry = RemoveHeadList(&ext->irp_queue);
while(entry != &ext->irp_queue) while(entry != &ext->irp_queue)
......
...@@ -35,6 +35,9 @@ ...@@ -35,6 +35,9 @@
typedef NTSTATUS (WINAPI *pAddDevice)(DRIVER_OBJECT *DriverObject, DEVICE_OBJECT *PhysicalDeviceObject); typedef NTSTATUS (WINAPI *pAddDevice)(DRIVER_OBJECT *DriverObject, DEVICE_OBJECT *PhysicalDeviceObject);
/* Ring buffer functions */
struct ReportRingBuffer;
typedef struct _BASE_DEVICE_EXTENSTION { typedef struct _BASE_DEVICE_EXTENSTION {
HID_DEVICE_EXTENSION deviceExtension; HID_DEVICE_EXTENSION deviceExtension;
...@@ -44,6 +47,7 @@ typedef struct _BASE_DEVICE_EXTENSTION { ...@@ -44,6 +47,7 @@ typedef struct _BASE_DEVICE_EXTENSTION {
ULONG poll_interval; ULONG poll_interval;
WCHAR *device_name; WCHAR *device_name;
WCHAR *link_name; WCHAR *link_name;
struct ReportRingBuffer *ring_buffer;
HANDLE halt_event; HANDLE halt_event;
HANDLE thread; HANDLE thread;
...@@ -52,6 +56,9 @@ typedef struct _BASE_DEVICE_EXTENSTION { ...@@ -52,6 +56,9 @@ typedef struct _BASE_DEVICE_EXTENSTION {
/* Minidriver Specific stuff will end up here */ /* Minidriver Specific stuff will end up here */
} BASE_DEVICE_EXTENSION; } BASE_DEVICE_EXTENSION;
void RingBuffer_Destroy(struct ReportRingBuffer *buffer) DECLSPEC_HIDDEN;
struct ReportRingBuffer* RingBuffer_Create(UINT buffer_size) DECLSPEC_HIDDEN;
typedef struct _minidriver typedef struct _minidriver
{ {
struct list entry; struct list entry;
......
...@@ -126,6 +126,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO) ...@@ -126,6 +126,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
ext->poll_interval = DEFAULT_POLL_INTERVAL; ext->poll_interval = DEFAULT_POLL_INTERVAL;
InitializeListHead(&ext->irp_queue); InitializeListHead(&ext->irp_queue);
ext->ring_buffer = RingBuffer_Create(sizeof(HID_XFER_PACKET) + ext->preparseData->caps.InputReportByteLength);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment