Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
10ddee1c
Commit
10ddee1c
authored
Sep 14, 2021
by
Rémi Bernon
Committed by
Alexandre Julliard
Sep 14, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dinput8/tests: Control expected READ_REPORT reports from the test executable.
Signed-off-by:
Rémi Bernon
<
rbernon@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1eb56b20
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
155 additions
and
21 deletions
+155
-21
driver_hid.c
dlls/dinput8/tests/driver_hid.c
+104
-21
driver_hid.h
dlls/dinput8/tests/driver_hid.h
+1
-0
hid.c
dlls/dinput8/tests/hid.c
+50
-0
No files found.
dlls/dinput8/tests/driver_hid.c
View file @
10ddee1c
...
...
@@ -199,11 +199,97 @@ static void irp_queue_init( struct irp_queue *queue )
InitializeListHead
(
&
queue
->
list
);
}
struct
input_queue
{
KSPIN_LOCK
lock
;
struct
hid_expect
*
pos
;
struct
hid_expect
*
end
;
struct
hid_expect
*
buffer
;
struct
irp_queue
pending
;
};
static
void
input_queue_init
(
struct
input_queue
*
queue
)
{
KeInitializeSpinLock
(
&
queue
->
lock
);
queue
->
buffer
=
ExAllocatePool
(
PagedPool
,
EXPECT_QUEUE_BUFFER_SIZE
);
RtlSecureZeroMemory
(
queue
->
buffer
,
EXPECT_QUEUE_BUFFER_SIZE
);
queue
->
pos
=
queue
->
buffer
;
queue
->
end
=
queue
->
buffer
;
irp_queue_init
(
&
queue
->
pending
);
}
static
void
input_queue_cleanup
(
struct
input_queue
*
queue
)
{
ExFreePool
(
queue
->
buffer
);
}
static
BOOL
input_queue_read_locked
(
struct
input_queue
*
queue
,
IRP
*
irp
)
{
struct
hid_expect
*
tmp
=
queue
->
pos
;
if
(
tmp
>=
queue
->
end
)
return
FALSE
;
memcpy
(
irp
->
UserBuffer
,
tmp
->
report_buf
,
tmp
->
ret_length
);
irp
->
IoStatus
.
Information
=
tmp
->
ret_length
;
irp
->
IoStatus
.
Status
=
tmp
->
ret_status
;
if
(
tmp
<
queue
->
end
)
queue
->
pos
=
tmp
+
1
;
/* loop on the queue data in polled mode */
if
(
polled
&&
queue
->
pos
==
queue
->
end
)
queue
->
pos
=
queue
->
buffer
;
return
TRUE
;
}
static
NTSTATUS
input_queue_read
(
struct
input_queue
*
queue
,
IRP
*
irp
)
{
NTSTATUS
status
;
KIRQL
irql
;
KeAcquireSpinLock
(
&
queue
->
lock
,
&
irql
);
if
(
input_queue_read_locked
(
queue
,
irp
))
status
=
STATUS_SUCCESS
;
else
{
IoMarkIrpPending
(
irp
);
irp_queue_push
(
&
queue
->
pending
,
irp
);
status
=
STATUS_PENDING
;
}
KeReleaseSpinLock
(
&
queue
->
lock
,
irql
);
return
status
;
}
static
void
input_queue_reset
(
struct
input_queue
*
queue
,
void
*
in_buf
,
ULONG
in_size
)
{
struct
irp_queue
completed
;
ULONG
remaining
;
KIRQL
irql
;
IRP
*
irp
;
irp_queue_init
(
&
completed
);
KeAcquireSpinLock
(
&
queue
->
lock
,
&
irql
);
remaining
=
queue
->
end
-
queue
->
pos
;
queue
->
pos
=
queue
->
buffer
;
queue
->
end
=
queue
->
buffer
;
memcpy
(
queue
->
end
,
in_buf
,
in_size
);
queue
->
end
+=
in_size
/
sizeof
(
struct
hid_expect
);
while
(
!
polled
&&
queue
->
pos
<
queue
->
end
&&
(
irp
=
irp_queue_pop
(
&
queue
->
pending
)))
{
input_queue_read_locked
(
queue
,
irp
);
irp_queue_push
(
&
completed
,
irp
);
}
KeReleaseSpinLock
(
&
queue
->
lock
,
irql
);
if
(
!
polled
)
ok
(
!
remaining
,
"unread input
\n
"
);
while
((
irp
=
irp_queue_pop
(
&
completed
)))
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
}
static
struct
input_queue
input_queue
;
struct
hid_device
{
BOOL
removed
;
KSPIN_LOCK
lock
;
struct
irp_queue
irp_queue
;
};
static
NTSTATUS
WINAPI
driver_pnp
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
...
...
@@ -221,7 +307,6 @@ static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp )
++
got_start_device
;
impl
->
removed
=
FALSE
;
KeInitializeSpinLock
(
&
impl
->
lock
);
irp_queue_init
(
&
impl
->
irp_queue
);
IoSetDeviceInterfaceState
(
&
control_symlink
,
TRUE
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
...
...
@@ -231,7 +316,7 @@ static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp )
KeAcquireSpinLock
(
&
impl
->
lock
,
&
irql
);
impl
->
removed
=
TRUE
;
KeReleaseSpinLock
(
&
impl
->
lock
,
irql
);
irp_queue_clear
(
&
i
mpl
->
irp_queue
);
irp_queue_clear
(
&
i
nput_queue
.
pending
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
...
...
@@ -247,7 +332,7 @@ static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp )
break
;
case
IRP_MN_REMOVE_DEVICE
:
irp_queue_clear
(
&
i
mpl
->
irp_queue
);
irp_queue_clear
(
&
i
nput_queue
.
pending
);
IoSetDeviceInterfaceState
(
&
control_symlink
,
FALSE
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
break
;
...
...
@@ -275,10 +360,9 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
HID_DEVICE_EXTENSION
*
ext
=
device
->
DeviceExtension
;
struct
hid_device
*
impl
=
ext
->
MiniDeviceExtension
;
const
ULONG
in_size
=
stack
->
Parameters
.
DeviceIoControl
.
InputBufferLength
;
const
ULONG
out_size
=
stack
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
;
ULONG
out_size
=
stack
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
;
const
ULONG
code
=
stack
->
Parameters
.
DeviceIoControl
.
IoControlCode
;
struct
hid_expect
expect
=
{
0
};
static
BYTE
seq
=
0
;
NTSTATUS
ret
;
BOOL
removed
;
KIRQL
irql
;
...
...
@@ -358,21 +442,7 @@ static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
ULONG
expected_size
=
caps
.
InputReportByteLength
-
(
report_id
?
0
:
1
);
ok
(
!
in_size
,
"got input size %u
\n
"
,
in_size
);
ok
(
out_size
==
expected_size
,
"got output size %u
\n
"
,
out_size
);
if
(
polled
)
{
memset
(
irp
->
UserBuffer
,
0xa5
,
expected_size
);
if
(
report_id
)
((
char
*
)
irp
->
UserBuffer
)[
0
]
=
report_id
;
((
char
*
)
irp
->
UserBuffer
)[
1
]
=
seq
++
;
irp
->
IoStatus
.
Information
=
3
;
ret
=
STATUS_SUCCESS
;
}
else
{
IoMarkIrpPending
(
irp
);
irp_queue_push
(
&
impl
->
irp_queue
,
irp
);
ret
=
STATUS_PENDING
;
}
ret
=
input_queue_read
(
&
input_queue
,
irp
);
break
;
}
...
...
@@ -535,6 +605,11 @@ static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp )
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
STATUS_SUCCESS
;
case
IOCTL_WINETEST_HID_SEND_INPUT
:
input_queue_reset
(
&
input_queue
,
irp
->
AssociatedIrp
.
SystemBuffer
,
in_size
);
irp
->
IoStatus
.
Status
=
STATUS_SUCCESS
;
IoCompleteRequest
(
irp
,
IO_NO_INCREMENT
);
return
STATUS_SUCCESS
;
}
return
hidclass_driver_ioctl
(
device
,
irp
);
...
...
@@ -577,6 +652,7 @@ static NTSTATUS WINAPI driver_close( DEVICE_OBJECT *device, IRP *irp )
static
void
WINAPI
driver_unload
(
DRIVER_OBJECT
*
driver
)
{
input_queue_cleanup
(
&
input_queue
);
expect_queue_cleanup
(
&
expect_queue
);
winetest_cleanup
();
}
...
...
@@ -647,6 +723,13 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *registry )
ok
(
!
ret
,
"ZwQueryValueKey returned %#x
\n
"
,
ret
);
expect_queue_reset
(
&
expect_queue
,
buffer
+
info_size
,
size
-
info_size
);
input_queue_init
(
&
input_queue
);
RtlInitUnicodeString
(
&
name_str
,
L"Input"
);
size
=
info_size
+
EXPECT_QUEUE_BUFFER_SIZE
;
ret
=
ZwQueryValueKey
(
hkey
,
&
name_str
,
KeyValuePartialInformation
,
buffer
,
size
,
&
size
);
ok
(
!
ret
,
"ZwQueryValueKey returned %#x
\n
"
,
ret
);
input_queue_reset
(
&
input_queue
,
buffer
+
info_size
,
size
-
info_size
);
driver
->
DriverExtension
->
AddDevice
=
driver_add_device
;
driver
->
DriverUnload
=
driver_unload
;
driver
->
MajorFunction
[
IRP_MJ_PNP
]
=
driver_pnp
;
...
...
dlls/dinput8/tests/driver_hid.h
View file @
10ddee1c
...
...
@@ -40,6 +40,7 @@
DEFINE_GUID
(
control_class
,
0xdeadbeef
,
0x29ef
,
0x4538
,
0xa5
,
0xfd
,
0xb6
,
0x95
,
0x73
,
0xa3
,
0x62
,
0xc0
);
#define IOCTL_WINETEST_HID_SET_EXPECT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x800, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_WINETEST_HID_SEND_INPUT CTL_CODE(FILE_DEVICE_KEYBOARD, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS)
struct
hid_expect
{
...
...
dlls/dinput8/tests/hid.c
View file @
10ddee1c
...
...
@@ -743,6 +743,25 @@ static void set_hid_expect_( int line, HANDLE file, struct hid_expect *expect, D
ok
(
ret
,
"IOCTL_WINETEST_HID_SET_EXPECT failed, last error %u
\n
"
,
GetLastError
()
);
}
#define send_hid_input( a, b, c ) send_hid_input_( __LINE__, a, b, c )
static
void
send_hid_input_
(
int
line
,
HANDLE
file
,
struct
hid_expect
*
expect
,
DWORD
expect_size
)
{
const
char
*
source_file
;
BOOL
ret
;
int
i
;
source_file
=
strrchr
(
__FILE__
,
'/'
);
if
(
!
source_file
)
source_file
=
strrchr
(
__FILE__
,
'\\'
);
if
(
!
source_file
)
source_file
=
__FILE__
;
else
source_file
++
;
for
(
i
=
0
;
i
<
expect_size
/
sizeof
(
struct
hid_expect
);
++
i
)
snprintf
(
expect
[
i
].
context
,
ARRAY_SIZE
(
expect
[
i
].
context
),
"%s:%d"
,
source_file
,
line
);
ret
=
sync_ioctl
(
file
,
IOCTL_WINETEST_HID_SEND_INPUT
,
expect
,
expect_size
,
NULL
,
0
);
ok
(
ret
,
"IOCTL_WINETEST_HID_SEND_INPUT failed, last error %u
\n
"
,
GetLastError
()
);
}
static
void
test_hidp_get_input
(
HANDLE
file
,
int
report_id
,
ULONG
report_len
,
PHIDP_PREPARSED_DATA
preparsed
)
{
struct
hid_expect
expect
[]
=
...
...
@@ -2049,6 +2068,26 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
if
(
polled
)
{
struct
hid_expect
expect
[]
=
{
{
.
code
=
IOCTL_HID_READ_REPORT
,
.
report_len
=
caps
.
InputReportByteLength
-
(
report_id
?
0
:
1
),
.
report_buf
=
{
report_id
?
report_id
:
0x5a
,
0x5a
,
0
},
.
ret_length
=
3
,
.
ret_status
=
STATUS_SUCCESS
,
},
{
.
code
=
IOCTL_HID_READ_REPORT
,
.
report_len
=
caps
.
InputReportByteLength
-
(
report_id
?
0
:
1
),
.
report_buf
=
{
report_id
?
report_id
:
0x5a
,
0x5a
,
1
},
.
ret_length
=
3
,
.
ret_status
=
STATUS_SUCCESS
,
},
};
send_hid_input
(
file
,
expect
,
sizeof
(
expect
)
);
memset
(
report
,
0xcd
,
sizeof
(
report
)
);
SetLastError
(
0xdeadbeef
);
ret
=
ReadFile
(
file
,
report
,
caps
.
InputReportByteLength
,
&
value
,
NULL
);
...
...
@@ -2541,6 +2580,14 @@ static void test_hid_driver( DWORD report_id, DWORD polled )
.
NumberFeatureValueCaps
=
6
,
.
NumberFeatureDataIndices
=
8
,
};
const
struct
hid_expect
expect_in
=
{
.
code
=
IOCTL_HID_READ_REPORT
,
.
report_len
=
caps
.
InputReportByteLength
-
(
report_id
?
0
:
1
),
.
report_buf
=
{
report_id
?
report_id
:
0x5a
,
0x5a
,
0x5a
},
.
ret_length
=
3
,
.
ret_status
=
STATUS_SUCCESS
,
};
WCHAR
cwd
[
MAX_PATH
],
tempdir
[
MAX_PATH
];
LSTATUS
status
;
...
...
@@ -2572,6 +2619,9 @@ static void test_hid_driver( DWORD report_id, DWORD polled )
status
=
RegSetValueExW
(
hkey
,
L"Expect"
,
0
,
REG_BINARY
,
NULL
,
0
);
ok
(
!
status
,
"RegSetValueExW returned %#x
\n
"
,
status
);
status
=
RegSetValueExW
(
hkey
,
L"Input"
,
0
,
REG_BINARY
,
(
void
*
)
&
expect_in
,
polled
?
sizeof
(
expect_in
)
:
0
);
ok
(
!
status
,
"RegSetValueExW returned %#x
\n
"
,
status
);
if
(
pnp_driver_start
(
L"driver_hid.dll"
))
test_hid_device
(
report_id
,
polled
,
&
caps
);
pnp_driver_stop
();
...
...
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