win32u: Don't report cloned monitors in EnumDisplayMonitors().
[wine.git] / dlls / wineusb.sys / wineusb.c
blob87669b5c65df296c580ff1db9e57e86bbf6185b2
1 /*
2 * USB root device enumerator using libusb
4 * Copyright 2020 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 <assert.h>
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <libusb.h>
26 #include "ntstatus.h"
27 #define WIN32_NO_STATUS
28 #include "windef.h"
29 #include "winioctl.h"
30 #include "winternl.h"
31 #include "ddk/wdm.h"
32 #include "ddk/usb.h"
33 #include "ddk/usbioctl.h"
34 #include "wine/asm.h"
35 #include "wine/debug.h"
36 #include "wine/list.h"
37 #include "wine/unicode.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
41 #ifdef __ASM_USE_FASTCALL_WRAPPER
43 extern void * WINAPI wrap_fastcall_func1( void *func, const void *a );
44 __ASM_STDCALL_FUNC( wrap_fastcall_func1, 8,
45 "popl %ecx\n\t"
46 "popl %eax\n\t"
47 "xchgl (%esp),%ecx\n\t"
48 "jmp *%eax" );
50 #define call_fastcall_func1(func,a) wrap_fastcall_func1(func,a)
52 #else
54 #define call_fastcall_func1(func,a) func(a)
56 #endif
58 #define DECLARE_CRITICAL_SECTION(cs) \
59 static CRITICAL_SECTION cs; \
60 static CRITICAL_SECTION_DEBUG cs##_debug = \
61 { 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \
62 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \
63 static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
65 DECLARE_CRITICAL_SECTION(wineusb_cs);
67 static struct list device_list = LIST_INIT(device_list);
69 struct usb_device
71 struct list entry;
72 BOOL removed;
74 DEVICE_OBJECT *device_obj;
76 /* Points to the parent USB device if this is a USB interface; otherwise
77 * NULL. */
78 struct usb_device *parent;
79 uint8_t interface_index;
81 uint8_t class, subclass, protocol;
83 libusb_device *libusb_device;
84 libusb_device_handle *handle;
86 LIST_ENTRY irp_list;
89 static DRIVER_OBJECT *driver_obj;
90 static DEVICE_OBJECT *bus_fdo, *bus_pdo;
92 static libusb_hotplug_callback_handle hotplug_cb_handle;
94 static void add_usb_interface(struct usb_device *parent, const struct libusb_interface_descriptor *desc)
96 struct usb_device *device;
97 DEVICE_OBJECT *device_obj;
98 NTSTATUS status;
100 if ((status = IoCreateDevice(driver_obj, sizeof(*device), NULL,
101 FILE_DEVICE_USB, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &device_obj)))
103 ERR("Failed to create device, status %#x.\n", status);
104 return;
107 device = device_obj->DeviceExtension;
108 device->device_obj = device_obj;
109 device->parent = parent;
110 device->handle = parent->handle;
111 device->libusb_device = parent->libusb_device;
112 device->interface_index = desc->bInterfaceNumber;
113 device->class = desc->bInterfaceClass;
114 device->subclass = desc->bInterfaceSubClass;
115 device->protocol = desc->bInterfaceProtocol;
116 InitializeListHead(&device->irp_list);
118 EnterCriticalSection(&wineusb_cs);
119 list_add_tail(&device_list, &device->entry);
120 LeaveCriticalSection(&wineusb_cs);
123 static void add_usb_device(libusb_device *libusb_device)
125 static const WCHAR formatW[] = {'\\','D','e','v','i','c','e','\\','U','S','B','P','D','O','-','%','u',0};
126 struct libusb_config_descriptor *config_desc;
127 struct libusb_device_descriptor device_desc;
128 static unsigned int name_index;
129 libusb_device_handle *handle;
130 struct usb_device *device;
131 DEVICE_OBJECT *device_obj;
132 UNICODE_STRING string;
133 NTSTATUS status;
134 WCHAR name[26];
135 int ret;
137 libusb_get_device_descriptor(libusb_device, &device_desc);
139 TRACE("Adding new device %p, vendor %04x, product %04x.\n", libusb_device,
140 device_desc.idVendor, device_desc.idProduct);
142 if ((ret = libusb_open(libusb_device, &handle)))
144 WARN("Failed to open device: %s\n", libusb_strerror(ret));
145 return;
148 sprintfW(name, formatW, name_index++);
149 RtlInitUnicodeString(&string, name);
150 if ((status = IoCreateDevice(driver_obj, sizeof(*device), &string,
151 FILE_DEVICE_USB, 0, FALSE, &device_obj)))
153 ERR("Failed to create device, status %#x.\n", status);
154 libusb_close(handle);
155 return;
158 device = device_obj->DeviceExtension;
159 device->device_obj = device_obj;
160 device->libusb_device = libusb_ref_device(libusb_device);
161 device->handle = handle;
162 InitializeListHead(&device->irp_list);
164 EnterCriticalSection(&wineusb_cs);
165 list_add_tail(&device_list, &device->entry);
166 device->removed = FALSE;
167 LeaveCriticalSection(&wineusb_cs);
169 device->class = device_desc.bDeviceClass;
170 device->subclass = device_desc.bDeviceSubClass;
171 device->protocol = device_desc.bDeviceProtocol;
173 if (!(ret = libusb_get_active_config_descriptor(libusb_device, &config_desc)))
175 /* Create new devices for interfaces of composite devices.
177 * On Windows this is the job of usbccgp.sys, a separate driver that
178 * layers on top of the base USB driver. While we could take this
179 * approach as well, implementing usbccgp is a lot more work, whereas
180 * interface support is effectively built into libusb.
182 * FIXME: usbccgp does not create separate interfaces in some cases,
183 * e.g. when there is an interface association descriptor available.
185 if (config_desc->bNumInterfaces > 1)
187 uint8_t i;
189 for (i = 0; i < config_desc->bNumInterfaces; ++i)
191 const struct libusb_interface *interface = &config_desc->interface[i];
193 if (interface->num_altsetting != 1)
194 FIXME("Interface %u has %u alternate settings; using the first one.\n",
195 i, interface->num_altsetting);
196 add_usb_interface(device, &interface->altsetting[0]);
199 libusb_free_config_descriptor(config_desc);
201 else
203 ERR("Failed to get configuration descriptor: %s\n", libusb_strerror(ret));
206 IoInvalidateDeviceRelations(bus_pdo, BusRelations);
209 static void remove_usb_device(libusb_device *libusb_device)
211 struct usb_device *device;
213 TRACE("Removing device %p.\n", libusb_device);
215 EnterCriticalSection(&wineusb_cs);
216 LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
218 if (device->libusb_device == libusb_device)
220 if (!device->removed)
222 device->removed = TRUE;
223 list_remove(&device->entry);
225 break;
228 LeaveCriticalSection(&wineusb_cs);
230 IoInvalidateDeviceRelations(bus_pdo, BusRelations);
233 static BOOL thread_shutdown;
234 static HANDLE event_thread;
236 static int LIBUSB_CALL hotplug_cb(libusb_context *context, libusb_device *device,
237 libusb_hotplug_event event, void *user_data)
239 if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
240 add_usb_device(device);
241 else
242 remove_usb_device(device);
244 return 0;
247 static DWORD CALLBACK event_thread_proc(void *arg)
249 int ret;
251 TRACE("Starting event thread.\n");
253 while (!thread_shutdown)
255 if ((ret = libusb_handle_events(NULL)))
256 ERR("Error handling events: %s\n", libusb_strerror(ret));
259 TRACE("Shutting down event thread.\n");
260 return 0;
263 static NTSTATUS fdo_pnp(IRP *irp)
265 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
266 NTSTATUS ret;
268 TRACE("irp %p, minor function %#x.\n", irp, stack->MinorFunction);
270 switch (stack->MinorFunction)
272 case IRP_MN_QUERY_DEVICE_RELATIONS:
274 struct usb_device *device;
275 DEVICE_RELATIONS *devices;
276 unsigned int i = 0;
278 if (stack->Parameters.QueryDeviceRelations.Type != BusRelations)
280 FIXME("Unhandled device relations type %#x.\n", stack->Parameters.QueryDeviceRelations.Type);
281 break;
284 EnterCriticalSection(&wineusb_cs);
286 if (!(devices = ExAllocatePool(PagedPool,
287 offsetof(DEVICE_RELATIONS, Objects[list_count(&device_list)]))))
289 LeaveCriticalSection(&wineusb_cs);
290 irp->IoStatus.Status = STATUS_NO_MEMORY;
291 break;
294 LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
296 devices->Objects[i++] = device->device_obj;
297 call_fastcall_func1(ObfReferenceObject, device->device_obj);
300 LeaveCriticalSection(&wineusb_cs);
302 devices->Count = i;
303 irp->IoStatus.Information = (ULONG_PTR)devices;
304 irp->IoStatus.Status = STATUS_SUCCESS;
305 break;
308 case IRP_MN_START_DEVICE:
309 if ((ret = libusb_hotplug_register_callback(NULL,
310 LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
311 LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
312 LIBUSB_HOTPLUG_MATCH_ANY, hotplug_cb, NULL, &hotplug_cb_handle)))
314 ERR("Failed to register callback: %s\n", libusb_strerror(ret));
315 irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
316 break;
318 irp->IoStatus.Status = STATUS_SUCCESS;
319 break;
321 case IRP_MN_SURPRISE_REMOVAL:
322 irp->IoStatus.Status = STATUS_SUCCESS;
323 break;
325 case IRP_MN_REMOVE_DEVICE:
327 struct usb_device *device, *cursor;
329 libusb_hotplug_deregister_callback(NULL, hotplug_cb_handle);
330 thread_shutdown = TRUE;
331 libusb_interrupt_event_handler(NULL);
332 WaitForSingleObject(event_thread, INFINITE);
333 CloseHandle(event_thread);
335 EnterCriticalSection(&wineusb_cs);
336 /* Normally we unlink all devices either:
338 * - as a result of hot-unplug, which unlinks the device, and causes
339 * a subsequent IRP_MN_REMOVE_DEVICE which will free it;
341 * - if the parent is deleted (at shutdown time), in which case
342 * ntoskrnl will send us IRP_MN_SURPRISE_REMOVAL and
343 * IRP_MN_REMOVE_DEVICE unprompted.
345 * But we can get devices hotplugged between when shutdown starts
346 * and now, in which case they'll be stuck in this list and never
347 * freed.
349 * FIXME: This is still broken, though. If a device is hotplugged
350 * and then removed, it'll be unlinked and never freed. */
351 LIST_FOR_EACH_ENTRY_SAFE(device, cursor, &device_list, struct usb_device, entry)
353 assert(!device->removed);
354 if (!device->parent)
356 libusb_unref_device(device->libusb_device);
357 libusb_close(device->handle);
359 list_remove(&device->entry);
360 IoDeleteDevice(device->device_obj);
362 LeaveCriticalSection(&wineusb_cs);
364 irp->IoStatus.Status = STATUS_SUCCESS;
365 IoSkipCurrentIrpStackLocation(irp);
366 ret = IoCallDriver(bus_pdo, irp);
367 IoDetachDevice(bus_pdo);
368 IoDeleteDevice(bus_fdo);
369 return ret;
372 default:
373 FIXME("Unhandled minor function %#x.\n", stack->MinorFunction);
376 IoSkipCurrentIrpStackLocation(irp);
377 return IoCallDriver(bus_pdo, irp);
380 struct string_buffer
382 WCHAR *string;
383 size_t len;
386 static void WINAPIV append_id(struct string_buffer *buffer, const WCHAR *format, ...)
388 __ms_va_list args;
389 WCHAR *string;
390 int len;
392 __ms_va_start(args, format);
394 len = _vsnwprintf(NULL, 0, format, args) + 1;
395 if (!(string = ExAllocatePool(PagedPool, (buffer->len + len) * sizeof(WCHAR))))
397 if (buffer->string)
398 ExFreePool(buffer->string);
399 buffer->string = NULL;
400 return;
402 if (buffer->string)
404 memcpy(string, buffer->string, buffer->len * sizeof(WCHAR));
405 ExFreePool(buffer->string);
407 _vsnwprintf(string + buffer->len, len, format, args);
408 buffer->string = string;
409 buffer->len += len;
411 __ms_va_end(args);
414 static const WCHAR emptyW[] = {0};
416 static void get_device_id(const struct usb_device *device, struct string_buffer *buffer)
418 static const WCHAR interface_formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
419 '&','P','I','D','_','%','0','4','X','&','M','I','_','%','0','2','X',0};
420 static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
421 '&','P','I','D','_','%','0','4','X',0};
422 struct libusb_device_descriptor desc;
424 libusb_get_device_descriptor(device->libusb_device, &desc);
425 if (device->parent)
426 append_id(buffer, interface_formatW, desc.idVendor, desc.idProduct, device->interface_index);
427 else
428 append_id(buffer, formatW, desc.idVendor, desc.idProduct);
431 static void get_hardware_ids(const struct usb_device *device, struct string_buffer *buffer)
433 static const WCHAR interface_formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
434 '&','P','I','D','_','%','0','4','X','&','R','E','V','_','%','0','4','X','&','M','I','_','%','0','2','X',0};
435 static const WCHAR formatW[] = {'U','S','B','\\','V','I','D','_','%','0','4','X',
436 '&','P','I','D','_','%','0','4','X','&','R','E','V','_','%','0','4','X',0};
437 struct libusb_device_descriptor desc;
439 libusb_get_device_descriptor(device->libusb_device, &desc);
441 if (device->parent)
442 append_id(buffer, interface_formatW, desc.idVendor, desc.idProduct, desc.bcdDevice, device->interface_index);
443 else
444 append_id(buffer, formatW, desc.idVendor, desc.idProduct, desc.bcdDevice);
445 get_device_id(device, buffer);
446 append_id(buffer, emptyW);
449 static void get_compatible_ids(const struct usb_device *device, struct string_buffer *buffer)
451 static const WCHAR prot_format[] = {'U','S','B','\\','C','l','a','s','s','_','%','0','2','x',
452 '&','S','u','b','C','l','a','s','s','_','%','0','2','x',
453 '&','P','r','o','t','_','%','0','2','x',0};
454 static const WCHAR subclass_format[] = {'U','S','B','\\','C','l','a','s','s','_','%','0','2','x',
455 '&','S','u','b','C','l','a','s','s','_','%','0','2','x',0};
456 static const WCHAR class_format[] = {'U','S','B','\\','C','l','a','s','s','_','%','0','2','x',0};
458 append_id(buffer, prot_format, device->class, device->subclass, device->protocol);
459 append_id(buffer, subclass_format, device->class, device->subclass);
460 append_id(buffer, class_format, device->class);
461 append_id(buffer, emptyW);
464 static NTSTATUS query_id(struct usb_device *device, IRP *irp, BUS_QUERY_ID_TYPE type)
466 static const WCHAR instance_idW[] = {'0',0};
467 struct string_buffer buffer = {0};
469 TRACE("type %#x.\n", type);
471 switch (type)
473 case BusQueryDeviceID:
474 get_device_id(device, &buffer);
475 break;
477 case BusQueryInstanceID:
478 append_id(&buffer, instance_idW);
479 break;
481 case BusQueryHardwareIDs:
482 get_hardware_ids(device, &buffer);
483 break;
485 case BusQueryCompatibleIDs:
486 get_compatible_ids(device, &buffer);
487 break;
489 default:
490 FIXME("Unhandled ID query type %#x.\n", type);
491 return irp->IoStatus.Status;
494 if (!buffer.string)
495 return STATUS_NO_MEMORY;
497 irp->IoStatus.Information = (ULONG_PTR)buffer.string;
498 return STATUS_SUCCESS;
501 static void remove_pending_irps(struct usb_device *device)
503 LIST_ENTRY *entry;
504 IRP *irp;
506 while ((entry = RemoveHeadList(&device->irp_list)) != &device->irp_list)
508 irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
509 irp->IoStatus.Status = STATUS_DELETE_PENDING;
510 irp->IoStatus.Information = 0;
511 IoCompleteRequest(irp, IO_NO_INCREMENT);
515 static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
517 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
518 struct usb_device *device = device_obj->DeviceExtension;
519 NTSTATUS ret = irp->IoStatus.Status;
521 TRACE("device_obj %p, irp %p, minor function %#x.\n", device_obj, irp, stack->MinorFunction);
523 switch (stack->MinorFunction)
525 case IRP_MN_QUERY_ID:
526 ret = query_id(device, irp, stack->Parameters.QueryId.IdType);
527 break;
529 case IRP_MN_QUERY_CAPABILITIES:
531 DEVICE_CAPABILITIES *caps = stack->Parameters.DeviceCapabilities.Capabilities;
533 caps->RawDeviceOK = 1;
535 ret = STATUS_SUCCESS;
536 break;
539 case IRP_MN_START_DEVICE:
540 ret = STATUS_SUCCESS;
541 break;
543 case IRP_MN_SURPRISE_REMOVAL:
544 EnterCriticalSection(&wineusb_cs);
545 remove_pending_irps(device);
546 if (!device->removed)
548 device->removed = TRUE;
549 list_remove(&device->entry);
551 LeaveCriticalSection(&wineusb_cs);
552 ret = STATUS_SUCCESS;
553 break;
555 case IRP_MN_REMOVE_DEVICE:
556 assert(device->removed);
557 remove_pending_irps(device);
559 if (!device->parent)
561 libusb_unref_device(device->libusb_device);
562 libusb_close(device->handle);
565 IoDeleteDevice(device->device_obj);
566 ret = STATUS_SUCCESS;
567 break;
569 default:
570 FIXME("Unhandled minor function %#x.\n", stack->MinorFunction);
573 irp->IoStatus.Status = ret;
574 IoCompleteRequest(irp, IO_NO_INCREMENT);
575 return ret;
578 static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp)
580 if (device == bus_fdo)
581 return fdo_pnp(irp);
582 return pdo_pnp(device, irp);
585 static NTSTATUS usbd_status_from_libusb(enum libusb_transfer_status status)
587 switch (status)
589 case LIBUSB_TRANSFER_CANCELLED:
590 return USBD_STATUS_CANCELED;
591 case LIBUSB_TRANSFER_COMPLETED:
592 return USBD_STATUS_SUCCESS;
593 case LIBUSB_TRANSFER_NO_DEVICE:
594 return USBD_STATUS_DEVICE_GONE;
595 case LIBUSB_TRANSFER_STALL:
596 return USBD_STATUS_ENDPOINT_HALTED;
597 case LIBUSB_TRANSFER_TIMED_OUT:
598 return USBD_STATUS_TIMEOUT;
599 default:
600 FIXME("Unhandled status %#x.\n", status);
601 case LIBUSB_TRANSFER_ERROR:
602 return USBD_STATUS_REQUEST_FAILED;
606 static void LIBUSB_CALL transfer_cb(struct libusb_transfer *transfer)
608 IRP *irp = transfer->user_data;
609 URB *urb = IoGetCurrentIrpStackLocation(irp)->Parameters.Others.Argument1;
611 TRACE("Completing IRP %p, status %#x.\n", irp, transfer->status);
613 urb->UrbHeader.Status = usbd_status_from_libusb(transfer->status);
615 if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
617 switch (urb->UrbHeader.Function)
619 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
620 urb->UrbBulkOrInterruptTransfer.TransferBufferLength = transfer->actual_length;
621 break;
623 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
625 struct _URB_CONTROL_DESCRIPTOR_REQUEST *req = &urb->UrbControlDescriptorRequest;
626 req->TransferBufferLength = transfer->actual_length;
627 memcpy(req->TransferBuffer, libusb_control_transfer_get_data(transfer), transfer->actual_length);
628 break;
631 case URB_FUNCTION_VENDOR_INTERFACE:
633 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *req = &urb->UrbControlVendorClassRequest;
634 req->TransferBufferLength = transfer->actual_length;
635 if (req->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
636 memcpy(req->TransferBuffer, libusb_control_transfer_get_data(transfer), transfer->actual_length);
637 break;
640 default:
641 ERR("Unexpected function %#x.\n", urb->UrbHeader.Function);
645 EnterCriticalSection(&wineusb_cs);
646 RemoveEntryList(&irp->Tail.Overlay.ListEntry);
647 LeaveCriticalSection(&wineusb_cs);
649 irp->IoStatus.Status = STATUS_SUCCESS;
650 IoCompleteRequest(irp, IO_NO_INCREMENT);
653 static void queue_irp(struct usb_device *device, IRP *irp, struct libusb_transfer *transfer)
655 IoMarkIrpPending(irp);
656 irp->Tail.Overlay.DriverContext[0] = transfer;
657 EnterCriticalSection(&wineusb_cs);
658 InsertTailList(&device->irp_list, &irp->Tail.Overlay.ListEntry);
659 LeaveCriticalSection(&wineusb_cs);
662 struct pipe
664 unsigned char endpoint;
665 unsigned char type;
668 static HANDLE make_pipe_handle(unsigned char endpoint, USBD_PIPE_TYPE type)
670 union
672 struct pipe pipe;
673 HANDLE handle;
674 } u;
676 u.pipe.endpoint = endpoint;
677 u.pipe.type = type;
678 return u.handle;
681 static struct pipe get_pipe(HANDLE handle)
683 union
685 struct pipe pipe;
686 HANDLE handle;
687 } u;
689 u.handle = handle;
690 return u.pipe;
693 static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
695 URB *urb = IoGetCurrentIrpStackLocation(irp)->Parameters.Others.Argument1;
696 struct libusb_transfer *transfer;
697 int ret;
699 TRACE("type %#x.\n", urb->UrbHeader.Function);
701 switch (urb->UrbHeader.Function)
703 case URB_FUNCTION_ABORT_PIPE:
705 LIST_ENTRY *entry, *mark;
707 /* The documentation states that URB_FUNCTION_ABORT_PIPE may
708 * complete before outstanding requests complete, so we don't need
709 * to wait for them. */
710 EnterCriticalSection(&wineusb_cs);
711 mark = &device->irp_list;
712 for (entry = mark->Flink; entry != mark; entry = entry->Flink)
714 IRP *queued_irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
716 if ((ret = libusb_cancel_transfer(queued_irp->Tail.Overlay.DriverContext[0])) < 0)
717 ERR("Failed to cancel transfer: %s\n", libusb_strerror(ret));
719 LeaveCriticalSection(&wineusb_cs);
721 return STATUS_SUCCESS;
724 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
726 struct _URB_PIPE_REQUEST *req = &urb->UrbPipeRequest;
727 struct pipe pipe = get_pipe(req->PipeHandle);
729 if ((ret = libusb_clear_halt(device->handle, pipe.endpoint)) < 0)
730 ERR("Failed to clear halt: %s\n", libusb_strerror(ret));
732 return STATUS_SUCCESS;
735 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
737 struct _URB_BULK_OR_INTERRUPT_TRANSFER *req = &urb->UrbBulkOrInterruptTransfer;
738 struct pipe pipe = get_pipe(req->PipeHandle);
740 if (req->TransferBufferMDL)
741 FIXME("Unhandled MDL output buffer.\n");
743 if (!(transfer = libusb_alloc_transfer(0)))
744 return STATUS_NO_MEMORY;
746 if (pipe.type == UsbdPipeTypeBulk)
748 libusb_fill_bulk_transfer(transfer, device->handle, pipe.endpoint,
749 req->TransferBuffer, req->TransferBufferLength, transfer_cb, irp, 0);
751 else if (pipe.type == UsbdPipeTypeInterrupt)
753 libusb_fill_interrupt_transfer(transfer, device->handle, pipe.endpoint,
754 req->TransferBuffer, req->TransferBufferLength, transfer_cb, irp, 0);
756 else
758 WARN("Invalid pipe type %#x.\n", pipe.type);
759 libusb_free_transfer(transfer);
760 return USBD_STATUS_INVALID_PIPE_HANDLE;
763 queue_irp(device, irp, transfer);
764 transfer->flags = LIBUSB_TRANSFER_FREE_TRANSFER;
765 ret = libusb_submit_transfer(transfer);
766 if (ret < 0)
767 ERR("Failed to submit bulk transfer: %s\n", libusb_strerror(ret));
769 return STATUS_PENDING;
772 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
774 struct _URB_CONTROL_DESCRIPTOR_REQUEST *req = &urb->UrbControlDescriptorRequest;
775 unsigned char *buffer;
777 if (req->TransferBufferMDL)
778 FIXME("Unhandled MDL output buffer.\n");
780 if (!(transfer = libusb_alloc_transfer(0)))
781 return STATUS_NO_MEMORY;
783 if (!(buffer = malloc(sizeof(struct libusb_control_setup) + req->TransferBufferLength)))
785 libusb_free_transfer(transfer);
786 return STATUS_NO_MEMORY;
789 queue_irp(device, irp, transfer);
790 libusb_fill_control_setup(buffer,
791 LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,
792 LIBUSB_REQUEST_GET_DESCRIPTOR, (req->DescriptorType << 8) | req->Index,
793 req->LanguageId, req->TransferBufferLength);
794 libusb_fill_control_transfer(transfer, device->handle, buffer, transfer_cb, irp, 0);
795 transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
796 ret = libusb_submit_transfer(transfer);
797 if (ret < 0)
798 ERR("Failed to submit GET_DESCRIPTOR transfer: %s\n", libusb_strerror(ret));
800 return STATUS_PENDING;
803 case URB_FUNCTION_SELECT_CONFIGURATION:
805 struct _URB_SELECT_CONFIGURATION *req = &urb->UrbSelectConfiguration;
806 ULONG i;
808 /* FIXME: In theory, we'd call libusb_set_configuration() here, but
809 * the CASIO FX-9750GII (which has only one configuration) goes into
810 * an error state if it receives a SET_CONFIGURATION request. Maybe
811 * we should skip setting that if and only if the configuration is
812 * already active? */
814 for (i = 0; i < req->Interface.NumberOfPipes; ++i)
816 USBD_PIPE_INFORMATION *pipe = &req->Interface.Pipes[i];
817 pipe->PipeHandle = make_pipe_handle(pipe->EndpointAddress, pipe->PipeType);
820 return STATUS_SUCCESS;
823 case URB_FUNCTION_VENDOR_INTERFACE:
825 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *req = &urb->UrbControlVendorClassRequest;
826 uint8_t req_type = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE;
827 unsigned char *buffer;
829 if (req->TransferFlags & USBD_TRANSFER_DIRECTION_IN)
830 req_type |= LIBUSB_ENDPOINT_IN;
831 if (req->TransferFlags & ~USBD_TRANSFER_DIRECTION_IN)
832 FIXME("Unhandled flags %#x.\n", req->TransferFlags);
834 if (req->TransferBufferMDL)
835 FIXME("Unhandled MDL output buffer.\n");
837 if (!(transfer = libusb_alloc_transfer(0)))
838 return STATUS_NO_MEMORY;
840 if (!(buffer = malloc(sizeof(struct libusb_control_setup) + req->TransferBufferLength)))
842 libusb_free_transfer(transfer);
843 return STATUS_NO_MEMORY;
846 queue_irp(device, irp, transfer);
847 libusb_fill_control_setup(buffer, req_type, req->Request,
848 req->Value, req->Index, req->TransferBufferLength);
849 if (!(req->TransferFlags & USBD_TRANSFER_DIRECTION_IN))
850 memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, req->TransferBuffer, req->TransferBufferLength);
851 libusb_fill_control_transfer(transfer, device->handle, buffer, transfer_cb, irp, 0);
852 transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER | LIBUSB_TRANSFER_FREE_TRANSFER;
853 ret = libusb_submit_transfer(transfer);
854 if (ret < 0)
855 ERR("Failed to submit vendor-specific interface transfer: %s\n", libusb_strerror(ret));
857 return STATUS_PENDING;
860 default:
861 FIXME("Unhandled function %#x.\n", urb->UrbHeader.Function);
864 return STATUS_NOT_IMPLEMENTED;
867 static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device_obj, IRP *irp)
869 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
870 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
871 struct usb_device *device = device_obj->DeviceExtension;
872 NTSTATUS status = STATUS_NOT_IMPLEMENTED;
873 BOOL removed;
875 TRACE("device_obj %p, irp %p, code %#x.\n", device_obj, irp, code);
877 EnterCriticalSection(&wineusb_cs);
878 removed = device->removed;
879 LeaveCriticalSection(&wineusb_cs);
881 if (removed)
883 irp->IoStatus.Status = STATUS_DELETE_PENDING;
884 IoCompleteRequest(irp, IO_NO_INCREMENT);
885 return STATUS_DELETE_PENDING;
888 switch (code)
890 case IOCTL_INTERNAL_USB_SUBMIT_URB:
891 status = usb_submit_urb(device, irp);
892 break;
894 default:
895 FIXME("Unhandled ioctl %#x (device %#x, access %#x, function %#x, method %#x).\n",
896 code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
899 if (status != STATUS_PENDING)
901 irp->IoStatus.Status = status;
902 IoCompleteRequest(irp, IO_NO_INCREMENT);
904 return status;
907 static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo)
909 NTSTATUS ret;
911 TRACE("driver %p, pdo %p.\n", driver, pdo);
913 if ((ret = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &bus_fdo)))
915 ERR("Failed to create FDO, status %#x.\n", ret);
916 return ret;
919 IoAttachDeviceToDeviceStack(bus_fdo, pdo);
920 bus_pdo = pdo;
921 bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING;
923 return STATUS_SUCCESS;
926 static void WINAPI driver_unload(DRIVER_OBJECT *driver)
928 libusb_exit(NULL);
931 NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
933 int err;
935 TRACE("driver %p, path %s.\n", driver, debugstr_w(path->Buffer));
937 driver_obj = driver;
939 if ((err = libusb_init(NULL)))
941 ERR("Failed to initialize libusb: %s\n", libusb_strerror(err));
942 return STATUS_UNSUCCESSFUL;
945 event_thread = CreateThread(NULL, 0, event_thread_proc, NULL, 0, NULL);
947 driver->DriverExtension->AddDevice = driver_add_device;
948 driver->DriverUnload = driver_unload;
949 driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
950 driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = driver_internal_ioctl;
952 return STATUS_SUCCESS;