diff --git a/Makefile b/Makefile index e008748..5ee124a 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,10 @@ endif run_check = printf "$(1)" | $(CC) -x c -c -S -Wall -Werror $(CFLAGS) -o - - > /dev/null 2>&1; echo $$? -have_plat_devid=\#include \n int main(void) { return sizeof(libusb_get_platform_device_id); } +have_get_session_data=\#include \n int main(void) { return sizeof(libusb_get_session_data); } -ifeq (0, $(shell $(call run_check,$(have_plat_devid)))) -CFLAGS += -DHAVE_PLAT_DEVID +ifeq (0, $(shell $(call run_check,$(have_get_session_data)))) +CFLAGS += -DHAVE_GET_SESSION_DATA endif ifneq (, $(findstring linux, $(HOST))) @@ -44,7 +44,8 @@ LDCONFIG ?= ldconfig else ifneq (, $(findstring darwin, $(HOST))) C_SOURCES += src/darwin_lib.c SONAME = $(LIBRARY).dylib -LDFLAGS += -framework IOKit -framework CoreFoundation -dynamiclib +LDFLAGS += -framework IOKit -framework CoreFoundation -framework Security +LIB_LDFLAGS += -dynamiclib SET_SONAME = install_name_tool -id $(PREFIX)/lib/$(SONAME) $(BUILD_DIR)/$(SONAME) else ifneq (, $(findstring msys, $(HOST))) PREFIX := /usr @@ -101,7 +102,7 @@ $(PROGRAM): $(OBJECTS) $(CC) $^ $(LDFLAGS) -o $@ $(BUILD_DIR)/$(SONAME): $(OBJECTS) - $(CC) -shared $^ $(LDFLAGS) -o $@ + $(CC) -shared $^ $(LDFLAGS) $(LIB_LDFLAGS) -o $@ $(SET_SONAME) $(BUILD_DIR)/$(LIBRARY).a: $(OBJECTS) @@ -113,8 +114,8 @@ $(BUILD_DIR)/$(LIBRARY).pc: $(BUILD_DIR) Makefile $(call _file,$(PKG_CONFIG_FILE),>,$@) install: all - install -m 755 -d $(PREFIX)/include/$(LIBRARY)/ - install -m 644 src/$(LIBRARY).h $(PREFIX)/include/$(LIBRARY)/ + install -m 755 -d $(PREFIX)/include/$(LIBRARY) + install -m 644 src/$(LIBRARY).h $(PREFIX)/include/$(LIBRARY) install -m 644 $(BUILD_DIR)/$(SONAME) $(PREFIX)/lib install -m 644 $(BUILD_DIR)/$(LIBRARY).a $(PREFIX)/lib install -m 644 $(BUILD_DIR)/$(LIBRARY).pc $(PREFIX)/lib/pkgconfig diff --git a/src/darwin_lib.c b/src/darwin_lib.c index d276b9b..67e4c3a 100644 --- a/src/darwin_lib.c +++ b/src/darwin_lib.c @@ -74,31 +74,32 @@ static IOReturn IORegistryChildConformsTo(const io_service_t *service, io_servic return kIOReturnNoDevice; } -#ifdef HAVE_PLAT_DEVID +#ifdef HAVE_GET_SESSION_DATA +static io_service_t usb_find_matching_session(UInt64 sessionID) { + CFMutableDictionaryRef matchingDict = IOServiceMatching ("IOUSBDevice"); + CFMutableDictionaryRef propertyMatchDict = CFDictionaryCreateMutable (kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFTypeRef sessionCF = CFNumberCreate (NULL, kCFNumberSInt64Type, &sessionID); + + CFDictionarySetValue (matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict); + CFDictionarySetValue (propertyMatchDict, CFSTR("sessionID"), sessionCF); + + CFRelease (sessionCF); + CFRelease (propertyMatchDict); + + return IOServiceGetMatchingService (darwin_default_master_port, matchingDict); +} + static int darwin_get_location(struct libusb_device *dev, UInt32 *location) { - CFMutableDictionaryRef matchingDict; - unsigned long long int loc; io_service_t service = IO_OBJECT_NULL; CFTypeRef cf_location; UInt32 ret_loc; bool success; - char *path; - int ret; - - ret = libusb_get_platform_device_id(dev, &path); - if (ret != LIBUSB_SUCCESS) { - return ret; - } - - loc = strtoull(path, NULL, 10); - free(path); - - if (loc == 0 || loc >= UINT64_MAX) - return LIBUSB_ERROR_INVALID_PARAM; - - matchingDict = IORegistryEntryIDMatching(loc); + unsigned long sessionID; - service = IOServiceGetMatchingService (darwin_default_master_port, matchingDict); + sessionID = libusb_get_session_data(dev); + service = usb_find_matching_session(sessionID); cf_location = IORegistryEntryCreateCFProperty (service, CFSTR("locationID"), kCFAllocatorDefault, 0); if (!cf_location) { diff --git a/src/linux_lib.c b/src/linux_lib.c index 4676dda..addaaa0 100644 --- a/src/linux_lib.c +++ b/src/linux_lib.c @@ -110,13 +110,6 @@ static int get_subsytem(char **buf, return ret; } -#ifdef HAVE_PLAT_DEVID -static int get_sysfs_dir(struct libusb_device *dev, char **path) -{ - return libusb_get_platform_device_id(dev, path); -} -#else - #define USB_FMT(index, nindex, max) "%" #index "$.0u%" #max "$.*" #nindex "$s" static int get_sysfs_dir(struct libusb_device *dev, char **path) @@ -150,7 +143,6 @@ static int get_sysfs_dir(struct libusb_device *dev, char **path) return LIBUSB_SUCCESS; } -#endif int get_dev_path(struct libusb_device *dev, int iface_idx, enum usbi_dev_type dev_type, char **path) diff --git a/src/windows_lib.c b/src/windows_lib.c index cfcecdd..a1e826d 100644 --- a/src/windows_lib.c +++ b/src/windows_lib.c @@ -8,26 +8,28 @@ #include #include #include +#include #include #include "libusbgetdev.h" #include "libusbgetdevi.h" -static int match_dev_path(enum usbi_dev_type dev_type, const char *dev_reg_path, char **path); -static int get_parent(HDEVINFO device_info_set, PSP_DEVINFO_DATA device_info_data, char** parent); +static int match_dev_path(enum usbi_dev_type dev_type, DEVINST devinst, char **path); static int get_chardev(HDEVINFO device_info_set, PSP_DEVINFO_DATA device_info_data, char** com); static int get_blockdev(HDEVINFO device_info_set, PSP_DEVICE_INTERFACE_DATA device_interface_data, char **path); -#ifdef HAVE_PLAT_DEVID -static int get_devid(struct libusb_device *dev, char **DeviceID) +#ifdef HAVE_GET_SESSION_DATA +static int get_devid(struct libusb_device *dev, DEVINST *devinst) { - return libusb_get_platform_device_id(dev, DeviceID); + *devinst = libusb_get_session_data(dev); + + return LIBUSB_SUCCESS; } #else -static int get_devid(struct libusb_device *dev, char **DeviceID) +static int get_devid(struct libusb_device *dev, DEVINST *devinst) { (void)dev; - (void)DeviceID; + (void)devinst; return LIBUSB_ERROR_NOT_FOUND; } @@ -36,33 +38,31 @@ static int get_devid(struct libusb_device *dev, char **DeviceID) int get_dev_path(struct libusb_device *dev, int iface_idx, enum usbi_dev_type dev_type, char **path) { - char *DeviceID; + DEVINST devinst; (void)iface_idx; - if (get_devid(dev, &DeviceID) != LIBUSB_SUCCESS) + if (get_devid(dev, &devinst) != LIBUSB_SUCCESS) return LIBUSB_ERROR_NOT_FOUND; - return match_dev_path(dev_type, DeviceID, path); + return match_dev_path(dev_type, devinst, path); } -static int match_dev_path(enum usbi_dev_type dev_type, const char *DeviceID, char **path) { +static int match_dev_path(enum usbi_dev_type dev_type, DEVINST devinst, char **path) { HDEVINFO device_info_set; + DEVINST parent_devinst; SP_DEVINFO_DATA device_info_data; SP_DEVICE_INTERFACE_DATA device_interface_data; DWORD deviceIndex = 0; const GUID *ClassGuid; - char* parent; - int ret; + int ret = -1; *path = NULL; if (dev_type == USBI_DEV_BLOCK) ClassGuid = (const GUID *) &GUID_DEVINTERFACE_DISK; - else if (dev_type == USBI_DEV_CHAR) - ClassGuid = (const GUID *) &GUID_DEVCLASS_PORTS; else - return -1; + ClassGuid = (const GUID *) &GUID_DEVCLASS_PORTS; device_info_set = SetupDiGetClassDevs(ClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); @@ -74,16 +74,16 @@ static int match_dev_path(enum usbi_dev_type dev_type, const char *DeviceID, cha SetupDiEnumDeviceInterfaces(device_info_set, NULL, ClassGuid, deviceIndex, &device_interface_data); - get_parent(device_info_set, &device_info_data, &parent); + if (CM_Get_Parent(&parent_devinst, device_info_data.DevInst, 0) != CR_SUCCESS) { + ret = -2; + break; + } - if (strcmp(parent, DeviceID) != 0) { - free(parent); + if (parent_devinst != devinst) { deviceIndex++; continue; } - free(parent); - if (dev_type == USBI_DEV_BLOCK) ret = get_blockdev(device_info_set, &device_interface_data, path); else @@ -101,26 +101,6 @@ static int match_dev_path(enum usbi_dev_type dev_type, const char *DeviceID, cha } -static int get_parent(HDEVINFO device_info_set, PSP_DEVINFO_DATA device_info_data, char** parent) { - DEVPROPTYPE property_type; - DWORD required_size; - LPWSTR wpath; - size_t path_size; - - SetupDiGetDevicePropertyW(device_info_set, device_info_data, &DEVPKEY_Device_Parent, &property_type, NULL, 0, &required_size, 0); - - wpath = (LPWSTR)malloc(required_size); - SetupDiGetDevicePropertyW(device_info_set, device_info_data, &DEVPKEY_Device_Parent, &property_type, (PBYTE)wpath, required_size, NULL, 0); - - path_size = WideCharToMultiByte(CP_UTF8, 0, wpath, required_size / sizeof(wchar_t), NULL, 0, NULL, NULL); - - *parent = (char*)malloc(path_size + 1); - WideCharToMultiByte(CP_UTF8, 0, wpath, required_size / sizeof(wchar_t), *parent, path_size, NULL, NULL); - - free(wpath); - return 0; -} - static int get_chardev(HDEVINFO device_info_set, PSP_DEVINFO_DATA device_info_data, char** path) { HKEY hkey; LSTATUS return_code;