summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2020-12-19 15:33:56 -0800
committerChris Dickens <christopher.a.dickens@gmail.com>2020-12-19 15:33:56 -0800
commit073f229fd11f0d3e3098af44e59b5607aae113e2 (patch)
treeed45443b8cf852d0952566b026bbbd33bbee1b17
parent9cb2e5c111a7fc1eec13dcf73667187b06f68628 (diff)
downloadlibusb-073f229fd11f0d3e3098af44e59b5607aae113e2.tar.gz
Windows: Break dependency on OLE32
The OLE32 library provides the IIDFromString() function to parse a string to a GUID, but we can implement a simple GUID parsing function and remove this dependence. Doing so also avoids fetching the Unicode form of the "DeviceInterfaceGUIDs" property. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/os/windows_winusb.c86
-rw-r--r--libusb/os/windows_winusb.h6
-rw-r--r--libusb/version_nano.h2
3 files changed, 59 insertions, 35 deletions
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
index d38788e..e9fcc8e 100644
--- a/libusb/os/windows_winusb.c
+++ b/libusb/os/windows_winusb.c
@@ -104,12 +104,12 @@ static struct winusb_interface WinUSBX[SUB_API_MAX];
} while (0)
#if defined(ENABLE_LOGGING)
-static const char *guid_to_string(const GUID *guid)
+static const char *guid_to_string(const GUID *guid, char guid_string[MAX_GUID_STRING_LENGTH])
{
- static char guid_string[MAX_GUID_STRING_LENGTH];
-
- if (guid == NULL)
- return "";
+ if (guid == NULL) {
+ guid_string[0] = '\0';
+ return guid_string;
+ }
sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
(unsigned int)guid->Data1, guid->Data2, guid->Data3,
@@ -120,6 +120,37 @@ static const char *guid_to_string(const GUID *guid)
}
#endif
+static bool string_to_guid(const char guid_string[MAX_GUID_STRING_LENGTH], GUID *guid)
+{
+ unsigned short tmp[4];
+ int num_chars = -1;
+ char extra;
+ int r;
+
+ // Unfortunately MinGW complains that '%hhx' is not a valid format specifier,
+ // even though Visual Studio 2013 and later support it. Rather than complicating
+ // the logic in this function with '#ifdef's, use a temporary array on the stack
+ // to store the conversions.
+ r = sscanf(guid_string, "{%8x-%4hx-%4hx-%4hx-%4hx%4hx%4hx}%n%c",
+ (unsigned int *)&guid->Data1, &guid->Data2, &guid->Data3,
+ &tmp[0], &tmp[1], &tmp[2], &tmp[3], &num_chars, &extra);
+
+ if ((r != 7) || (num_chars != 38))
+ return false;
+
+ // Extract the bytes from the 2-byte shorts
+ guid->Data4[0] = (unsigned char)((tmp[0] >> 8) & 0xFF);
+ guid->Data4[1] = (unsigned char)(tmp[0] & 0xFF);
+ guid->Data4[2] = (unsigned char)((tmp[1] >> 8) & 0xFF);
+ guid->Data4[3] = (unsigned char)(tmp[1] & 0xFF);
+ guid->Data4[4] = (unsigned char)((tmp[2] >> 8) & 0xFF);
+ guid->Data4[5] = (unsigned char)(tmp[2] & 0xFF);
+ guid->Data4[6] = (unsigned char)((tmp[3] >> 8) & 0xFF);
+ guid->Data4[7] = (unsigned char)(tmp[3] & 0xFF);
+
+ return true;
+}
+
/*
* Normalize Microsoft's paths: return a duplicate of the given path
* with all characters converted to uppercase
@@ -149,12 +180,9 @@ static bool init_dlls(struct libusb_context *ctx)
// Prefixed to avoid conflict with header files
DLL_GET_HANDLE(ctx, AdvAPI32);
- DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExW, true);
+ DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegQueryValueExA, true);
DLL_LOAD_FUNC_PREFIXED(AdvAPI32, p, RegCloseKey, true);
- DLL_GET_HANDLE(ctx, OLE32);
- DLL_LOAD_FUNC_PREFIXED(OLE32, p, IIDFromString, true);
-
DLL_GET_HANDLE(ctx, SetupAPI);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetClassDevsA, true);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, true);
@@ -172,7 +200,6 @@ static bool init_dlls(struct libusb_context *ctx)
static void exit_dlls(void)
{
DLL_FREE_HANDLE(SetupAPI);
- DLL_FREE_HANDLE(OLE32);
DLL_FREE_HANDLE(AdvAPI32);
DLL_FREE_HANDLE(Cfgmgr32);
}
@@ -233,6 +260,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
{
SP_DEVICE_INTERFACE_DATA dev_interface_data;
PSP_DEVICE_INTERFACE_DETAIL_DATA_A dev_interface_details;
+ char guid_string[MAX_GUID_STRING_LENGTH];
DWORD size;
dev_info_data->cbSize = sizeof(SP_DEVINFO_DATA);
@@ -241,7 +269,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) {
if (GetLastError() != ERROR_NO_MORE_ITEMS) {
usbi_err(ctx, "Could not obtain device info data for %s index %lu: %s",
- guid_to_string(guid), ULONG_CAST(*_index), windows_error_str(0));
+ guid_to_string(guid, guid_string), ULONG_CAST(*_index), windows_error_str(0));
return LIBUSB_ERROR_OTHER;
}
@@ -257,7 +285,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
if (GetLastError() != ERROR_NO_MORE_ITEMS) {
usbi_err(ctx, "Could not obtain interface data for %s devInst %lX: %s",
- guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
+ guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
return LIBUSB_ERROR_OTHER;
}
@@ -269,7 +297,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
// The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
usbi_err(ctx, "could not access interface data (dummy) for %s devInst %lX: %s",
- guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
+ guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
return LIBUSB_ERROR_OTHER;
}
} else {
@@ -280,7 +308,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
dev_interface_details = malloc(size);
if (dev_interface_details == NULL) {
usbi_err(ctx, "could not allocate interface data for %s devInst %lX",
- guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst));
+ guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
return LIBUSB_ERROR_NO_MEM;
}
@@ -288,7 +316,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data,
dev_interface_details, size, NULL, NULL)) {
usbi_err(ctx, "could not access interface data (actual) for %s devInst %lX: %s",
- guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
+ guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
free(dev_interface_details);
return LIBUSB_ERROR_OTHER;
}
@@ -298,7 +326,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
if (*dev_interface_path == NULL) {
usbi_err(ctx, "could not allocate interface path for %s devInst %lX",
- guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst));
+ guid_to_string(guid, guid_string), ULONG_CAST(dev_info_data->DevInst));
return LIBUSB_ERROR_NO_MEM;
}
@@ -381,7 +409,7 @@ static int get_interface_details_filter(struct libusb_context *ctx, HDEVINFO *de
DWORD value_length = sizeof(DWORD);
LONG status;
- status = pRegQueryValueExW(hkey_dev_interface, L"LUsb0", NULL, NULL,
+ status = pRegQueryValueExA(hkey_dev_interface, "LUsb0", NULL, NULL,
(LPBYTE)&libusb0_symboliclink_index, &value_length);
if (status == ERROR_SUCCESS) {
if (libusb0_symboliclink_index < 256) {
@@ -1379,7 +1407,7 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
unsigned long session_id;
DWORD size, port_nr, reg_type, install_state;
HKEY key;
- WCHAR guid_string_w[MAX_GUID_STRING_LENGTH];
+ char guid_string[MAX_GUID_STRING_LENGTH];
GUID *if_guid;
LONG s;
#define HUB_PASS 0
@@ -1449,7 +1477,7 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
//#define ENUM_DEBUG
#if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG)
const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"};
- usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass]));
+ usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass], guid_string));
#endif
if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL))
continue;
@@ -1550,16 +1578,16 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
if (key == INVALID_HANDLE_VALUE)
break;
// Look for both DeviceInterfaceGUIDs *and* DeviceInterfaceGUID, in that order
- size = sizeof(guid_string_w);
- s = pRegQueryValueExW(key, L"DeviceInterfaceGUIDs", NULL, &reg_type,
- (LPBYTE)guid_string_w, &size);
+ size = sizeof(guid_string);
+ s = pRegQueryValueExA(key, "DeviceInterfaceGUIDs", NULL, &reg_type,
+ (LPBYTE)guid_string, &size);
if (s == ERROR_FILE_NOT_FOUND)
- s = pRegQueryValueExW(key, L"DeviceInterfaceGUID", NULL, &reg_type,
- (LPBYTE)guid_string_w, &size);
+ s = pRegQueryValueExA(key, "DeviceInterfaceGUID", NULL, &reg_type,
+ (LPBYTE)guid_string, &size);
pRegCloseKey(key);
if ((s == ERROR_SUCCESS) &&
- (((reg_type == REG_SZ) && (size == (sizeof(guid_string_w) - sizeof(WCHAR)))) ||
- ((reg_type == REG_MULTI_SZ) && (size == sizeof(guid_string_w))))) {
+ (((reg_type == REG_SZ) && (size == (sizeof(guid_string) - sizeof(char)))) ||
+ ((reg_type == REG_MULTI_SZ) && (size == sizeof(guid_string))))) {
if (nb_guids == guid_size) {
new_guid_list = realloc((void *)guid_list, (guid_size + GUID_SIZE_STEP) * sizeof(void *));
if (new_guid_list == NULL) {
@@ -1574,8 +1602,8 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
usbi_err(ctx, "failed to alloc if_guid");
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
}
- if (pIIDFromString(guid_string_w, if_guid) != 0) {
- usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string, skipping", dev_id);
+ if (!string_to_guid(guid_string, if_guid)) {
+ usbi_warn(ctx, "device '%s' has malformed DeviceInterfaceGUID string '%s', skipping", dev_id, guid_string);
free(if_guid);
} else {
// Check if we've already seen this GUID
@@ -1584,7 +1612,7 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
break;
}
if (j == nb_guids) {
- usbi_dbg("extra GUID: %s", guid_to_string(if_guid));
+ usbi_dbg("extra GUID: %s", guid_string);
guid_list[nb_guids++] = if_guid;
} else {
// Duplicate, ignore
diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h
index 439042f..6646dc7 100644
--- a/libusb/os/windows_winusb.h
+++ b/libusb/os/windows_winusb.h
@@ -236,13 +236,9 @@ DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
/* AdvAPI32 dependencies */
DLL_DECLARE_HANDLE(AdvAPI32);
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExA, (HKEY, LPCSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
-/* OLE32 dependency */
-DLL_DECLARE_HANDLE(OLE32);
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID));
-
/* SetupAPI dependencies */
DLL_DECLARE_HANDLE(SetupAPI);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD));
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index e0cb374..c30b57d 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11590
+#define LIBUSB_NANO 11591