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
d0039106
Commit
d0039106
authored
Nov 29, 2016
by
Aric Stewart
Committed by
Alexandre Julliard
Dec 01, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hidclass: All reports read or written to user space lead with a reportId.
Signed-off-by:
Aric Stewart
<
aric@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
95298b44
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
56 deletions
+107
-56
descriptor.c
dlls/hidclass.sys/descriptor.c
+7
-24
device.c
dlls/hidclass.sys/device.c
+64
-30
bus_udev.c
dlls/winebus.sys/bus_udev.c
+36
-2
No files found.
dlls/hidclass.sys/descriptor.c
View file @
d0039106
...
...
@@ -919,10 +919,8 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
new_report
(
wine_report
,
input_features
[
0
]);
data
->
dwInputReportCount
++
;
if
(
input_features
[
0
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
/* Room for the reportID */
bitOffset
=
8
;
for
(
i
=
0
;
i
<
i_count
;
i
++
)
{
...
...
@@ -933,10 +931,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
new_report
(
wine_report
,
input_features
[
i
]);
data
->
dwInputReportCount
++
;
bitLength
=
max
(
bitOffset
,
bitLength
);
if
(
input_features
[
i
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
bitOffset
=
8
;
}
build_elements
(
wine_report
,
input_features
[
i
],
&
bitOffset
);
count_elements
(
input_features
[
i
],
&
data
->
caps
.
NumberInputButtonCaps
,
...
...
@@ -954,10 +949,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
data
->
dwOutputReportOffset
=
(
BYTE
*
)
wine_report
-
(
BYTE
*
)
data
->
InputReports
;
new_report
(
wine_report
,
output_features
[
0
]);
data
->
dwOutputReportCount
++
;
if
(
output_features
[
0
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
bitOffset
=
8
;
for
(
i
=
0
;
i
<
o_count
;
i
++
)
{
...
...
@@ -968,10 +960,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
new_report
(
wine_report
,
output_features
[
i
]);
data
->
dwOutputReportCount
++
;
bitLength
=
max
(
bitOffset
,
bitLength
);
if
(
output_features
[
0
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
bitOffset
=
8
;
}
build_elements
(
wine_report
,
output_features
[
i
],
&
bitOffset
);
count_elements
(
output_features
[
i
],
&
data
->
caps
.
NumberOutputButtonCaps
,
...
...
@@ -989,10 +978,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
data
->
dwFeatureReportOffset
=
(
BYTE
*
)
wine_report
-
(
BYTE
*
)
data
->
InputReports
;
new_report
(
wine_report
,
feature_features
[
0
]);
data
->
dwFeatureReportCount
++
;
if
(
feature_features
[
0
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
bitOffset
=
8
;
for
(
i
=
0
;
i
<
f_count
;
i
++
)
{
...
...
@@ -1003,10 +989,7 @@ static WINE_HIDP_PREPARSED_DATA* build_PreparseData(
new_report
(
wine_report
,
feature_features
[
i
]);
data
->
dwFeatureReportCount
++
;
bitLength
=
max
(
bitOffset
,
bitLength
);
if
(
feature_features
[
0
]
->
caps
.
ReportID
!=
0
)
bitOffset
=
8
;
else
bitOffset
=
0
;
bitOffset
=
8
;
}
build_elements
(
wine_report
,
feature_features
[
i
],
&
bitOffset
);
count_elements
(
feature_features
[
i
],
&
data
->
caps
.
NumberFeatureButtonCaps
,
...
...
dlls/hidclass.sys/device.c
View file @
d0039106
...
...
@@ -197,6 +197,32 @@ void HID_DeleteDevice(HID_MINIDRIVER_REGISTRATION *driver, DEVICE_OBJECT *device
IoDeleteDevice
(
device
);
}
static
NTSTATUS
copy_packet_into_buffer
(
HID_XFER_PACKET
*
packet
,
BYTE
*
buffer
,
ULONG
buffer_length
,
ULONG
*
out_length
)
{
BOOL
zero_id
=
(
packet
->
reportId
==
0
);
*
out_length
=
0
;
if
((
zero_id
&&
buffer_length
>
packet
->
reportBufferLen
)
||
(
!
zero_id
&&
buffer_length
>=
packet
->
reportBufferLen
))
{
if
(
packet
->
reportId
!=
0
)
{
memcpy
(
buffer
,
packet
->
reportBuffer
,
packet
->
reportBufferLen
);
*
out_length
=
packet
->
reportBufferLen
;
}
else
{
buffer
[
0
]
=
0
;
memcpy
(
&
buffer
[
1
],
packet
->
reportBuffer
,
packet
->
reportBufferLen
);
*
out_length
=
packet
->
reportBufferLen
+
1
;
}
return
STATUS_SUCCESS
;
}
else
return
STATUS_BUFFER_OVERFLOW
;
}
static
void
HID_Device_processQueue
(
DEVICE_OBJECT
*
device
)
{
LIST_ENTRY
*
entry
;
...
...
@@ -217,20 +243,14 @@ static void HID_Device_processQueue(DEVICE_OBJECT *device)
RingBuffer_Read
(
ext
->
ring_buffer
,
ptr
,
packet
,
&
buffer_size
);
if
(
buffer_size
)
{
NTSTATUS
rc
;
ULONG
out_length
;
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
packet
->
reportBuffer
=
(
BYTE
*
)
packet
+
sizeof
(
*
packet
);
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
;
}
rc
=
copy_packet_into_buffer
(
packet
,
irp
->
AssociatedIrp
.
SystemBuffer
,
irpsp
->
Parameters
.
Read
.
Length
,
&
out_length
);
irp
->
IoStatus
.
u
.
Status
=
rc
;
irp
->
IoStatus
.
Information
=
out_length
;
}
else
{
...
...
@@ -331,7 +351,10 @@ static DWORD CALLBACK hid_device_thread(void *args)
if
(
!
exit_now
&&
irp
->
IoStatus
.
u
.
Status
==
STATUS_SUCCESS
)
{
packet
->
reportBufferLen
=
irp
->
IoStatus
.
Information
;
packet
->
reportId
=
packet
->
reportBuffer
[
0
];
if
(
ext
->
preparseData
->
InputReports
[
0
].
reportID
)
packet
->
reportId
=
packet
->
reportBuffer
[
0
];
else
packet
->
reportId
=
0
;
RingBuffer_Write
(
ext
->
ring_buffer
,
packet
);
HID_Device_processQueue
(
device
);
}
...
...
@@ -461,9 +484,17 @@ static NTSTATUS HID_set_to_device(DEVICE_OBJECT *device, IRP *irp)
NTSTATUS
rc
;
TRACE_
(
hid_report
)(
"Device %p Buffer length %i Buffer %p
\n
"
,
device
,
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
,
irp
->
AssociatedIrp
.
SystemBuffer
);
packet
.
reportBuffer
=
irp
->
AssociatedIrp
.
SystemBuffer
;
packet
.
reportId
=
((
char
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
0
];
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
;
packet
.
reportId
=
((
BYTE
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
0
];
if
(
packet
.
reportId
==
0
)
{
packet
.
reportBuffer
=
&
((
BYTE
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
1
];
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
-
1
;
}
else
{
packet
.
reportBuffer
=
irp
->
AssociatedIrp
.
SystemBuffer
;
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
DeviceIoControl
.
InputBufferLength
;
}
TRACE_
(
hid_report
)(
"(id %i, len %i buffer %p)
\n
"
,
packet
.
reportId
,
packet
.
reportBufferLen
,
packet
.
reportBuffer
);
rc
=
call_minidriver
(
irpsp
->
Parameters
.
DeviceIoControl
.
IoControlCode
,
...
...
@@ -636,20 +667,15 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp)
if
(
buffer_size
)
{
IO_STACK_LOCATION
*
irpsp
=
IoGetCurrentIrpStackLocation
(
irp
);
NTSTATUS
rc
;
ULONG
out_length
;
packet
->
reportBuffer
=
(
BYTE
*
)
packet
+
sizeof
(
*
packet
);
TRACE_
(
hid_report
)(
"Got Packet %p %i
\n
"
,
packet
->
reportBuffer
,
packet
->
reportBufferLen
);
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
;
}
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
rc
=
copy_packet_into_buffer
(
packet
,
irp
->
AssociatedIrp
.
SystemBuffer
,
irpsp
->
Parameters
.
Read
.
Length
,
&
out_length
);
irp
->
IoStatus
.
Information
=
out_length
;
irp
->
IoStatus
.
u
.
Status
=
rc
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
}
else
{
...
...
@@ -671,9 +697,17 @@ NTSTATUS WINAPI HID_Device_write(DEVICE_OBJECT *device, IRP *irp)
irp
->
IoStatus
.
Information
=
0
;
TRACE_
(
hid_report
)(
"Device %p Buffer length %i Buffer %p
\n
"
,
device
,
irpsp
->
Parameters
.
Write
.
Length
,
irp
->
AssociatedIrp
.
SystemBuffer
);
packet
.
reportBuffer
=
irp
->
AssociatedIrp
.
SystemBuffer
;
packet
.
reportId
=
((
char
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
0
];
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
Write
.
Length
;
packet
.
reportId
=
((
BYTE
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
0
];
if
(
packet
.
reportId
==
0
)
{
packet
.
reportBuffer
=
&
((
BYTE
*
)
irp
->
AssociatedIrp
.
SystemBuffer
)[
1
];
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
Write
.
Length
-
1
;
}
else
{
packet
.
reportBuffer
=
irp
->
AssociatedIrp
.
SystemBuffer
;
packet
.
reportBufferLen
=
irpsp
->
Parameters
.
Write
.
Length
;
}
TRACE_
(
hid_report
)(
"(id %i, len %i buffer %p)
\n
"
,
packet
.
reportId
,
packet
.
reportBufferLen
,
packet
.
reportBuffer
);
rc
=
call_minidriver
(
IOCTL_HID_WRITE_REPORT
,
device
,
NULL
,
0
,
&
packet
,
sizeof
(
packet
));
...
...
dlls/winebus.sys/bus_udev.c
View file @
d0039106
...
...
@@ -288,7 +288,23 @@ static NTSTATUS hidraw_set_output_report(DEVICE_OBJECT *device, UCHAR id, BYTE *
{
struct
platform_private
*
ext
=
impl_from_DEVICE_OBJECT
(
device
);
ssize_t
rc
;
rc
=
write
(
ext
->
device_fd
,
report
,
length
);
if
(
id
!=
0
)
rc
=
write
(
ext
->
device_fd
,
report
,
length
);
else
{
BYTE
report_buffer
[
1024
];
if
(
length
+
1
>
sizeof
(
report_buffer
))
{
ERR
(
"Output report buffer too small
\n
"
);
return
STATUS_UNSUCCESSFUL
;
}
report_buffer
[
0
]
=
0
;
memcpy
(
&
report_buffer
[
1
],
report
,
length
);
rc
=
write
(
ext
->
device_fd
,
report_buffer
,
length
+
1
);
}
if
(
rc
>
0
)
{
*
written
=
rc
;
...
...
@@ -306,6 +322,7 @@ static NTSTATUS hidraw_get_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE
#ifdef HAVE_LINUX_HIDRAW_H
int
rc
;
struct
platform_private
*
ext
=
impl_from_DEVICE_OBJECT
(
device
);
report
[
0
]
=
id
;
length
=
min
(
length
,
0x1fff
);
rc
=
ioctl
(
ext
->
device_fd
,
HIDIOCGFEATURE
(
length
),
report
);
if
(
rc
>=
0
)
...
...
@@ -329,8 +346,25 @@ static NTSTATUS hidraw_set_feature_report(DEVICE_OBJECT *device, UCHAR id, BYTE
#ifdef HAVE_LINUX_HIDRAW_H
int
rc
;
struct
platform_private
*
ext
=
impl_from_DEVICE_OBJECT
(
device
);
BYTE
*
feature_buffer
;
BYTE
buffer
[
1024
];
if
(
id
==
0
)
{
if
(
length
+
1
>
sizeof
(
feature_buffer
))
{
ERR
(
"Output feature buffer too small
\n
"
);
return
STATUS_UNSUCCESSFUL
;
}
buffer
[
0
]
=
0
;
memcpy
(
&
buffer
[
1
],
report
,
length
);
feature_buffer
=
buffer
;
length
=
length
+
1
;
}
else
feature_buffer
=
report
;
length
=
min
(
length
,
0x1fff
);
rc
=
ioctl
(
ext
->
device_fd
,
HIDIOCSFEATURE
(
length
),
report
);
rc
=
ioctl
(
ext
->
device_fd
,
HIDIOCSFEATURE
(
length
),
feature_buffer
);
if
(
rc
>=
0
)
{
*
written
=
rc
;
...
...
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