libusb 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -0
- data/History.md +10 -0
- data/README.md +19 -6
- data/Rakefile +1 -1
- data/ext/extconf.rb +17 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
- data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
- data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
- data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
- data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
- data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
- data/ext/libusbx-1.0.17/android/README +114 -0
- data/ext/libusbx-1.0.17/android/config.h +90 -0
- data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
- data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
- data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
- data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
- data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
- data/ext/libusbx-1.0.17/compile +347 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
- data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
- data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
- data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
- data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
- data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
- data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
- data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
- data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
- data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
- data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
- data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
- data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
- data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
- data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
- data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
- data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
- data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
- data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
- data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
- data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
- data/ext/libusbx-1.0.17/missing +215 -0
- data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
- data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
- data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
- data/ext/libusbx-1.0.17/tests/stress.c +160 -0
- data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
- data/lib/libusb.rb +4 -0
- data/lib/libusb/call.rb +43 -1
- data/lib/libusb/constants.rb +5 -0
- data/lib/libusb/context.rb +100 -0
- data/lib/libusb/dev_handle.rb +27 -0
- data/lib/libusb/device.rb +10 -4
- data/lib/libusb/version_gem.rb +1 -1
- data/test/test_libusb_capability.rb +2 -2
- data/test/test_libusb_compat.rb +2 -2
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +4 -2
- data/test/test_libusb_event_machine.rb +2 -2
- data/test/test_libusb_gc.rb +2 -2
- data/test/test_libusb_hotplug.rb +115 -0
- data/test/test_libusb_iso_transfer.rb +3 -3
- data/test/test_libusb_mass_storage.rb +6 -16
- data/test/test_libusb_mass_storage2.rb +26 -3
- data/test/test_libusb_structs.rb +2 -2
- data/test/test_libusb_threads.rb +2 -2
- data/test/test_libusb_version.rb +2 -2
- metadata +127 -68
- metadata.gz.sig +0 -0
- data/ext/libusbx-1.0.14/THANKS +0 -7
- data/ext/libusbx-1.0.14/compile +0 -143
- data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
- data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
- data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
- data/ext/libusbx-1.0.14/missing +0 -376
@@ -0,0 +1,131 @@
|
|
1
|
+
/*
|
2
|
+
* Windows CE backend for libusbx 1.0
|
3
|
+
* Copyright © 2011-2013 RealVNC Ltd.
|
4
|
+
* Portions taken from Windows backend, which is
|
5
|
+
* Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
|
6
|
+
* With contributions from Michael Plante, Orin Eman et al.
|
7
|
+
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
|
8
|
+
* Major code testing contribution by Xiaofan Chen
|
9
|
+
*
|
10
|
+
* This library is free software; you can redistribute it and/or
|
11
|
+
* modify it under the terms of the GNU Lesser General Public
|
12
|
+
* License as published by the Free Software Foundation; either
|
13
|
+
* version 2.1 of the License, or (at your option) any later version.
|
14
|
+
*
|
15
|
+
* This library is distributed in the hope that it will be useful,
|
16
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
18
|
+
* Lesser General Public License for more details.
|
19
|
+
*
|
20
|
+
* You should have received a copy of the GNU Lesser General Public
|
21
|
+
* License along with this library; if not, write to the Free Software
|
22
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
23
|
+
*/
|
24
|
+
#pragma once
|
25
|
+
|
26
|
+
#include "windows_common.h"
|
27
|
+
|
28
|
+
#include <windows.h>
|
29
|
+
#include "poll_windows.h"
|
30
|
+
|
31
|
+
#define MAX_DEVICE_COUNT 256
|
32
|
+
|
33
|
+
// This is a modified dump of the types in the ceusbkwrapper.h library header
|
34
|
+
// with functions transformed into extern pointers.
|
35
|
+
//
|
36
|
+
// This backend dynamically loads ceusbkwrapper.dll and doesn't include
|
37
|
+
// ceusbkwrapper.h directly to simplify the build process. The kernel
|
38
|
+
// side wrapper driver is built using the platform image build tools,
|
39
|
+
// which makes it difficult to reference directly from the libusbx build
|
40
|
+
// system.
|
41
|
+
struct UKW_DEVICE_PRIV;
|
42
|
+
typedef struct UKW_DEVICE_PRIV *UKW_DEVICE;
|
43
|
+
typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE;
|
44
|
+
|
45
|
+
typedef struct {
|
46
|
+
UINT8 bLength;
|
47
|
+
UINT8 bDescriptorType;
|
48
|
+
UINT16 bcdUSB;
|
49
|
+
UINT8 bDeviceClass;
|
50
|
+
UINT8 bDeviceSubClass;
|
51
|
+
UINT8 bDeviceProtocol;
|
52
|
+
UINT8 bMaxPacketSize0;
|
53
|
+
UINT16 idVendor;
|
54
|
+
UINT16 idProduct;
|
55
|
+
UINT16 bcdDevice;
|
56
|
+
UINT8 iManufacturer;
|
57
|
+
UINT8 iProduct;
|
58
|
+
UINT8 iSerialNumber;
|
59
|
+
UINT8 bNumConfigurations;
|
60
|
+
} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR;
|
61
|
+
|
62
|
+
typedef struct {
|
63
|
+
UINT8 bmRequestType;
|
64
|
+
UINT8 bRequest;
|
65
|
+
UINT16 wValue;
|
66
|
+
UINT16 wIndex;
|
67
|
+
UINT16 wLength;
|
68
|
+
} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER;
|
69
|
+
|
70
|
+
// Collection of flags which can be used when issuing transfer requests
|
71
|
+
/* Indicates that the transfer direction is 'in' */
|
72
|
+
#define UKW_TF_IN_TRANSFER 0x00000001
|
73
|
+
/* Indicates that the transfer direction is 'out' */
|
74
|
+
#define UKW_TF_OUT_TRANSFER 0x00000000
|
75
|
+
/* Specifies that the transfer should complete as soon as possible,
|
76
|
+
* even if no OVERLAPPED structure has been provided. */
|
77
|
+
#define UKW_TF_NO_WAIT 0x00000100
|
78
|
+
/* Indicates that transfers shorter than the buffer are ok */
|
79
|
+
#define UKW_TF_SHORT_TRANSFER_OK 0x00000200
|
80
|
+
#define UKW_TF_SEND_TO_DEVICE 0x00010000
|
81
|
+
#define UKW_TF_SEND_TO_INTERFACE 0x00020000
|
82
|
+
#define UKW_TF_SEND_TO_ENDPOINT 0x00040000
|
83
|
+
/* Don't block when waiting for memory allocations */
|
84
|
+
#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000
|
85
|
+
|
86
|
+
/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor,
|
87
|
+
* to specify the currently active configuration for the device. */
|
88
|
+
#define UKW_ACTIVE_CONFIGURATION -1
|
89
|
+
|
90
|
+
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
|
91
|
+
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
|
92
|
+
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
|
93
|
+
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
|
94
|
+
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
|
95
|
+
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
|
96
|
+
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
|
97
|
+
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
|
98
|
+
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
|
99
|
+
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
|
100
|
+
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
|
101
|
+
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
|
102
|
+
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
|
103
|
+
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
|
104
|
+
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
|
105
|
+
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
|
106
|
+
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
|
107
|
+
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
|
108
|
+
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
|
109
|
+
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
|
110
|
+
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
|
111
|
+
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
|
112
|
+
|
113
|
+
// Used to determine if an endpoint status really is halted on a failed transfer.
|
114
|
+
#define STATUS_HALT_FLAG 0x1
|
115
|
+
|
116
|
+
struct wince_device_priv {
|
117
|
+
UKW_DEVICE dev;
|
118
|
+
UKW_DEVICE_DESCRIPTOR desc;
|
119
|
+
};
|
120
|
+
|
121
|
+
struct wince_device_handle_priv {
|
122
|
+
// This member isn't used, but only exists to avoid an empty structure
|
123
|
+
// for private data for the device handle.
|
124
|
+
int reserved;
|
125
|
+
};
|
126
|
+
|
127
|
+
struct wince_transfer_priv {
|
128
|
+
struct winfd pollable_fd;
|
129
|
+
uint8_t interface_number;
|
130
|
+
};
|
131
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
/*
|
2
|
+
* Windows backend common header for libusbx 1.0
|
3
|
+
*
|
4
|
+
* This file brings together header code common between
|
5
|
+
* the desktop Windows and Windows CE backends.
|
6
|
+
* Copyright © 2012-2013 RealVNC Ltd.
|
7
|
+
* Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
|
8
|
+
* With contributions from Michael Plante, Orin Eman et al.
|
9
|
+
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
|
10
|
+
* Major code testing contribution by Xiaofan Chen
|
11
|
+
*
|
12
|
+
* This library is free software; you can redistribute it and/or
|
13
|
+
* modify it under the terms of the GNU Lesser General Public
|
14
|
+
* License as published by the Free Software Foundation; either
|
15
|
+
* version 2.1 of the License, or (at your option) any later version.
|
16
|
+
*
|
17
|
+
* This library is distributed in the hope that it will be useful,
|
18
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
20
|
+
* Lesser General Public License for more details.
|
21
|
+
*
|
22
|
+
* You should have received a copy of the GNU Lesser General Public
|
23
|
+
* License along with this library; if not, write to the Free Software
|
24
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
25
|
+
*/
|
26
|
+
|
27
|
+
#pragma once
|
28
|
+
|
29
|
+
// Windows API default is uppercase - ugh!
|
30
|
+
#if !defined(bool)
|
31
|
+
#define bool BOOL
|
32
|
+
#endif
|
33
|
+
#if !defined(true)
|
34
|
+
#define true TRUE
|
35
|
+
#endif
|
36
|
+
#if !defined(false)
|
37
|
+
#define false FALSE
|
38
|
+
#endif
|
39
|
+
|
40
|
+
#define safe_free(p) do {if (p != NULL) {free((void*)p); p = NULL;}} while(0)
|
41
|
+
#define safe_closehandle(h) do {if (h != INVALID_HANDLE_VALUE) {CloseHandle(h); h = INVALID_HANDLE_VALUE;}} while(0)
|
42
|
+
#define safe_min(a, b) min((size_t)(a), (size_t)(b))
|
43
|
+
#define safe_strcp(dst, dst_max, src, count) do {memcpy(dst, src, safe_min(count, dst_max)); \
|
44
|
+
((char*)dst)[safe_min(count, dst_max)-1] = 0;} while(0)
|
45
|
+
#define safe_strcpy(dst, dst_max, src) safe_strcp(dst, dst_max, src, safe_strlen(src)+1)
|
46
|
+
#define safe_strncat(dst, dst_max, src, count) strncat(dst, src, safe_min(count, dst_max - safe_strlen(dst) - 1))
|
47
|
+
#define safe_strcat(dst, dst_max, src) safe_strncat(dst, dst_max, src, safe_strlen(src)+1)
|
48
|
+
#define safe_strcmp(str1, str2) strcmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
|
49
|
+
#define safe_stricmp(str1, str2) _stricmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2))
|
50
|
+
#define safe_strncmp(str1, str2, count) strncmp(((str1==NULL)?"<NULL>":str1), ((str2==NULL)?"<NULL>":str2), count)
|
51
|
+
#define safe_strlen(str) ((str==NULL)?0:strlen(str))
|
52
|
+
#define safe_sprintf(dst, count, ...) do {_snprintf(dst, count, __VA_ARGS__); (dst)[(count)-1] = 0; } while(0)
|
53
|
+
#define safe_stprintf _sntprintf
|
54
|
+
#define safe_tcslen(str) ((str==NULL)?0:_tcslen(str))
|
55
|
+
#define safe_unref_device(dev) do {if (dev != NULL) {libusb_unref_device(dev); dev = NULL;}} while(0)
|
56
|
+
#define wchar_to_utf8_ms(wstr, str, strlen) WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, strlen, NULL, NULL)
|
57
|
+
#ifndef ARRAYSIZE
|
58
|
+
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
59
|
+
#endif
|
60
|
+
|
61
|
+
#define ERR_BUFFER_SIZE 256
|
62
|
+
#define TIMER_REQUEST_RETRY_MS 100
|
63
|
+
#define MAX_TIMER_SEMAPHORES 128
|
64
|
+
|
65
|
+
|
66
|
+
/*
|
67
|
+
* API macros - from libusb-win32 1.x
|
68
|
+
*/
|
69
|
+
#define DLL_DECLARE_PREFIXNAME(api, ret, prefixname, name, args) \
|
70
|
+
typedef ret (api * __dll_##name##_t)args; \
|
71
|
+
static __dll_##name##_t prefixname = NULL
|
72
|
+
|
73
|
+
#ifndef _WIN32_WCE
|
74
|
+
#define DLL_STRINGIFY(dll) #dll
|
75
|
+
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandleA(DLL_STRINGIFY(dll))
|
76
|
+
#define DLL_LOAD_LIBRARY(dll) LoadLibraryA(DLL_STRINGIFY(dll))
|
77
|
+
#else
|
78
|
+
#define DLL_STRINGIFY(dll) L#dll
|
79
|
+
#define DLL_GET_MODULE_HANDLE(dll) GetModuleHandle(DLL_STRINGIFY(dll))
|
80
|
+
#define DLL_LOAD_LIBRARY(dll) LoadLibrary(DLL_STRINGIFY(dll))
|
81
|
+
#endif
|
82
|
+
|
83
|
+
#define DLL_LOAD_PREFIXNAME(dll, prefixname, name, ret_on_failure) \
|
84
|
+
do { \
|
85
|
+
HMODULE h = DLL_GET_MODULE_HANDLE(dll); \
|
86
|
+
if (!h) \
|
87
|
+
h = DLL_LOAD_LIBRARY(dll); \
|
88
|
+
if (!h) { \
|
89
|
+
if (ret_on_failure) { return LIBUSB_ERROR_NOT_FOUND; } \
|
90
|
+
else { break; } \
|
91
|
+
} \
|
92
|
+
prefixname = (__dll_##name##_t)GetProcAddress(h, \
|
93
|
+
DLL_STRINGIFY(name)); \
|
94
|
+
if (prefixname) break; \
|
95
|
+
prefixname = (__dll_##name##_t)GetProcAddress(h, \
|
96
|
+
DLL_STRINGIFY(name) DLL_STRINGIFY(A)); \
|
97
|
+
if (prefixname) break; \
|
98
|
+
prefixname = (__dll_##name##_t)GetProcAddress(h, \
|
99
|
+
DLL_STRINGIFY(name) DLL_STRINGIFY(W)); \
|
100
|
+
if (prefixname) break; \
|
101
|
+
if(ret_on_failure) \
|
102
|
+
return LIBUSB_ERROR_NOT_FOUND; \
|
103
|
+
} while(0)
|
104
|
+
|
105
|
+
#define DLL_DECLARE(api, ret, name, args) DLL_DECLARE_PREFIXNAME(api, ret, name, name, args)
|
106
|
+
#define DLL_LOAD(dll, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, name, name, ret_on_failure)
|
107
|
+
#define DLL_DECLARE_PREFIXED(api, ret, prefix, name, args) DLL_DECLARE_PREFIXNAME(api, ret, prefix##name, name, args)
|
108
|
+
#define DLL_LOAD_PREFIXED(dll, prefix, name, ret_on_failure) DLL_LOAD_PREFIXNAME(dll, prefix##name, name, ret_on_failure)
|
@@ -34,7 +34,7 @@
|
|
34
34
|
#include <objbase.h>
|
35
35
|
#include <winioctl.h>
|
36
36
|
|
37
|
-
#include
|
37
|
+
#include "libusbi.h"
|
38
38
|
#include "poll_windows.h"
|
39
39
|
#include "windows_usb.h"
|
40
40
|
|
@@ -42,8 +42,6 @@
|
|
42
42
|
#define LOOP_CHECK(fcall) { r=fcall; if (r != LIBUSB_SUCCESS) continue; }
|
43
43
|
#define LOOP_BREAK(err) { r=err; continue; }
|
44
44
|
|
45
|
-
extern void usbi_fd_notification(struct libusb_context *ctx);
|
46
|
-
|
47
45
|
// Helper prototypes
|
48
46
|
static int windows_get_active_config_descriptor(struct libusb_device *dev, unsigned char *buffer, size_t len, int *host_endian);
|
49
47
|
static int windows_clock_gettime(int clk_id, struct timespec *tp);
|
@@ -153,7 +151,7 @@ static char *windows_error_str(uint32_t retval)
|
|
153
151
|
static char err_string[ERR_BUFFER_SIZE];
|
154
152
|
|
155
153
|
DWORD size;
|
156
|
-
|
154
|
+
ssize_t i;
|
157
155
|
uint32_t error_code, format_error;
|
158
156
|
|
159
157
|
error_code = retval?retval:GetLastError();
|
@@ -172,7 +170,7 @@ static char err_string[ERR_BUFFER_SIZE];
|
|
172
170
|
safe_sprintf(err_string, ERR_BUFFER_SIZE, "Unknown error code %u", error_code);
|
173
171
|
} else {
|
174
172
|
// Remove CR/LF terminators
|
175
|
-
for (i=safe_strlen(err_string)-1; ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
|
173
|
+
for (i=safe_strlen(err_string)-1; (i>=0) && ((err_string[i]==0x0A) || (err_string[i]==0x0D)); i--) {
|
176
174
|
err_string[i] = 0;
|
177
175
|
}
|
178
176
|
}
|
@@ -261,7 +259,7 @@ static int init_dlls(void)
|
|
261
259
|
* incremented index starting at zero) until all interfaces have been returned.
|
262
260
|
*/
|
263
261
|
static bool get_devinfo_data(struct libusb_context *ctx,
|
264
|
-
HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, char* usb_class, unsigned _index)
|
262
|
+
HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const char* usb_class, unsigned _index)
|
265
263
|
{
|
266
264
|
if (_index <= 0) {
|
267
265
|
*dev_info = pSetupDiGetClassDevsA(NULL, usb_class, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
|
@@ -365,7 +363,7 @@ err_exit:
|
|
365
363
|
}
|
366
364
|
|
367
365
|
/* For libusb0 filter */
|
368
|
-
SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
|
366
|
+
static SP_DEVICE_INTERFACE_DETAIL_DATA_A *get_interface_details_filter(struct libusb_context *ctx,
|
369
367
|
HDEVINFO *dev_info, SP_DEVINFO_DATA *dev_info_data, const GUID* guid, unsigned _index, char* filter_path){
|
370
368
|
SP_DEVICE_INTERFACE_DATA dev_interface_data;
|
371
369
|
SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
|
@@ -537,6 +535,9 @@ static unsigned long htab_hash(char* str)
|
|
537
535
|
int c;
|
538
536
|
char* sz = str;
|
539
537
|
|
538
|
+
if (str == NULL)
|
539
|
+
return 0;
|
540
|
+
|
540
541
|
// Compute main hash value (algorithm suggested by Nokia)
|
541
542
|
while ((c = *sz++) != 0)
|
542
543
|
r = ((r << 5) + r) + c;
|
@@ -635,7 +636,7 @@ static unsigned long get_ancestor_session_id(DWORD devinst, unsigned level)
|
|
635
636
|
if (CM_Get_Device_IDA(devinst, path, MAX_PATH_LENGTH, 0) != CR_SUCCESS) {
|
636
637
|
return 0;
|
637
638
|
}
|
638
|
-
// TODO (post hotplug): try without sanitizing
|
639
|
+
// TODO: (post hotplug): try without sanitizing
|
639
640
|
sanitized_path = sanitize_path(path);
|
640
641
|
if (sanitized_path == NULL) {
|
641
642
|
return 0;
|
@@ -688,7 +689,7 @@ static int windows_assign_endpoints(struct libusb_device_handle *dev_handle, int
|
|
688
689
|
|
689
690
|
// Lookup for a match in the list of API driver names
|
690
691
|
// return -1 if not found, driver match number otherwise
|
691
|
-
int get_sub_api(char* driver, int api){
|
692
|
+
static int get_sub_api(char* driver, int api){
|
692
693
|
int i;
|
693
694
|
const char sep_str[2] = {LIST_SEPARATOR, 0};
|
694
695
|
char *tok, *tmp_str;
|
@@ -885,6 +886,12 @@ static int windows_init(struct libusb_context *ctx)
|
|
885
886
|
}
|
886
887
|
SetThreadAffinityMask(timer_thread, 0);
|
887
888
|
|
889
|
+
// Wait for timer thread to init before continuing.
|
890
|
+
if (WaitForSingleObject(timer_response, INFINITE) != WAIT_OBJECT_0) {
|
891
|
+
usbi_err(ctx, "Failed to wait for timer thread to become ready - aborting");
|
892
|
+
goto init_exit;
|
893
|
+
}
|
894
|
+
|
888
895
|
// Create a hash table to store session ids. Second parameter is better if prime
|
889
896
|
htab_create(ctx, HTAB_SIZE);
|
890
897
|
}
|
@@ -1109,7 +1116,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
1109
1116
|
dev->port_number = port_number;
|
1110
1117
|
priv->depth = parent_priv->depth + 1;
|
1111
1118
|
priv->parent_dev = parent_dev;
|
1112
|
-
dev->parent_dev = parent_dev;
|
1119
|
+
dev->parent_dev = libusb_ref_device(parent_dev);
|
1113
1120
|
|
1114
1121
|
// If the device address is already set, we can stop here
|
1115
1122
|
if (dev->device_address != 0) {
|
@@ -1169,6 +1176,8 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
1169
1176
|
force_hcd_device_descriptor(dev);
|
1170
1177
|
}
|
1171
1178
|
|
1179
|
+
usbi_sanitize_device(dev);
|
1180
|
+
|
1172
1181
|
usbi_dbg("(bus: %d, addr: %d, depth: %d, port: %d): '%s'",
|
1173
1182
|
dev->bus_number, dev->device_address, priv->depth, priv->port, device_id);
|
1174
1183
|
|
@@ -1176,7 +1185,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
|
|
1176
1185
|
}
|
1177
1186
|
|
1178
1187
|
// Returns the api type, or 0 if not found/unsupported
|
1179
|
-
void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
|
1188
|
+
static void get_api_type(struct libusb_context *ctx, HDEVINFO *dev_info,
|
1180
1189
|
SP_DEVINFO_DATA *dev_info_data, int *api, int *sub_api)
|
1181
1190
|
{
|
1182
1191
|
// Precedence for filter drivers vs driver is in the order of this array
|
@@ -1277,7 +1286,7 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev
|
|
1277
1286
|
priv->usb_interface[interface_number].apib = &usb_api_backend[api];
|
1278
1287
|
priv->usb_interface[interface_number].sub_api = sub_api;
|
1279
1288
|
if ((api == USB_API_HID) && (priv->hid == NULL)) {
|
1280
|
-
priv->hid = calloc(1, sizeof(struct hid_device_priv));
|
1289
|
+
priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv));
|
1281
1290
|
if (priv->hid == NULL)
|
1282
1291
|
return LIBUSB_ERROR_NO_MEM;
|
1283
1292
|
}
|
@@ -1288,6 +1297,7 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev
|
|
1288
1297
|
static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev,
|
1289
1298
|
char* dev_interface_path)
|
1290
1299
|
{
|
1300
|
+
int i;
|
1291
1301
|
struct windows_device_priv *priv = _device_priv(dev);
|
1292
1302
|
|
1293
1303
|
if (priv->hid == NULL) {
|
@@ -1298,8 +1308,11 @@ static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* d
|
|
1298
1308
|
usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device");
|
1299
1309
|
return LIBUSB_ERROR_NO_DEVICE;
|
1300
1310
|
}
|
1301
|
-
|
1302
|
-
|
1311
|
+
for (i=0; i<priv->hid->nb_interfaces; i++) {
|
1312
|
+
if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
|
1313
|
+
usbi_dbg("interface[%d] already set to %s", i, dev_interface_path);
|
1314
|
+
return LIBUSB_SUCCESS;
|
1315
|
+
}
|
1303
1316
|
}
|
1304
1317
|
|
1305
1318
|
priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
|
@@ -1316,7 +1329,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
1316
1329
|
{
|
1317
1330
|
struct discovered_devs *discdevs;
|
1318
1331
|
HDEVINFO dev_info = { 0 };
|
1319
|
-
char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
|
1332
|
+
const char* usb_class[] = {"USB", "NUSB3", "IUSB3"};
|
1320
1333
|
SP_DEVINFO_DATA dev_info_data = { 0 };
|
1321
1334
|
SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
|
1322
1335
|
GUID hid_guid;
|
@@ -1329,7 +1342,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
|
|
1329
1342
|
#define HID_PASS 4
|
1330
1343
|
int r = LIBUSB_SUCCESS;
|
1331
1344
|
int api, sub_api;
|
1332
|
-
|
1345
|
+
size_t class_index = 0;
|
1333
1346
|
unsigned int nb_guids, pass, i, j, ancestor;
|
1334
1347
|
char path[MAX_PATH_LENGTH];
|
1335
1348
|
char strbuf[MAX_PATH_LENGTH];
|
@@ -1750,8 +1763,9 @@ static int windows_get_config_descriptor(struct libusb_device *dev, uint8_t conf
|
|
1750
1763
|
|
1751
1764
|
size = min(config_header->wTotalLength, len);
|
1752
1765
|
memcpy(buffer, priv->config_descriptor[config_index], size);
|
1766
|
+
*host_endian = 0;
|
1753
1767
|
|
1754
|
-
return
|
1768
|
+
return (int)size;
|
1755
1769
|
}
|
1756
1770
|
|
1757
1771
|
/*
|
@@ -1906,7 +1920,7 @@ static void windows_clear_transfer_priv(struct usbi_transfer *itransfer)
|
|
1906
1920
|
{
|
1907
1921
|
struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
|
1908
1922
|
|
1909
|
-
usbi_free_fd(transfer_priv->pollable_fd
|
1923
|
+
usbi_free_fd(&transfer_priv->pollable_fd);
|
1910
1924
|
safe_free(transfer_priv->hid_buffer);
|
1911
1925
|
// When auto claim is in use, attempt to release the auto-claimed interface
|
1912
1926
|
auto_release(itransfer);
|
@@ -2030,9 +2044,9 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t
|
|
2030
2044
|
{
|
2031
2045
|
struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
|
2032
2046
|
struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev);
|
2033
|
-
int status;
|
2047
|
+
int status, istatus;
|
2034
2048
|
|
2035
|
-
usbi_dbg("handling I/O completion with errcode %d", io_result);
|
2049
|
+
usbi_dbg("handling I/O completion with errcode %d, size %d", io_result, io_size);
|
2036
2050
|
|
2037
2051
|
switch(io_result) {
|
2038
2052
|
case NO_ERROR:
|
@@ -2047,6 +2061,10 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t
|
|
2047
2061
|
status = LIBUSB_TRANSFER_TIMED_OUT;
|
2048
2062
|
break;
|
2049
2063
|
case ERROR_OPERATION_ABORTED:
|
2064
|
+
istatus = priv->apib->copy_transfer_data(SUB_API_NOTSET, itransfer, io_size);
|
2065
|
+
if (istatus != LIBUSB_TRANSFER_COMPLETED) {
|
2066
|
+
usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus);
|
2067
|
+
}
|
2050
2068
|
if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) {
|
2051
2069
|
usbi_dbg("detected timeout");
|
2052
2070
|
status = LIBUSB_TRANSFER_TIMED_OUT;
|
@@ -2056,7 +2074,7 @@ static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t
|
|
2056
2074
|
}
|
2057
2075
|
break;
|
2058
2076
|
default:
|
2059
|
-
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(0));
|
2077
|
+
usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %d: %s", io_result, windows_error_str(0));
|
2060
2078
|
status = LIBUSB_TRANSFER_ERROR;
|
2061
2079
|
break;
|
2062
2080
|
}
|
@@ -2160,6 +2178,11 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
|
2160
2178
|
usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
|
2161
2179
|
}
|
2162
2180
|
|
2181
|
+
// Signal windows_init() that we're ready to service requests
|
2182
|
+
if (ReleaseSemaphore(timer_response, 1, NULL) == 0) {
|
2183
|
+
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
2184
|
+
}
|
2185
|
+
|
2163
2186
|
// Main loop - wait for requests
|
2164
2187
|
while (1) {
|
2165
2188
|
timer_index = WaitForMultipleObjects(2, timer_request, FALSE, INFINITE) - WAIT_OBJECT_0;
|
@@ -2194,7 +2217,7 @@ unsigned __stdcall windows_clock_gettime_threaded(void* param)
|
|
2194
2217
|
nb_responses = InterlockedExchange((LONG*)&request_count[0], 0);
|
2195
2218
|
if ( (nb_responses)
|
2196
2219
|
&& (ReleaseSemaphore(timer_response, nb_responses, NULL) == 0) ) {
|
2197
|
-
usbi_dbg("unable to release timer semaphore
|
2220
|
+
usbi_dbg("unable to release timer semaphore: %s", windows_error_str(0));
|
2198
2221
|
}
|
2199
2222
|
continue;
|
2200
2223
|
case 1: // time to quit
|
@@ -2253,16 +2276,19 @@ static int windows_clock_gettime(int clk_id, struct timespec *tp)
|
|
2253
2276
|
// NB: MSVC6 does not support named initializers.
|
2254
2277
|
const struct usbi_os_backend windows_backend = {
|
2255
2278
|
"Windows",
|
2279
|
+
USBI_CAP_HAS_HID_ACCESS,
|
2256
2280
|
windows_init,
|
2257
2281
|
windows_exit,
|
2258
2282
|
|
2259
2283
|
windows_get_device_list,
|
2284
|
+
NULL, /* hotplug_poll */
|
2260
2285
|
windows_open,
|
2261
2286
|
windows_close,
|
2262
2287
|
|
2263
2288
|
windows_get_device_descriptor,
|
2264
2289
|
windows_get_active_config_descriptor,
|
2265
2290
|
windows_get_config_descriptor,
|
2291
|
+
NULL, /* get_config_descriptor_by_value() */
|
2266
2292
|
|
2267
2293
|
windows_get_configuration,
|
2268
2294
|
windows_set_configuration,
|
@@ -2594,6 +2620,8 @@ static void winusbx_close(int sub_api, struct libusb_device_handle *dev_handle)
|
|
2594
2620
|
HANDLE file_handle;
|
2595
2621
|
int i;
|
2596
2622
|
|
2623
|
+
if (sub_api == SUB_API_NOTSET)
|
2624
|
+
sub_api = priv->sub_api;
|
2597
2625
|
if (!WinUSBX[sub_api].initialized)
|
2598
2626
|
return;
|
2599
2627
|
|
@@ -2662,9 +2690,10 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
|
|
2662
2690
|
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
2663
2691
|
bool is_using_usbccgp = (priv->apib->id == USB_API_COMPOSITE);
|
2664
2692
|
HANDLE file_handle, winusb_handle;
|
2693
|
+
DWORD err;
|
2665
2694
|
int i;
|
2666
2695
|
SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL;
|
2667
|
-
HDEVINFO dev_info;
|
2696
|
+
HDEVINFO dev_info = INVALID_HANDLE_VALUE;
|
2668
2697
|
SP_DEVINFO_DATA dev_info_data;
|
2669
2698
|
char* dev_path_no_guid = NULL;
|
2670
2699
|
char filter_path[] = "\\\\.\\libusb0-0000";
|
@@ -2683,15 +2712,15 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
|
|
2683
2712
|
|
2684
2713
|
if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
|
2685
2714
|
handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
|
2686
|
-
|
2687
|
-
switch(
|
2715
|
+
err = GetLastError();
|
2716
|
+
switch(err) {
|
2688
2717
|
case ERROR_BAD_COMMAND:
|
2689
2718
|
// The device was disconnected
|
2690
2719
|
usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
|
2691
2720
|
return LIBUSB_ERROR_NO_DEVICE;
|
2692
2721
|
default:
|
2693
2722
|
// it may be that we're using the libusb0 filter driver.
|
2694
|
-
//
|
2723
|
+
// TODO: can we move this whole business into the K/0 DLL?
|
2695
2724
|
for (i = 0; ; i++) {
|
2696
2725
|
safe_free(dev_interface_details);
|
2697
2726
|
safe_free(dev_path_no_guid);
|
@@ -2717,7 +2746,7 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
|
|
2717
2746
|
}
|
2718
2747
|
}
|
2719
2748
|
if (!found_filter) {
|
2720
|
-
usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(
|
2749
|
+
usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(err));
|
2721
2750
|
return LIBUSB_ERROR_ACCESS;
|
2722
2751
|
}
|
2723
2752
|
}
|
@@ -2730,11 +2759,11 @@ static int winusbx_claim_interface(int sub_api, struct libusb_device_handle *dev
|
|
2730
2759
|
// must first claim the first interface before you claim the others
|
2731
2760
|
if ((winusb_handle == 0) || (winusb_handle == INVALID_HANDLE_VALUE)) {
|
2732
2761
|
file_handle = handle_priv->interface_handle[0].dev_handle;
|
2733
|
-
if (
|
2762
|
+
if (WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
|
2734
2763
|
handle_priv->interface_handle[0].api_handle = winusb_handle;
|
2735
2764
|
usbi_warn(ctx, "auto-claimed interface 0 (required to claim %d with WinUSB)", iface);
|
2736
2765
|
} else {
|
2737
|
-
usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB)", iface);
|
2766
|
+
usbi_warn(ctx, "failed to auto-claim interface 0 (required to claim %d with WinUSB): %s", iface, windows_error_str(0));
|
2738
2767
|
return LIBUSB_ERROR_ACCESS;
|
2739
2768
|
}
|
2740
2769
|
}
|
@@ -2860,7 +2889,7 @@ static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *it
|
|
2860
2889
|
usbi_dbg("will use interface %d", current_interface);
|
2861
2890
|
winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
|
2862
2891
|
|
2863
|
-
wfd = usbi_create_fd(winusb_handle,
|
2892
|
+
wfd = usbi_create_fd(winusb_handle, RW_READ, NULL, NULL);
|
2864
2893
|
// Always use the handle returned from usbi_create_fd (wfd.handle)
|
2865
2894
|
if (wfd.fd < 0) {
|
2866
2895
|
return LIBUSB_ERROR_NO_MEM;
|
@@ -2871,7 +2900,7 @@ static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *it
|
|
2871
2900
|
&& (setup->request == LIBUSB_REQUEST_SET_CONFIGURATION) ) {
|
2872
2901
|
if (setup->value != priv->active_config) {
|
2873
2902
|
usbi_warn(ctx, "cannot set configuration other than the default one");
|
2874
|
-
usbi_free_fd(wfd
|
2903
|
+
usbi_free_fd(&wfd);
|
2875
2904
|
return LIBUSB_ERROR_INVALID_PARAM;
|
2876
2905
|
}
|
2877
2906
|
wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY;
|
@@ -2880,7 +2909,7 @@ static int winusbx_submit_control_transfer(int sub_api, struct usbi_transfer *it
|
|
2880
2909
|
if (!WinUSBX[sub_api].ControlTransfer(wfd.handle, *setup, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, size, NULL, wfd.overlapped)) {
|
2881
2910
|
if(GetLastError() != ERROR_IO_PENDING) {
|
2882
2911
|
usbi_warn(ctx, "ControlTransfer failed: %s", windows_error_str(0));
|
2883
|
-
usbi_free_fd(wfd
|
2912
|
+
usbi_free_fd(&wfd);
|
2884
2913
|
return LIBUSB_ERROR_IO;
|
2885
2914
|
}
|
2886
2915
|
} else {
|
@@ -2949,7 +2978,7 @@ static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itran
|
|
2949
2978
|
|
2950
2979
|
winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
|
2951
2980
|
|
2952
|
-
wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ?
|
2981
|
+
wfd = usbi_create_fd(winusb_handle, IS_XFERIN(transfer) ? RW_READ : RW_WRITE, NULL, NULL);
|
2953
2982
|
// Always use the handle returned from usbi_create_fd (wfd.handle)
|
2954
2983
|
if (wfd.fd < 0) {
|
2955
2984
|
return LIBUSB_ERROR_NO_MEM;
|
@@ -2965,7 +2994,7 @@ static int winusbx_submit_bulk_transfer(int sub_api, struct usbi_transfer *itran
|
|
2965
2994
|
if (!ret) {
|
2966
2995
|
if(GetLastError() != ERROR_IO_PENDING) {
|
2967
2996
|
usbi_err(ctx, "ReadPipe/WritePipe failed: %s", windows_error_str(0));
|
2968
|
-
usbi_free_fd(wfd
|
2997
|
+
usbi_free_fd(&wfd);
|
2969
2998
|
return LIBUSB_ERROR_IO;
|
2970
2999
|
}
|
2971
3000
|
} else {
|
@@ -3055,7 +3084,7 @@ static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer)
|
|
3055
3084
|
* IOCTL_USB_HUB_CYCLE_PORT ioctl was removed from Vista => the best we can do is
|
3056
3085
|
* cycle the pipes (and even then, the control pipe can not be reset using WinUSB)
|
3057
3086
|
*/
|
3058
|
-
// TODO (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
|
3087
|
+
// TODO: (post hotplug): see if we can force eject the device and redetect it (reuse hotplug?)
|
3059
3088
|
static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle)
|
3060
3089
|
{
|
3061
3090
|
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
|
@@ -3074,7 +3103,7 @@ static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_ha
|
|
3074
3103
|
{
|
3075
3104
|
// Cancel any pollable I/O
|
3076
3105
|
usbi_remove_pollfd(ctx, wfd.fd);
|
3077
|
-
usbi_free_fd(wfd
|
3106
|
+
usbi_free_fd(&wfd);
|
3078
3107
|
wfd = handle_to_winfd(winusb_handle);
|
3079
3108
|
}
|
3080
3109
|
|
@@ -3214,8 +3243,7 @@ static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, s
|
|
3214
3243
|
ed->bmAttributes = 3;
|
3215
3244
|
ed->wMaxPacketSize = dev->input_report_size - 1;
|
3216
3245
|
ed->bInterval = 10;
|
3217
|
-
|
3218
|
-
ed++;
|
3246
|
+
ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE);
|
3219
3247
|
}
|
3220
3248
|
|
3221
3249
|
if (dev->output_report_size) {
|
@@ -3626,7 +3654,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
|
|
3626
3654
|
int i, j;
|
3627
3655
|
// report IDs handling
|
3628
3656
|
ULONG size[3];
|
3629
|
-
char* type[3] = {"input", "output", "feature"};
|
3657
|
+
const char* type[3] = {"input", "output", "feature"};
|
3630
3658
|
int nb_ids[2]; // zero and nonzero report IDs
|
3631
3659
|
|
3632
3660
|
CHECK_HID_AVAILABLE;
|
@@ -3882,9 +3910,9 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
|
|
3882
3910
|
usbi_dbg("will use interface %d", current_interface);
|
3883
3911
|
hid_handle = handle_priv->interface_handle[current_interface].api_handle;
|
3884
3912
|
// Always use the handle returned from usbi_create_fd (wfd.handle)
|
3885
|
-
wfd = usbi_create_fd(hid_handle,
|
3913
|
+
wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL);
|
3886
3914
|
if (wfd.fd < 0) {
|
3887
|
-
return
|
3915
|
+
return LIBUSB_ERROR_NOT_FOUND;
|
3888
3916
|
}
|
3889
3917
|
|
3890
3918
|
switch(LIBUSB_REQ_TYPE(setup->request_type)) {
|
@@ -3952,7 +3980,7 @@ static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itrans
|
|
3952
3980
|
transfer_priv->pollable_fd = wfd;
|
3953
3981
|
transfer_priv->interface_number = (uint8_t)current_interface;
|
3954
3982
|
} else {
|
3955
|
-
usbi_free_fd(wfd
|
3983
|
+
usbi_free_fd(&wfd);
|
3956
3984
|
}
|
3957
3985
|
|
3958
3986
|
return r;
|
@@ -3988,7 +4016,7 @@ static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer
|
|
3988
4016
|
hid_handle = handle_priv->interface_handle[current_interface].api_handle;
|
3989
4017
|
direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
|
3990
4018
|
|
3991
|
-
wfd = usbi_create_fd(hid_handle, direction_in?
|
4019
|
+
wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL);
|
3992
4020
|
// Always use the handle returned from usbi_create_fd (wfd.handle)
|
3993
4021
|
if (wfd.fd < 0) {
|
3994
4022
|
return LIBUSB_ERROR_NO_MEM;
|
@@ -4010,7 +4038,7 @@ static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer
|
|
4010
4038
|
|
4011
4039
|
if (direction_in) {
|
4012
4040
|
transfer_priv->hid_dest = transfer->buffer;
|
4013
|
-
usbi_dbg("reading %d bytes (report ID:
|
4041
|
+
usbi_dbg("reading %d bytes (report ID: 0x00)", length);
|
4014
4042
|
ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped);
|
4015
4043
|
} else {
|
4016
4044
|
if (!priv->hid->uses_report_ids[1]) {
|
@@ -4025,7 +4053,7 @@ static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer
|
|
4025
4053
|
if (!ret) {
|
4026
4054
|
if (GetLastError() != ERROR_IO_PENDING) {
|
4027
4055
|
usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0));
|
4028
|
-
usbi_free_fd(wfd
|
4056
|
+
usbi_free_fd(&wfd);
|
4029
4057
|
safe_free(transfer_priv->hid_buffer);
|
4030
4058
|
return LIBUSB_ERROR_IO;
|
4031
4059
|
}
|
@@ -4169,30 +4197,37 @@ static int composite_exit(int sub_api)
|
|
4169
4197
|
static int composite_open(int sub_api, struct libusb_device_handle *dev_handle)
|
4170
4198
|
{
|
4171
4199
|
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
|
4172
|
-
int r;
|
4200
|
+
int r = LIBUSB_ERROR_NOT_FOUND;
|
4173
4201
|
uint8_t i;
|
4174
|
-
|
4175
|
-
|
4176
|
-
for (i = 0; i<SUB_API_MAX; i++) {
|
4177
|
-
available[i] = false;
|
4178
|
-
}
|
4202
|
+
// SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID
|
4203
|
+
bool available[SUB_API_MAX+1] = {0};
|
4179
4204
|
|
4180
4205
|
for (i=0; i<USB_MAXINTERFACES; i++) {
|
4181
|
-
|
4182
|
-
|
4183
|
-
|
4206
|
+
switch (priv->usb_interface[i].apib->id) {
|
4207
|
+
case USB_API_WINUSBX:
|
4208
|
+
if (priv->usb_interface[i].sub_api != SUB_API_NOTSET)
|
4209
|
+
available[priv->usb_interface[i].sub_api] = true;
|
4210
|
+
break;
|
4211
|
+
case USB_API_HID:
|
4212
|
+
available[SUB_API_MAX] = true;
|
4213
|
+
break;
|
4214
|
+
default:
|
4215
|
+
break;
|
4184
4216
|
}
|
4185
4217
|
}
|
4186
4218
|
|
4187
|
-
for (i=0; i<SUB_API_MAX; i++) {
|
4219
|
+
for (i=0; i<SUB_API_MAX; i++) { // WinUSB-like drivers
|
4188
4220
|
if (available[i]) {
|
4189
|
-
r = usb_api_backend[USB_API_WINUSBX].open(
|
4221
|
+
r = usb_api_backend[USB_API_WINUSBX].open(i, dev_handle);
|
4190
4222
|
if (r != LIBUSB_SUCCESS) {
|
4191
4223
|
return r;
|
4192
4224
|
}
|
4193
4225
|
}
|
4194
4226
|
}
|
4195
|
-
|
4227
|
+
if (available[SUB_API_MAX]) { // HID driver
|
4228
|
+
r = hid_open(SUB_API_NOTSET, dev_handle);
|
4229
|
+
}
|
4230
|
+
return r;
|
4196
4231
|
}
|
4197
4232
|
|
4198
4233
|
static void composite_close(int sub_api, struct libusb_device_handle *dev_handle)
|