1 /* libusb-win32, Generic Windows USB Library
2 * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19
20 #define __LIBUSB_DRIVER_C__
21
22 #include "libusb_driver.h"
23 #include "libusb-win32_version.h"
24
25 // Device objects with an attached device using the
26 // driver names listed here skipped in the add_device() routine.
27 //
28 const char* attached_driver_skip_list[] =
29 {
30 "\\driver\\picopp",
31 "\\driver\\libusb0",
32 NULL
33 };
34
35 // Device objects with an attached device using the
36 // driver names listed here have wdf below them. Special
37 // restrictions apply to these devices.
38 //
39 const char* attached_driver_wdf_list[] =
40 {
41 "\\driver\\winusb",
42 "\\driver\\wudfrd",
43 NULL
44 };
45
46 static bool_t match_driver(PDEVICE_OBJECT deviceObject, const char* driverString);
47
48
49 #ifdef DBG
50
debug_show_devices(PDEVICE_OBJECT deviceObject,int index,bool_t showNextDevice)51 static void debug_show_devices(PDEVICE_OBJECT deviceObject, int index, bool_t showNextDevice)
52 {
53 ANSI_STRING driverName;
54
55 if (index > 16) return;
56
57 if (deviceObject)
58 {
59 if (deviceObject->DriverObject)
60 {
61 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&driverName, &deviceObject->DriverObject->DriverName, TRUE)))
62 {
63 USBDBG("[%s #%d] %s\n",
64 (showNextDevice ? "NextDevice" : "AttachedDevice"),
65 index, driverName.Buffer);
66 RtlFreeAnsiString(&driverName);
67 }
68 }
69 if (deviceObject->AttachedDevice && !showNextDevice)
70 debug_show_devices(deviceObject->AttachedDevice, index+1, showNextDevice);
71 if (deviceObject->NextDevice && showNextDevice)
72 debug_show_devices(deviceObject->NextDevice, index+1, showNextDevice);
73 }
74 }
75 #endif
76
match_driver(PDEVICE_OBJECT deviceObject,const char * driverString)77 static bool_t match_driver(PDEVICE_OBJECT deviceObject, const char* driverString)
78 {
79 ANSI_STRING driverName;
80 bool_t ret = FALSE;
81
82 if (deviceObject)
83 {
84 if (deviceObject->DriverObject)
85 {
86 if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&driverName, &deviceObject->DriverObject->DriverName, TRUE)))
87 {
88 _strlwr(driverName.Buffer);
89
90 if (strstr(driverName.Buffer,driverString))
91 {
92 ret = TRUE;
93 }
94 RtlFreeAnsiString(&driverName);
95 }
96 }
97 }
98
99 return ret;
100 }
101
102 static void DDKAPI unload(DRIVER_OBJECT *driver_object);
103 static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object,
104 IRP *irp,
105 void *context);
106
DriverEntry(DRIVER_OBJECT * driver_object,UNICODE_STRING * registry_path)107 NTSTATUS DDKAPI DriverEntry(DRIVER_OBJECT *driver_object,
108 UNICODE_STRING *registry_path)
109 {
110 int i;
111
112 USBMSG("[loading-driver] v%d.%d.%d.%d\n",
113 VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO, VERSION_NANO);
114
115 /* initialize the driver object's dispatch table */
116 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
117 {
118 driver_object->MajorFunction[i] = dispatch;
119 }
120
121 driver_object->DriverExtension->AddDevice = add_device;
122 driver_object->DriverUnload = unload;
123
124 return STATUS_SUCCESS;
125 }
126
add_device(DRIVER_OBJECT * driver_object,DEVICE_OBJECT * physical_device_object)127 NTSTATUS DDKAPI add_device(DRIVER_OBJECT *driver_object,
128 DEVICE_OBJECT *physical_device_object)
129 {
130 NTSTATUS status;
131 DEVICE_OBJECT *device_object = NULL;
132 libusb_device_t *dev;
133 ULONG device_type;
134 UNICODE_STRING nt_device_name;
135 UNICODE_STRING symbolic_link_name;
136 WCHAR tmp_name_0[128];
137 WCHAR tmp_name_1[128];
138 char id[256];
139 char compat_id[256];
140 int i;
141 DEVICE_OBJECT* attached_device;
142 bool_t has_wdf = FALSE;
143
144 /* get the hardware ID from the registry */
145 if (!reg_get_hardware_id(physical_device_object, id, sizeof(id)))
146 {
147 USBERR0("unable to read registry\n");
148 return STATUS_SUCCESS;
149 }
150
151 /* only attach the (filter) driver to USB devices, skip hubs */
152 if (!strstr(id, "usb\\") ||
153 strstr(id, "hub") ||
154 !strstr(id, "vid_") ||
155 !strstr(id, "pid_"))
156 {
157 USBDBG("skipping non-usb device or hub %s\n",id);
158 return STATUS_SUCCESS;
159 }
160
161 if (!reg_get_compatible_id(physical_device_object, compat_id, sizeof(compat_id)))
162 {
163 USBERR0("unable to read registry\n");
164 return STATUS_SUCCESS;
165 }
166 // Don't attach to usb device hubs
167 if (strstr(compat_id, "class_09"))
168 {
169 USBDBG("skipping usb device hub (%s) %s\n",compat_id, id);
170 return STATUS_SUCCESS;
171 }
172
173 #ifdef DBG
174 debug_show_devices(physical_device_object->AttachedDevice, 0, FALSE);
175 #endif
176
177 attached_device = physical_device_object->AttachedDevice;
178 while (attached_device)
179 {
180 // make sure this device isn't already using a driver that is
181 // incompatible with libusb-win32.
182 for (i=0; attached_driver_skip_list[i] != NULL; i++)
183 {
184 if (match_driver(attached_device, attached_driver_skip_list[i]))
185 {
186 USBDBG("skipping device %s\n", id);
187 return STATUS_SUCCESS;
188 }
189 }
190
191 // look for wdf
192 for (i=0; attached_driver_wdf_list[i] != NULL; i++)
193 {
194 if (match_driver(attached_device, attached_driver_wdf_list[i]))
195 {
196 has_wdf = TRUE;
197 }
198 }
199
200 attached_device=attached_device->AttachedDevice;
201 }
202
203 device_object = IoGetAttachedDeviceReference(physical_device_object);
204 if (device_object)
205 {
206 device_type = device_object->DeviceType;
207 ObDereferenceObject(device_object);
208 }
209 else
210 {
211 device_type = FILE_DEVICE_UNKNOWN;
212 }
213
214 /* try to create a new device object */
215 for (i = 1; i < LIBUSB_MAX_NUMBER_OF_DEVICES; i++)
216 {
217 /* initialize some unicode strings */
218 _snwprintf(tmp_name_0, sizeof(tmp_name_0)/sizeof(WCHAR), L"%s%04d",
219 LIBUSB_NT_DEVICE_NAME, i);
220 _snwprintf(tmp_name_1, sizeof(tmp_name_1)/sizeof(WCHAR), L"%s%04d",
221 LIBUSB_SYMBOLIC_LINK_NAME, i);
222
223 RtlInitUnicodeString(&nt_device_name, tmp_name_0);
224 RtlInitUnicodeString(&symbolic_link_name, tmp_name_1);
225
226 /* create the object */
227 status = IoCreateDevice(driver_object,
228 sizeof(libusb_device_t),
229 &nt_device_name, device_type, 0, FALSE,
230 &device_object);
231
232 if (NT_SUCCESS(status))
233 {
234 USBMSG("device #%d created for %s\n", i, id);
235 break;
236 }
237
238 device_object = NULL;
239
240 /* continue until an unused device name is found */
241 }
242
243 if (!device_object)
244 {
245 USBERR0("creating device failed\n");
246 return status;
247 }
248
249 status = IoCreateSymbolicLink(&symbolic_link_name, &nt_device_name);
250
251 if (!NT_SUCCESS(status))
252 {
253 USBERR0("creating symbolic link failed\n");
254 IoDeleteDevice(device_object);
255 return status;
256 }
257
258 /* setup the "device object" */
259 dev = device_object->DeviceExtension;
260
261 memset(dev, 0, sizeof(libusb_device_t));
262
263 // [trobinso] See patch: 2873573 (Tim Green)
264 dev->self = device_object;
265 dev->physical_device_object = physical_device_object;
266 dev->id = i;
267
268 // store the device id in the device extentions
269 RtlCopyMemory(dev->device_id, id, sizeof(dev->device_id));
270
271 /* set initial power states */
272 dev->power_state.DeviceState = PowerDeviceD0;
273 dev->power_state.SystemState = PowerSystemWorking;
274
275 dev->disallow_power_control = has_wdf;
276
277 /* get device properties from the registry */
278 if (!reg_get_properties(dev))
279 {
280 USBERR0("getting device properties failed\n");
281 IoDeleteSymbolicLink(&symbolic_link_name);
282 IoDeleteDevice(device_object);
283 return STATUS_SUCCESS;
284 }
285
286 if (dev->is_filter && !physical_device_object->AttachedDevice)
287 {
288 USBWRN("[FILTER-MODE-MISMATCH] device is reporting itself as filter when there are no attached device(s).\n%s\n", id);
289 }
290 else if (!dev->is_filter && physical_device_object->AttachedDevice)
291 {
292 USBWRN("[FILTER-MODE-MISMATCH] device is reporting itself as normal when there are already attached device(s).\n%s\n", id);
293 //dev->is_filter = TRUE;
294 }
295
296 clear_pipe_info(dev);
297
298 remove_lock_initialize(dev);
299
300 if (dev->device_interface_in_use)
301 {
302 status = IoRegisterDeviceInterface(physical_device_object,
303 (LPGUID)&dev->device_interface_guid,
304 NULL,
305 &dev->device_interface_name);
306 if (!NT_SUCCESS (status))
307 {
308 dev->device_interface_name.Buffer = NULL;
309
310 USBERR0("creating device interface failed\n");
311 IoDeleteSymbolicLink(&symbolic_link_name);
312 IoDeleteDevice(device_object);
313 return status;
314 }
315 else
316 {
317 set_filter_interface_key(dev,dev->id);
318 if (dev->device_interface_in_use)
319 {
320 HANDLE hKey=NULL;
321 if (NT_SUCCESS(IoOpenDeviceInterfaceRegistryKey(&dev->device_interface_name,KEY_ALL_ACCESS,&hKey)))
322 {
323 UNICODE_STRING valueName;
324 RtlInitUnicodeString(&valueName, L"LUsb0");
325
326 if (NT_SUCCESS(ZwSetValueKey(hKey,&valueName, 0, REG_DWORD, &dev->id,sizeof(ULONG))))
327 {
328 USBMSG("updated interface registry with LUsb0 direct-access symbolic link. id=%04d\n",dev->id);
329 }
330 else
331 {
332 USBERR0("IoOpenDeviceInterfaceRegistryKey:ZwSetValueKey failed\n");
333 }
334 ZwClose(hKey);
335 }
336 else
337 {
338 USBERR0("IoOpenDeviceInterfaceRegistryKey failed\n");
339 }
340 }
341 }
342 }
343 // make sure the the devices can't be removed
344 // before we are done adding it.
345 if (!NT_SUCCESS(remove_lock_acquire(dev)))
346 {
347 USBERR0("remove_lock_acquire failed\n");
348 IoDeleteSymbolicLink(&symbolic_link_name);
349 IoDeleteDevice(device_object);
350 return STATUS_SUCCESS;
351 }
352
353 /* attach the newly created device object to the stack */
354 dev->next_stack_device = IoAttachDeviceToDeviceStack(device_object, physical_device_object);
355
356 if (!dev->next_stack_device)
357 {
358 USBERR("attaching %s to device stack failed\n", id);
359 IoDeleteSymbolicLink(&symbolic_link_name);
360 IoDeleteDevice(device_object);
361 remove_lock_release(dev); // always release acquired locks
362 return STATUS_NO_SUCH_DEVICE;
363 }
364
365 if (dev->is_filter)
366 {
367 USBDBG("[filter-mode] id=#%d %s\n",dev->id, dev->device_id);
368
369 /* send all USB requests to the PDO in filter driver mode */
370 dev->target_device = dev->physical_device_object;
371
372 /* use the same flags as the underlying object */
373 device_object->Flags |= dev->next_stack_device->Flags
374 & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
375
376 // use the same DeviceType as the underlying object
377 device_object->DeviceType = dev->next_stack_device->DeviceType;
378
379 // use the same Characteristics as the underlying object
380 device_object->Characteristics = dev->next_stack_device->Characteristics;
381 }
382 else
383 {
384 USBDBG("[normal-mode] id=#%d %s\n",dev->id, dev->device_id);
385
386 /* send all USB requests to the lower object in device driver mode */
387 dev->target_device = dev->next_stack_device;
388 device_object->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
389 }
390
391 UpdateContextConfigDescriptor(dev,NULL,0,0,-1);
392
393 device_object->Flags &= ~DO_DEVICE_INITIALIZING;
394 remove_lock_release(dev);
395
396 USBMSG("complete status=%08X\n",status);
397 return status;
398 }
399
400
unload(DRIVER_OBJECT * driver_object)401 VOID DDKAPI unload(DRIVER_OBJECT *driver_object)
402 {
403 USBMSG("[unloading-driver] v%d.%d.%d.%d\n",
404 VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO, VERSION_NANO);
405 }
406
complete_irp(IRP * irp,NTSTATUS status,ULONG info)407 NTSTATUS complete_irp(IRP *irp, NTSTATUS status, ULONG info)
408 {
409 irp->IoStatus.Status = status;
410 irp->IoStatus.Information = info;
411 IoCompleteRequest(irp, IO_NO_INCREMENT);
412
413 return status;
414 }
415
call_usbd_ex(libusb_device_t * dev,void * urb,ULONG control_code,int timeout,int max_timeout)416 NTSTATUS call_usbd_ex(libusb_device_t *dev, void *urb, ULONG control_code,
417 int timeout, int max_timeout)
418 {
419 KEVENT event;
420 NTSTATUS status;
421 IRP *irp;
422 IO_STACK_LOCATION *next_irp_stack;
423 LARGE_INTEGER _timeout;
424 IO_STATUS_BLOCK io_status;
425
426 if (max_timeout > 0 && timeout > max_timeout)
427 {
428 timeout = max_timeout;
429 }
430 if (timeout <= 0)
431 timeout = LIBUSB_MAX_CONTROL_TRANSFER_TIMEOUT;
432
433 KeInitializeEvent(&event, NotificationEvent, FALSE);
434
435 irp = IoBuildDeviceIoControlRequest(control_code, dev->target_device,
436 NULL, 0, NULL, 0, TRUE,
437 NULL, &io_status);
438
439 if (!irp)
440 {
441 return STATUS_NO_MEMORY;
442 }
443
444 next_irp_stack = IoGetNextIrpStackLocation(irp);
445 next_irp_stack->Parameters.Others.Argument1 = urb;
446 next_irp_stack->Parameters.Others.Argument2 = NULL;
447
448 IoSetCompletionRoutine(irp, on_usbd_complete, &event, TRUE, TRUE, TRUE);
449
450 status = IoCallDriver(dev->target_device, irp);
451 if(status == STATUS_PENDING)
452 {
453 _timeout.QuadPart = -(timeout * 10000);
454
455 if(KeWaitForSingleObject(&event, Executive, KernelMode,
456 FALSE, &_timeout) == STATUS_TIMEOUT)
457 {
458 USBERR0("request timed out\n");
459 IoCancelIrp(irp);
460 }
461 }
462
463 /* wait until completion routine is called */
464 KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
465
466 status = irp->IoStatus.Status;
467
468 /* complete the request */
469 IoCompleteRequest(irp, IO_NO_INCREMENT);
470
471 USBDBG("status = %08Xh\n",status);
472 return status;
473 }
474
on_usbd_complete(DEVICE_OBJECT * device_object,IRP * irp,void * context)475 static NTSTATUS DDKAPI on_usbd_complete(DEVICE_OBJECT *device_object,
476 IRP *irp, void *context)
477 {
478 KeSetEvent((KEVENT *) context, IO_NO_INCREMENT, FALSE);
479
480 return STATUS_MORE_PROCESSING_REQUIRED;
481 }
482
483
pass_irp_down(libusb_device_t * dev,IRP * irp,PIO_COMPLETION_ROUTINE completion_routine,void * context)484 NTSTATUS pass_irp_down(libusb_device_t *dev, IRP *irp,
485 PIO_COMPLETION_ROUTINE completion_routine,
486 void *context)
487 {
488 if (completion_routine)
489 {
490 IoCopyCurrentIrpStackLocationToNext(irp);
491 IoSetCompletionRoutine(irp, completion_routine, context,
492 TRUE, TRUE, TRUE);
493 }
494 else
495 {
496 IoSkipCurrentIrpStackLocation(irp);
497 }
498
499 return IoCallDriver(dev->next_stack_device, irp);
500 }
501 /*
502 bool_t accept_irp(libusb_device_t *dev, IRP *irp)
503 {
504 if (irp->Tail.Overlay.OriginalFileObject)
505 {
506 return irp->Tail.Overlay.OriginalFileObject->DeviceObject
507 == dev->self ? TRUE : FALSE;
508 }
509
510 return FALSE;
511 }
512 */
accept_irp(libusb_device_t * dev,IRP * irp)513 bool_t accept_irp(libusb_device_t *dev, IRP *irp)
514 {
515 /* check if the IRP is sent to libusb's device object or to */
516 /* the lower one. This check is necessary since the device object */
517 /* might be a filter */
518 if(!irp->Tail.Overlay.OriginalFileObject)
519 return FALSE;
520 if (irp->Tail.Overlay.OriginalFileObject->DeviceObject == dev->self)
521 return TRUE;
522
523 /* cover the cases when access is made by using device interfaces */
524 if (!dev->is_filter &&
525 dev->device_interface_in_use &&
526 (irp->Tail.Overlay.OriginalFileObject->DeviceObject == dev->physical_device_object))
527 return TRUE;
528
529 return FALSE;
530 }
531
get_pipe_handle(libusb_device_t * dev,int endpoint_address,USBD_PIPE_HANDLE * pipe_handle)532 bool_t get_pipe_handle(libusb_device_t *dev, int endpoint_address,
533 USBD_PIPE_HANDLE *pipe_handle)
534 {
535 int i, j;
536
537 *pipe_handle = NULL;
538
539 for (i = 0; i < LIBUSB_MAX_NUMBER_OF_INTERFACES; i++)
540 {
541 if (dev->config.interfaces[i].valid)
542 {
543 for (j = 0; j < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; j++)
544 {
545 if (dev->config.interfaces[i].endpoints[j].address
546 == endpoint_address)
547 {
548 *pipe_handle = dev->config.interfaces[i].endpoints[j].handle;
549
550 return !*pipe_handle ? FALSE : TRUE;
551 }
552 }
553 }
554 }
555
556 return FALSE;
557 }
558
get_pipe_info(libusb_device_t * dev,int endpoint_address,libusb_endpoint_t ** pipe_info)559 bool_t get_pipe_info(libusb_device_t *dev, int endpoint_address,
560 libusb_endpoint_t** pipe_info)
561 {
562 int i, j;
563
564 *pipe_info = NULL;
565
566 for (i = 0; i < LIBUSB_MAX_NUMBER_OF_INTERFACES; i++)
567 {
568 if (dev->config.interfaces[i].valid)
569 {
570 for (j = 0; j < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; j++)
571 {
572 if (dev->config.interfaces[i].endpoints[j].address
573 == endpoint_address)
574 {
575 *pipe_info = &dev->config.interfaces[i].endpoints[j];
576
577 return !*pipe_info ? FALSE : TRUE;
578 }
579 }
580 }
581 }
582
583 return FALSE;
584 }
585
clear_pipe_info(libusb_device_t * dev)586 void clear_pipe_info(libusb_device_t *dev)
587 {
588 memset(dev->config.interfaces, 0 , sizeof(dev->config.interfaces));
589 }
590
update_pipe_info(libusb_device_t * dev,USBD_INTERFACE_INFORMATION * interface_info)591 bool_t update_pipe_info(libusb_device_t *dev,
592 USBD_INTERFACE_INFORMATION *interface_info)
593 {
594 int i;
595 int number;
596 int maxTransferSize;
597 int maxPacketSize;
598
599 if (!interface_info)
600 {
601 return FALSE;
602 }
603
604 number = interface_info->InterfaceNumber;
605
606 if (interface_info->InterfaceNumber >= LIBUSB_MAX_NUMBER_OF_INTERFACES)
607 {
608 return FALSE;
609 }
610
611 USBMSG("interface %d\n", number);
612
613 dev->config.interfaces[number].valid = TRUE;
614
615 for (i = 0; i < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; i++)
616 {
617 dev->config.interfaces[number].endpoints[i].address = 0;
618 dev->config.interfaces[number].endpoints[i].handle = NULL;
619 }
620
621 if (interface_info)
622 {
623 for (i = 0; i < (int)interface_info->NumberOfPipes
624 && i < LIBUSB_MAX_NUMBER_OF_ENDPOINTS; i++)
625 {
626 maxPacketSize = interface_info->Pipes[i].MaximumPacketSize;
627 maxTransferSize = interface_info->Pipes[i].MaximumTransferSize;
628
629 USBMSG("EP%02Xh maximum-packet-size=%d maximum-transfer-size=%d\n",
630 interface_info->Pipes[i].EndpointAddress,
631 maxPacketSize,
632 maxTransferSize);
633
634 dev->config.interfaces[number].endpoints[i].handle = interface_info->Pipes[i].PipeHandle;
635 dev->config.interfaces[number].endpoints[i].address = interface_info->Pipes[i].EndpointAddress;
636 dev->config.interfaces[number].endpoints[i].maximum_packet_size = maxPacketSize;
637 dev->config.interfaces[number].endpoints[i].interval = interface_info->Pipes[i].Interval;
638 dev->config.interfaces[number].endpoints[i].pipe_type = interface_info->Pipes[i].PipeType;
639 dev->config.interfaces[number].endpoints[i].pipe_flags = interface_info->Pipes[i].PipeFlags;
640
641 if (maxPacketSize)
642 {
643 // set max the maximum transfer size default to an interval of max packet size.
644 maxTransferSize = maxTransferSize - (maxTransferSize % maxPacketSize);
645 if (maxTransferSize < maxPacketSize)
646 {
647 maxTransferSize = LIBUSB_MAX_READ_WRITE;
648 }
649 else if (maxTransferSize > LIBUSB_MAX_READ_WRITE)
650 {
651 maxTransferSize = LIBUSB_MAX_READ_WRITE - (LIBUSB_MAX_READ_WRITE % maxPacketSize);
652 }
653
654 if (maxTransferSize != interface_info->Pipes[i].MaximumTransferSize)
655 {
656 USBWRN("overriding EP%02Xh maximum-transfer-size=%d\n",
657 dev->config.interfaces[number].endpoints[i].address,
658 maxTransferSize);
659 }
660 }
661 else
662 {
663 if (!maxTransferSize)
664 {
665 // use the libusb-win32 default
666 maxTransferSize = LIBUSB_MAX_READ_WRITE;
667 }
668 }
669 dev->config.interfaces[number].endpoints[i].maximum_transfer_size = maxTransferSize;
670 }
671 }
672 return TRUE;
673 }
674
675
remove_lock_initialize(libusb_device_t * dev)676 void remove_lock_initialize(libusb_device_t *dev)
677 {
678 KeInitializeEvent(&dev->remove_lock.event, NotificationEvent, FALSE);
679 dev->remove_lock.usage_count = 1;
680 dev->remove_lock.remove_pending = FALSE;
681 }
682
683
remove_lock_acquire(libusb_device_t * dev)684 NTSTATUS remove_lock_acquire(libusb_device_t *dev)
685 {
686 InterlockedIncrement(&dev->remove_lock.usage_count);
687
688 if (dev->remove_lock.remove_pending)
689 {
690 if (InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
691 {
692 KeSetEvent(&dev->remove_lock.event, 0, FALSE);
693 }
694 return STATUS_DELETE_PENDING;
695 }
696 return STATUS_SUCCESS;
697 }
698
699
remove_lock_release(libusb_device_t * dev)700 void remove_lock_release(libusb_device_t *dev)
701 {
702 if (InterlockedDecrement(&dev->remove_lock.usage_count) == 0)
703 {
704 KeSetEvent(&dev->remove_lock.event, 0, FALSE);
705 }
706 }
707
708
remove_lock_release_and_wait(libusb_device_t * dev)709 void remove_lock_release_and_wait(libusb_device_t *dev)
710 {
711 dev->remove_lock.remove_pending = TRUE;
712 remove_lock_release(dev);
713 remove_lock_release(dev);
714 KeWaitForSingleObject(&dev->remove_lock.event, Executive, KernelMode,
715 FALSE, NULL);
716 }
717
718
719 USB_INTERFACE_DESCRIPTOR *
find_interface_desc(USB_CONFIGURATION_DESCRIPTOR * config_desc,unsigned int size,int interface_number,int altsetting)720 find_interface_desc(USB_CONFIGURATION_DESCRIPTOR *config_desc,
721 unsigned int size, int interface_number, int altsetting)
722 {
723 usb_descriptor_header_t *desc = (usb_descriptor_header_t *)config_desc;
724 char *p = (char *)desc;
725 USB_INTERFACE_DESCRIPTOR *if_desc = NULL;
726
727 if (!config_desc || (size < config_desc->wTotalLength))
728 return NULL;
729
730 while (size && desc->length <= size)
731 {
732 if (desc->type == USB_INTERFACE_DESCRIPTOR_TYPE)
733 {
734 if_desc = (USB_INTERFACE_DESCRIPTOR *)desc;
735
736 if ((if_desc->bInterfaceNumber == (UCHAR)interface_number)
737 && (if_desc->bAlternateSetting == (UCHAR)altsetting))
738 {
739 return if_desc;
740 }
741 }
742
743 size -= desc->length;
744 p += desc->length;
745 desc = (usb_descriptor_header_t *)p;
746 }
747
748 return NULL;
749 }
750
find_interface_desc_ex(USB_CONFIGURATION_DESCRIPTOR * config_desc,unsigned int size,interface_request_t * intf,unsigned int * size_left)751 USB_INTERFACE_DESCRIPTOR* find_interface_desc_ex(USB_CONFIGURATION_DESCRIPTOR *config_desc,
752 unsigned int size,
753 interface_request_t* intf,
754 unsigned int* size_left)
755 {
756 #define INTF_FIELD 0
757 #define ALTF_FIELD 1
758
759 usb_descriptor_header_t *desc = (usb_descriptor_header_t *)config_desc;
760 char *p = (char *)desc;
761 int lastInfNumber, lastAltNumber;
762 int currentInfIndex;
763 short InterfacesByIndex[LIBUSB_MAX_NUMBER_OF_INTERFACES][2];
764
765 USB_INTERFACE_DESCRIPTOR *if_desc = NULL;
766
767 memset(InterfacesByIndex,0xFF,sizeof(InterfacesByIndex));
768
769 if (!config_desc)
770 return NULL;
771
772 size = size > config_desc->wTotalLength ? config_desc->wTotalLength : size;
773
774 while (size && desc->length <= size)
775 {
776 if (desc->type == USB_INTERFACE_DESCRIPTOR_TYPE)
777 {
778 // this is a new interface or alternate interface
779 if_desc = (USB_INTERFACE_DESCRIPTOR *)desc;
780 for (currentInfIndex=0; currentInfIndex<LIBUSB_MAX_NUMBER_OF_INTERFACES;currentInfIndex++)
781 {
782 if (InterfacesByIndex[currentInfIndex][INTF_FIELD]==-1)
783 {
784 // this is a new interface
785 InterfacesByIndex[currentInfIndex][INTF_FIELD]=if_desc->bInterfaceNumber;
786 InterfacesByIndex[currentInfIndex][ALTF_FIELD]=0;
787 break;
788 }
789 else if (InterfacesByIndex[currentInfIndex][INTF_FIELD]==if_desc->bInterfaceNumber)
790 {
791 // this is a new alternate interface
792 InterfacesByIndex[currentInfIndex][ALTF_FIELD]++;
793 break;
794 }
795 }
796
797 // if the interface index is -1, then we don't care;
798 // i.e. any interface number or index
799 if (intf->interface_index!=FIND_INTERFACE_INDEX_ANY)
800 {
801 if (intf->intf_use_index)
802 {
803 // looking for a particular interface index; if this is not it then continue on.
804 if (intf->interface_index != currentInfIndex)
805 goto NextInterface;
806 }
807 else
808 {
809 // looking for a particular interface number; if this is not it then continue on.
810 if (intf->interface_number != if_desc->bInterfaceNumber)
811 goto NextInterface;
812 }
813 }
814
815 if (intf->altsetting_index!=FIND_INTERFACE_INDEX_ANY)
816 {
817 if (intf->altf_use_index)
818 {
819 // looking for a particular alternate interface index; if this is not it then continue on.
820 if (intf->altsetting_index != InterfacesByIndex[currentInfIndex][ALTF_FIELD])
821 goto NextInterface;
822 }
823 else
824 {
825 // looking for a particular alternate interface number; if this is not it then continue on.
826 if (intf->altsetting_number != if_desc->bAlternateSetting)
827 goto NextInterface;
828 }
829 }
830
831 // found a match
832 intf->interface_index = (unsigned char)currentInfIndex;
833 intf->altsetting_index = (unsigned char)InterfacesByIndex[currentInfIndex][ALTF_FIELD];
834 intf->interface_number = if_desc->bInterfaceNumber;
835 intf->altsetting_number = if_desc->bAlternateSetting;
836
837 if (size_left)
838 {
839 *size_left=size;
840 }
841 return if_desc;
842
843 }
844
845 NextInterface:
846 size -= desc->length;
847 p += desc->length;
848 desc = (usb_descriptor_header_t *)p;
849 }
850
851 return NULL;
852 }
853
854 USB_ENDPOINT_DESCRIPTOR *
find_endpoint_desc_by_index(USB_INTERFACE_DESCRIPTOR * interface_desc,unsigned int size,int pipe_index)855 find_endpoint_desc_by_index(USB_INTERFACE_DESCRIPTOR *interface_desc,
856 unsigned int size, int pipe_index)
857 {
858 usb_descriptor_header_t *desc = (usb_descriptor_header_t *)interface_desc;
859 char *p = (char *)desc;
860 int currentPipeIndex;
861 short PipesByIndex[LIBUSB_MAX_NUMBER_OF_ENDPOINTS];
862
863 USB_ENDPOINT_DESCRIPTOR *ep_desc = NULL;
864 memset(PipesByIndex,0xFF,sizeof(PipesByIndex));
865
866 if (size && desc->length <= size)
867 {
868 size -= desc->length;
869 p += desc->length;
870 desc = (usb_descriptor_header_t *)p;
871 }
872
873 while (size && desc->length <= size)
874 {
875 if (desc->type == USB_ENDPOINT_DESCRIPTOR_TYPE)
876 {
877 ep_desc = (USB_ENDPOINT_DESCRIPTOR *)desc;
878 for (currentPipeIndex=0; currentPipeIndex<LIBUSB_MAX_NUMBER_OF_ENDPOINTS;currentPipeIndex++)
879 {
880 if (PipesByIndex[currentPipeIndex]==-1)
881 {
882 PipesByIndex[currentPipeIndex]=ep_desc->bEndpointAddress;
883 break;
884 }
885 else if (PipesByIndex[currentPipeIndex]==ep_desc->bEndpointAddress)
886 {
887 // the pipe is defined twice in the same interface
888 USBWRN("invalid endpoint descriptor at pipe index=%d\n",currentPipeIndex);
889 break;
890 }
891 }
892
893 if (pipe_index == currentPipeIndex)
894 {
895 return ep_desc;
896 }
897 }
898 else
899 {
900 break;
901 }
902
903 size -= desc->length;
904 p += desc->length;
905 desc = (usb_descriptor_header_t *)p;
906 }
907
908 return NULL;
909 }
910
911
get_current_frame(IN PDEVICE_EXTENSION deviceExtension,IN PIRP Irp)912 ULONG get_current_frame(IN PDEVICE_EXTENSION deviceExtension, IN PIRP Irp)
913 /*++
914
915 Routine Description:
916
917 This routine send an irp/urb pair with
918 function code URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
919 to fetch the current frame
920
921 Arguments:
922
923 DeviceObject - pointer to device object
924 PIRP - I/O request packet
925
926 Return Value:
927
928 Current frame
929
930 --*/
931 {
932 KEVENT event;
933 PIO_STACK_LOCATION nextStack;
934 struct _URB_GET_CURRENT_FRAME_NUMBER urb;
935
936 //
937 // initialize the urb
938 //
939
940 urb.Hdr.Function = URB_FUNCTION_GET_CURRENT_FRAME_NUMBER;
941 urb.Hdr.Length = sizeof(urb);
942 urb.FrameNumber = (ULONG) -1;
943
944 nextStack = IoGetNextIrpStackLocation(Irp);
945 nextStack->Parameters.Others.Argument1 = (PVOID) &urb;
946 nextStack->Parameters.DeviceIoControl.IoControlCode =
947 IOCTL_INTERNAL_USB_SUBMIT_URB;
948 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
949
950 KeInitializeEvent(&event,
951 NotificationEvent,
952 FALSE);
953
954 IoSetCompletionRoutine(Irp,
955 on_usbd_complete,
956 &event,
957 TRUE,
958 TRUE,
959 TRUE);
960
961
962 IoCallDriver(deviceExtension->target_device, Irp);
963
964 KeWaitForSingleObject((PVOID) &event,
965 Executive,
966 KernelMode,
967 FALSE,
968 NULL);
969
970 return urb.FrameNumber;
971 }
972