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
150f1797
Commit
150f1797
authored
Jan 31, 2017
by
Aric Stewart
Committed by
Alexandre Julliard
Feb 01, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
hid/tests: Test device reads.
Signed-off-by:
Aric Stewart
<
aric@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
bc84397e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
221 additions
and
0 deletions
+221
-0
device.c
dlls/hid/tests/device.c
+221
-0
No files found.
dlls/hid/tests/device.c
View file @
150f1797
...
...
@@ -16,14 +16,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windows.h"
#include "setupapi.h"
#include "hidusage.h"
#include "ddk/hidsdi.h"
#include "wine/test.h"
#define READ_MAX_TIME 5000
typedef
void
(
device_test
)(
HANDLE
device
);
static
void
test_device_info
(
HANDLE
device
)
...
...
@@ -85,7 +89,224 @@ static void run_for_each_device(device_test *test)
SetupDiDestroyDeviceInfoList
(
info_set
);
}
static
HANDLE
get_device
(
USHORT
page
,
USHORT
usages
[],
UINT
usage_count
,
DWORD
access
)
{
GUID
hid_guid
;
HDEVINFO
info_set
;
DWORD
index
=
0
;
SP_DEVICE_INTERFACE_DATA
interface_data
;
DWORD
detail_size
=
MAX_PATH
*
sizeof
(
WCHAR
);
SP_DEVICE_INTERFACE_DETAIL_DATA_W
*
data
;
NTSTATUS
status
;
BOOL
rc
;
HidD_GetHidGuid
(
&
hid_guid
);
ZeroMemory
(
&
interface_data
,
sizeof
(
interface_data
));
interface_data
.
cbSize
=
sizeof
(
interface_data
);
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
)
+
detail_size
);
data
->
cbSize
=
sizeof
(
*
data
);
info_set
=
SetupDiGetClassDevsW
(
&
hid_guid
,
NULL
,
NULL
,
DIGCF_DEVICEINTERFACE
);
while
(
SetupDiEnumDeviceInterfaces
(
info_set
,
NULL
,
&
hid_guid
,
index
,
&
interface_data
))
{
index
++
;
if
(
SetupDiGetDeviceInterfaceDetailW
(
info_set
,
&
interface_data
,
data
,
sizeof
(
*
data
)
+
detail_size
,
NULL
,
NULL
))
{
PHIDP_PREPARSED_DATA
ppd
;
HIDP_CAPS
Caps
;
HANDLE
file
=
CreateFileW
(
data
->
DevicePath
,
access
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
OPEN_EXISTING
,
FILE_FLAG_OVERLAPPED
,
0
);
if
(
file
==
INVALID_HANDLE_VALUE
)
{
trace
(
"Failed to access device %s, likely not plugged in or access is denied.
\n
"
,
wine_dbgstr_w
(
data
->
DevicePath
));
continue
;
}
rc
=
HidD_GetPreparsedData
(
file
,
&
ppd
);
ok
(
rc
,
"Failed to get preparsed data(0x%x)
\n
"
,
GetLastError
());
status
=
HidP_GetCaps
(
ppd
,
&
Caps
);
ok
(
status
==
HIDP_STATUS_SUCCESS
,
"Failed to get Caps(0x%x)
\n
"
,
status
);
rc
=
HidD_FreePreparsedData
(
ppd
);
ok
(
rc
,
"Failed to free preparsed data(0x%x)
\n
"
,
GetLastError
());
if
(
!
page
||
page
==
Caps
.
UsagePage
)
{
int
j
;
if
(
!
usage_count
)
{
HeapFree
(
GetProcessHeap
(),
0
,
data
);
SetupDiDestroyDeviceInfoList
(
info_set
);
return
file
;
}
for
(
j
=
0
;
j
<
usage_count
;
j
++
)
if
(
!
usages
[
j
]
||
usages
[
j
]
==
Caps
.
Usage
)
{
HeapFree
(
GetProcessHeap
(),
0
,
data
);
SetupDiDestroyDeviceInfoList
(
info_set
);
return
file
;
}
}
CloseHandle
(
file
);
}
}
HeapFree
(
GetProcessHeap
(),
0
,
data
);
SetupDiDestroyDeviceInfoList
(
info_set
);
return
NULL
;
}
static
void
process_data
(
HIDP_CAPS
Caps
,
PHIDP_PREPARSED_DATA
ppd
,
CHAR
*
data
,
DWORD
data_length
)
{
INT
i
;
NTSTATUS
status
;
if
(
Caps
.
NumberInputButtonCaps
)
{
USAGE
button_pages
[
100
];
for
(
i
=
1
;
i
<
0xff
;
i
++
)
{
ULONG
usage_length
=
100
;
status
=
HidP_GetUsages
(
HidP_Input
,
i
,
0
,
button_pages
,
&
usage_length
,
ppd
,
data
,
data_length
);
ok
(
status
==
HIDP_STATUS_SUCCESS
||
(
status
!=
HIDP_STATUS_SUCCESS
&&
usage_length
==
0
),
"HidP_GetUsages failed (%x) but usage length still %i
\n
"
,
status
,
usage_length
);
if
(
usage_length
)
{
CHAR
report
[
50
];
int
count
;
int
j
;
count
=
usage_length
;
j
=
0
;
report
[
0
]
=
0
;
trace
(
"
\t
Buttons [0x%x: %i buttons]:
\n
"
,
i
,
usage_length
);
for
(
count
=
0
;
count
<
usage_length
;
count
+=
15
)
{
for
(
j
=
count
;
j
<
count
+
15
&&
j
<
usage_length
;
j
++
)
{
CHAR
btn
[
5
];
sprintf
(
btn
,
"%i "
,
button_pages
[
j
]);
strcat
(
report
,
btn
);
}
trace
(
"
\t\t
%s
\n
"
,
report
);
}
}
}
}
if
(
Caps
.
NumberInputValueCaps
)
{
ULONG
value
;
USHORT
length
;
HIDP_VALUE_CAPS
*
values
=
NULL
;
values
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
HIDP_VALUE_CAPS
)
*
Caps
.
NumberInputValueCaps
);
length
=
Caps
.
NumberInputValueCaps
;
status
=
HidP_GetValueCaps
(
HidP_Input
,
values
,
&
length
,
ppd
);
ok
(
status
==
HIDP_STATUS_SUCCESS
,
"Failed to get value caps (%x)
\n
"
,
status
);
trace
(
"
\t
Values:
\n
"
);
for
(
i
=
0
;
i
<
length
;
i
++
)
{
status
=
HidP_GetUsageValue
(
HidP_Input
,
values
[
i
].
UsagePage
,
0
,
values
[
i
].
Range
.
UsageMin
,
&
value
,
ppd
,
data
,
data_length
);
ok
(
status
==
HIDP_STATUS_SUCCESS
,
"Failed to get value [%i,%i] (%x)
\n
"
,
values
[
i
].
UsagePage
,
values
[
i
].
Range
.
UsageMin
,
status
);
trace
(
"[%02x, %02x]: %u
\n
"
,
values
[
i
].
UsagePage
,
values
[
i
].
Range
.
UsageMin
,
value
);
}
HeapFree
(
GetProcessHeap
(),
0
,
values
);
}
}
static
void
test_read_device
(
void
)
{
PHIDP_PREPARSED_DATA
ppd
;
HIDP_CAPS
Caps
;
OVERLAPPED
overlapped
;
WCHAR
device_name
[
128
];
CHAR
*
data
=
NULL
;
DWORD
read
;
BOOL
rc
;
NTSTATUS
status
;
DWORD
timeout
,
tick
,
spent
,
max_time
;
char
*
report
;
USAGE
device_usages
[]
=
{
HID_USAGE_GENERIC_JOYSTICK
,
HID_USAGE_GENERIC_GAMEPAD
};
HANDLE
device
=
get_device
(
HID_USAGE_PAGE_GENERIC
,
device_usages
,
2
,
GENERIC_READ
);
if
(
!
device
)
device
=
get_device
(
0x0
,
NULL
,
0x0
,
GENERIC_READ
);
if
(
!
device
)
{
trace
(
"No device found for reading
\n
"
);
return
;
}
rc
=
HidD_GetProductString
(
device
,
device_name
,
sizeof
(
device_name
));
ok
(
rc
,
"Failed to get product string(0x%x)
\n
"
,
GetLastError
());
trace
(
"Read tests on device :%s
\n
"
,
wine_dbgstr_w
(
device_name
));
rc
=
HidD_GetPreparsedData
(
device
,
&
ppd
);
ok
(
rc
,
"Failed to get preparsed data(0x%x)
\n
"
,
GetLastError
());
status
=
HidP_GetCaps
(
ppd
,
&
Caps
);
ok
(
status
==
HIDP_STATUS_SUCCESS
,
"Failed to get Caps(0x%x)
\n
"
,
status
);
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
Caps
.
InputReportByteLength
);
memset
(
&
overlapped
,
0
,
sizeof
(
overlapped
));
overlapped
.
hEvent
=
CreateEventA
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
winetest_interactive
)
{
max_time
=
READ_MAX_TIME
;
timeout
=
1000
;
}
else
max_time
=
timeout
=
100
;
if
(
winetest_interactive
)
trace
(
"Test your device for the next %i seconds
\n
"
,
max_time
/
1000
);
report
=
HeapAlloc
(
GetProcessHeap
(),
0
,
3
*
Caps
.
InputReportByteLength
);
tick
=
GetTickCount
();
spent
=
0
;
do
{
ReadFile
(
device
,
data
,
Caps
.
InputReportByteLength
,
NULL
,
&
overlapped
);
if
(
WaitForSingleObject
(
overlapped
.
hEvent
,
timeout
)
!=
WAIT_OBJECT_0
)
{
ResetEvent
(
overlapped
.
hEvent
);
spent
=
GetTickCount
()
-
tick
;
trace
(
"REMAINING: %d ms
\n
"
,
max_time
-
spent
);
continue
;
}
ResetEvent
(
overlapped
.
hEvent
);
spent
=
GetTickCount
()
-
tick
;
GetOverlappedResult
(
device
,
&
overlapped
,
&
read
,
FALSE
);
if
(
read
)
{
int
i
;
report
[
0
]
=
0
;
for
(
i
=
0
;
i
<
read
&&
i
<
Caps
.
InputReportByteLength
;
i
++
)
{
char
bytestr
[
5
];
sprintf
(
bytestr
,
"%x "
,
(
BYTE
)
data
[
i
]);
strcat
(
report
,
bytestr
);
}
trace
(
"Input report (%i): %s
\n
"
,
read
,
report
);
process_data
(
Caps
,
ppd
,
data
,
read
);
}
trace
(
"REMAINING: %d ms
\n
"
,
max_time
-
spent
);
}
while
(
spent
<
max_time
);
CloseHandle
(
overlapped
.
hEvent
);
rc
=
HidD_FreePreparsedData
(
ppd
);
ok
(
rc
,
"Failed to free preparsed data(0x%x)
\n
"
,
GetLastError
());
CloseHandle
(
device
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
HeapFree
(
GetProcessHeap
(),
0
,
report
);
}
START_TEST
(
device
)
{
run_for_each_device
(
test_device_info
);
test_read_device
();
}
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