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