修复win7 BULK_OUT端口通信问题
This commit is contained in:
parent
2fb912efde
commit
72db1a49ff
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue