diff --git a/device/win_usb/win_usb.cpp b/device/win_usb/win_usb.cpp index 80ee6f8..bcff699 100644 --- a/device/win_usb/win_usb.cpp +++ b/device/win_usb/win_usb.cpp @@ -146,7 +146,7 @@ ovl_cls* ovl_mgr::get_ovl(void) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // usb_device ... usb_device::usb_device(const char* name) : ref_(1), name_(name ? name : ""), is_ok_(false) - , dev_desc_(NULL), handle_(NULL), online_(true), timout_ms_(1000) + , dev_desc_(NULL), handle_(NULL), online_(true), timout_ms_(1000), reg_key_("") { bzero(&guid_, sizeof(guid_)); id_ = usb_device::vid_pid_from_name(name); @@ -262,7 +262,7 @@ std::string usb_device::driver_key_name(HANDLE file) return ret; } -std::string usb_device::parent_hub_path_name(int vid, int pid, int *addr) +std::string usb_device::parent_hub_path_name(int vid, int pid, int *addr, std::string* reg_key) { std::string ret(""); GUID guid = GUID_DEVINTERFACE_USB_HUB; @@ -291,7 +291,7 @@ std::string usb_device::parent_hub_path_name(int vid, int pid, int *addr) if (SetupDiGetDeviceInterfaceDetailW(dev, &id, buf, buf->cbSize + size, NULL, NULL)) { std::string n(u2utf8(buf->DevicePath)); - if (find_vid_pid_in_hub(n.c_str(), vid, pid, &port)) + if (find_vid_pid_in_hub(n.c_str(), vid, pid, &port, reg_key)) ret = n; } delete[] buf; @@ -307,7 +307,7 @@ std::string usb_device::parent_hub_path_name(int vid, int pid, int *addr) return ret; } -bool usb_device::find_vid_pid_in_hub(const char* utf8_hub_path_name, int vid, int pid, int* addr) +bool usb_device::find_vid_pid_in_hub(const char* utf8_hub_path_name, int vid, int pid, int* addr, std::string* reg_key) { bool ret = false; HANDLE h = CreateFileA(utf8_hub_path_name, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); @@ -324,6 +324,15 @@ bool usb_device::find_vid_pid_in_hub(const char* utf8_hub_path_name, int vid, in DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX, connectionInfoEx, bytes, connectionInfoEx, bytes, (LPDWORD)&bytes, NULL); ret = connectionInfoEx->DeviceDescriptor.idVendor == vid && connectionInfoEx->DeviceDescriptor.idProduct == pid; + if (ret && reg_key) + { + char buf[512] = { 0 }; + USB_NODE_CONNECTION_DRIVERKEY_NAME* name = (USB_NODE_CONNECTION_DRIVERKEY_NAME*)buf; + name->ConnectionIndex = *addr; + name->ActualLength = (sizeof(buf) - sizeof(*name)) / 2 - 1; + DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, name, sizeof(*name), name, name->ActualLength, (LPDWORD)&bytes, NULL); + *reg_key = u2utf8(name->DriverKeyName); + } } else { @@ -449,6 +458,28 @@ std::string usb_device::usb_scan_name(DEVID id, const char* guid) return name; } +std::string usb_device::usb_scan_name(const char* reg_key) +{ + std::wstring path(L"SYSTEM\\CurrentControlSet\\Control\\Class\\" + ansi2unicode(reg_key, CP_UTF8)); + HKEY key = NULL; + int err = RegOpenKeyW(HKEY_LOCAL_MACHINE, path.c_str(), &key); + std::string ret(""); + + if (key) + { + char val[256] = { 0 }; + DWORD len = _countof(val) - 1, + type = REG_SZ; + if (RegQueryValueExW(key, L"CreateFileName", NULL, &type, (LPBYTE)val, &len) == ERROR_SUCCESS) + { + val[len] = 0; + ret = u2utf8((wchar_t*)val); + } + RegCloseKey(key); + } + + return ret; +} long usb_device::add_ref(void) { @@ -532,7 +563,7 @@ bool usb_device::init(void) addr = usb_device::get_device_address(name_.c_str(), &guid); //if (addr != -1) { - std::string path(usb_device::parent_hub_path_name(id_.vid, id_.pid, &addr)); + std::string path(usb_device::parent_hub_path_name(id_.vid, id_.pid, &addr, ®_key_)); if (!path.empty()) { HANDLE h = CreateFileA(path.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); @@ -737,7 +768,12 @@ int usb_device::open(libusb_device_handle** dev_handle) USBSCAN_PIPE_CONFIGURATION upc = { 0 }; DWORD cbr = 0; - std::string fmt("\\%d"), root(usb_device::usb_scan_name(id_)); + std::string fmt("\\%d"), root(""); // (usb_device::usb_scan_name(reg_key_.empty() ? id_ : reg_key_.c_str())); + + if (reg_key_.length()) + root = usb_device::usb_scan_name(reg_key_.c_str()); + if (root.empty()) + root = usb_device::usb_scan_name(id_); if (root.empty()) { @@ -1015,8 +1051,12 @@ void usb_monitor::notify_usb_event(usb_device*& dev, bool arrive) int ev = arrive ? LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED : LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT; DEVID id = dev->id(); + if (id.vid != PRODUCT_VID && id.vid != PRODUCT_VENDOR_HG1) + return; + VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "WINUSB %04X:%04X(%d) %s\r\n", dev->id().vid, dev->id().pid, dev->id().addr, arrive ? "Connected" : "Left"); + if (arrive) { bool found = false; diff --git a/device/win_usb/win_usb.h b/device/win_usb/win_usb.h index f834a94..4c50f5b 100644 --- a/device/win_usb/win_usb.h +++ b/device/win_usb/win_usb.h @@ -84,6 +84,7 @@ class usb_device // consider as libusb_device volatile long ref_; GUID guid_; std::string name_; + std::string reg_key_; DEVID id_; bool is_ok_; bool online_; @@ -112,10 +113,11 @@ public: static DEVID vid_pid_from_name(const char* name); // device name like '\\?\usb#vid_3072&pid_0239#01234567aabbccddee#{a5dcbf10-6530-11d2-901f-00c04fb951ed}' static DWORD from_hex_string(const char* hex_str); static std::string driver_key_name(HANDLE file); - static std::string parent_hub_path_name(int vid, int pid, int *addr = NULL); - static bool find_vid_pid_in_hub(const char* utf8_hub_path_name, int vid, int pid, int *addr/*if *addr is not -1 or NULL, search the device with vid:pid and set the address in addr if it was not null, or-else chekc the device at *addr is vid:pid or not*/); + static std::string parent_hub_path_name(int vid, int pid, int *addr = NULL, std::string* reg_key = NULL); + static bool find_vid_pid_in_hub(const char* utf8_hub_path_name, int vid, int pid, int *addr/*if *addr is not -1 or NULL, search the device with vid:pid and set the address in addr if it was not null, or-else chekc the device at *addr is vid:pid or not*/, std::string* reg_key/*{6bdd1fc6-810f-11d0-bec7-08002be2092f}\\0007*/); static int get_device_address(const char* device_name, LPGUID lpguid); static std::string usb_scan_name(DEVID id, const char* guid = HG_SCANNER_GUID); // return \\.\Usbscan1 ... + static std::string usb_scan_name(const char* reg_key/*{6bdd1fc6-810f-11d0-bec7-08002be2092f}\\0007*/); // return \\.\Usbscan1 ... long add_ref(void); long release(void);