dinput/tests: Create all HID devices from the Bus driver.
[wine.git] / dlls / dinput / tests / driver.c
blob38b4776a3f0aa0d9173618343c6d8a52bbddd3ac
1 /*
2 * HID Plug and Play test driver
4 * Copyright 2021 Zebediah Figura
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <stdio.h>
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winternl.h"
29 #include "winioctl.h"
30 #include "ddk/wdm.h"
31 #include "hidusage.h"
32 #include "ddk/hidpi.h"
33 #include "ddk/hidport.h"
35 #include "wine/list.h"
37 #include "initguid.h"
38 #include "driver_hid.h"
40 static UNICODE_STRING control_symlink;
42 static unsigned int got_start_device;
43 static HID_DEVICE_ATTRIBUTES attributes;
44 static char report_descriptor_buf[4096];
45 static DWORD report_descriptor_len;
46 static HIDP_CAPS caps;
47 static DWORD report_id;
48 static DWORD polled;
50 #define EXPECT_QUEUE_BUFFER_SIZE (64 * sizeof(struct hid_expect))
52 struct expect_queue
54 KSPIN_LOCK lock;
55 struct hid_expect *pos;
56 struct hid_expect *end;
57 struct hid_expect spurious;
58 struct hid_expect *buffer;
59 IRP *pending_wait;
60 char context[64];
63 static void expect_queue_init( struct expect_queue *queue )
65 KeInitializeSpinLock( &queue->lock );
66 queue->buffer = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE );
67 RtlSecureZeroMemory( queue->buffer, EXPECT_QUEUE_BUFFER_SIZE );
68 queue->pos = queue->buffer;
69 queue->end = queue->buffer;
72 static void expect_queue_cleanup( struct expect_queue *queue )
74 KIRQL irql;
75 IRP *irp;
77 KeAcquireSpinLock( &queue->lock, &irql );
78 if ((irp = queue->pending_wait))
80 queue->pending_wait = NULL;
81 if (!IoSetCancelRoutine( irp, NULL )) irp = NULL;
83 KeReleaseSpinLock( &queue->lock, irql );
85 if (irp)
87 irp->IoStatus.Information = 0;
88 irp->IoStatus.Status = STATUS_DELETE_PENDING;
89 IoCompleteRequest( irp, IO_NO_INCREMENT );
92 ExFreePool( queue->buffer );
95 static void expect_queue_reset( struct expect_queue *queue, void *buffer, unsigned int size )
97 struct hid_expect *missing, *missing_end, *tmp;
98 char context[64];
99 KIRQL irql;
101 missing = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE );
102 RtlSecureZeroMemory( missing, EXPECT_QUEUE_BUFFER_SIZE );
103 missing_end = missing;
105 KeAcquireSpinLock( &queue->lock, &irql );
106 tmp = queue->pos;
107 while (tmp < queue->end) *missing_end++ = *tmp++;
109 queue->pos = queue->buffer;
110 queue->end = queue->buffer;
112 if (size) memcpy( queue->end, buffer, size );
113 queue->end = queue->end + size / sizeof(struct hid_expect);
114 memcpy( context, queue->context, sizeof(context) );
115 KeReleaseSpinLock( &queue->lock, irql );
117 tmp = missing;
118 while (tmp != missing_end)
120 winetest_push_context( "%s expect[%Id]", context, tmp - missing );
121 if (tmp->broken)
123 todo_wine_if( tmp->todo )
124 win_skip( "broken (code %#lx id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len );
126 else
128 todo_wine_if( tmp->todo )
129 ok( tmp->wine_only, "missing (code %#lx id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len );
131 winetest_pop_context();
132 tmp++;
135 ExFreePool( missing );
138 static void WINAPI wait_cancel_routine( DEVICE_OBJECT *device, IRP *irp )
140 struct expect_queue *queue = irp->Tail.Overlay.DriverContext[0];
141 KIRQL irql;
143 IoReleaseCancelSpinLock( irp->CancelIrql );
145 KeAcquireSpinLock( &queue->lock, &irql );
146 queue->pending_wait = NULL;
147 KeReleaseSpinLock( &queue->lock, irql );
149 irp->IoStatus.Information = 0;
150 irp->IoStatus.Status = STATUS_CANCELLED;
151 IoCompleteRequest( irp, IO_NO_INCREMENT );
154 static NTSTATUS expect_queue_wait( struct expect_queue *queue, IRP *irp )
156 NTSTATUS status;
157 KIRQL irql;
159 KeAcquireSpinLock( &queue->lock, &irql );
160 if (queue->pos == queue->end)
161 status = STATUS_SUCCESS;
162 else
164 IoSetCancelRoutine( irp, wait_cancel_routine );
165 if (irp->Cancel && !IoSetCancelRoutine( irp, NULL ))
166 status = STATUS_CANCELLED;
167 else
169 irp->Tail.Overlay.DriverContext[0] = queue;
170 IoMarkIrpPending( irp );
171 queue->pending_wait = irp;
172 status = STATUS_PENDING;
175 KeReleaseSpinLock( &queue->lock, irql );
177 if (status == STATUS_SUCCESS)
179 irp->IoStatus.Status = STATUS_SUCCESS;
180 IoCompleteRequest( irp, IO_NO_INCREMENT );
183 return status;
186 static void expect_queue_next( struct expect_queue *queue, ULONG code, HID_XFER_PACKET *packet,
187 LONG *index, struct hid_expect *expect, BOOL compare_buf,
188 char *context, ULONG context_size )
190 struct hid_expect *missing, *missing_end, *tmp;
191 ULONG len = packet->reportBufferLen;
192 BYTE *buf = packet->reportBuffer;
193 BYTE id = packet->reportId;
194 IRP *irp = NULL;
195 KIRQL irql;
197 missing = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE );
198 RtlSecureZeroMemory( missing, EXPECT_QUEUE_BUFFER_SIZE );
199 missing_end = missing;
201 KeAcquireSpinLock( &queue->lock, &irql );
202 tmp = queue->pos;
203 while (tmp < queue->end)
205 if (running_under_wine && !tmp->todo) break;
206 if (!running_under_wine && !tmp->broken && !tmp->wine_only) break;
207 if (tmp->code == code && tmp->report_id == id && tmp->report_len == len &&
208 (!compare_buf || RtlCompareMemory( tmp->report_buf, buf, len ) == len))
209 break;
210 *missing_end++ = *tmp++;
212 *index = tmp - queue->buffer;
213 if (tmp < queue->end) queue->pos = tmp + 1;
214 else tmp = &queue->spurious;
215 *expect = *tmp;
217 while (queue->pos < queue->end)
219 if (running_under_wine || !queue->pos->wine_only) break;
220 queue->pos++;
222 if (queue->pos == queue->end && (irp = queue->pending_wait))
224 queue->pending_wait = NULL;
225 if (!IoSetCancelRoutine( irp, NULL )) irp = NULL;
227 memcpy( context, queue->context, context_size );
228 KeReleaseSpinLock( &queue->lock, irql );
230 if (irp)
232 irp->IoStatus.Information = 0;
233 irp->IoStatus.Status = STATUS_SUCCESS;
234 IoCompleteRequest( irp, IO_NO_INCREMENT );
237 ok( tmp != &queue->spurious, "%s got spurious packet\n", context );
239 winetest_push_context( "%s expect[%Id]", context, tmp - queue->buffer );
240 todo_wine_if( tmp->todo )
241 ok( !tmp->wine_only, "found code %#lx id %u len %u\n", tmp->code, tmp->report_id, tmp->report_len );
242 winetest_pop_context();
244 tmp = missing;
245 while (tmp != missing_end)
247 winetest_push_context( "%s expect[%Id]", context, tmp - missing );
248 if (tmp->broken)
250 todo_wine_if( tmp->todo )
251 win_skip( "broken (code %#lx id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len );
253 else
255 todo_wine_if( tmp->todo )
256 ok( tmp->wine_only, "missing (code %#lx id %u len %u)\n", tmp->code, tmp->report_id, tmp->report_len );
258 winetest_pop_context();
259 tmp++;
262 ExFreePool( missing );
265 static struct expect_queue expect_queue;
267 struct irp_queue
269 KSPIN_LOCK lock;
270 LIST_ENTRY list;
273 static IRP *irp_queue_pop( struct irp_queue *queue )
275 KIRQL irql;
276 IRP *irp;
278 KeAcquireSpinLock( &queue->lock, &irql );
279 if (IsListEmpty( &queue->list )) irp = NULL;
280 else irp = CONTAINING_RECORD( RemoveHeadList( &queue->list ), IRP, Tail.Overlay.ListEntry );
281 KeReleaseSpinLock( &queue->lock, irql );
283 return irp;
286 static void irp_queue_push( struct irp_queue *queue, IRP *irp )
288 KIRQL irql;
290 KeAcquireSpinLock( &queue->lock, &irql );
291 InsertTailList( &queue->list, &irp->Tail.Overlay.ListEntry );
292 KeReleaseSpinLock( &queue->lock, irql );
295 static void irp_queue_clear( struct irp_queue *queue )
297 IRP *irp;
299 while ((irp = irp_queue_pop( queue )))
301 irp->IoStatus.Status = STATUS_DELETE_PENDING;
302 IoCompleteRequest( irp, IO_NO_INCREMENT );
306 static void irp_queue_init( struct irp_queue *queue )
308 KeInitializeSpinLock( &queue->lock );
309 InitializeListHead( &queue->list );
312 struct input_queue
314 KSPIN_LOCK lock;
315 struct hid_expect *pos;
316 struct hid_expect *end;
317 struct hid_expect *buffer;
318 struct irp_queue pending;
321 static void input_queue_init( struct input_queue *queue )
323 KeInitializeSpinLock( &queue->lock );
324 queue->buffer = ExAllocatePool( PagedPool, EXPECT_QUEUE_BUFFER_SIZE );
325 RtlSecureZeroMemory( queue->buffer, EXPECT_QUEUE_BUFFER_SIZE );
326 queue->pos = queue->buffer;
327 queue->end = queue->buffer;
328 irp_queue_init( &queue->pending );
331 static void input_queue_cleanup( struct input_queue *queue )
333 ExFreePool( queue->buffer );
336 static BOOL input_queue_read_locked( struct input_queue *queue, IRP *irp )
338 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
339 ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength;
340 struct hid_expect *tmp = queue->pos;
342 if (tmp >= queue->end) return FALSE;
343 if (tmp->ret_length) out_size = tmp->ret_length;
345 memcpy( irp->UserBuffer, tmp->report_buf, out_size );
346 irp->IoStatus.Information = out_size;
347 irp->IoStatus.Status = tmp->ret_status;
348 if (tmp < queue->end) queue->pos = tmp + 1;
350 /* loop on the queue data in polled mode */
351 if (polled && queue->pos == queue->end) queue->pos = queue->buffer;
352 return TRUE;
355 static NTSTATUS input_queue_read( struct input_queue *queue, IRP *irp )
357 NTSTATUS status;
358 KIRQL irql;
360 KeAcquireSpinLock( &queue->lock, &irql );
361 if (input_queue_read_locked( queue, irp )) status = STATUS_SUCCESS;
362 else
364 IoMarkIrpPending( irp );
365 irp_queue_push( &queue->pending, irp );
366 status = STATUS_PENDING;
368 KeReleaseSpinLock( &queue->lock, irql );
370 return status;
373 static void input_queue_reset( struct input_queue *queue, void *in_buf, ULONG in_size )
375 struct irp_queue completed;
376 ULONG remaining;
377 KIRQL irql;
378 IRP *irp;
380 irp_queue_init( &completed );
382 KeAcquireSpinLock( &queue->lock, &irql );
383 remaining = queue->end - queue->pos;
384 queue->pos = queue->buffer;
385 queue->end = queue->buffer;
386 memcpy( queue->end, in_buf, in_size );
387 queue->end += in_size / sizeof(struct hid_expect);
389 while (!polled && queue->pos < queue->end && (irp = irp_queue_pop( &queue->pending )))
391 input_queue_read_locked( queue, irp );
392 irp_queue_push( &completed, irp );
394 KeReleaseSpinLock( &queue->lock, irql );
396 if (!polled) ok( !remaining, "unread input\n" );
398 while ((irp = irp_queue_pop( &completed ))) IoCompleteRequest( irp, IO_NO_INCREMENT );
401 static struct input_queue input_queue;
403 struct hid_device
405 BOOL removed;
406 KSPIN_LOCK lock;
409 static DRIVER_OBJECT *expect_driver;
410 static DEVICE_OBJECT *expect_bus_pdo;
411 static DEVICE_OBJECT *expect_hid_fdo;
412 static DEVICE_OBJECT *expect_hid_pdo;
413 static struct hid_device *expect_hid_ext;
415 static void check_device( DEVICE_OBJECT *device )
417 static int checked_fdo, checked_pdo;
418 HID_DEVICE_EXTENSION *ext = device->DeviceExtension;
420 ok( device == expect_hid_pdo || device == expect_hid_fdo, "got device %p\n", device );
421 ok( device->DriverObject == expect_driver, "got DriverObject %p\n", device->DriverObject );
422 if (!device->NextDevice) ok( device == expect_hid_fdo, "got device %p\n", device );
423 else ok( device->NextDevice == expect_hid_fdo, "got NextDevice %p\n", device->NextDevice );
424 ok( !device->AttachedDevice, "got AttachedDevice %p\n", device->AttachedDevice );
426 if (device == expect_hid_pdo && checked_pdo++) return;
427 if (device == expect_hid_fdo && checked_fdo++) return;
429 todo_wine_if( device != expect_hid_fdo )
430 ok( ext->MiniDeviceExtension == expect_hid_ext, "got MiniDeviceExtension %p\n", ext->MiniDeviceExtension );
431 if (ext->MiniDeviceExtension != expect_hid_ext) return;
432 ok( ext->PhysicalDeviceObject == expect_bus_pdo, "got PhysicalDeviceObject %p\n", ext->PhysicalDeviceObject );
433 ok( ext->NextDeviceObject == expect_bus_pdo, "got NextDeviceObject %p\n", ext->NextDeviceObject );
436 static NTSTATUS WINAPI driver_pnp( DEVICE_OBJECT *device, IRP *irp )
438 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
439 HID_DEVICE_EXTENSION *ext = device->DeviceExtension;
440 struct hid_device *impl = ext->MiniDeviceExtension;
441 ULONG code = stack->MinorFunction;
442 KIRQL irql;
444 if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_pnp(code) );
446 switch (code)
448 case IRP_MN_START_DEVICE:
449 ++got_start_device;
450 impl->removed = FALSE;
451 KeInitializeSpinLock( &impl->lock );
452 IoSetDeviceInterfaceState( &control_symlink, TRUE );
453 irp->IoStatus.Status = STATUS_SUCCESS;
454 break;
456 case IRP_MN_SURPRISE_REMOVAL:
457 case IRP_MN_QUERY_REMOVE_DEVICE:
458 KeAcquireSpinLock( &impl->lock, &irql );
459 impl->removed = TRUE;
460 KeReleaseSpinLock( &impl->lock, irql );
461 irp_queue_clear( &input_queue.pending );
462 irp->IoStatus.Status = STATUS_SUCCESS;
463 break;
465 case IRP_MN_CANCEL_REMOVE_DEVICE:
466 KeAcquireSpinLock( &impl->lock, &irql );
467 impl->removed = FALSE;
468 KeReleaseSpinLock( &impl->lock, irql );
469 irp->IoStatus.Status = STATUS_SUCCESS;
470 break;
472 case IRP_MN_STOP_DEVICE:
473 irp->IoStatus.Status = STATUS_SUCCESS;
474 break;
476 case IRP_MN_REMOVE_DEVICE:
477 irp_queue_clear( &input_queue.pending );
478 IoSetDeviceInterfaceState( &control_symlink, FALSE );
479 irp->IoStatus.Status = STATUS_SUCCESS;
480 break;
483 IoSkipCurrentIrpStackLocation( irp );
484 return IoCallDriver( ext->NextDeviceObject, irp );
487 #define check_buffer( a, b ) check_buffer_( __LINE__, a, b )
488 static void check_buffer_( int line, HID_XFER_PACKET *packet, struct hid_expect *expect )
490 ULONG match_len, i;
492 match_len = RtlCompareMemory( packet->reportBuffer, expect->report_buf, expect->report_len );
493 ok( match_len == expect->report_len, "unexpected data:\n" );
494 if (match_len == expect->report_len) return;
496 for (i = 0; i < packet->reportBufferLen;)
498 char buffer[256], *buf = buffer;
499 buf += sprintf( buf, "%08lx ", i );
500 do buf += sprintf( buf, " %02x", packet->reportBuffer[i] );
501 while (++i % 16 && i < packet->reportBufferLen);
502 ok( 0, " %s\n", buffer );
506 static NTSTATUS WINAPI driver_internal_ioctl( DEVICE_OBJECT *device, IRP *irp )
508 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
509 HID_DEVICE_EXTENSION *ext = device->DeviceExtension;
510 struct hid_device *impl = ext->MiniDeviceExtension;
511 const ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength;
512 ULONG out_size = stack->Parameters.DeviceIoControl.OutputBufferLength;
513 const ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
514 struct hid_expect expect = {0};
515 char context[64];
516 NTSTATUS ret;
517 BOOL removed;
518 KIRQL irql;
519 LONG index;
521 if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) );
523 ok( expect_hid_fdo == device, "got device %p\n", device );
524 check_device( device );
526 ok( got_start_device, "expected IRP_MN_START_DEVICE before any ioctls\n" );
528 irp->IoStatus.Information = 0;
530 KeAcquireSpinLock( &impl->lock, &irql );
531 removed = impl->removed;
532 KeReleaseSpinLock( &impl->lock, irql );
534 if (removed)
536 irp->IoStatus.Status = STATUS_DELETE_PENDING;
537 IoCompleteRequest( irp, IO_NO_INCREMENT );
538 return STATUS_DELETE_PENDING;
541 winetest_push_context( "id %ld%s", report_id, polled ? " poll" : "" );
543 switch (code)
545 case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
547 HID_DESCRIPTOR *desc = irp->UserBuffer;
549 ok( !in_size, "got input size %lu\n", in_size );
550 ok( out_size == sizeof(*desc), "got output size %lu\n", out_size );
552 if (out_size == sizeof(*desc))
554 ok( !desc->bLength, "got size %u\n", desc->bLength );
556 desc->bLength = sizeof(*desc);
557 desc->bDescriptorType = HID_HID_DESCRIPTOR_TYPE;
558 desc->bcdHID = HID_REVISION;
559 desc->bCountry = 0;
560 desc->bNumDescriptors = 1;
561 desc->DescriptorList[0].bReportType = HID_REPORT_DESCRIPTOR_TYPE;
562 desc->DescriptorList[0].wReportLength = report_descriptor_len;
563 irp->IoStatus.Information = sizeof(*desc);
565 ret = STATUS_SUCCESS;
566 break;
569 case IOCTL_HID_GET_REPORT_DESCRIPTOR:
570 ok( !in_size, "got input size %lu\n", in_size );
571 ok( out_size == report_descriptor_len, "got output size %lu\n", out_size );
573 if (out_size == report_descriptor_len)
575 memcpy( irp->UserBuffer, report_descriptor_buf, report_descriptor_len );
576 irp->IoStatus.Information = report_descriptor_len;
578 ret = STATUS_SUCCESS;
579 break;
581 case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
582 ok( !in_size, "got input size %lu\n", in_size );
583 ok( out_size == sizeof(attributes), "got output size %lu\n", out_size );
585 if (out_size == sizeof(attributes))
587 memcpy( irp->UserBuffer, &attributes, sizeof(attributes) );
588 irp->IoStatus.Information = sizeof(attributes);
590 ret = STATUS_SUCCESS;
591 break;
593 case IOCTL_HID_READ_REPORT:
595 ULONG expected_size = caps.InputReportByteLength - (report_id ? 0 : 1);
596 ok( !in_size, "got input size %lu\n", in_size );
597 ok( out_size == expected_size, "got output size %lu\n", out_size );
598 ret = input_queue_read( &input_queue, irp );
599 break;
602 case IOCTL_HID_WRITE_REPORT:
604 HID_XFER_PACKET *packet = irp->UserBuffer;
605 ULONG expected_size = caps.OutputReportByteLength - (report_id ? 0 : 1);
607 ok( in_size == sizeof(*packet), "got input size %lu\n", in_size );
608 ok( !out_size, "got output size %lu\n", out_size );
609 ok( packet->reportBufferLen >= expected_size, "got report size %lu\n", packet->reportBufferLen );
611 expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
612 winetest_push_context( "%s expect[%ld]", context, index );
613 ok( code == expect.code, "got %#lx, expected %#lx\n", code, expect.code );
614 ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
615 ok( packet->reportBufferLen == expect.report_len, "got len %lu\n", packet->reportBufferLen );
616 check_buffer( packet, &expect );
617 winetest_pop_context();
619 irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
620 ret = expect.ret_status;
621 break;
624 case IOCTL_HID_GET_INPUT_REPORT:
626 HID_XFER_PACKET *packet = irp->UserBuffer;
627 ULONG expected_size = caps.InputReportByteLength - (report_id ? 0 : 1);
628 ok( !in_size, "got input size %lu\n", in_size );
629 ok( out_size == sizeof(*packet), "got output size %lu\n", out_size );
631 ok( packet->reportBufferLen >= expected_size, "got len %lu\n", packet->reportBufferLen );
632 ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
634 expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) );
635 winetest_push_context( "%s expect[%ld]", context, index );
636 ok( code == expect.code, "got %#lx, expected %#lx\n", code, expect.code );
637 ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
638 ok( packet->reportBufferLen == expect.report_len, "got len %lu\n", packet->reportBufferLen );
639 winetest_pop_context();
641 irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
642 memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information );
643 ret = expect.ret_status;
644 break;
647 case IOCTL_HID_SET_OUTPUT_REPORT:
649 HID_XFER_PACKET *packet = irp->UserBuffer;
650 ULONG expected_size = caps.OutputReportByteLength - (report_id ? 0 : 1);
651 ok( in_size == sizeof(*packet), "got input size %lu\n", in_size );
652 ok( !out_size, "got output size %lu\n", out_size );
654 ok( packet->reportBufferLen >= expected_size, "got len %lu\n", packet->reportBufferLen );
655 ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
657 expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
658 winetest_push_context( "%s expect[%ld]", context, index );
659 ok( code == expect.code, "got %#lx, expected %#lx\n", code, expect.code );
660 ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
661 ok( packet->reportBufferLen == expect.report_len, "got len %lu\n", packet->reportBufferLen );
662 check_buffer( packet, &expect );
663 winetest_pop_context();
665 irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
666 ret = expect.ret_status;
667 break;
670 case IOCTL_HID_GET_FEATURE:
672 HID_XFER_PACKET *packet = irp->UserBuffer;
673 ULONG expected_size = caps.FeatureReportByteLength - (report_id ? 0 : 1);
674 ok( !in_size, "got input size %lu\n", in_size );
675 ok( out_size == sizeof(*packet), "got output size %lu\n", out_size );
677 ok( packet->reportBufferLen >= expected_size, "got len %lu\n", packet->reportBufferLen );
678 ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
680 expect_queue_next( &expect_queue, code, packet, &index, &expect, FALSE, context, sizeof(context) );
681 winetest_push_context( "%s expect[%ld]", context, index );
682 ok( code == expect.code, "got %#lx, expected %#lx\n", code, expect.code );
683 ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
684 ok( packet->reportBufferLen == expect.report_len, "got len %lu\n", packet->reportBufferLen );
685 winetest_pop_context();
687 irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
688 memcpy( packet->reportBuffer, expect.report_buf, irp->IoStatus.Information );
689 ret = expect.ret_status;
690 break;
693 case IOCTL_HID_SET_FEATURE:
695 HID_XFER_PACKET *packet = irp->UserBuffer;
696 ULONG expected_size = caps.FeatureReportByteLength - (report_id ? 0 : 1);
697 ok( in_size == sizeof(*packet), "got input size %lu\n", in_size );
698 ok( !out_size, "got output size %lu\n", out_size );
700 ok( packet->reportBufferLen >= expected_size, "got len %lu\n", packet->reportBufferLen );
701 ok( !!packet->reportBuffer, "got buffer %p\n", packet->reportBuffer );
703 expect_queue_next( &expect_queue, code, packet, &index, &expect, TRUE, context, sizeof(context) );
704 winetest_push_context( "%s expect[%ld]", context, index );
705 ok( code == expect.code, "got %#lx, expected %#lx\n", code, expect.code );
706 ok( packet->reportId == expect.report_id, "got id %u\n", packet->reportId );
707 ok( packet->reportBufferLen == expect.report_len, "got len %lu\n", packet->reportBufferLen );
708 check_buffer( packet, &expect );
709 winetest_pop_context();
711 irp->IoStatus.Information = expect.ret_length ? expect.ret_length : expect.report_len;
712 ret = expect.ret_status;
713 break;
716 case IOCTL_HID_GET_STRING:
718 memcpy( irp->UserBuffer, L"Wine Test", sizeof(L"Wine Test") );
719 irp->IoStatus.Information = sizeof(L"Wine Test");
720 ret = STATUS_SUCCESS;
721 break;
724 default:
725 ok( 0, "unexpected ioctl %#lx\n", code );
726 ret = STATUS_NOT_IMPLEMENTED;
729 winetest_pop_context();
731 if (ret != STATUS_PENDING)
733 irp->IoStatus.Status = ret;
734 IoCompleteRequest( irp, IO_NO_INCREMENT );
736 return ret;
739 static NTSTATUS (WINAPI *hidclass_driver_ioctl)( DEVICE_OBJECT *device, IRP *irp );
740 static NTSTATUS WINAPI driver_ioctl( DEVICE_OBJECT *device, IRP *irp )
742 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp );
743 ULONG in_size = stack->Parameters.DeviceIoControl.InputBufferLength;
744 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
745 KIRQL irql;
747 if (winetest_debug > 1) trace( "%s: device %p, code %#lx %s\n", __func__, device, code, debugstr_ioctl(code) );
749 if (!expect_hid_pdo) expect_hid_pdo = device;
750 else ok( expect_hid_pdo == device, "got device %p\n", device );
751 check_device( device );
753 switch (code)
755 case IOCTL_WINETEST_HID_SET_EXPECT:
756 expect_queue_reset( &expect_queue, irp->AssociatedIrp.SystemBuffer, in_size );
757 irp->IoStatus.Status = STATUS_SUCCESS;
758 IoCompleteRequest( irp, IO_NO_INCREMENT );
759 return STATUS_SUCCESS;
760 case IOCTL_WINETEST_HID_WAIT_EXPECT:
761 return expect_queue_wait( &expect_queue, irp );
762 case IOCTL_WINETEST_HID_SEND_INPUT:
763 input_queue_reset( &input_queue, irp->AssociatedIrp.SystemBuffer, in_size );
764 irp->IoStatus.Status = STATUS_SUCCESS;
765 IoCompleteRequest( irp, IO_NO_INCREMENT );
766 return STATUS_SUCCESS;
767 case IOCTL_WINETEST_HID_SET_CONTEXT:
768 KeAcquireSpinLock( &expect_queue.lock, &irql );
769 memcpy( expect_queue.context, irp->AssociatedIrp.SystemBuffer, in_size );
770 KeReleaseSpinLock( &expect_queue.lock, irql );
772 irp->IoStatus.Status = STATUS_SUCCESS;
773 IoCompleteRequest( irp, IO_NO_INCREMENT );
774 return STATUS_SUCCESS;
776 case IOCTL_WINETEST_REMOVE_DEVICE:
777 case IOCTL_WINETEST_CREATE_DEVICE:
778 ok( 0, "unexpected call\n" );
779 irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
780 IoCompleteRequest( irp, IO_NO_INCREMENT );
781 return STATUS_NOT_SUPPORTED;
784 return hidclass_driver_ioctl( device, irp );
787 static NTSTATUS WINAPI driver_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *device )
789 HID_DEVICE_EXTENSION *ext = device->DeviceExtension;
790 NTSTATUS ret;
792 if (winetest_debug > 1) trace( "%s: driver %p, device %p\n", __func__, driver, device );
794 expect_hid_fdo = device;
795 expect_bus_pdo = ext->PhysicalDeviceObject;
796 expect_hid_ext = ext->MiniDeviceExtension;
798 todo_wine
799 ok( expect_bus_pdo->AttachedDevice == device, "got AttachedDevice %p\n", expect_bus_pdo->AttachedDevice );
800 ok( driver == expect_driver, "got driver %p\n", driver );
801 check_device( device );
803 ret = IoRegisterDeviceInterface( ext->PhysicalDeviceObject, &control_class, NULL, &control_symlink );
804 ok( !ret, "got %#lx\n", ret );
806 if (winetest_debug > 1) trace( "Created HID FDO %p for Bus PDO %p\n", device, ext->PhysicalDeviceObject );
808 device->Flags &= ~DO_DEVICE_INITIALIZING;
809 return STATUS_SUCCESS;
812 static NTSTATUS WINAPI driver_create( DEVICE_OBJECT *device, IRP *irp )
814 if (winetest_debug > 1) trace( "%s: device %p\n", __func__, device );
815 ok( 0, "unexpected call\n" );
816 irp->IoStatus.Status = STATUS_SUCCESS;
817 IoCompleteRequest( irp, IO_NO_INCREMENT );
818 return STATUS_SUCCESS;
821 static NTSTATUS WINAPI driver_close( DEVICE_OBJECT *device, IRP *irp )
823 if (winetest_debug > 1) trace( "%s: device %p\n", __func__, device );
824 ok( 0, "unexpected call\n" );
825 irp->IoStatus.Status = STATUS_SUCCESS;
826 IoCompleteRequest( irp, IO_NO_INCREMENT );
827 return STATUS_SUCCESS;
830 static void WINAPI driver_unload( DRIVER_OBJECT *driver )
832 if (winetest_debug > 1) trace( "%s: driver %p\n", __func__, driver );
833 input_queue_cleanup( &input_queue );
834 expect_queue_cleanup( &expect_queue );
835 winetest_cleanup();
838 NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *registry )
840 static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
841 HID_MINIDRIVER_REGISTRATION params =
843 .Revision = HID_REVISION,
844 .DriverObject = driver,
845 .DeviceExtensionSize = sizeof(struct hid_device),
846 .RegistryPath = registry,
848 UNICODE_STRING name_str;
849 OBJECT_ATTRIBUTES attr;
850 NTSTATUS ret;
851 char *buffer;
852 HANDLE hkey;
853 DWORD size;
855 expect_driver = driver;
857 if ((ret = winetest_init())) return ret;
858 if (winetest_debug > 1) trace( "%s: driver %p\n", __func__, driver );
860 InitializeObjectAttributes( &attr, registry, 0, NULL, NULL );
861 ret = ZwOpenKey( &hkey, KEY_ALL_ACCESS, &attr );
862 ok( !ret, "ZwOpenKey returned %#lx\n", ret );
864 buffer = ExAllocatePool( PagedPool, info_size + EXPECT_QUEUE_BUFFER_SIZE );
865 ok( buffer != NULL, "ExAllocatePool failed\n" );
866 if (!buffer) return STATUS_NO_MEMORY;
868 RtlInitUnicodeString( &name_str, L"ReportID" );
869 size = info_size + sizeof(report_id);
870 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
871 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
872 memcpy( &report_id, buffer + info_size, size - info_size );
874 RtlInitUnicodeString( &name_str, L"PolledMode" );
875 size = info_size + sizeof(polled);
876 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
877 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
878 memcpy( &polled, buffer + info_size, size - info_size );
879 params.DevicesArePolled = polled;
880 /* polled mode calls this in a state where printing anything locks the system up */
881 if (polled) winetest_debug = 0;
883 RtlInitUnicodeString( &name_str, L"Descriptor" );
884 size = info_size + sizeof(report_descriptor_buf);
885 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
886 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
887 memcpy( report_descriptor_buf, buffer + info_size, size - info_size );
888 report_descriptor_len = size - info_size;
890 RtlInitUnicodeString( &name_str, L"Attributes" );
891 size = info_size + sizeof(attributes);
892 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
893 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
894 memcpy( &attributes, buffer + info_size, size - info_size );
896 RtlInitUnicodeString( &name_str, L"Caps" );
897 size = info_size + sizeof(caps);
898 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
899 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
900 memcpy( &caps, buffer + info_size, size - info_size );
902 expect_queue_init( &expect_queue );
903 RtlInitUnicodeString( &name_str, L"Expect" );
904 size = info_size + EXPECT_QUEUE_BUFFER_SIZE;
905 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
906 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
907 expect_queue_reset( &expect_queue, buffer + info_size, size - info_size );
909 input_queue_init( &input_queue );
910 RtlInitUnicodeString( &name_str, L"Input" );
911 size = info_size + EXPECT_QUEUE_BUFFER_SIZE;
912 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
913 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
914 input_queue_reset( &input_queue, buffer + info_size, size - info_size );
916 RtlInitUnicodeString( &name_str, L"Context" );
917 size = info_size + sizeof(expect_queue.context);
918 ret = ZwQueryValueKey( hkey, &name_str, KeyValuePartialInformation, buffer, size, &size );
919 ok( !ret, "ZwQueryValueKey returned %#lx\n", ret );
920 memcpy( expect_queue.context, buffer + info_size, size - info_size );
922 driver->DriverExtension->AddDevice = driver_add_device;
923 driver->DriverUnload = driver_unload;
924 driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
925 driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_ioctl;
926 driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = driver_internal_ioctl;
927 driver->MajorFunction[IRP_MJ_CREATE] = driver_create;
928 driver->MajorFunction[IRP_MJ_CLOSE] = driver_close;
930 ExFreePool( buffer );
932 ret = HidRegisterMinidriver( &params );
933 ok( !ret, "got %#lx\n", ret );
935 hidclass_driver_ioctl = driver->MajorFunction[IRP_MJ_DEVICE_CONTROL];
936 driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driver_ioctl;
938 return STATUS_SUCCESS;