winhttp: Don't refill buffer after receiving server response.
[wine.git] / dlls / wineusb.sys / wineusb.c
blob9512ecc8d12ab9a1209c5fd90c4f85bf8b17b4a4
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 <stdbool.h>
24 #include <stdint.h>
25 #include <stdlib.h>
27 #include "ntstatus.h"
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winioctl.h"
31 #include "winternl.h"
32 #include "ddk/wdm.h"
33 #include "ddk/usb.h"
34 #include "ddk/usbioctl.h"
35 #include "wine/asm.h"
36 #include "wine/debug.h"
37 #include "wine/list.h"
39 #include "unixlib.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(wineusb);
43 #ifdef __ASM_USE_FASTCALL_WRAPPER
45 extern void * WINAPI wrap_fastcall_func1( void *func, const void *a );
46 __ASM_STDCALL_FUNC( wrap_fastcall_func1, 8,
47 "popl %ecx\n\t"
48 "popl %eax\n\t"
49 "xchgl (%esp),%ecx\n\t"
50 "jmp *%eax" );
52 #define call_fastcall_func1(func,a) wrap_fastcall_func1(func,a)
54 #else
56 #define call_fastcall_func1(func,a) func(a)
58 #endif
60 #define DECLARE_CRITICAL_SECTION(cs) \
61 static CRITICAL_SECTION cs; \
62 static CRITICAL_SECTION_DEBUG cs##_debug = \
63 { 0, 0, &cs, { &cs##_debug.ProcessLocksList, &cs##_debug.ProcessLocksList }, \
64 0, 0, { (DWORD_PTR)(__FILE__ ": " # cs) }}; \
65 static CRITICAL_SECTION cs = { &cs##_debug, -1, 0, 0, 0, 0 };
67 DECLARE_CRITICAL_SECTION(wineusb_cs);
69 static struct list device_list = LIST_INIT(device_list);
71 struct usb_device
73 struct list entry;
74 BOOL removed;
76 DEVICE_OBJECT *device_obj;
78 bool interface;
79 uint8_t interface_index;
81 uint8_t class, subclass, protocol;
83 uint16_t vendor, product, revision;
85 struct unix_device *unix_device;
87 LIST_ENTRY irp_list;
90 static DRIVER_OBJECT *driver_obj;
91 static DEVICE_OBJECT *bus_fdo, *bus_pdo;
93 static void destroy_unix_device(struct unix_device *unix_device)
95 struct usb_destroy_device_params params =
97 .device = unix_device,
100 WINE_UNIX_CALL(unix_usb_destroy_device, &params);
103 static void add_unix_device(const struct usb_add_device_event *event)
105 static unsigned int name_index;
106 struct usb_device *device;
107 DEVICE_OBJECT *device_obj;
108 UNICODE_STRING string;
109 NTSTATUS status;
110 WCHAR name[26];
112 TRACE("Adding new device %p, vendor %04x, product %04x.\n", event->device,
113 event->vendor, event->product);
115 swprintf(name, ARRAY_SIZE(name), L"\\Device\\USBPDO-%u", name_index++);
116 RtlInitUnicodeString(&string, name);
117 if ((status = IoCreateDevice(driver_obj, sizeof(*device), &string,
118 FILE_DEVICE_USB, 0, FALSE, &device_obj)))
120 ERR("Failed to create device, status %#lx.\n", status);
121 return;
124 device = device_obj->DeviceExtension;
125 device->device_obj = device_obj;
126 device->unix_device = event->device;
127 InitializeListHead(&device->irp_list);
128 device->removed = FALSE;
130 device->class = event->class;
131 device->subclass = event->subclass;
132 device->protocol = event->protocol;
133 device->vendor = event->vendor;
134 device->product = event->product;
135 device->revision = event->revision;
137 EnterCriticalSection(&wineusb_cs);
138 list_add_tail(&device_list, &device->entry);
139 LeaveCriticalSection(&wineusb_cs);
141 IoInvalidateDeviceRelations(bus_pdo, BusRelations);
144 static void remove_unix_device(struct unix_device *unix_device)
146 struct usb_device *device;
148 TRACE("Removing device %p.\n", unix_device);
150 EnterCriticalSection(&wineusb_cs);
151 LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
153 if (device->unix_device == unix_device)
155 if (!device->removed)
157 device->removed = TRUE;
158 list_remove(&device->entry);
160 break;
163 LeaveCriticalSection(&wineusb_cs);
165 IoInvalidateDeviceRelations(bus_pdo, BusRelations);
168 static HANDLE event_thread;
170 static void complete_irp(IRP *irp)
172 EnterCriticalSection(&wineusb_cs);
173 RemoveEntryList(&irp->Tail.Overlay.ListEntry);
174 LeaveCriticalSection(&wineusb_cs);
176 irp->IoStatus.Status = STATUS_SUCCESS;
177 IoCompleteRequest(irp, IO_NO_INCREMENT);
180 static DWORD CALLBACK event_thread_proc(void *arg)
182 struct usb_event event;
183 struct usb_main_loop_params params =
185 .event = &event,
188 TRACE("Starting event thread.\n");
190 if (WINE_UNIX_CALL(unix_usb_init, NULL) != STATUS_SUCCESS)
191 return 0;
193 while (WINE_UNIX_CALL(unix_usb_main_loop, &params) == STATUS_PENDING)
195 switch (event.type)
197 case USB_EVENT_ADD_DEVICE:
198 add_unix_device(&event.u.added_device);
199 break;
201 case USB_EVENT_REMOVE_DEVICE:
202 remove_unix_device(event.u.removed_device);
203 break;
205 case USB_EVENT_TRANSFER_COMPLETE:
206 complete_irp(event.u.completed_irp);
207 break;
211 TRACE("Shutting down event thread.\n");
212 return 0;
215 static NTSTATUS fdo_pnp(IRP *irp)
217 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
218 NTSTATUS ret;
220 TRACE("irp %p, minor function %#x.\n", irp, stack->MinorFunction);
222 switch (stack->MinorFunction)
224 case IRP_MN_QUERY_DEVICE_RELATIONS:
226 struct usb_device *device;
227 DEVICE_RELATIONS *devices;
228 unsigned int i = 0;
230 if (stack->Parameters.QueryDeviceRelations.Type != BusRelations)
232 FIXME("Unhandled device relations type %#x.\n", stack->Parameters.QueryDeviceRelations.Type);
233 break;
236 EnterCriticalSection(&wineusb_cs);
238 if (!(devices = ExAllocatePool(PagedPool,
239 offsetof(DEVICE_RELATIONS, Objects[list_count(&device_list)]))))
241 LeaveCriticalSection(&wineusb_cs);
242 irp->IoStatus.Status = STATUS_NO_MEMORY;
243 break;
246 LIST_FOR_EACH_ENTRY(device, &device_list, struct usb_device, entry)
248 devices->Objects[i++] = device->device_obj;
249 call_fastcall_func1(ObfReferenceObject, device->device_obj);
252 LeaveCriticalSection(&wineusb_cs);
254 devices->Count = i;
255 irp->IoStatus.Information = (ULONG_PTR)devices;
256 irp->IoStatus.Status = STATUS_SUCCESS;
257 break;
260 case IRP_MN_START_DEVICE:
261 event_thread = CreateThread(NULL, 0, event_thread_proc, NULL, 0, NULL);
263 irp->IoStatus.Status = STATUS_SUCCESS;
264 break;
266 case IRP_MN_SURPRISE_REMOVAL:
267 irp->IoStatus.Status = STATUS_SUCCESS;
268 break;
270 case IRP_MN_REMOVE_DEVICE:
272 struct usb_device *device, *cursor;
274 WINE_UNIX_CALL(unix_usb_exit, NULL);
275 WaitForSingleObject(event_thread, INFINITE);
276 CloseHandle(event_thread);
278 EnterCriticalSection(&wineusb_cs);
279 /* Normally we unlink all devices either:
281 * - as a result of hot-unplug, which unlinks the device, and causes
282 * a subsequent IRP_MN_REMOVE_DEVICE which will free it;
284 * - if the parent is deleted (at shutdown time), in which case
285 * ntoskrnl will send us IRP_MN_SURPRISE_REMOVAL and
286 * IRP_MN_REMOVE_DEVICE unprompted.
288 * But we can get devices hotplugged between when shutdown starts
289 * and now, in which case they'll be stuck in this list and never
290 * freed.
292 * FIXME: This is still broken, though. If a device is hotplugged
293 * and then removed, it'll be unlinked and never freed. */
294 LIST_FOR_EACH_ENTRY_SAFE(device, cursor, &device_list, struct usb_device, entry)
296 assert(!device->removed);
297 destroy_unix_device(device->unix_device);
298 list_remove(&device->entry);
299 IoDeleteDevice(device->device_obj);
301 LeaveCriticalSection(&wineusb_cs);
303 irp->IoStatus.Status = STATUS_SUCCESS;
304 IoSkipCurrentIrpStackLocation(irp);
305 ret = IoCallDriver(bus_pdo, irp);
306 IoDetachDevice(bus_pdo);
307 IoDeleteDevice(bus_fdo);
308 return ret;
311 default:
312 FIXME("Unhandled minor function %#x.\n", stack->MinorFunction);
315 IoSkipCurrentIrpStackLocation(irp);
316 return IoCallDriver(bus_pdo, irp);
319 struct string_buffer
321 WCHAR *string;
322 size_t len;
325 static void WINAPIV append_id(struct string_buffer *buffer, const WCHAR *format, ...)
327 __ms_va_list args;
328 WCHAR *string;
329 int len;
331 __ms_va_start(args, format);
333 len = _vsnwprintf(NULL, 0, format, args) + 1;
334 if (!(string = ExAllocatePool(PagedPool, (buffer->len + len) * sizeof(WCHAR))))
336 if (buffer->string)
337 ExFreePool(buffer->string);
338 buffer->string = NULL;
339 return;
341 if (buffer->string)
343 memcpy(string, buffer->string, buffer->len * sizeof(WCHAR));
344 ExFreePool(buffer->string);
346 _vsnwprintf(string + buffer->len, len, format, args);
347 buffer->string = string;
348 buffer->len += len;
350 __ms_va_end(args);
353 static void get_device_id(const struct usb_device *device, struct string_buffer *buffer)
355 if (device->interface)
356 append_id(buffer, L"USB\\VID_%04X&PID_%04X&MI_%02X",
357 device->vendor, device->product, device->interface_index);
358 else
359 append_id(buffer, L"USB\\VID_%04X&PID_%04X", device->vendor, device->product);
362 static void get_hardware_ids(const struct usb_device *device, struct string_buffer *buffer)
364 if (device->interface)
365 append_id(buffer, L"USB\\VID_%04X&PID_%04X&REV_%04X&MI_%02X",
366 device->vendor, device->product, device->revision, device->interface_index);
367 else
368 append_id(buffer, L"USB\\VID_%04X&PID_%04X&REV_%04X",
369 device->vendor, device->product, device->revision);
371 get_device_id(device, buffer);
372 append_id(buffer, L"");
375 static void get_compatible_ids(const struct usb_device *device, struct string_buffer *buffer)
377 append_id(buffer, L"USB\\Class_%02x&SubClass_%02x&Prot_%02x",
378 device->class, device->subclass, device->protocol);
379 append_id(buffer, L"USB\\Class_%02x&SubClass_%02x", device->class, device->subclass);
380 append_id(buffer, L"USB\\Class_%02x", device->class);
381 append_id(buffer, L"");
384 static NTSTATUS query_id(struct usb_device *device, IRP *irp, BUS_QUERY_ID_TYPE type)
386 struct string_buffer buffer = {0};
388 TRACE("type %#x.\n", type);
390 switch (type)
392 case BusQueryDeviceID:
393 get_device_id(device, &buffer);
394 break;
396 case BusQueryInstanceID:
397 append_id(&buffer, L"0");
398 break;
400 case BusQueryHardwareIDs:
401 get_hardware_ids(device, &buffer);
402 break;
404 case BusQueryCompatibleIDs:
405 get_compatible_ids(device, &buffer);
406 break;
408 default:
409 FIXME("Unhandled ID query type %#x.\n", type);
410 return irp->IoStatus.Status;
413 if (!buffer.string)
414 return STATUS_NO_MEMORY;
416 irp->IoStatus.Information = (ULONG_PTR)buffer.string;
417 return STATUS_SUCCESS;
420 static void remove_pending_irps(struct usb_device *device)
422 LIST_ENTRY *entry;
423 IRP *irp;
425 while ((entry = RemoveHeadList(&device->irp_list)) != &device->irp_list)
427 irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
428 irp->IoStatus.Status = STATUS_DELETE_PENDING;
429 irp->IoStatus.Information = 0;
430 IoCompleteRequest(irp, IO_NO_INCREMENT);
434 static NTSTATUS pdo_pnp(DEVICE_OBJECT *device_obj, IRP *irp)
436 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
437 struct usb_device *device = device_obj->DeviceExtension;
438 NTSTATUS ret = irp->IoStatus.Status;
440 TRACE("device_obj %p, irp %p, minor function %#x.\n", device_obj, irp, stack->MinorFunction);
442 switch (stack->MinorFunction)
444 case IRP_MN_QUERY_ID:
445 ret = query_id(device, irp, stack->Parameters.QueryId.IdType);
446 break;
448 case IRP_MN_QUERY_CAPABILITIES:
450 DEVICE_CAPABILITIES *caps = stack->Parameters.DeviceCapabilities.Capabilities;
452 caps->RawDeviceOK = 1;
454 ret = STATUS_SUCCESS;
455 break;
458 case IRP_MN_START_DEVICE:
459 ret = STATUS_SUCCESS;
460 break;
462 case IRP_MN_SURPRISE_REMOVAL:
463 EnterCriticalSection(&wineusb_cs);
464 remove_pending_irps(device);
465 if (!device->removed)
467 device->removed = TRUE;
468 list_remove(&device->entry);
470 LeaveCriticalSection(&wineusb_cs);
471 ret = STATUS_SUCCESS;
472 break;
474 case IRP_MN_REMOVE_DEVICE:
475 assert(device->removed);
476 remove_pending_irps(device);
478 destroy_unix_device(device->unix_device);
480 IoDeleteDevice(device->device_obj);
481 ret = STATUS_SUCCESS;
482 break;
484 default:
485 FIXME("Unhandled minor function %#x.\n", stack->MinorFunction);
488 irp->IoStatus.Status = ret;
489 IoCompleteRequest(irp, IO_NO_INCREMENT);
490 return ret;
493 static NTSTATUS WINAPI driver_pnp(DEVICE_OBJECT *device, IRP *irp)
495 if (device == bus_fdo)
496 return fdo_pnp(irp);
497 return pdo_pnp(device, irp);
500 static NTSTATUS usb_submit_urb(struct usb_device *device, IRP *irp)
502 URB *urb = IoGetCurrentIrpStackLocation(irp)->Parameters.Others.Argument1;
503 NTSTATUS status;
505 TRACE("type %#x.\n", urb->UrbHeader.Function);
507 switch (urb->UrbHeader.Function)
509 case URB_FUNCTION_ABORT_PIPE:
511 LIST_ENTRY *entry, *mark;
513 /* The documentation states that URB_FUNCTION_ABORT_PIPE may
514 * complete before outstanding requests complete, so we don't need
515 * to wait for them. */
516 EnterCriticalSection(&wineusb_cs);
517 mark = &device->irp_list;
518 for (entry = mark->Flink; entry != mark; entry = entry->Flink)
520 IRP *queued_irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry);
521 struct usb_cancel_transfer_params params =
523 .transfer = queued_irp->Tail.Overlay.DriverContext[0],
526 WINE_UNIX_CALL(unix_usb_cancel_transfer, &params);
528 LeaveCriticalSection(&wineusb_cs);
530 return STATUS_SUCCESS;
533 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
534 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
535 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
536 case URB_FUNCTION_SELECT_CONFIGURATION:
537 case URB_FUNCTION_VENDOR_INTERFACE:
539 struct usb_submit_urb_params params =
541 .device = device->unix_device,
542 .irp = irp,
545 switch (urb->UrbHeader.Function)
547 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
549 struct _URB_BULK_OR_INTERRUPT_TRANSFER *req = &urb->UrbBulkOrInterruptTransfer;
550 if (req->TransferBufferMDL)
551 params.transfer_buffer = MmGetSystemAddressForMdlSafe(req->TransferBufferMDL, NormalPagePriority);
552 else
553 params.transfer_buffer = req->TransferBuffer;
554 break;
557 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
559 struct _URB_CONTROL_DESCRIPTOR_REQUEST *req = &urb->UrbControlDescriptorRequest;
560 if (req->TransferBufferMDL)
561 params.transfer_buffer = MmGetSystemAddressForMdlSafe(req->TransferBufferMDL, NormalPagePriority);
562 else
563 params.transfer_buffer = req->TransferBuffer;
564 break;
567 case URB_FUNCTION_VENDOR_INTERFACE:
569 struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST *req = &urb->UrbControlVendorClassRequest;
570 if (req->TransferBufferMDL)
571 params.transfer_buffer = MmGetSystemAddressForMdlSafe(req->TransferBufferMDL, NormalPagePriority);
572 else
573 params.transfer_buffer = req->TransferBuffer;
574 break;
578 /* Hold the wineusb lock while submitting and queuing, and
579 * similarly hold it in complete_irp(). That way, if libusb reports
580 * completion between submitting and queuing, we won't try to
581 * dequeue the IRP until it's actually been queued. */
582 EnterCriticalSection(&wineusb_cs);
583 status = WINE_UNIX_CALL(unix_usb_submit_urb, &params);
584 if (status == STATUS_PENDING)
586 IoMarkIrpPending(irp);
587 InsertTailList(&device->irp_list, &irp->Tail.Overlay.ListEntry);
589 LeaveCriticalSection(&wineusb_cs);
591 return status;
594 default:
595 FIXME("Unhandled function %#x.\n", urb->UrbHeader.Function);
598 return STATUS_NOT_IMPLEMENTED;
601 static NTSTATUS WINAPI driver_internal_ioctl(DEVICE_OBJECT *device_obj, IRP *irp)
603 IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp);
604 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
605 struct usb_device *device = device_obj->DeviceExtension;
606 NTSTATUS status = STATUS_NOT_IMPLEMENTED;
607 BOOL removed;
609 TRACE("device_obj %p, irp %p, code %#lx.\n", device_obj, irp, code);
611 EnterCriticalSection(&wineusb_cs);
612 removed = device->removed;
613 LeaveCriticalSection(&wineusb_cs);
615 if (removed)
617 irp->IoStatus.Status = STATUS_DELETE_PENDING;
618 IoCompleteRequest(irp, IO_NO_INCREMENT);
619 return STATUS_DELETE_PENDING;
622 switch (code)
624 case IOCTL_INTERNAL_USB_SUBMIT_URB:
625 status = usb_submit_urb(device, irp);
626 break;
628 default:
629 FIXME("Unhandled ioctl %#lx (device %#lx, access %#lx, function %#lx, method %#lx).\n",
630 code, code >> 16, (code >> 14) & 3, (code >> 2) & 0xfff, code & 3);
633 if (status != STATUS_PENDING)
635 irp->IoStatus.Status = status;
636 IoCompleteRequest(irp, IO_NO_INCREMENT);
638 return status;
641 static NTSTATUS WINAPI driver_add_device(DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo)
643 NTSTATUS ret;
645 TRACE("driver %p, pdo %p.\n", driver, pdo);
647 if ((ret = IoCreateDevice(driver, 0, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &bus_fdo)))
649 ERR("Failed to create FDO, status %#lx.\n", ret);
650 return ret;
653 IoAttachDeviceToDeviceStack(bus_fdo, pdo);
654 bus_pdo = pdo;
655 bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING;
657 return STATUS_SUCCESS;
660 static void WINAPI driver_unload(DRIVER_OBJECT *driver)
664 NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, UNICODE_STRING *path)
666 NTSTATUS status;
668 TRACE("driver %p, path %s.\n", driver, debugstr_w(path->Buffer));
670 if ((status = __wine_init_unix_call()))
672 ERR("Failed to initialize Unix library, status %#lx.\n", status);
673 return status;
676 driver_obj = driver;
678 driver->DriverExtension->AddDevice = driver_add_device;
679 driver->DriverUnload = driver_unload;
680 driver->MajorFunction[IRP_MJ_PNP] = driver_pnp;
681 driver->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = driver_internal_ioctl;
683 return STATUS_SUCCESS;