summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPete Batard <pbatard@gmail.com>2010-10-08 17:14:01 +0100
committerPete Batard <pbatard@gmail.com>2010-10-08 17:14:01 +0100
commit20e706f33a6caff186340732fa68ce3f261de1c0 (patch)
tree67ca86d51fe3a18a34d731582421b62d89f886ad
parent6cb025b4c853f2c034f72e12b1ab243d9d6e2a59 (diff)
downloadlibusb-20e706f33a6caff186340732fa68ce3f261de1c0.tar.gz
hotplug - Windows
-rw-r--r--examples/lsusb_sources1
-rw-r--r--examples/xusb.c4
-rw-r--r--examples/xusb_sources1
-rw-r--r--libusb/libusb-1.0.def40
-rw-r--r--libusb/os/libusb_sources7
-rw-r--r--libusb/os/windows_usb.c178
-rw-r--r--libusb/os/windows_usb.h15
-rw-r--r--msvc/config.h2
8 files changed, 224 insertions, 24 deletions
diff --git a/examples/lsusb_sources b/examples/lsusb_sources
index c61f810..dcc871b 100644
--- a/examples/lsusb_sources
+++ b/examples/lsusb_sources
@@ -21,6 +21,7 @@ INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
TARGETLIBS=$(SDK_LIB_PATH)\setupapi.lib \
+ $(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\ole32.lib \
$(SDK_LIB_PATH)\advapi32.lib
diff --git a/examples/xusb.c b/examples/xusb.c
index 742c931..70f3997 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -731,6 +731,10 @@ int test_device(uint16_t vid, uint16_t pid)
}
#endif
+ printf("\nPress Enter to exit this program\n");
+ while(getchar() != 0x0A);
+
+
printf("Closing device...\n");
libusb_close(handle);
diff --git a/examples/xusb_sources b/examples/xusb_sources
index 79cd038..52662ac 100644
--- a/examples/xusb_sources
+++ b/examples/xusb_sources
@@ -21,6 +21,7 @@ INCLUDES=..\..\msvc;..\..;$(DDK_INC_PATH)
UMLIBS=..\..\libusb\os\obj$(BUILD_ALT_DIR)\*\libusb-1.0.lib
TARGETLIBS=$(SDK_LIB_PATH)\setupapi.lib \
+ $(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\ole32.lib \
$(SDK_LIB_PATH)\advapi32.lib
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index fe609e0..cbd727d 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -4,6 +4,7 @@ EXPORTS
libusb_free_device_list
libusb_get_bus_number
libusb_get_device_address
+ libusb_get_session_id
libusb_get_max_packet_size
libusb_get_max_iso_packet_size
libusb_unref_device
@@ -22,6 +23,9 @@ EXPORTS
libusb_set_debug
libusb_init
libusb_exit
+ libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners
+ libusb_get_status
libusb_get_device_descriptor
libusb_get_active_config_descriptor
libusb_get_config_descriptor
@@ -61,6 +65,7 @@ EXPORTS
libusb_free_device_list@0 = libusb_free_device_list
libusb_get_bus_number@0 = libusb_get_bus_number
libusb_get_device_address@0 = libusb_get_device_address
+ libusb_get_session_id@0 = libusb_get_session_id
libusb_get_max_packet_size@0 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@0 = libusb_get_max_iso_packet_size
libusb_unref_device@0 = libusb_unref_device
@@ -79,6 +84,9 @@ EXPORTS
libusb_set_debug@0 = libusb_set_debug
libusb_init@0 = libusb_init
libusb_exit@0 = libusb_exit
+ libusb_register_hotplug_listeners@0 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@0 = libusb_unregister_hotplug_listeners
+ libusb_get_status@0 = libusb_get_status
libusb_get_device_descriptor@0 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@0 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@0 = libusb_get_config_descriptor
@@ -118,6 +126,7 @@ EXPORTS
libusb_free_device_list@4 = libusb_free_device_list
libusb_get_bus_number@4 = libusb_get_bus_number
libusb_get_device_address@4 = libusb_get_device_address
+ libusb_get_session_id@4 = libusb_get_session_id
libusb_get_max_packet_size@4 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@4 = libusb_get_max_iso_packet_size
libusb_unref_device@4 = libusb_unref_device
@@ -136,6 +145,9 @@ EXPORTS
libusb_set_debug@4 = libusb_set_debug
libusb_init@4 = libusb_init
libusb_exit@4 = libusb_exit
+ libusb_register_hotplug_listeners@4 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@4 = libusb_unregister_hotplug_listeners
+ libusb_get_status@4 = libusb_get_status
libusb_get_device_descriptor@4 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@4 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@4 = libusb_get_config_descriptor
@@ -175,6 +187,7 @@ EXPORTS
libusb_free_device_list@8 = libusb_free_device_list
libusb_get_bus_number@8 = libusb_get_bus_number
libusb_get_device_address@8 = libusb_get_device_address
+ libusb_get_session_id@8 = libusb_get_session_id
libusb_get_max_packet_size@8 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@8 = libusb_get_max_iso_packet_size
libusb_unref_device@8 = libusb_unref_device
@@ -193,6 +206,9 @@ EXPORTS
libusb_set_debug@8 = libusb_set_debug
libusb_init@8 = libusb_init
libusb_exit@8 = libusb_exit
+ libusb_register_hotplug_listeners@8 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@8 = libusb_unregister_hotplug_listeners
+ libusb_get_status@8 = libusb_get_status
libusb_get_device_descriptor@8 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@8 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@8 = libusb_get_config_descriptor
@@ -232,6 +248,7 @@ EXPORTS
libusb_free_device_list@12 = libusb_free_device_list
libusb_get_bus_number@12 = libusb_get_bus_number
libusb_get_device_address@12 = libusb_get_device_address
+ libusb_get_session_id@12 = libusb_get_session_id
libusb_get_max_packet_size@12 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@12 = libusb_get_max_iso_packet_size
libusb_unref_device@12 = libusb_unref_device
@@ -250,6 +267,9 @@ EXPORTS
libusb_set_debug@12 = libusb_set_debug
libusb_init@12 = libusb_init
libusb_exit@12 = libusb_exit
+ libusb_register_hotplug_listeners@12 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@12 = libusb_unregister_hotplug_listeners
+ libusb_get_status@12 = libusb_get_status
libusb_get_device_descriptor@12 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@12 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@12 = libusb_get_config_descriptor
@@ -289,6 +309,7 @@ EXPORTS
libusb_free_device_list@16 = libusb_free_device_list
libusb_get_bus_number@16 = libusb_get_bus_number
libusb_get_device_address@16 = libusb_get_device_address
+ libusb_get_session_id@16 = libusb_get_session_id
libusb_get_max_packet_size@16 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@16 = libusb_get_max_iso_packet_size
libusb_unref_device@16 = libusb_unref_device
@@ -307,6 +328,9 @@ EXPORTS
libusb_set_debug@16 = libusb_set_debug
libusb_init@16 = libusb_init
libusb_exit@16 = libusb_exit
+ libusb_register_hotplug_listeners@16 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@16 = libusb_unregister_hotplug_listeners
+ libusb_get_status@16 = libusb_get_status
libusb_get_device_descriptor@16 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@16 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@16 = libusb_get_config_descriptor
@@ -346,6 +370,7 @@ EXPORTS
libusb_free_device_list@20 = libusb_free_device_list
libusb_get_bus_number@20 = libusb_get_bus_number
libusb_get_device_address@20 = libusb_get_device_address
+ libusb_get_session_id@20 = libusb_get_session_id
libusb_get_max_packet_size@20 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@20 = libusb_get_max_iso_packet_size
libusb_unref_device@20 = libusb_unref_device
@@ -364,6 +389,9 @@ EXPORTS
libusb_set_debug@20 = libusb_set_debug
libusb_init@20 = libusb_init
libusb_exit@20 = libusb_exit
+ libusb_register_hotplug_listeners@20 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@20 = libusb_unregister_hotplug_listeners
+ libusb_get_status@20 = libusb_get_status
libusb_get_device_descriptor@20 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@20 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@20 = libusb_get_config_descriptor
@@ -403,6 +431,7 @@ EXPORTS
libusb_free_device_list@24 = libusb_free_device_list
libusb_get_bus_number@24 = libusb_get_bus_number
libusb_get_device_address@24 = libusb_get_device_address
+ libusb_get_session_id@24 = libusb_get_session_id
libusb_get_max_packet_size@24 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@24 = libusb_get_max_iso_packet_size
libusb_unref_device@24 = libusb_unref_device
@@ -421,6 +450,9 @@ EXPORTS
libusb_set_debug@24 = libusb_set_debug
libusb_init@24 = libusb_init
libusb_exit@24 = libusb_exit
+ libusb_register_hotplug_listeners@24 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@24 = libusb_unregister_hotplug_listeners
+ libusb_get_status@24 = libusb_get_status
libusb_get_device_descriptor@24 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@24 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@24 = libusb_get_config_descriptor
@@ -460,6 +492,7 @@ EXPORTS
libusb_free_device_list@28 = libusb_free_device_list
libusb_get_bus_number@28 = libusb_get_bus_number
libusb_get_device_address@28 = libusb_get_device_address
+ libusb_get_session_id@28 = libusb_get_session_id
libusb_get_max_packet_size@28 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@28 = libusb_get_max_iso_packet_size
libusb_unref_device@28 = libusb_unref_device
@@ -478,6 +511,9 @@ EXPORTS
libusb_set_debug@28 = libusb_set_debug
libusb_init@28 = libusb_init
libusb_exit@28 = libusb_exit
+ libusb_register_hotplug_listeners@28 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@28 = libusb_unregister_hotplug_listeners
+ libusb_get_status@28 = libusb_get_status
libusb_get_device_descriptor@28 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@28 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@28 = libusb_get_config_descriptor
@@ -517,6 +553,7 @@ EXPORTS
libusb_free_device_list@32 = libusb_free_device_list
libusb_get_bus_number@32 = libusb_get_bus_number
libusb_get_device_address@32 = libusb_get_device_address
+ libusb_get_session_id@32 = libusb_get_session_id
libusb_get_max_packet_size@32 = libusb_get_max_packet_size
libusb_get_max_iso_packet_size@32 = libusb_get_max_iso_packet_size
libusb_unref_device@32 = libusb_unref_device
@@ -535,6 +572,9 @@ EXPORTS
libusb_set_debug@32 = libusb_set_debug
libusb_init@32 = libusb_init
libusb_exit@32 = libusb_exit
+ libusb_register_hotplug_listeners@32 = libusb_register_hotplug_listeners
+ libusb_unregister_hotplug_listeners@32 = libusb_unregister_hotplug_listeners
+ libusb_get_status@32 = libusb_get_status
libusb_get_device_descriptor@32 = libusb_get_device_descriptor
libusb_get_active_config_descriptor@32 = libusb_get_active_config_descriptor
libusb_get_config_descriptor@32 = libusb_get_config_descriptor
diff --git a/libusb/os/libusb_sources b/libusb/os/libusb_sources
index 176f36e..3e5b661 100644
--- a/libusb/os/libusb_sources
+++ b/libusb/os/libusb_sources
@@ -12,9 +12,10 @@ INCLUDES=..;..\..\msvc;$(DDK_INC_PATH)
C_DEFINES = $(C_DEFINES) $(LIBUSB_DEFINES) /DDDKBUILD
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
- $(SDK_LIB_PATH)\advapi32.lib \
- $(SDK_LIB_PATH)\setupapi.lib \
- $(SDK_LIB_PATH)\ole32.lib
+ $(SDK_LIB_PATH)\user32.lib \
+ $(SDK_LIB_PATH)\advapi32.lib \
+ $(SDK_LIB_PATH)\setupapi.lib \
+ $(SDK_LIB_PATH)\ole32.lib
SOURCES=..\core.c \
..\descriptor.c \
diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c
index 9b279d6..b809801 100644
--- a/libusb/os/windows_usb.c
+++ b/libusb/os/windows_usb.c
@@ -42,6 +42,7 @@
#include <inttypes.h>
#include <objbase.h> // for string to GUID conv. requires libole32.a
#include <winioctl.h>
+#include <dbt.h>
#include <libusbi.h>
#include "poll_windows.h"
@@ -144,7 +145,7 @@ static int concurrent_usage = -1;
#if defined(AUTO_CLAIM)
usbi_mutex_t autoclaim_lock;
#endif
-// Timer thread
+// Timer & Hotplug threads
// NB: index 0 is for monotonic and 1 is for the thread exit event
HANDLE timer_thread = NULL;
HANDLE timer_mutex = NULL;
@@ -152,6 +153,7 @@ struct timespec timer_tp;
volatile LONG request_count[2] = {0, 1}; // last one must be > 0
HANDLE timer_request[2] = { NULL, NULL };
HANDLE timer_response = NULL;
+HANDLE hotplug_thread = NULL;
// API globals
bool api_winusb_available = false;
#define CHECK_WINUSB_AVAILABLE do { if (!api_winusb_available) return LIBUSB_ERROR_ACCESS; } while (0)
@@ -327,6 +329,9 @@ SP_DEVICE_INTERFACE_DETAIL_DATA *get_interface_details(struct libusb_context *ct
if (_index <= 0) {
*dev_info = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
}
+ if (*dev_info == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
if (dev_info_data != NULL) {
dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
@@ -386,19 +391,6 @@ err_exit:
}
/*
- * Hash a string (Nokia suggestion)
- * TODO: add collision detection (also flag 0x00000000 as reserved)
- */
-static inline unsigned long hash(const char* sz)
-{
- unsigned long r = 5381;
- int c;
- while ((c = *sz++))
- r = ((r << 5) + r) + c; /* r * 33 + c */
- return r;
-}
-
-/*
* Returns the Device ID path of a device's parent
*/
static unsigned long get_parent_session_id(DWORD devinst)
@@ -418,7 +410,7 @@ static unsigned long get_parent_session_id(DWORD devinst)
if (sanitized_path == NULL) {
return 0;
}
- session_id = hash(sanitized_path);
+ session_id = usbi_hash(sanitized_path);
safe_free(sanitized_path);
return session_id;
}
@@ -454,7 +446,7 @@ static unsigned long get_grandparent_session_id(DWORD devinst, bool* non_usb_gp)
if (sanitized_path == NULL) {
return 0;
}
- session_id = hash(sanitized_path);
+ session_id = usbi_hash(sanitized_path);
safe_free(sanitized_path);
return session_id;
}
@@ -606,6 +598,139 @@ static void auto_release(struct usbi_transfer *itransfer)
/*
+ * Hotplug messaging callback
+ */
+// TODO: Windows limitations mean we cannot detect driverless devices with this
+// => add another more generic callback for driverless, and check against this one?
+LRESULT CALLBACK messaging_callback(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static struct libusb_context* ctx;
+ LRESULT ret = TRUE;
+ DEV_BROADCAST_HDR* dev_bhd;
+ DEV_BROADCAST_DEVICEINTERFACE* dev_bdi;
+ libusb_device **devs;
+ struct libusb_device *dev;
+ struct windows_device_priv *priv;
+ char* hotplug_path;
+ bool online;
+ ssize_t i;
+
+ switch (message) {
+ case WM_CREATE:
+ ctx = (libusb_context*)((CREATESTRUCT*)lParam)->lpCreateParams;
+ break;
+ case WM_DEVICECHANGE:
+ if ((wParam == DBT_DEVICEARRIVAL) || (wParam == DBT_DEVICEREMOVECOMPLETE)) {
+ dev_bhd = (DEV_BROADCAST_HDR*)lParam;
+ if ( (dev_bhd->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) ) {
+ dev_bdi = (DEV_BROADCAST_DEVICEINTERFACE*)dev_bhd;
+ // We assert that a device interface path is just a device id plus a GUID
+ for (i = safe_strlen(dev_bdi->dbcc_name)-38; i >= 0; ) { // GUID is 38 chars
+ if ((dev_bdi->dbcc_name[i--] == '{') && (dev_bdi->dbcc_name[i--] == '#')) {
+ dev_bdi->dbcc_name[++i] = 0;
+ break;
+ }
+ }
+ if (i < 0) {
+ usbi_err(ctx, "program assertion failed: %s is not a device interface path", dev_bdi->dbcc_name);
+ break;
+ }
+ hotplug_path = sanitize_path(dev_bdi->dbcc_name);
+ if (hotplug_path == NULL) {
+ usbi_err(ctx, "could not sanitize", dev_bdi->dbcc_name);
+ break;
+ }
+ online = (wParam == DBT_DEVICEARRIVAL);
+ if (online) {
+ // If it's an insertion, update the list
+ libusb_get_device_list(ctx, &devs);
+ }
+ dev = usbi_get_device_by_session_id(ctx, usbi_hash(hotplug_path));
+ if (dev == NULL) {
+ usbi_warn(ctx, "%s: '%s' (not active)", (online)?"INSERTION":"REMOVAL",
+ hotplug_path);
+ } else {
+ priv = __device_priv(dev);
+ usbi_warn(ctx, "(bus: %d, addr: %d, depth: %d, port: %d)",
+ dev->bus_number, dev->device_address, priv->depth, priv->port);
+ usbi_warn(ctx, "%s: '%s'", (online)?"INSERTION":"REMOVAL",
+ hotplug_path);
+ usbi_mutex_lock(&dev->status_online_lock);
+ dev->status_online = online;
+ usbi_mutex_unlock(&dev->status_online_lock);
+ usbi_notify_device_state(dev, online);
+ // TODO: do we need unref as with Linux?
+ }
+ safe_free(hotplug_path);
+ }
+ }
+ break;
+ default:
+ ret = DefWindowProc(hWnd, message, wParam, lParam);
+ break;
+ }
+ return ret;
+}
+
+unsigned __stdcall windows_hotplug_threaded(void* param)
+{
+ MSG msg;
+ WNDCLASSEX wc;
+ DEV_BROADCAST_DEVICEINTERFACE dev_bdi;
+ struct libusb_context* ctx = (struct libusb_context *)param;
+ struct windows_context_priv* ctx_priv = __context_priv(ctx);
+ BOOL r;
+
+ memset(&wc, 0, sizeof(wc));
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_DBLCLKS | CS_SAVEBITS;
+ wc.lpfnWndProc = messaging_callback;
+ wc.lpszClassName = "libusb_messaging_class";
+
+ if (!RegisterClassExA(&wc)) {
+ usbi_err(ctx, "can't register class %s", windows_error_str(0));
+ return LIBUSB_ERROR_ACCESS;
+ }
+
+ ctx_priv->hMessage = CreateWindowExA(WS_EX_TOPMOST,
+ "libusb_messaging_class", "libusb_messaging",
+ 0, 100, 100, 287, 102,
+ // Note: Using HWND_MESSAGE removes broadcast events, like the ones from
+ // driverless devices. However the broadcast events you get on driverless
+ // provide no data whatsoever about the device, the event (insertion or
+ // removal), or even if the device is actually USB. Bummer!
+ HWND_MESSAGE, NULL, NULL, ctx);
+ if (ctx_priv->hMessage == NULL) {
+ usbi_err(ctx, "Unable to create progress dialog: %s", windows_error_str(0));
+ return LIBUSB_ERROR_ACCESS;
+ }
+
+ memset(&dev_bdi, 0, sizeof(dev_bdi));
+ dev_bdi.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
+ dev_bdi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+ dev_bdi.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; //GUID_DEVCLASS_WCEUSBS;
+
+ if (RegisterDeviceNotification(ctx_priv->hMessage,
+ &dev_bdi, DEVICE_NOTIFY_WINDOW_HANDLE) == NULL ) {
+ return LIBUSB_ERROR_ACCESS;
+ }
+
+ // We need to handle the message pump
+ while( (r = GetMessage(&msg, NULL, 0, 0)) != 0) {
+ if (r == -1) {
+ usbi_err(ctx, "GetMessage error");
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ usbi_dbg("terminating thread");
+
+ return LIBUSB_SUCCESS;
+}
+
+/*
* init: libusb backend init function
*
* This function enumerates the HCDs (Host Controller Drivers) and populates our private HCD list
@@ -696,6 +821,7 @@ static int windows_init(struct libusb_context *ctx)
usbi_err(ctx, "could not create timer mutex - aborting");
goto init_exit;
}
+ // TODO: pass ctx to timer thread
timer_thread = (HANDLE)_beginthreadex(NULL, 0, windows_clock_gettime_threaded, NULL, 0, NULL);
if (timer_thread == NULL) {
usbi_err(ctx, "Unable to create timer thread - aborting");
@@ -703,6 +829,12 @@ static int windows_init(struct libusb_context *ctx)
}
SetThreadAffinityMask(timer_thread, 0);
+ hotplug_thread = (HANDLE)_beginthreadex(NULL, 0, windows_hotplug_threaded, ctx, 0, NULL);
+ if (hotplug_thread == NULL) {
+ usbi_err(ctx, "Unable to create hotplug thread - aborting");
+ goto init_exit;
+ }
+
r = LIBUSB_SUCCESS;
}
@@ -1341,7 +1473,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
// Create new or match existing device, using the (hashed) device_id as session id
if (pass <= DEV_PASS) { // For subsequent passes, we'll lookup the parent
// These are the passes that create "new" devices
- session_id = hash(dev_id_path);
+ session_id = usbi_hash(dev_id_path);
dev = usbi_get_device_by_session_id(ctx, session_id);
if (dev != NULL) {
// No need to re-process hubs
@@ -1468,8 +1600,9 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
/*
* exit: libusb backend deinitialization function
*/
-static void windows_exit(void)
+static void windows_exit(struct libusb_context *ctx)
{
+ struct windows_context_priv *ctx_priv = __context_priv(ctx);
int i;
HANDLE semaphore;
TCHAR sem_name[11+1+8]; // strlen(libusb_init)+'\0'+(32-bit hex PID)
@@ -1517,6 +1650,14 @@ static void windows_exit(void)
CloseHandle(timer_mutex);
timer_mutex = NULL;
}
+
+ if (hotplug_thread) {
+ if (ctx_priv->hMessage != NULL) {
+ DestroyWindow(ctx_priv->hMessage);
+ } else {
+ TerminateThread(hotplug_thread, 1);
+ }
+ }
}
ReleaseSemaphore(semaphore, 1, NULL); // increase count back to 1
@@ -2106,6 +2247,7 @@ const struct usbi_os_backend windows_backend = {
#if defined(USBI_TIMERFD_AVAILABLE)
NULL,
#endif
+ sizeof(struct windows_context_priv),
sizeof(struct windows_device_priv),
sizeof(struct windows_device_handle_priv),
sizeof(struct windows_transfer_priv),
diff --git a/libusb/os/windows_usb.h b/libusb/os/windows_usb.h
index e8ab43d..a1319ca 100644
--- a/libusb/os/windows_usb.h
+++ b/libusb/os/windows_usb.h
@@ -49,7 +49,7 @@
#define SPDRP_INSTALL_STATE 34
#endif
-#if defined(__CYGWIN__ )
+#if defined(__CYGWIN__)
// cygwin produces a warning unless these prototypes are defined
extern int _snprintf(char *buffer, size_t count, const char *format, ...);
extern char *_strdup(const char *strSource);
@@ -107,6 +107,9 @@ const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0
#if !defined(GUID_DEVINTERFACE_USB_HUB)
const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
#endif
+#if !defined(GUID_DEVCLASS_WCEUSBS)
+const GUID GUID_DEVCLASS_WCEUSBS = { 0x36FC9E60, 0xC465, 0x11CF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
+#endif
const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
@@ -123,7 +126,7 @@ const GUID GUID_NULL = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x
#define CLASS_GUID_UNSUPPORTED GUID_NULL
const GUID CLASS_GUID_HID = { 0x745A17A0, 0x74D3, 0x11D0, {0xB6, 0xFE, 0x00, 0xA0, 0xC9, 0x0F, 0x57, 0xDA} };
const GUID CLASS_GUID_LIBUSB_WINUSB = { 0x78A1C341, 0x4539, 0x11D3, {0xB8, 0x8D, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71} };
-const GUID CLASS_GUID_COMPOSITE = { 0x36FC9E60, 0xC465, 0x11cF, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00} };
+#define CLASS_GUID_COMPOSITE GUID_DEVCLASS_WCEUSBS
struct windows_usb_api_backend {
const uint8_t id;
@@ -224,6 +227,14 @@ struct hid_device_priv {
uint8_t string_index[3]; // man, prod, ser
};
+struct windows_context_priv {
+ HWND hMessage;
+};
+
+static inline struct windows_context_priv *__context_priv(struct libusb_context *ctx) {
+ return (struct windows_context_priv *)ctx->os_priv;
+}
+
typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
struct windows_device_priv {
uint8_t depth; // distance to HCD
diff --git a/msvc/config.h b/msvc/config.h
index 29261fe..e68aa80 100644
--- a/msvc/config.h
+++ b/msvc/config.h
@@ -9,7 +9,7 @@
#define DEFAULT_VISIBILITY /**/
/* Debug message logging (forced) */
-//#define ENABLE_DEBUG_LOGGING 1
+#define ENABLE_DEBUG_LOGGING 1
/* Debug message logging (toggable) */
#define INCLUDE_DEBUG_LOGGING 1