修复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, "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);
@ -732,8 +809,15 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
{
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)
{

View File

@ -13,7 +13,6 @@
#include <memory>
#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<USBPIPE> 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);