From 72db1a49ff0dca8883ae8f170ee18becb6fc38fe Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Thu, 11 Aug 2022 18:05:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dwin7=20BULK=5FOUT=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E9=80=9A=E4=BF=A1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device/win_usb/win_usb.cpp | 136 ++++++++++++++++++++++++++++++------- device/win_usb/win_usb.h | 22 ++++-- 2 files changed, 128 insertions(+), 30 deletions(-) diff --git a/device/win_usb/win_usb.cpp b/device/win_usb/win_usb.cpp index 8c1dda2..9a7ca99 100644 --- a/device/win_usb/win_usb.cpp +++ b/device/win_usb/win_usb.cpp @@ -15,10 +15,18 @@ #pragma comment(lib, "hid.lib") #pragma comment(lib, "winusb.lib") #pragma comment(lib, "rpcrt4.lib") +#pragma comment(lib, "advapi32.lib") // for Reg... +#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG) #include "../wrapper/hg_log.h" -#include "scanner_manager.h" // for hg_scanner_mgr::ui_default_callback +#else +#define VLOG_MINI_1(l, f, d) printf(f, d) +#define VLOG_MINI_2(l, f, d1, d2) printf(f, d1, d2) +#define VLOG_MINI_3(l, f, d1, d2, d3) printf(f, d1, d2, d3) +#define VLOG_MINI_4(l, f, d1, d2, d3, d4) printf(f, d1, d2, d3, d4) +#endif #include "usbview/enum.h" +#pragma warning(disable: 4996) #define MSG_DEVICE_PNP WM_USER + 1 // wParam: (bool)arrive; lParam: usb_device* #define bzero(a, l) memset(a, 0, l) @@ -38,9 +46,9 @@ void usb_callback::notify(libusb_context* ctx, usb_device* dev, int ev) } std::string u2utf8(const wchar_t* u) { - //* +#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG) return hg_log::u2utf8(u); - /*/ +#else int len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); char *ansi = new char[len + 4]; @@ -51,12 +59,25 @@ std::string u2utf8(const wchar_t* u) delete[] ansi; return utf8; - /////*/////////////////////// +#endif } +std::wstring ansi2unicode(const char* ansi, UINT cp = CP_ACP) +{ + int len = MultiByteToWideChar(cp, 0, ansi, lstrlenA(ansi), NULL, 0); + wchar_t* buf = new wchar_t[len + 4]; + memset(buf, 0, (len + 4) * 2); + len = MultiByteToWideChar(cp, 0, ansi, lstrlenA(ansi), buf, len); + buf[len--] = 0; + + std::wstring unic(buf); + delete[] buf; + + return unic; +} ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // OVERLAPPED ... -ovl_cls::ovl_cls() : io_bytes_(0) +ovl_cls::ovl_cls() : ref_(1), io_bytes_(0) { memset(&ovl_, 0, sizeof(ovl_)); ovl_.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); @@ -127,17 +148,6 @@ ovl_cls* ovl_mgr::get_ovl(void) 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) { - size_t pos = name_.find("#{"); - if (pos != std::string::npos) - { - HANDLE h = open_usb((name_.substr(0, pos) + "#{" + HG_SCANNER_GUID + "}").c_str()); - if (h != INVALID_HANDLE_NAME) - { - CloseHandle(h); - name_ = name_.substr(0, pos) + "#{" + HG_SCANNER_GUID + "}"; - } - } - bzero(&guid_, sizeof(guid_)); id_ = usb_device::vid_pid_from_name(name); } @@ -160,9 +170,15 @@ HANDLE usb_device::find_pipe(UCHAR addr, int type, int* index) return NULL; } -HANDLE usb_device::open_usb(const char* usb_name) +HANDLE usb_device::open_usb(const char* usb_name, DWORD access, DWORD share) { - return CreateFileA(usb_name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + std::wstring unic(ansi2unicode(usb_name)); + SECURITY_ATTRIBUTES sa = { 0 }; + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + return CreateFileW(unic.c_str(), access, share, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); } int usb_device::set_timeout(HANDLE h) { @@ -172,6 +188,13 @@ int usb_device::set_timeout(HANDLE h) uto.TimeoutEvent = uto.TimeoutRead = uto.TimeoutWrite = (timout_ms_ + 500) / 1000; return DeviceIoControl(h, IOCTL_SET_TIMEOUT, &uto, sizeof(uto), NULL, 0, &cbr, NULL) ? LIBUSB_SUCCESS : LIBUSB_ERROR_IO; + + //COMMTIMEOUTS to = { 0 }; + //to.ReadIntervalTimeout = timout_ms_; + //to.ReadTotalTimeoutConstant = timout_ms_; + //to.ReadTotalTimeoutMultiplier = 1; + // + //SetCommTimeouts(h, &to); } DEVID usb_device::vid_pid_from_name(const char* name) @@ -374,6 +397,45 @@ int usb_device::get_device_address(const char* device_name, LPGUID lpguid) return addr; } +std::string usb_device::usb_scan_name(DEVID id, const char* guid) +{ + // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{6BDD1FC6-810F-11D0-BEC7-08002BE2092F} + HKEY key = NULL; + std::string path("SYSTEM\\CurrentControlSet\\Control\\Class\\{"), name(""); + char strind[20] = { "0000" }, val[256] = { 0 }; + int ind = 0, err = 0; + + path += guid; + path += "}\\"; + err = RegOpenKeyA(HKEY_LOCAL_MACHINE, (path + strind).c_str(), &key); + while (key) + { + DWORD len = _countof(val) - 1, + type = REG_SZ; + if (RegQueryValueExA(key, "MatchingDeviceId", NULL, &type, (LPBYTE)val, &len) == ERROR_SUCCESS) + { + val[len] = 0; + DEVID cid = usb_device::vid_pid_from_name(val); + if (cid == id) + { + len = _countof(val) - 1; + type = REG_SZ; + if (RegQueryValueExA(key, "CreateFileName", NULL, &type, (LPBYTE)val, &len) == ERROR_SUCCESS) + { + val[len] = 0; + name = val; + } + } + } + RegCloseKey(key); + if (!name.empty()) + break; + sprintf_s(strind, _countof(strind) - 1, "%04d", ++ind); + RegOpenKeyA(HKEY_LOCAL_MACHINE, (path + strind).c_str(), &key); + } + + return name; +} long usb_device::add_ref(void) { @@ -497,9 +559,9 @@ bool usb_device::init(void) { libusb_config_descriptor* desc = NULL; PUSB_COMMON_DESCRIPTOR cmn = (PUSB_COMMON_DESCRIPTOR)(info->ConfigDesc + 1); - int if_ind = 0, ep_ind = 0; + int if_ind = 0, ep_ind = 0, used = 0; - while (cmn->bLength) + while (used < info->ConfigDesc->SetupPacket.wLength && cmn->bLength) { if (USB_CONFIGURATION_DESCRIPTOR_TYPE == cmn->bDescriptorType) { @@ -556,6 +618,7 @@ bool usb_device::init(void) COPY_MEMBER(uep, endp, bInterval); ep_ind++; } + used += cmn->bLength; cmn = (PUSB_COMMON_DESCRIPTOR)((PCHAR)cmn + cmn->bLength); } @@ -660,16 +723,30 @@ 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_)); + + if (root.empty()) + { + VLOG_MINI_1(LOG_LEVEL_WARNING, "Cannot find '\\\\.\\Usbscan' name for '%s', try run in Administrator!\r\n", name_.c_str()); + root = name_; + fmt = "\\%04d"; + } + else + { + VLOG_MINI_2(LOG_LEVEL_WARNING, "Nice: '%s' for '%s'.\r\n", root.c_str(), name_.c_str()); + } if (DeviceIoControl(h, IOCTL_GET_PIPE_CONFIGURATION, NULL, 0, &upc, sizeof(upc), &cbr, NULL)) { + int type = PIPE_TYPE::WRITE_DATA_PIPE; + DeviceIoControl(h, IOCTL_RESET_PIPE, &type, sizeof(type), NULL, NULL, &cbr, NULL); for (int i = 0; i < upc.NumberOfPipes; ++i) { USBPIPE up = { 0 }; - char ind[20] = { 0 }; + char ind[80] = { 0 }; up.address = upc.PipeInfo[i].EndpointAddress; up.type = upc.PipeInfo[i].PipeType; - sprintf_s(ind, _countof(ind) - 1, "\\%04d", i); - up.pipe = open_usb((name_ + ind).c_str()); + sprintf_s(ind, _countof(ind) - 1, fmt.c_str(), i); + up.pipe = open_usb((root + ind).c_str()); if (up.pipe != INVALID_HANDLE_VALUE) { set_timeout(up.pipe); @@ -730,10 +807,17 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt if (h) { - ovl_cls *oc = ovl_mgr_.get_ovl(); + ovl_cls* oc = ovl_mgr_.get_ovl(); DWORD io = 0; - BOOL result = (endpoint & BULKIN_FLAG) ? ReadFile(h, data, *length, oc->io_bytes(), oc->over_lapped()) - : WriteFile(h, data, *length, oc->io_bytes(), oc->over_lapped()); + BOOL result = FALSE; + + if (endpoint & BULKIN_FLAG) + result = ReadFile(h, data, *length, oc->io_bytes(), oc->over_lapped()); + else + { + // oc->over_lapped()->Offset = oc->over_lapped()->OffsetHigh = -1; + result = WriteFile(h, data, *length, oc->io_bytes(), oc->over_lapped()); + } if (result) { diff --git a/device/win_usb/win_usb.h b/device/win_usb/win_usb.h index e1d1b31..abb35c3 100644 --- a/device/win_usb/win_usb.h +++ b/device/win_usb/win_usb.h @@ -13,7 +13,6 @@ #include #include "libusb-1.0/libusb.h" -#include "../../../code_device/hgdriver/hgdev/hg_ipc.h" // HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f} #define HG_SCANNER_GUID "6BDD1FC6-810F-11D0-BEC7-08002BE2092F" @@ -31,8 +30,9 @@ typedef struct _dev_id } }DEVID; -class ovl_cls : public refer +class ovl_cls// : public refer { + volatile long ref_; OVERLAPPED ovl_; DWORD io_bytes_; @@ -43,6 +43,19 @@ protected: ~ovl_cls(); public: + long add_ref(void) + { + return InterlockedIncrement(&ref_); + } + long release(void) + { + long r = InterlockedDecrement(&ref_); + + if (r == 0) + delete this; + + return r; + } LPOVERLAPPED over_lapped(void); LPDWORD io_bytes(void); void reset(void); @@ -85,8 +98,7 @@ class usb_device // consider as libusb_device }USBPIPE; std::vector pipes_; DWORD timout_ms_; - HANDLE find_pipe(UCHAR addr, int type, int *index = NULL); - HANDLE open_usb(const char* usb_name); + HANDLE open_usb(const char* usb_name, DWORD access = GENERIC_READ | GENERIC_WRITE, DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE); int set_timeout(HANDLE h); public: @@ -98,6 +110,7 @@ public: 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 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 ... long add_ref(void); long release(void); @@ -129,6 +142,7 @@ public: int open(libusb_device_handle** dev_handle); int close(void); int set_timeout(unsigned milliseconds); + HANDLE find_pipe(UCHAR addr, int type, int* index = NULL); int transfer_bulk(unsigned endpoint, unsigned char* data, int* length, unsigned int timeout); int transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout);