Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hid multi TLC and Fanatec wheel-bases hidraw white-list #269

Open
wants to merge 2 commits into
base: proton_9.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions dlls/dinput/tests/hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,6 @@ void hid_device_stop( struct hid_device_desc *desc, UINT count )
for (i = 0; i < count; ++i)
{
ret = WaitForSingleObject( device_removed, i > 0 ? 500 : 5000 );
todo_wine_if(i > 0)
ok( !ret, "WaitForSingleObject returned %#lx\n", ret );
}
}
Expand Down Expand Up @@ -4017,8 +4016,27 @@ static void test_hid_multiple_tlc(void)
.usage_page = 0x01,
},
};
struct hid_expect input[] =
{
{
.code = IOCTL_HID_READ_REPORT,
.report_len = desc.caps.InputReportByteLength,
.report_buf = {1,0x01,0x02,0x03,0x04,0x05,0x06},
.ret_length = 6,
.ret_status = STATUS_SUCCESS,
},
{
.code = IOCTL_HID_READ_REPORT,
.report_len = desc.caps.InputReportByteLength,
.report_buf = {2,0x11,0x12,0x13,0x14,0x15,0x16},
.ret_length = 6,
.ret_status = STATUS_SUCCESS,
},
};

WCHAR device_path[MAX_PATH];
char report[16];
ULONG value;
HANDLE file;
BOOL ret;

Expand All @@ -4031,15 +4049,24 @@ static void test_hid_multiple_tlc(void)
swprintf( device_path, MAX_PATH, L"\\\\?\\hid#vid_%04x&pid_%04x&col01", desc.attributes.VendorID,
desc.attributes.ProductID );
ret = find_hid_device_path( device_path );
todo_wine
ok( ret, "Failed to find HID device matching %s\n", debugstr_w( device_path ) );
if (!ret) goto done;

file = CreateFileW( device_path, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
check_preparsed_data( file, &expect_kdr_joystick, ARRAY_SIZE(expect_caps_joystick), expect_caps_joystick,
ARRAY_SIZE(expect_nodes_joystick), expect_nodes_joystick );

send_hid_input( file, input, sizeof(input) );

memset( report, 0xcd, sizeof(report) );
SetLastError( 0xdeadbeef );
ret = ReadFile( file, report, desc.caps.InputReportByteLength, &value, NULL );
ok( ret, "ReadFile failed, last error %lu\n", GetLastError() );
ok( value == 6, "ReadFile returned %lx\n", value );
ok( report[0] == 1, "unexpected report data\n" );
ok( report[1] == 0x01, "unexpected report data\n" );

CloseHandle( file );

swprintf( device_path, MAX_PATH, L"\\\\?\\hid#vid_%04x&pid_%04x&col02", desc.attributes.VendorID,
Expand All @@ -4052,6 +4079,17 @@ static void test_hid_multiple_tlc(void)
ok( file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError() );
check_preparsed_data( file, &expect_kdr_gamepad, ARRAY_SIZE(expect_caps_gamepad), expect_caps_gamepad,
ARRAY_SIZE(expect_nodes_gamepad), expect_nodes_gamepad );

send_hid_input( file, input, sizeof(input) );

memset( report, 0xcd, sizeof(report) );
SetLastError( 0xdeadbeef );
ret = ReadFile( file, report, desc.caps.InputReportByteLength, &value, NULL );
ok( ret, "ReadFile failed, last error %lu\n", GetLastError() );
ok( value == 6, "ReadFile returned %lx\n", value );
ok( report[0] == 2, "unexpected report data\n" );
ok( report[1] == 0x11, "unexpected report data\n" );

CloseHandle( file );

swprintf( device_path, MAX_PATH, L"\\\\?\\hid#vid_%04x&pid_%04x&col03", desc.attributes.VendorID,
Expand Down
14 changes: 8 additions & 6 deletions dlls/hidclass.sys/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ static struct hid_report *hid_queue_pop_report( struct hid_queue *queue )
static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *packet )
{
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc;
const BOOL polled = ext->u.pdo.information.Polled;
ULONG size, report_len = polled ? packet->reportBufferLen : desc->InputLength;
struct hid_report *last_report, *report;
Expand Down Expand Up @@ -303,11 +303,13 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack

static HIDP_REPORT_IDS *find_report_with_type_and_id( BASE_DEVICE_EXTENSION *ext, BYTE type, BYTE id, BOOL any_id )
{
HIDP_REPORT_IDS *report, *reports = ext->u.pdo.device_desc.ReportIDs;
ULONG report_count = ext->u.pdo.device_desc.ReportIDsLength;
BASE_DEVICE_EXTENSION *fdo_ext = ext->u.pdo.parent_fdo->DeviceExtension;
HIDP_REPORT_IDS *report, *reports = fdo_ext->u.fdo.device_desc.ReportIDs;
ULONG report_count = fdo_ext->u.fdo.device_desc.ReportIDsLength;

for (report = reports; report != reports + report_count; report++)
{
if (ext->u.pdo.collection_desc->CollectionNumber != report->CollectionNumber) continue;
if (!any_id && report->ReportID && report->ReportID != id) continue;
if (type == HidP_Input && report->InputLength) return report;
if (type == HidP_Output && report->OutputLength) return report;
Expand All @@ -321,7 +323,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
{
DEVICE_OBJECT *device = (DEVICE_OBJECT*)args;
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc;
BOOL polled = ext->u.pdo.information.Polled;
HIDP_REPORT_IDS *report;
HID_XFER_PACKET *packet;
Expand Down Expand Up @@ -627,7 +629,7 @@ NTSTATUS WINAPI pdo_ioctl(DEVICE_OBJECT *device, IRP *irp)
}
case IOCTL_HID_GET_COLLECTION_DESCRIPTOR:
{
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc;

irp->IoStatus.Information = desc->PreparsedDataLength;
if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < desc->PreparsedDataLength)
Expand Down Expand Up @@ -699,7 +701,7 @@ NTSTATUS WINAPI pdo_read(DEVICE_OBJECT *device, IRP *irp)
{
struct hid_queue *queue = irp->Tail.Overlay.OriginalFileObject->FsContext;
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.collection_desc;
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
struct hid_report *report;
BOOL removed;
Expand Down
9 changes: 7 additions & 2 deletions dlls/hidclass.sys/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,20 @@ typedef struct _BASE_DEVICE_EXTENSION
/* this must be the first member */
HID_DEVICE_EXTENSION hid_ext;

DEVICE_OBJECT *child_pdo;
HID_DEVICE_ATTRIBUTES attrs;
HIDP_DEVICE_DESC device_desc;
WCHAR serial[256];

DEVICE_OBJECT **child_pdos;
UINT child_count;
} fdo;

struct
{
DEVICE_OBJECT *parent_fdo;

HIDP_COLLECTION_DESC *collection_desc;
HID_COLLECTION_INFORMATION information;
HIDP_DEVICE_DESC device_desc;

ULONG poll_interval;
HANDLE halt_event;
Expand Down
Loading