usb 2.17.0 → 2.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +14 -0
- package/binding.gyp +2 -9
- package/dist/usb/bindings.d.ts +27 -2
- package/dist/usb/bindings.js.map +1 -1
- package/dist/usb/index.d.ts +0 -29
- package/dist/usb/index.js +4 -18
- package/dist/usb/index.js.map +1 -1
- package/libusb/.clang-tidy +5 -3
- package/libusb/.private/ci-build.sh +5 -1
- package/libusb/AUTHORS +14 -0
- package/libusb/ChangeLog +15 -2
- package/libusb/README +8 -5
- package/libusb/Xcode/libusb.xcodeproj/project.pbxproj +4 -0
- package/libusb/configure.ac +12 -2
- package/libusb/examples/hotplugtest.c +19 -11
- package/libusb/examples/listdevs.c +41 -3
- package/libusb/examples/xusb.c +6 -1
- package/libusb/libusb/Makefile.am +4 -0
- package/libusb/libusb/core.c +175 -14
- package/libusb/libusb/descriptor.c +163 -14
- package/libusb/libusb/io.c +7 -3
- package/libusb/libusb/libusb-1.0.def +10 -0
- package/libusb/libusb/libusb.h +59 -9
- package/libusb/libusb/libusbi.h +89 -25
- package/libusb/libusb/os/darwin_usb.c +126 -46
- package/libusb/libusb/os/darwin_usb.h +10 -8
- package/libusb/libusb/os/emscripten_webusb.cpp +31 -10
- package/libusb/libusb/os/haiku_usb_raw.cpp +4 -0
- package/libusb/libusb/os/linux_usbfs.c +73 -25
- package/libusb/libusb/os/netbsd_usb.c +2 -0
- package/libusb/libusb/os/openbsd_usb.c +2 -0
- package/libusb/libusb/os/sunos_usb.c +2 -0
- package/libusb/libusb/os/threads_posix.c +3 -3
- package/libusb/libusb/os/threads_posix.h +8 -2
- package/libusb/libusb/os/threads_windows.h +2 -1
- package/libusb/libusb/os/windows_common.c +86 -1
- package/libusb/libusb/os/windows_common.h +20 -1
- package/libusb/libusb/os/windows_hotplug.c +321 -0
- package/libusb/libusb/os/windows_hotplug.h +28 -0
- package/libusb/libusb/os/windows_usbdk.c +16 -8
- package/libusb/libusb/os/windows_winusb.c +753 -41
- package/libusb/libusb/os/windows_winusb.h +11 -6
- package/libusb/libusb/version.h +1 -1
- package/libusb/libusb/version_nano.h +1 -1
- package/libusb/msvc/Base.props +1 -1
- package/libusb/msvc/Configuration.Base.props +2 -1
- package/libusb/msvc/Configuration.DynamicLibrary.props +12 -0
- package/libusb/msvc/ProjectConfigurations.Base.props +69 -16
- package/libusb/msvc/build_all.ps1 +2 -2
- package/libusb/msvc/config.h +4 -0
- package/libusb/msvc/getopt/bits/getopt_core.h +96 -0
- package/libusb/msvc/getopt/bits/getopt_ext.h +77 -0
- package/libusb/msvc/getopt/features.h +21 -0
- package/libusb/msvc/getopt/getopt.c +456 -705
- package/libusb/msvc/getopt/getopt.h +16 -158
- package/libusb/msvc/getopt/getopt1.c +40 -69
- package/libusb/msvc/getopt/getopt_int.h +118 -0
- package/libusb/msvc/getopt/gettext.h +7 -0
- package/libusb/msvc/getopt/unistd.h +5 -0
- package/libusb/msvc/getopt.vcxproj +11 -4
- package/libusb/msvc/libusb.sln +515 -268
- package/libusb/msvc/libusb_dll.vcxproj +2 -0
- package/libusb/msvc/libusb_static.vcxproj +2 -0
- package/libusb/msvc/xusb.vcxproj +1 -1
- package/libusb/tests/Makefile.am +10 -1
- package/libusb/tests/fuzz/corpus/bos/min.bos +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/min_valid_config.bin +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_a_endpoint_null.bin +0 -0
- package/libusb/tests/fuzz/corpus/descriptor_parsers/regression_bug_b_iad_oob.bin +0 -0
- package/libusb/tests/fuzz/fuzz_bos_descriptor.c +49 -0
- package/libusb/tests/fuzz/fuzz_descriptor_parsers.c +83 -0
- package/libusb/tests/stress_mt.c +2 -1
- package/libusb/tests/webusb-test-shim/index.js +6 -5
- package/libusb.gypi +5 -0
- package/package.json +1 -1
- package/prebuilds/android-arm/node.napi.armv7.node +0 -0
- package/prebuilds/android-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv6.node +0 -0
- package/prebuilds/linux-arm/node.napi.armv7.node +0 -0
- package/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
- package/prebuilds/linux-ia32/node.napi.node +0 -0
- package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
- package/prebuilds/linux-x64/node.napi.musl.node +0 -0
- package/prebuilds/win32-arm64/node.napi.node +0 -0
- package/prebuilds/win32-ia32/node.napi.node +0 -0
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/{hotplug/libusb.cc → hotplug.cc} +2 -3
- package/src/{hotplug/hotplug.h → hotplug.h} +2 -6
- package/src/node_usb.cc +3 -3
- package/test/usb.coffee +4 -4
- package/test/webusb.coffee +22 -12
- package/src/hotplug/windows.cc +0 -168
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* windows hotplug backend for libusb 1.0
|
|
3
|
+
* Copyright © 2024 Sylvain Fasel <sylvain@sonatique.net>
|
|
4
|
+
*
|
|
5
|
+
* This library is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
* License as published by the Free Software Foundation; either
|
|
8
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This library is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this library; if not, write to the Free Software
|
|
17
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include "libusbi.h"
|
|
21
|
+
#include "threads_windows.h"
|
|
22
|
+
|
|
23
|
+
#include "windows_common.h"
|
|
24
|
+
#include "windows_hotplug.h"
|
|
25
|
+
|
|
26
|
+
#include <stdio.h>
|
|
27
|
+
#include <dbt.h>
|
|
28
|
+
|
|
29
|
+
/* The Windows Hotplug system is a two steps process.
|
|
30
|
+
* 1. We create a hidden window and listen for DBT_DEVNODES_CHANGED, which Windows
|
|
31
|
+
* broadcasts to all top-level windows whenever the device tree changes (no
|
|
32
|
+
* registration required). Multiple rapid events (e.g. a hub with many children)
|
|
33
|
+
* are coalesced via a short debounce timer so we only scan once the burst settles.
|
|
34
|
+
* A maximum delay ceiling guarantees a scan fires within a bounded time even
|
|
35
|
+
* during sustained bursts, preventing unbounded latency.
|
|
36
|
+
* 2. Upon timer expiry, we snapshot the current device list, run a full re-enumeration
|
|
37
|
+
* via the Windows backend, then diff the result: newly found devices that have been
|
|
38
|
+
* successfully initialized generate DEVICE_ARRIVED events; devices that were not
|
|
39
|
+
* encountered by the re-enumeration (physically removed) generate DEVICE_LEFT events.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
#define HOTPLUG_DEBOUNCE_TIMER_ID 1
|
|
43
|
+
#define HOTPLUG_DEBOUNCE_MS 10
|
|
44
|
+
#define HOTPLUG_DEBOUNCE_MAX_DELAY_MS 100
|
|
45
|
+
|
|
46
|
+
static ULONGLONG first_debounce_tick;
|
|
47
|
+
static HWND windows_event_hwnd;
|
|
48
|
+
static HANDLE windows_event_thread_handle;
|
|
49
|
+
static DWORD WINAPI windows_event_thread_main(LPVOID lpParam);
|
|
50
|
+
static LRESULT CALLBACK windows_proc_callback(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
51
|
+
|
|
52
|
+
#define log_error(operation) do { \
|
|
53
|
+
usbi_err(NULL, "%s failed with error: %s", operation, windows_error_str(0)); \
|
|
54
|
+
} while (0)
|
|
55
|
+
|
|
56
|
+
int windows_start_event_monitor(void)
|
|
57
|
+
{
|
|
58
|
+
windows_event_thread_handle = CreateThread(
|
|
59
|
+
NULL, // Default security descriptor
|
|
60
|
+
0, // Default stack size
|
|
61
|
+
windows_event_thread_main,
|
|
62
|
+
NULL, // No parameters to pass to the thread
|
|
63
|
+
0, // Start immediately
|
|
64
|
+
NULL // No need to keep track of thread ID
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (windows_event_thread_handle == NULL)
|
|
68
|
+
{
|
|
69
|
+
log_error("CreateThread");
|
|
70
|
+
return LIBUSB_ERROR_OTHER;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return LIBUSB_SUCCESS;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
int windows_stop_event_monitor(void)
|
|
77
|
+
{
|
|
78
|
+
if (windows_event_hwnd == NULL)
|
|
79
|
+
{
|
|
80
|
+
return LIBUSB_SUCCESS;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!SUCCEEDED(SendMessage(windows_event_hwnd, WM_CLOSE, 0, 0)))
|
|
84
|
+
{
|
|
85
|
+
log_error("SendMessage");
|
|
86
|
+
return LIBUSB_ERROR_OTHER;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (WaitForSingleObject(windows_event_thread_handle, INFINITE) != WAIT_OBJECT_0)
|
|
90
|
+
{
|
|
91
|
+
log_error("WaitForSingleObject");
|
|
92
|
+
return LIBUSB_ERROR_OTHER;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!CloseHandle(windows_event_thread_handle))
|
|
96
|
+
{
|
|
97
|
+
log_error("CloseHandle");
|
|
98
|
+
return LIBUSB_ERROR_OTHER;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return LIBUSB_SUCCESS;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static int windows_get_device_list(struct libusb_context *ctx)
|
|
105
|
+
{
|
|
106
|
+
// note: context device list is protected by active_contexts_lock
|
|
107
|
+
return ((struct windows_context_priv *)usbi_get_context_priv(ctx))->backend->get_device_list(ctx, NULL);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void windows_initial_scan_devices(struct libusb_context *ctx)
|
|
111
|
+
{
|
|
112
|
+
usbi_mutex_static_lock(&active_contexts_lock);
|
|
113
|
+
|
|
114
|
+
const int ret = windows_get_device_list(ctx);
|
|
115
|
+
if (ret != LIBUSB_SUCCESS)
|
|
116
|
+
{
|
|
117
|
+
usbi_err(ctx, "hotplug failed to retrieve initial list with error: %s", libusb_error_name(ret));
|
|
118
|
+
}
|
|
119
|
+
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static void windows_refresh_device_list(struct libusb_context *ctx)
|
|
123
|
+
{
|
|
124
|
+
struct libusb_device *dev, *next_dev;
|
|
125
|
+
|
|
126
|
+
// Step 1: clear seen_during_scan so the scan can mark which devices are still
|
|
127
|
+
// physically present, and set seen_before_scan so we can distinguish newly
|
|
128
|
+
// created devices (which start with seen_before_scan=false via calloc).
|
|
129
|
+
for_each_device_safe(ctx, dev, next_dev)
|
|
130
|
+
{
|
|
131
|
+
struct winusb_device_priv *priv = (struct winusb_device_priv *)usbi_get_device_priv(dev);
|
|
132
|
+
priv->seen_during_scan = false;
|
|
133
|
+
priv->seen_before_scan = true;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Step 2: re-enumerate — winusb_get_device_list attaches newly-arrived devices
|
|
137
|
+
// and sets seen_during_scan=true for every device it physically encounters.
|
|
138
|
+
// seen_before_scan is untouched and will be left in default state (false) for newly created devices, allowing us to identify them in the next step.
|
|
139
|
+
const int ret = windows_get_device_list(ctx);
|
|
140
|
+
if (ret != LIBUSB_SUCCESS)
|
|
141
|
+
{
|
|
142
|
+
usbi_err(ctx, "hotplug failed to retrieve current list with error: %s", libusb_error_name(ret));
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Step 3: diff old vs new.
|
|
147
|
+
for_each_device_safe(ctx, dev, next_dev)
|
|
148
|
+
{
|
|
149
|
+
struct winusb_device_priv *priv = (struct winusb_device_priv *)usbi_get_device_priv(dev);
|
|
150
|
+
|
|
151
|
+
if (!priv->seen_during_scan)
|
|
152
|
+
{
|
|
153
|
+
// Not encountered by the scan: device was physically removed.
|
|
154
|
+
if (priv->initialized)
|
|
155
|
+
{
|
|
156
|
+
usbi_disconnect_device(dev); // fires DEVICE_LEFT
|
|
157
|
+
}
|
|
158
|
+
else
|
|
159
|
+
{
|
|
160
|
+
usbi_detach_device(dev);
|
|
161
|
+
// No DEVICE_LEFT message is posted for uninitialized
|
|
162
|
+
// devices, so no message handler will drop the initial
|
|
163
|
+
// ref. We must drop it here to avoid a leak.
|
|
164
|
+
libusb_unref_device(dev);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else if (!priv->seen_before_scan)
|
|
168
|
+
{
|
|
169
|
+
if (priv->initialized)
|
|
170
|
+
{
|
|
171
|
+
usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static void windows_refresh_device_list_for_all_ctx(void)
|
|
178
|
+
{
|
|
179
|
+
usbi_mutex_static_lock(&active_contexts_lock);
|
|
180
|
+
|
|
181
|
+
struct libusb_context *ctx;
|
|
182
|
+
for_each_context(ctx)
|
|
183
|
+
{
|
|
184
|
+
windows_refresh_device_list(ctx);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
usbi_mutex_static_unlock(&active_contexts_lock);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
#define WND_CLASS_NAME TEXT("libusb-1.0-windows-hotplug")
|
|
191
|
+
|
|
192
|
+
static bool init_wnd_class(void)
|
|
193
|
+
{
|
|
194
|
+
WNDCLASS wndClass = { 0 };
|
|
195
|
+
wndClass.lpfnWndProc = windows_proc_callback;
|
|
196
|
+
wndClass.hInstance = GetModuleHandle(NULL);
|
|
197
|
+
wndClass.lpszClassName = WND_CLASS_NAME;
|
|
198
|
+
|
|
199
|
+
if (!RegisterClass(&wndClass))
|
|
200
|
+
{
|
|
201
|
+
log_error("event thread: RegisterClass");
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
static DWORD WINAPI windows_event_thread_main(LPVOID lpParam)
|
|
209
|
+
{
|
|
210
|
+
UNUSED(lpParam);
|
|
211
|
+
|
|
212
|
+
usbi_dbg(NULL, "windows event thread entering");
|
|
213
|
+
|
|
214
|
+
if (!init_wnd_class())
|
|
215
|
+
{
|
|
216
|
+
return (DWORD)-1;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
windows_event_hwnd = CreateWindow(
|
|
220
|
+
WND_CLASS_NAME,
|
|
221
|
+
TEXT(""),
|
|
222
|
+
0,
|
|
223
|
+
0, 0, 0, 0,
|
|
224
|
+
NULL, NULL,
|
|
225
|
+
GetModuleHandle(NULL),
|
|
226
|
+
NULL);
|
|
227
|
+
|
|
228
|
+
if (windows_event_hwnd == NULL)
|
|
229
|
+
{
|
|
230
|
+
log_error("event thread: CreateWindow");
|
|
231
|
+
return (DWORD)-1;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
MSG msg;
|
|
235
|
+
BOOL ret_val;
|
|
236
|
+
|
|
237
|
+
while ((ret_val = GetMessage(&msg, windows_event_hwnd, 0, 0)) != 0)
|
|
238
|
+
{
|
|
239
|
+
if (ret_val == -1)
|
|
240
|
+
{
|
|
241
|
+
log_error("event thread: GetMessage");
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!SUCCEEDED(TranslateMessage(&msg)))
|
|
246
|
+
{
|
|
247
|
+
log_error("event thread: TranslateMessage");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!SUCCEEDED(DispatchMessage(&msg)))
|
|
251
|
+
{
|
|
252
|
+
log_error("event thread: DispatchMessage");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
usbi_dbg(NULL, "windows event thread exiting");
|
|
257
|
+
|
|
258
|
+
return 0;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
static LRESULT CALLBACK windows_proc_callback(
|
|
262
|
+
HWND hwnd,
|
|
263
|
+
UINT message,
|
|
264
|
+
WPARAM wParam,
|
|
265
|
+
LPARAM lParam)
|
|
266
|
+
{
|
|
267
|
+
switch (message)
|
|
268
|
+
{
|
|
269
|
+
case WM_DEVICECHANGE:
|
|
270
|
+
if (wParam == DBT_DEVNODES_CHANGED)
|
|
271
|
+
{
|
|
272
|
+
if (first_debounce_tick == 0)
|
|
273
|
+
{
|
|
274
|
+
// First event in a new burst — record the time and start the debounce timer.
|
|
275
|
+
first_debounce_tick = GetTickCount64();
|
|
276
|
+
SetTimer(hwnd, HOTPLUG_DEBOUNCE_TIMER_ID, HOTPLUG_DEBOUNCE_MS, NULL);
|
|
277
|
+
}
|
|
278
|
+
else if (GetTickCount64() - first_debounce_tick >= HOTPLUG_DEBOUNCE_MAX_DELAY_MS)
|
|
279
|
+
{
|
|
280
|
+
// Maximum delay reached — force an immediate scan so devices
|
|
281
|
+
// are not invisible for the entire duration of a sustained burst.
|
|
282
|
+
KillTimer(hwnd, HOTPLUG_DEBOUNCE_TIMER_ID);
|
|
283
|
+
first_debounce_tick = 0;
|
|
284
|
+
windows_refresh_device_list_for_all_ctx();
|
|
285
|
+
}
|
|
286
|
+
else
|
|
287
|
+
{
|
|
288
|
+
// Still within the max-delay window — reset the debounce timer.
|
|
289
|
+
SetTimer(hwnd, HOTPLUG_DEBOUNCE_TIMER_ID, HOTPLUG_DEBOUNCE_MS, NULL);
|
|
290
|
+
}
|
|
291
|
+
return TRUE;
|
|
292
|
+
}
|
|
293
|
+
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
294
|
+
|
|
295
|
+
case WM_TIMER:
|
|
296
|
+
if (wParam == HOTPLUG_DEBOUNCE_TIMER_ID)
|
|
297
|
+
{
|
|
298
|
+
KillTimer(hwnd, HOTPLUG_DEBOUNCE_TIMER_ID);
|
|
299
|
+
first_debounce_tick = 0;
|
|
300
|
+
windows_refresh_device_list_for_all_ctx();
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
304
|
+
|
|
305
|
+
case WM_CLOSE:
|
|
306
|
+
KillTimer(hwnd, HOTPLUG_DEBOUNCE_TIMER_ID);
|
|
307
|
+
first_debounce_tick = 0;
|
|
308
|
+
if (!DestroyWindow(hwnd))
|
|
309
|
+
{
|
|
310
|
+
log_error("DestroyWindow");
|
|
311
|
+
}
|
|
312
|
+
return 0;
|
|
313
|
+
|
|
314
|
+
case WM_DESTROY:
|
|
315
|
+
PostQuitMessage(0);
|
|
316
|
+
return 0;
|
|
317
|
+
|
|
318
|
+
default:
|
|
319
|
+
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* windows hotplug backend for libusb 1.0
|
|
3
|
+
* Copyright © 2024 Sylvain Fasel <sylvain@sonatique.net>
|
|
4
|
+
*
|
|
5
|
+
* This library is free software; you can redistribute it and/or
|
|
6
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
* License as published by the Free Software Foundation; either
|
|
8
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+
*
|
|
10
|
+
* This library is distributed in the hope that it will be useful,
|
|
11
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Lesser General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
16
|
+
* License along with this library; if not, write to the Free Software
|
|
17
|
+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#ifndef WINDOWS_HOTPLUG_H
|
|
21
|
+
#define WINDOWS_HOTPLUG_H
|
|
22
|
+
|
|
23
|
+
int windows_start_event_monitor(void);
|
|
24
|
+
int windows_stop_event_monitor(void);
|
|
25
|
+
|
|
26
|
+
void windows_initial_scan_devices(struct libusb_context *ctx);
|
|
27
|
+
|
|
28
|
+
#endif
|
|
@@ -341,17 +341,21 @@ static int usbdk_get_device_list(struct libusb_context *ctx, struct discovered_d
|
|
|
341
341
|
libusb_unref_device(dev);
|
|
342
342
|
continue;
|
|
343
343
|
}
|
|
344
|
-
}
|
|
345
344
|
|
|
346
|
-
|
|
347
|
-
libusb_unref_device(dev);
|
|
348
|
-
if (!discdevs) {
|
|
349
|
-
usbi_err(ctx, "cannot append new device to list");
|
|
350
|
-
r = LIBUSB_ERROR_NO_MEM;
|
|
351
|
-
goto func_exit;
|
|
345
|
+
usbi_connect_device(dev);
|
|
352
346
|
}
|
|
353
347
|
|
|
354
|
-
|
|
348
|
+
if (_discdevs) {
|
|
349
|
+
discdevs = discovered_devs_append(*_discdevs, dev);
|
|
350
|
+
libusb_unref_device(dev);
|
|
351
|
+
if (!discdevs) {
|
|
352
|
+
usbi_err(ctx, "cannot append new device to list");
|
|
353
|
+
r = LIBUSB_ERROR_NO_MEM;
|
|
354
|
+
goto func_exit;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
*_discdevs = discdevs;
|
|
358
|
+
}
|
|
355
359
|
}
|
|
356
360
|
|
|
357
361
|
func_exit:
|
|
@@ -704,6 +708,7 @@ const struct windows_backend usbdk_backend = {
|
|
|
704
708
|
usbdk_init,
|
|
705
709
|
usbdk_exit,
|
|
706
710
|
usbdk_get_device_list,
|
|
711
|
+
NULL, /* usbdk_get_device_string */
|
|
707
712
|
usbdk_open,
|
|
708
713
|
usbdk_close,
|
|
709
714
|
usbdk_get_active_config_descriptor,
|
|
@@ -721,4 +726,7 @@ const struct windows_backend usbdk_backend = {
|
|
|
721
726
|
NULL, /* cancel_transfer */
|
|
722
727
|
usbdk_clear_transfer_priv,
|
|
723
728
|
usbdk_copy_transfer_data,
|
|
729
|
+
NULL, /* endpoint_supports_raw_io */
|
|
730
|
+
NULL, /* endpoint_set_raw_io */
|
|
731
|
+
NULL, /* get_max_raw_io_transfer_size */
|
|
724
732
|
};
|