修复win7 BULK_OUT端口通信问题

This commit is contained in:
gb 2022-08-11 18:05:01 +08:00
parent 2fb912efde
commit 72db1a49ff
2 changed files with 128 additions and 30 deletions

View File

@ -15,10 +15,18 @@
#pragma comment(lib, "hid.lib") #pragma comment(lib, "hid.lib")
#pragma comment(lib, "winusb.lib") #pragma comment(lib, "winusb.lib")
#pragma comment(lib, "rpcrt4.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 "../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" #include "usbview/enum.h"
#pragma warning(disable: 4996)
#define MSG_DEVICE_PNP WM_USER + 1 // wParam: (bool)arrive; lParam: usb_device* #define MSG_DEVICE_PNP WM_USER + 1 // wParam: (bool)arrive; lParam: usb_device*
#define bzero(a, l) memset(a, 0, l) #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) std::string u2utf8(const wchar_t* u)
{ {
//* #if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG)
return hg_log::u2utf8(u); return hg_log::u2utf8(u);
/*/ #else
int len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); int len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
char *ansi = new char[len + 4]; char *ansi = new char[len + 4];
@ -51,12 +59,25 @@ std::string u2utf8(const wchar_t* u)
delete[] ansi; delete[] ansi;
return utf8; 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 ... // OVERLAPPED ...
ovl_cls::ovl_cls() : io_bytes_(0) ovl_cls::ovl_cls() : ref_(1), io_bytes_(0)
{ {
memset(&ovl_, 0, sizeof(ovl_)); memset(&ovl_, 0, sizeof(ovl_));
ovl_.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 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) 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)
{ {
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_)); bzero(&guid_, sizeof(guid_));
id_ = usb_device::vid_pid_from_name(name); 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; 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) 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; 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; 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) 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; 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) long usb_device::add_ref(void)
{ {
@ -497,9 +559,9 @@ bool usb_device::init(void)
{ {
libusb_config_descriptor* desc = NULL; libusb_config_descriptor* desc = NULL;
PUSB_COMMON_DESCRIPTOR cmn = (PUSB_COMMON_DESCRIPTOR)(info->ConfigDesc + 1); 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) if (USB_CONFIGURATION_DESCRIPTOR_TYPE == cmn->bDescriptorType)
{ {
@ -556,6 +618,7 @@ bool usb_device::init(void)
COPY_MEMBER(uep, endp, bInterval); COPY_MEMBER(uep, endp, bInterval);
ep_ind++; ep_ind++;
} }
used += cmn->bLength;
cmn = (PUSB_COMMON_DESCRIPTOR)((PCHAR)cmn + 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 }; USBSCAN_PIPE_CONFIGURATION upc = { 0 };
DWORD cbr = 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)) 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) for (int i = 0; i < upc.NumberOfPipes; ++i)
{ {
USBPIPE up = { 0 }; USBPIPE up = { 0 };
char ind[20] = { 0 }; char ind[80] = { 0 };
up.address = upc.PipeInfo[i].EndpointAddress; up.address = upc.PipeInfo[i].EndpointAddress;
up.type = upc.PipeInfo[i].PipeType; up.type = upc.PipeInfo[i].PipeType;
sprintf_s(ind, _countof(ind) - 1, "\\%04d", i); sprintf_s(ind, _countof(ind) - 1, fmt.c_str(), i);
up.pipe = open_usb((name_ + ind).c_str()); up.pipe = open_usb((root + ind).c_str());
if (up.pipe != INVALID_HANDLE_VALUE) if (up.pipe != INVALID_HANDLE_VALUE)
{ {
set_timeout(up.pipe); set_timeout(up.pipe);
@ -730,10 +807,17 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
if (h) if (h)
{ {
ovl_cls *oc = ovl_mgr_.get_ovl(); ovl_cls* oc = ovl_mgr_.get_ovl();
DWORD io = 0; DWORD io = 0;
BOOL result = (endpoint & BULKIN_FLAG) ? ReadFile(h, data, *length, oc->io_bytes(), oc->over_lapped()) BOOL result = FALSE;
: WriteFile(h, data, *length, oc->io_bytes(), oc->over_lapped());
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) if (result)
{ {

View File

@ -13,7 +13,6 @@
#include <memory> #include <memory>
#include "libusb-1.0/libusb.h" #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} // HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f}
#define HG_SCANNER_GUID "6BDD1FC6-810F-11D0-BEC7-08002BE2092F" #define HG_SCANNER_GUID "6BDD1FC6-810F-11D0-BEC7-08002BE2092F"
@ -31,8 +30,9 @@ typedef struct _dev_id
} }
}DEVID; }DEVID;
class ovl_cls : public refer class ovl_cls// : public refer
{ {
volatile long ref_;
OVERLAPPED ovl_; OVERLAPPED ovl_;
DWORD io_bytes_; DWORD io_bytes_;
@ -43,6 +43,19 @@ protected:
~ovl_cls(); ~ovl_cls();
public: 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); LPOVERLAPPED over_lapped(void);
LPDWORD io_bytes(void); LPDWORD io_bytes(void);
void reset(void); void reset(void);
@ -85,8 +98,7 @@ class usb_device // consider as libusb_device
}USBPIPE; }USBPIPE;
std::vector<USBPIPE> pipes_; std::vector<USBPIPE> pipes_;
DWORD timout_ms_; DWORD timout_ms_;
HANDLE find_pipe(UCHAR addr, int type, int *index = NULL); HANDLE open_usb(const char* usb_name, DWORD access = GENERIC_READ | GENERIC_WRITE, DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE);
HANDLE open_usb(const char* usb_name);
int set_timeout(HANDLE h); int set_timeout(HANDLE h);
public: public:
@ -98,6 +110,7 @@ public:
static std::string parent_hub_path_name(int vid, int pid, int *addr = NULL); 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 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 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 add_ref(void);
long release(void); long release(void);
@ -129,6 +142,7 @@ public:
int open(libusb_device_handle** dev_handle); int open(libusb_device_handle** dev_handle);
int close(void); int close(void);
int set_timeout(unsigned milliseconds); 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_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); int transfer_control(uint8_t type, uint8_t req, uint16_t val, uint16_t ind, unsigned char* data, uint16_t len, unsigned timeout);