Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
35938ed8
Commit
35938ed8
authored
Oct 08, 2015
by
Aric Stewart
Committed by
Alexandre Julliard
Oct 15, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass.sys: Add a processing thread for HID devices.
Signed-off-by:
Aric Stewart
<
aric@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0fc17534
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
199 additions
and
0 deletions
+199
-0
buffer.c
dlls/hidclass.sys/buffer.c
+21
-0
device.c
dlls/hidclass.sys/device.c
+174
-0
hid.h
dlls/hidclass.sys/hid.h
+2
-0
pnp.c
dlls/hidclass.sys/pnp.c
+2
-0
No files found.
dlls/hidclass.sys/buffer.c
View file @
35938ed8
...
...
@@ -140,3 +140,24 @@ void RingBuffer_RemovePointer(struct ReportRingBuffer *ring, UINT index)
ring
->
pointers
[
index
]
=
0xffffffff
;
LeaveCriticalSection
(
&
ring
->
lock
);
}
void
RingBuffer_Write
(
struct
ReportRingBuffer
*
ring
,
void
*
data
)
{
UINT
i
;
EnterCriticalSection
(
&
ring
->
lock
);
memcpy
(
&
ring
->
buffer
[
ring
->
end
*
ring
->
buffer_size
],
data
,
ring
->
buffer_size
);
ring
->
end
++
;
if
(
ring
->
end
==
ring
->
size
)
ring
->
end
=
0
;
if
(
ring
->
start
==
ring
->
end
)
{
ring
->
start
++
;
if
(
ring
->
start
==
ring
->
size
)
ring
->
start
=
0
;
}
for
(
i
=
0
;
i
<
ring
->
pointer_alloc
;
i
++
)
if
(
ring
->
pointers
[
i
]
==
ring
->
end
)
ring
->
pointers
[
i
]
=
ring
->
start
;
LeaveCriticalSection
(
&
ring
->
lock
);
}
dlls/hidclass.sys/device.c
View file @
35938ed8
...
...
@@ -198,6 +198,180 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
IoDeleteDevice
(
device
);
}
static
void
HID_Device_processQueue
(
DEVICE_OBJECT
*
device
)
{
LIST_ENTRY
*
entry
;
IRP
*
irp
;
BASE_DEVICE_EXTENSION
*
ext
=
device
->
DeviceExtension
;
UINT
buffer_size
=
RingBuffer_GetBufferSize
(
ext
->
ring_buffer
);
HID_XFER_PACKET
*
packet
;
packet
=
HeapAlloc
(
GetProcessHeap
(),
0
,
buffer_size
);
entry
=
RemoveHeadList
(
&
ext
->
irp_queue
);
while
(
entry
!=
&
ext
->
irp_queue
)
{
int
ptr
;
irp
=
CONTAINING_RECORD
(
entry
,
IRP
,
Tail
.
Overlay
.
ListEntry
);
ptr
=
PtrToUlong
(
irp
->
Tail
.
Overlay
.
OriginalFileObject
->
FsContext
);
RingBuffer_Read
(
ext
->
ring_buffer
,
ptr
,
packet
,
&
buffer_size
);
if
(
buffer_size
)
{
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
TRACE_
(
hid_report
)(
"Processing Request (%i)
\n
"
,
ptr
);
if
(
irpsp
->
Parameters
.
Read
.
Length
>=
packet
->
reportBufferLen
)
{
memcpy
(
irp
->
AssociatedIrp
.
SystemBuffer
,
packet
->
reportBuffer
,
packet
->
reportBufferLen
);
irp
->
IoStatus
.
Information
=
packet
->
reportBufferLen
;
irp
->
IoStatus
.
u
.
Status
=
STATUS_SUCCESS
;
}
else
{
irp
->
IoStatus
.
Information
=
0
;
irp
->
IoStatus
.
u
.
Status
=
STATUS_BUFFER_OVERFLOW
;
}
}
else
{
irp
->
IoStatus
.
Information
=
0
;
irp
->
IoStatus
.
u
.
Status
=
STATUS_UNSUCCESSFUL
;
}
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
entry
=
RemoveHeadList
(
&
ext
->
irp_queue
);
}
HeapFree
(
GetProcessHeap
(),
0
,
packet
);
}
static
NTSTATUS
WINAPI
read_Completion
(
DEVICE_OBJECT
*
deviceObject
,
IRP
*
irp
,
void
*
context
)
{
SetEvent
(
irp
->
UserEvent
);
return
STATUS_MORE_PROCESSING_REQUIRED
;
}
static
DWORD
CALLBACK
hid_device_thread
(
void
*
args
)
{
DEVICE_OBJECT
*
device
=
(
DEVICE_OBJECT
*
)
args
;
IRP
*
irp
;
IO_STATUS_BLOCK
irp_status
;
IO_STACK_LOCATION
*
irpsp
;
DWORD
rc
;
HANDLE
events
[
2
];
NTSTATUS
ntrc
;
BASE_DEVICE_EXTENSION
*
ext
=
device
->
DeviceExtension
;
events
[
0
]
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
events
[
1
]
=
ext
->
halt_event
;
if
(
ext
->
information
.
Polled
)
{
while
(
1
)
{
HID_XFER_PACKET
*
packet
;
ResetEvent
(
events
[
0
]);
packet
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
packet
)
+
ext
->
preparseData
->
caps
.
InputReportByteLength
);
packet
->
reportBufferLen
=
ext
->
preparseData
->
caps
.
InputReportByteLength
;
packet
->
reportBuffer
=
((
BYTE
*
)
packet
)
+
sizeof
(
*
packet
);
packet
->
reportId
=
0
;
irp
=
IoBuildDeviceIoControlRequest
(
IOCTL_HID_GET_INPUT_REPORT
,
device
,
NULL
,
0
,
packet
,
sizeof
(
packet
),
TRUE
,
events
[
0
],
&
irp_status
);
irpsp
=
IoGetNextIrpStackLocation
(
irp
);
irpsp
->
CompletionRoutine
=
read_Completion
;
irpsp
->
Control
=
SL_INVOKE_ON_SUCCESS
|
SL_INVOKE_ON_ERROR
;
ntrc
=
IoCallDriver
(
device
,
irp
);
if
(
ntrc
==
STATUS_PENDING
)
rc
=
WaitForMultipleObjects
(
2
,
events
,
FALSE
,
INFINITE
);
if
(
irp
->
IoStatus
.
u
.
Status
==
STATUS_SUCCESS
)
{
RingBuffer_Write
(
ext
->
ring_buffer
,
packet
);
HID_Device_processQueue
(
device
);
}
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
rc
=
WaitForSingleObject
(
ext
->
halt_event
,
ext
->
poll_interval
);
if
(
rc
==
WAIT_OBJECT_0
)
break
;
else
if
(
rc
!=
WAIT_TIMEOUT
)
ERR
(
"Wait returned unexpected value %x
\n
"
,
rc
);
}
}
else
{
INT
exit_now
=
FALSE
;
HID_XFER_PACKET
*
packet
;
packet
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
packet
)
+
ext
->
preparseData
->
caps
.
InputReportByteLength
);
packet
->
reportBufferLen
=
ext
->
preparseData
->
caps
.
InputReportByteLength
;
packet
->
reportBuffer
=
((
BYTE
*
)
packet
)
+
sizeof
(
*
packet
);
packet
->
reportId
=
0
;
while
(
1
)
{
BYTE
*
buffer
;
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ext
->
preparseData
->
caps
.
InputReportByteLength
);
ResetEvent
(
events
[
0
]);
irp
=
IoBuildDeviceIoControlRequest
(
IOCTL_HID_READ_REPORT
,
device
,
NULL
,
0
,
buffer
,
ext
->
preparseData
->
caps
.
InputReportByteLength
,
TRUE
,
events
[
0
],
&
irp_status
);
irpsp
=
IoGetNextIrpStackLocation
(
irp
);
irpsp
->
CompletionRoutine
=
read_Completion
;
irpsp
->
Control
=
SL_INVOKE_ON_SUCCESS
|
SL_INVOKE_ON_ERROR
;
ntrc
=
IoCallDriver
(
device
,
irp
);
if
(
ntrc
==
STATUS_PENDING
)
{
rc
=
WaitForMultipleObjects
(
2
,
events
,
FALSE
,
INFINITE
);
if
(
rc
==
WAIT_OBJECT_0
+
1
)
exit_now
=
TRUE
;
}
if
(
!
exit_now
&&
irp
->
IoStatus
.
u
.
Status
==
STATUS_SUCCESS
)
{
packet
->
reportId
=
buffer
[
0
];
memcpy
(
packet
->
reportBuffer
,
buffer
,
ext
->
preparseData
->
caps
.
InputReportByteLength
);
RingBuffer_Write
(
ext
->
ring_buffer
,
packet
);
HID_Device_processQueue
(
device
);
}
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
if
(
exit_now
)
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
packet
);
}
CloseHandle
(
events
[
0
]);
TRACE
(
"Device thread exiting
\n
"
);
return
1
;
}
void
HID_StartDeviceThread
(
DEVICE_OBJECT
*
device
)
{
BASE_DEVICE_EXTENSION
*
ext
=
device
->
DeviceExtension
;
ext
->
halt_event
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
ext
->
thread
=
CreateThread
(
NULL
,
0
,
hid_device_thread
,
device
,
0
,
NULL
);
}
static
NTSTATUS
handle_IOCTL_HID_GET_COLLECTION_INFORMATION
(
IRP
*
irp
,
BASE_DEVICE_EXTENSION
*
base
)
{
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
...
...
dlls/hidclass.sys/hid.h
View file @
35938ed8
...
...
@@ -56,6 +56,7 @@ typedef struct _BASE_DEVICE_EXTENSTION {
/* Minidriver Specific stuff will end up here */
}
BASE_DEVICE_EXTENSION
;
void
RingBuffer_Write
(
struct
ReportRingBuffer
*
buffer
,
void
*
data
)
DECLSPEC_HIDDEN
;
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
;
...
...
@@ -81,6 +82,7 @@ minidriver* find_minidriver(DRIVER_OBJECT* driver) DECLSPEC_HIDDEN;
NTSTATUS
HID_CreateDevice
(
DEVICE_OBJECT
*
native_device
,
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
**
device
)
DECLSPEC_HIDDEN
;
NTSTATUS
HID_LinkDevice
(
DEVICE_OBJECT
*
device
,
LPCWSTR
serial
,
LPCWSTR
index
)
DECLSPEC_HIDDEN
;
void
HID_DeleteDevice
(
HID_MINIDRIVER_REGISTRATION
*
driver
,
DEVICE_OBJECT
*
device
)
DECLSPEC_HIDDEN
;
void
HID_StartDeviceThread
(
DEVICE_OBJECT
*
device
)
DECLSPEC_HIDDEN
;
NTSTATUS
WINAPI
HID_Device_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
DECLSPEC_HIDDEN
;
NTSTATUS
WINAPI
HID_Device_read
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
DECLSPEC_HIDDEN
;
...
...
dlls/hidclass.sys/pnp.c
View file @
35938ed8
...
...
@@ -165,6 +165,8 @@ NTSTATUS WINAPI PNP_AddDevice(DRIVER_OBJECT *driver, DEVICE_OBJECT *PDO)
ext
->
ring_buffer
=
RingBuffer_Create
(
sizeof
(
HID_XFER_PACKET
)
+
ext
->
preparseData
->
caps
.
InputReportByteLength
);
HID_StartDeviceThread
(
device
);
return
STATUS_SUCCESS
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment