修复win7 BULK_OUT端口通信问题
This commit is contained in:
parent
2fb912efde
commit
72db1a49ff
|
@ -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);
|
||||||
|
@ -732,8 +809,15 @@ int usb_device::transfer_bulk(unsigned endpoint, unsigned char* data, int* lengt
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue