2023-04-08 00:56:20 +00:00
|
|
|
|
|
|
|
|
|
// usb_toolsDlg.cpp: 实现文件
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
|
#include "framework.h"
|
|
|
|
|
#include "usb_tools.h"
|
|
|
|
|
#include "usb_toolsDlg.h"
|
|
|
|
|
#include "afxdialogex.h"
|
|
|
|
|
#include "DlgScanner.h"
|
|
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
|
#include <coding/coding.h>
|
|
|
|
|
#include <win/win_util.h>
|
|
|
|
|
|
|
|
|
|
// CusbtoolsDlg 对话框
|
|
|
|
|
#pragma warning(disable: 4996)
|
|
|
|
|
|
|
|
|
|
|
2023-05-02 06:42:06 +00:00
|
|
|
|
#include <common/referer.h>
|
|
|
|
|
#include <common/log_util.h>
|
2023-04-08 00:56:20 +00:00
|
|
|
|
|
|
|
|
|
namespace usb
|
|
|
|
|
{
|
|
|
|
|
void enum_endpoints(libusb_device* device, std::vector<USBEP>& eps)
|
|
|
|
|
{
|
|
|
|
|
libusb_device_descriptor desc;
|
|
|
|
|
libusb_config_descriptor* conf = NULL;
|
|
|
|
|
int ret = libusb_get_device_descriptor(device, &desc);
|
|
|
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < (int)desc.bNumConfigurations; ++i)
|
|
|
|
|
{
|
|
|
|
|
ret = libusb_get_config_descriptor(device, i, &conf);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j < conf->bNumInterfaces; ++j)
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < conf->interface[j].num_altsetting; ++k)
|
|
|
|
|
{
|
|
|
|
|
for (int l = 0; l < conf->interface[j].altsetting[k].bNumEndpoints; ++l)
|
|
|
|
|
{
|
|
|
|
|
USBEP ep;
|
|
|
|
|
|
|
|
|
|
ep.iface = j;
|
|
|
|
|
ep.type = conf->interface[j].altsetting[k].endpoint[l].bmAttributes;
|
|
|
|
|
ep.addr = conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress;
|
|
|
|
|
ep.packet = conf->interface[j].altsetting[k].endpoint[l].wMaxPacketSize;
|
|
|
|
|
eps.push_back(std::move(ep));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
libusb_free_config_descriptor(conf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
BYTE type;
|
|
|
|
|
const wchar_t* str;
|
|
|
|
|
}g_ep_type[] = { {LIBUSB_TRANSFER_TYPE_BULK, L"Bulk"}
|
|
|
|
|
, {LIBUSB_TRANSFER_TYPE_BULK_STREAM, L"Bulk Stream"}
|
|
|
|
|
, {LIBUSB_TRANSFER_TYPE_CONTROL, L"Control"}
|
|
|
|
|
, {LIBUSB_TRANSFER_TYPE_INTERRUPT, L"Interrupt"}
|
|
|
|
|
, {LIBUSB_TRANSFER_TYPE_ISOCHRONOUS, L"Isochronous"}
|
|
|
|
|
};
|
|
|
|
|
const wchar_t* ep_type(BYTE type)
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : g_ep_type)
|
|
|
|
|
{
|
|
|
|
|
if (v.type == type)
|
|
|
|
|
return v.str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return L"Unknown type";
|
|
|
|
|
}
|
|
|
|
|
BYTE ep_type(const wchar_t* str)
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : g_ep_type)
|
|
|
|
|
{
|
|
|
|
|
if (wcsicmp(v.str, str) == 0)
|
|
|
|
|
return v.type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
BYTE from_hex_str(const wchar_t* str, bool* ok)
|
|
|
|
|
{
|
|
|
|
|
BYTE v = 0, cnt = 0;
|
|
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
|
*ok = false;
|
|
|
|
|
while (*str && cnt < 2)
|
|
|
|
|
{
|
|
|
|
|
if (*str >= L'0' && *str <= L'9')
|
|
|
|
|
{
|
|
|
|
|
v <<= 4;
|
|
|
|
|
v += *str - L'0';
|
|
|
|
|
}
|
|
|
|
|
else if (*str >= L'a' && *str <= L'f')
|
|
|
|
|
{
|
|
|
|
|
v <<= 4;
|
|
|
|
|
v += *str - L'a' + 10;
|
|
|
|
|
}
|
|
|
|
|
else if (*str >= L'A' && *str <= L'F')
|
|
|
|
|
{
|
|
|
|
|
v <<= 4;
|
|
|
|
|
v += *str - L'A' + 10;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
cnt++;
|
|
|
|
|
str++;
|
|
|
|
|
}
|
|
|
|
|
if (ok)
|
|
|
|
|
*ok = cnt == 2;
|
|
|
|
|
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int LIBUSB_CALL usb_pnp(libusb_context* ctx,
|
|
|
|
|
libusb_device* device,
|
|
|
|
|
libusb_hotplug_event event,
|
|
|
|
|
void* user_data)
|
|
|
|
|
{
|
|
|
|
|
LPUSBPNP pnp = new USBPNP;
|
|
|
|
|
HWND owner = (HWND)user_data;
|
|
|
|
|
libusb_device_descriptor desc;
|
|
|
|
|
|
|
|
|
|
pnp->arrive = event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
|
|
|
|
|
pnp->ctx = ctx;
|
|
|
|
|
pnp->device = libusb_ref_device(device);
|
|
|
|
|
libusb_get_device_descriptor(pnp->device, &desc);
|
|
|
|
|
pnp->vid = desc.idVendor;
|
|
|
|
|
pnp->pid = desc.idProduct;
|
|
|
|
|
// enum_endpoints(pnp->device, pnp->eps);
|
|
|
|
|
if (!PostMessage(owner, WM_USB_PNP, 0, (LPARAM)pnp))
|
|
|
|
|
{
|
|
|
|
|
libusb_unref_device(pnp->device);
|
|
|
|
|
delete pnp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static int transfer(libusb_device_handle* h, BYTE type, BYTE addr, unsigned char* buf, int *len, const wchar_t** desc = NULL, DWORD to = -1)
|
|
|
|
|
{
|
|
|
|
|
int ret = -1;
|
|
|
|
|
const wchar_t* tmp = NULL;
|
|
|
|
|
|
|
|
|
|
if (!desc)
|
|
|
|
|
desc = &tmp;
|
|
|
|
|
|
|
|
|
|
if (type == LIBUSB_TRANSFER_TYPE_BULK)
|
|
|
|
|
{
|
|
|
|
|
*desc = L"Bulk";
|
|
|
|
|
ret = libusb_bulk_transfer(h, addr, buf, *len, len, to);
|
|
|
|
|
}
|
|
|
|
|
else if (type == LIBUSB_TRANSFER_TYPE_CONTROL)
|
|
|
|
|
{
|
|
|
|
|
// ret = libusb_control_transfer()
|
|
|
|
|
}
|
|
|
|
|
else if (type == LIBUSB_TRANSFER_TYPE_INTERRUPT)
|
|
|
|
|
{
|
|
|
|
|
*desc = L"Interrupt";
|
|
|
|
|
ret = libusb_interrupt_transfer(h, addr, buf, *len, len, to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::wstring now(void)
|
|
|
|
|
{
|
|
|
|
|
std::string cur(std::move(chronograph::now()));
|
|
|
|
|
|
|
|
|
|
return std::move(a2u(cur.c_str()));
|
|
|
|
|
|
|
|
|
|
//wchar_t buf[40] = { 0 };
|
|
|
|
|
//time_t t = time(NULL);
|
|
|
|
|
//tm* lt = localtime(&t);
|
|
|
|
|
|
|
|
|
|
//swprintf_s(buf, _countof(buf) - 1, L"%04d-%02d-%02d %02d:%02d:%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);
|
|
|
|
|
|
|
|
|
|
//return buf;
|
|
|
|
|
}
|
|
|
|
|
const wchar_t* error_name(int err, wchar_t* unk)
|
|
|
|
|
{
|
|
|
|
|
#define RETURN_IF(e) \
|
|
|
|
|
if(err == e) \
|
|
|
|
|
return L###e;
|
|
|
|
|
|
|
|
|
|
RETURN_IF(LIBUSB_SUCCESS);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_IO);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_INVALID_PARAM);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_ACCESS);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_NO_DEVICE);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_NOT_FOUND);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_BUSY);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_TIMEOUT);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_OVERFLOW);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_PIPE);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_INTERRUPTED);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_NO_MEM);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_NOT_SUPPORTED);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_OTHER);
|
|
|
|
|
RETURN_IF(LIBUSB_ERROR_TRY_AGAIN);
|
|
|
|
|
|
|
|
|
|
if (unk)
|
|
|
|
|
{
|
|
|
|
|
swprintf(unk, L"%d", err);
|
|
|
|
|
|
|
|
|
|
return unk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wchar_t buf[20] = { 0 };
|
|
|
|
|
swprintf_s(buf, _countof(buf) - 1, L"%d", err);
|
|
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INTER_MODULE_CALLBACK(got_wstr)
|
|
|
|
|
{
|
|
|
|
|
*((std::wstring*)param) += std::wstring((const wchar_t*)data, len / 2);
|
|
|
|
|
|
|
|
|
|
return inter_module_data::SET_RESULT_CONTINUE;
|
|
|
|
|
}
|
|
|
|
|
INTER_MODULE_CALLBACK(got_str)
|
|
|
|
|
{
|
|
|
|
|
*((std::string*)param) += std::string(data, len);
|
|
|
|
|
|
|
|
|
|
return inter_module_data::SET_RESULT_CONTINUE;
|
|
|
|
|
}
|
|
|
|
|
std::wstring a2u(const char* ansi)
|
|
|
|
|
{
|
|
|
|
|
std::wstring u(L"");
|
|
|
|
|
|
|
|
|
|
coding_util::ansi_2_unicode(ansi, got_wstr, &u);
|
|
|
|
|
|
|
|
|
|
return std::move(u);
|
|
|
|
|
}
|
|
|
|
|
std::string u2a(const wchar_t* unic)
|
|
|
|
|
{
|
|
|
|
|
std::string a("");
|
|
|
|
|
|
|
|
|
|
coding_util::unicode_2_ansi(unic, got_str, &a);
|
|
|
|
|
|
|
|
|
|
return std::move(a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void register_tray(HWND owner, HICON icon, bool reg)
|
|
|
|
|
{
|
|
|
|
|
if(reg)
|
|
|
|
|
win_util::add_tray_icon(WM_TRAY_MSG, owner, WM_TRAY_MSG, L"Operate on USB device", icon);
|
|
|
|
|
else
|
|
|
|
|
win_util::remove_tray_icon(WM_TRAY_MSG, owner);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-05-02 01:50:55 +00:00
|
|
|
|
namespace test
|
|
|
|
|
{
|
|
|
|
|
enum data_type1
|
|
|
|
|
{
|
|
|
|
|
DATA_TYPE_BOOL = 0, // (bool*)
|
|
|
|
|
DATA_TYPE_INT1, // (uint8_t*)
|
|
|
|
|
DATA_TYPE_INT2, // (uint16_t*)
|
|
|
|
|
DATA_TYPE_INT4, // (uint32_t*)
|
|
|
|
|
DATA_TYPE_INT8, // (uint64_t*)
|
|
|
|
|
DATA_TYPE_FLOAT, // (double*)
|
|
|
|
|
DATA_TYPE_STRING, // (char*) with max_len space
|
|
|
|
|
DATA_TYPE_CUSTOM,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
data_type1 type_from_string(const char* type_desc)
|
|
|
|
|
{
|
|
|
|
|
if (strcmp(type_desc, "bool") == 0)
|
|
|
|
|
return DATA_TYPE_BOOL;
|
|
|
|
|
if (strcmp(type_desc, "int") == 0)
|
|
|
|
|
return DATA_TYPE_INT4;
|
|
|
|
|
if (strcmp(type_desc, "float") == 0)
|
|
|
|
|
return DATA_TYPE_FLOAT;
|
|
|
|
|
if (strcmp(type_desc, "string") == 0)
|
|
|
|
|
return DATA_TYPE_STRING;
|
|
|
|
|
|
|
|
|
|
return DATA_TYPE_CUSTOM;
|
|
|
|
|
}
|
|
|
|
|
bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result)
|
|
|
|
|
{
|
|
|
|
|
bool oper_not = false, calc = true, handled = false;
|
|
|
|
|
size_t pos = exp.find("==");
|
|
|
|
|
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
pos = exp.find("!=");
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
oper_not = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
handled = true;
|
|
|
|
|
if (pos)
|
|
|
|
|
{
|
|
|
|
|
std::string types("");
|
|
|
|
|
char buf[40] = { 0 }, * mem = nullptr;
|
|
|
|
|
size_t l = sizeof(buf) - 1;
|
|
|
|
|
|
|
|
|
|
*name = exp.substr(0, pos);
|
|
|
|
|
get_opt(name->c_str(), buf, &l, "type");
|
|
|
|
|
*type = type_from_string(buf);
|
|
|
|
|
l = 0;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
mem = new char[l + 4];
|
|
|
|
|
l += 4;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
*val = std::string(mem, l);
|
|
|
|
|
delete[] mem;
|
|
|
|
|
}
|
|
|
|
|
exp.erase(0, pos + 2);
|
|
|
|
|
|
|
|
|
|
if (*type == DATA_TYPE_BOOL)
|
|
|
|
|
{
|
|
|
|
|
calc = *(bool*)val->c_str() == (exp == "true");
|
|
|
|
|
}
|
|
|
|
|
else if (*type == DATA_TYPE_INT4)
|
|
|
|
|
{
|
|
|
|
|
// in range ?
|
|
|
|
|
if (exp[0] == '[')
|
|
|
|
|
{
|
|
|
|
|
int lower = atoi(exp.c_str() + 1),
|
|
|
|
|
upper = 0;
|
|
|
|
|
pos = exp.find(",");
|
|
|
|
|
if (pos++ != std::string::npos)
|
|
|
|
|
upper = atoi(exp.c_str() + pos);
|
|
|
|
|
calc = lower <= *(int*)val->c_str() && *(int*)val->c_str() <= upper;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
calc == *(int*)val->c_str() == atoi(exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (*type == DATA_TYPE_FLOAT)
|
|
|
|
|
{
|
|
|
|
|
// in range ?
|
|
|
|
|
if (exp[0] == '[')
|
|
|
|
|
{
|
|
|
|
|
double lower = atof(exp.c_str() + 1),
|
|
|
|
|
upper = 0;
|
|
|
|
|
pos = exp.find(",");
|
|
|
|
|
if (pos++ != std::string::npos)
|
|
|
|
|
upper = atof(exp.c_str() + pos);
|
|
|
|
|
calc = lower <= *(double*)val->c_str() && *(double*)val->c_str() <= upper;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
calc = IS_FLOAT_EQUAL(*(double*)val->c_str(), atof(exp.c_str()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (*type == DATA_TYPE_STRING)
|
|
|
|
|
{
|
|
|
|
|
calc = *val == exp;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "!=" : "==", exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*result = oper_not ^ calc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
|
}
|
|
|
|
|
bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result)
|
|
|
|
|
{
|
|
|
|
|
bool oper_not = false, calc = true, handled = false;
|
|
|
|
|
size_t pos = exp.find(">");
|
|
|
|
|
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
pos = exp.find("<=");
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
oper_not = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
handled = true;
|
|
|
|
|
if (pos)
|
|
|
|
|
{
|
|
|
|
|
std::string types("");
|
|
|
|
|
char buf[40] = { 0 }, * mem = nullptr;
|
|
|
|
|
size_t l = sizeof(buf) - 1;
|
|
|
|
|
|
|
|
|
|
*name = exp.substr(0, pos);
|
|
|
|
|
get_opt(name->c_str(), buf, &l, "type");
|
|
|
|
|
*type = type_from_string(buf);
|
|
|
|
|
l = 0;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
mem = new char[l + 4];
|
|
|
|
|
l += 4;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
*val = std::string(mem, l);
|
|
|
|
|
delete[] mem;
|
|
|
|
|
}
|
|
|
|
|
exp.erase(0, pos + 1 + oper_not);
|
|
|
|
|
|
|
|
|
|
if (*type == DATA_TYPE_INT4)
|
|
|
|
|
{
|
|
|
|
|
calc == *(int*)val->c_str() > atoi(exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (*type == DATA_TYPE_FLOAT)
|
|
|
|
|
{
|
|
|
|
|
calc = *(double*)val->c_str() > atof(exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? "<=" : ">", exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*result = oper_not ^ calc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
|
}
|
|
|
|
|
bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result)
|
|
|
|
|
{
|
|
|
|
|
bool oper_not = false, calc = true, handled = false;
|
|
|
|
|
size_t pos = exp.find("<");
|
|
|
|
|
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
pos = exp.find(">=");
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
oper_not = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pos != std::string::npos)
|
|
|
|
|
{
|
|
|
|
|
handled = true;
|
|
|
|
|
if (pos)
|
|
|
|
|
{
|
|
|
|
|
std::string types("");
|
|
|
|
|
char buf[40] = { 0 }, * mem = nullptr;
|
|
|
|
|
size_t l = sizeof(buf) - 1;
|
|
|
|
|
|
|
|
|
|
*name = exp.substr(0, pos);
|
|
|
|
|
get_opt(name->c_str(), buf, &l, "type");
|
|
|
|
|
*type = type_from_string(buf);
|
|
|
|
|
l = 0;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
mem = new char[l + 4];
|
|
|
|
|
l += 4;
|
|
|
|
|
get_opt(name->c_str(), mem, &l, "cur");
|
|
|
|
|
*val = std::string(mem, l);
|
|
|
|
|
delete[] mem;
|
|
|
|
|
}
|
|
|
|
|
exp.erase(0, pos + 1 + oper_not);
|
|
|
|
|
|
|
|
|
|
if (*type == DATA_TYPE_INT4)
|
|
|
|
|
{
|
|
|
|
|
calc == *(int*)val->c_str() < atoi(exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
else if (*type == DATA_TYPE_FLOAT)
|
|
|
|
|
{
|
|
|
|
|
calc = *(double*)val->c_str() < atof(exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_cls::log(LOG_LEVEL_FATAL, "Logic-operation error: un-supported type(%d) in '%s%s'\n", *type, oper_not ? ">=" : "<", exp.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*result = oper_not ^ calc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return handled;
|
|
|
|
|
}
|
|
|
|
|
bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt)
|
|
|
|
|
{
|
|
|
|
|
// ==, >, <
|
|
|
|
|
// !=, <=, >=
|
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
|
|
if (!try_equal(exp, name, type, val, get_opt, &ok))
|
|
|
|
|
{
|
|
|
|
|
if (!try_great(exp, name, type, val, get_opt, &ok))
|
|
|
|
|
{
|
|
|
|
|
try_less(exp, name, type, val, get_opt, &ok);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 00:56:20 +00:00
|
|
|
|
CusbtoolsDlg::CusbtoolsDlg(CWnd* pParent /*=nullptr*/)
|
|
|
|
|
: CDialogEx(IDD_USB_TOOLS_DIALOG, pParent)
|
|
|
|
|
{
|
|
|
|
|
log_cls::initialize(NULL);
|
2023-04-13 06:42:43 +00:00
|
|
|
|
log_cls::log(LOG_LEVEL_DEBUG, "--------------------New instance started ...--------------------\r\n");
|
2023-04-08 00:56:20 +00:00
|
|
|
|
|
2023-05-02 01:50:55 +00:00
|
|
|
|
auto get_opt_val = [&](const char* cfg_name, void* buf, size_t* len, const char* key) -> int32_t
|
|
|
|
|
{
|
|
|
|
|
if (strcmp(key, "type") == 0)
|
|
|
|
|
strcpy((char*)buf, "bool");
|
|
|
|
|
else if (strcmp(key, "cur") == 0)
|
|
|
|
|
{
|
|
|
|
|
if (*len < 1)
|
|
|
|
|
{
|
|
|
|
|
*len = 1;
|
|
|
|
|
return ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*(bool*)buf = false;
|
|
|
|
|
*len = sizeof(bool);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
std::string exp("is-check-dog-ear==true"), name(""), val("");
|
|
|
|
|
int type = 0;
|
|
|
|
|
bool chk = test::is_depends_item_ok(exp, &name, &type, &val, get_opt_val);
|
|
|
|
|
|
2023-04-08 00:56:20 +00:00
|
|
|
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::DoDataExchange(CDataExchange* pDX)
|
|
|
|
|
{
|
|
|
|
|
CDialogEx::DoDataExchange(pDX);
|
|
|
|
|
DDX_Control(pDX, IDC_LIST_DEVICES, devl_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CusbtoolsDlg, CDialogEx)
|
|
|
|
|
ON_WM_PAINT()
|
|
|
|
|
ON_WM_QUERYDRAGICON()
|
|
|
|
|
ON_BN_CLICKED(IDC_CHECK_AUTO_MON, &CusbtoolsDlg::OnBnClickedCheckAutoMon)
|
|
|
|
|
ON_MESSAGE(WM_USB_PNP, &CusbtoolsDlg::OnUsbPnp)
|
|
|
|
|
ON_MESSAGE(WM_RCV_MSG, &CusbtoolsDlg::OnRcvMsg)
|
|
|
|
|
ON_MESSAGE(WM_OPENNING_DLG_CLOSED, &CusbtoolsDlg::OnDevDlgClosed)
|
|
|
|
|
ON_MESSAGE(WM_TRAY_MSG, &CusbtoolsDlg::OnTray)
|
|
|
|
|
ON_NOTIFY(NM_DBLCLK, IDC_LIST_DEVICES, &CusbtoolsDlg::OnNMDblclkListDevices)
|
|
|
|
|
ON_BN_CLICKED(IDC_BUTTON_CLEAR, &CusbtoolsDlg::OnBnClickedButtonClear)
|
|
|
|
|
ON_WM_SYSCOMMAND()
|
|
|
|
|
ON_COMMAND(ID_TRAY_EXIT, &CusbtoolsDlg::OnTrayExit)
|
|
|
|
|
ON_COMMAND_RANGE(ID_TRAY_EXIT + 1, ID_TRAY_EXIT + 100, &CusbtoolsDlg::OnTrayDevice)
|
|
|
|
|
ON_BN_CLICKED(IDOK, &CusbtoolsDlg::OnBnClickedOk)
|
|
|
|
|
ON_WM_SIZE()
|
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CusbtoolsDlg 消息处理程序
|
|
|
|
|
bool show_balloon(int tray_id, HWND main_wnd, const wchar_t* tips, const wchar_t* title, DWORD dwTimeout, HICON hIcon, DWORD dwInfoFlag)
|
|
|
|
|
{
|
|
|
|
|
NOTIFYICONDATAW nid = { 0 };
|
|
|
|
|
|
|
|
|
|
nid.cbSize = NOTIFYICONDATA_V2_SIZE; // KEY parameter to show balloon message!
|
|
|
|
|
//nid.uVersion = NOTIFYICON_VERSION;
|
|
|
|
|
nid.hWnd = main_wnd;
|
|
|
|
|
nid.uID = tray_id;
|
|
|
|
|
nid.uFlags = /*NIF_INFO |*/ NIF_TIP;
|
|
|
|
|
wcscpy_s(nid.szTip, _countof(nid.szTip) - 1, tips);
|
|
|
|
|
wcscpy_s(nid.szInfoTitle, _countof(nid.szInfoTitle) - 1, title);
|
|
|
|
|
nid.hIcon = hIcon ? hIcon : (HICON)SendMessageW(main_wnd, WM_GETICON, ICON_SMALL, 0);
|
|
|
|
|
nid.uTimeout = dwTimeout;
|
|
|
|
|
nid.dwInfoFlags = dwInfoFlag;
|
|
|
|
|
|
|
|
|
|
return Shell_NotifyIconW(NIM_MODIFY, &nid) == TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL CusbtoolsDlg::OnInitDialog()
|
|
|
|
|
{
|
|
|
|
|
CDialogEx::OnInitDialog();
|
|
|
|
|
|
|
|
|
|
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
|
|
|
|
|
// 执行此操作
|
|
|
|
|
SetIcon(m_hIcon, TRUE); // 设置大图标
|
|
|
|
|
SetIcon(m_hIcon, FALSE); // 设置小图标
|
|
|
|
|
|
|
|
|
|
// TODO: 在此添加额外的初始化代码
|
|
|
|
|
int ind = 0;
|
|
|
|
|
devl_.InsertColumn(ind++, TEXT("No."), 0, 51);
|
|
|
|
|
devl_.InsertColumn(ind++, TEXT("VID"), 0, 75);
|
|
|
|
|
devl_.InsertColumn(ind++, TEXT("PID"), 0, 75);
|
|
|
|
|
devl_.SetExtendedStyle(devl_.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP);
|
|
|
|
|
|
|
|
|
|
//SetDlgItemInt(IDC_EDIT_TYPE, 0x40);
|
|
|
|
|
//SetDlgItemInt(IDC_EDIT_REQ, 0x64);
|
|
|
|
|
//SetDlgItemInt(IDC_EDIT_VALUE, 16);
|
|
|
|
|
//SetDlgItemInt(IDC_EDIT_INDEX, 0);
|
|
|
|
|
//SetDlgItemInt(IDC_EDIT_LEN, 20);
|
|
|
|
|
|
|
|
|
|
OnBnClickedCheckAutoMon();
|
|
|
|
|
|
|
|
|
|
tray_ = LoadMenu(NULL, MAKEINTRESOURCE(IDR_MENU1));
|
|
|
|
|
desktop_ = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL);
|
|
|
|
|
usb::register_tray(m_hWnd, m_hIcon, true);
|
|
|
|
|
|
|
|
|
|
SetPropW(m_hWnd, L"task_usb", m_hWnd);
|
2023-04-13 06:42:43 +00:00
|
|
|
|
::SetDlgItemTextA(m_hWnd, IDC_EDIT_LOG_FILE, log_cls::get_log_file().c_str());
|
2023-04-08 00:56:20 +00:00
|
|
|
|
|
|
|
|
|
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果向对话框添加最小化按钮,则需要下面的代码
|
|
|
|
|
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
|
|
|
|
|
// 这将由框架自动完成。
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnPaint()
|
|
|
|
|
{
|
|
|
|
|
if (IsIconic())
|
|
|
|
|
{
|
|
|
|
|
CPaintDC dc(this); // 用于绘制的设备上下文
|
|
|
|
|
|
|
|
|
|
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
|
|
|
|
|
|
|
|
|
// 使图标在工作区矩形中居中
|
|
|
|
|
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
|
|
|
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
|
|
|
CRect rect;
|
|
|
|
|
GetClientRect(&rect);
|
|
|
|
|
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
|
|
|
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
|
|
|
|
|
|
|
|
// 绘制图标
|
|
|
|
|
dc.DrawIcon(x, y, m_hIcon);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CDialogEx::OnPaint();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//当用户拖动最小化窗口时系统调用此函数取得光标
|
|
|
|
|
//显示。
|
|
|
|
|
HCURSOR CusbtoolsDlg::OnQueryDragIcon()
|
|
|
|
|
{
|
|
|
|
|
return static_cast<HCURSOR>(m_hIcon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::usb_monitor_thread(void)
|
|
|
|
|
{
|
|
|
|
|
while (mon_)
|
|
|
|
|
{
|
|
|
|
|
timeval tm = { 1,0 };
|
|
|
|
|
libusb_handle_events_timeout(ctx_, &tm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::enable_io_ui(bool enable)
|
|
|
|
|
{
|
|
|
|
|
GetDlgItem(IDC_BUTTON_SEND)->EnableWindow(enable);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GetDlgItem(IDC_CHECK_AUTO)->EnableWindow(enable);
|
|
|
|
|
enable &= ((CButton*)GetDlgItem(IDC_CHECK_AUTO))->GetCheck() != BST_CHECKED;
|
|
|
|
|
GetDlgItem(IDC_BUTTON_RECEIVE)->EnableWindow(enable);
|
|
|
|
|
//GetDlgItem(IDC_COMBO_EP2)->EnableWindow(enable);
|
|
|
|
|
|
|
|
|
|
//OnCbnSelchangeComboEp();
|
|
|
|
|
//GetDlgItem(IDC_EDIT_TYPE)->EnableWindow(enable);
|
|
|
|
|
//GetDlgItem(IDC_EDIT_REQ)->EnableWindow(enable);
|
|
|
|
|
//GetDlgItem(IDC_EDIT_VALUE)->EnableWindow(enable);
|
|
|
|
|
//GetDlgItem(IDC_EDIT_INDEX)->EnableWindow(enable);
|
|
|
|
|
//GetDlgItem(IDC_EDIT_LEN)->EnableWindow(enable);
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::add_pnp_que(usb::LPUSBPNP pnp)
|
|
|
|
|
{
|
|
|
|
|
int vid = pnp->vid,
|
|
|
|
|
pid = pnp->pid;
|
|
|
|
|
for (auto& v : pnp_que_)
|
|
|
|
|
{
|
|
|
|
|
if (v->ctx == pnp->ctx && v->device == pnp->device)
|
|
|
|
|
{
|
|
|
|
|
v->arrive = true;
|
|
|
|
|
libusb_unref_device(pnp->device);
|
|
|
|
|
if (v->dlg)
|
|
|
|
|
{
|
|
|
|
|
open_usb(v, false);
|
|
|
|
|
}
|
|
|
|
|
delete pnp;
|
|
|
|
|
pnp = NULL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pnp)
|
|
|
|
|
{
|
|
|
|
|
pnp_que_.push_back(pnp);
|
|
|
|
|
|
|
|
|
|
// add to UI ...
|
|
|
|
|
int item = devl_.InsertItem(devl_.GetItemCount(), std::to_wstring(devl_.GetItemCount() + 1).c_str());
|
|
|
|
|
TCHAR text[40] = { 0 };
|
|
|
|
|
libusb_device_descriptor desc;
|
|
|
|
|
|
|
|
|
|
libusb_get_device_descriptor(pnp->device, &desc);
|
|
|
|
|
_stprintf(text, TEXT("%04X"), desc.idVendor);
|
|
|
|
|
devl_.SetItemText(item, 1, text);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_stprintf(text, TEXT("%04X"), desc.idProduct);
|
|
|
|
|
devl_.SetItemText(item, 2, text);
|
|
|
|
|
|
|
|
|
|
devl_.SetItemData(item, (DWORD_PTR)pnp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IsWindowVisible())
|
|
|
|
|
{
|
|
|
|
|
wchar_t tips[128] = { 0 };
|
|
|
|
|
swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X arrived", vid, pid);
|
|
|
|
|
show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::remove_pnp_que(usb::LPUSBPNP pnp)
|
|
|
|
|
{
|
|
|
|
|
for (size_t i = 0; i < pnp_que_.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (!pnp || (pnp_que_[i]->ctx == pnp->ctx && pnp_que_[i]->device == pnp->device))
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < devl_.GetItemCount(); ++j)
|
|
|
|
|
{
|
|
|
|
|
if (!pnp || devl_.GetItemData(j) == (DWORD_PTR)pnp_que_[i])
|
|
|
|
|
{
|
|
|
|
|
//if (devl_.GetItemState(j, LVIS_SELECTED))
|
|
|
|
|
// enable_io_ui(false);
|
|
|
|
|
|
|
|
|
|
if (pnp_que_[i]->dlg == NULL)
|
|
|
|
|
{
|
|
|
|
|
devl_.SetItemData(j, 0);
|
|
|
|
|
devl_.DeleteItem(j);
|
|
|
|
|
for (; pnp && j < devl_.GetItemCount(); ++j)
|
|
|
|
|
devl_.SetItemText(j, 0, std::to_wstring(j + 1).c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pnp_que_[i]->arrive = false;
|
|
|
|
|
if (pnp)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pnp_que_[i]->dlg)
|
|
|
|
|
{
|
|
|
|
|
pnp_que_[i]->dlg->set_device(NULL);
|
|
|
|
|
//if(!pnp)
|
|
|
|
|
//{
|
|
|
|
|
// pnp_que_[i]->dlg->DestroyWindow();
|
|
|
|
|
// delete pnp_que_[i]->dlg;
|
|
|
|
|
// pnp_que_[i]->dlg = NULL;
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
close_device(pnp_que_[i]);
|
|
|
|
|
delete pnp_que_[i];
|
|
|
|
|
pnp_que_.erase(pnp_que_.begin() + i);
|
|
|
|
|
libusb_unref_device(pnp->device);
|
|
|
|
|
}
|
|
|
|
|
if(pnp)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!IsWindowVisible() && pnp)
|
|
|
|
|
{
|
|
|
|
|
wchar_t tips[128] = { 0 };
|
|
|
|
|
swprintf_s(tips, _countof(tips) - 1, L"%04X:%04X left", pnp->vid, pnp->pid);
|
|
|
|
|
show_balloon(WM_TRAY_MSG, m_hWnd, tips, L"USB", 1000, m_hIcon, NIF_TIP);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::append_log(const wchar_t* log, UINT id)
|
|
|
|
|
{
|
|
|
|
|
int len = ::GetWindowTextLength(GetDlgItem(id)->m_hWnd);
|
|
|
|
|
wchar_t* buf = new wchar_t[len + 128];
|
|
|
|
|
libusb_device_descriptor desc;
|
|
|
|
|
|
|
|
|
|
::GetDlgItemTextW(m_hWnd, id, buf, len + 20);
|
|
|
|
|
::SetDlgItemTextW(m_hWnd, id, (std::wstring(buf) + log).c_str());
|
|
|
|
|
while (::SendMessage(GetDlgItem(id)->m_hWnd, EM_SCROLL, SB_PAGEDOWN, 0));
|
|
|
|
|
|
|
|
|
|
delete[] buf;
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::log_pnp(usb::LPUSBPNP pnp)
|
|
|
|
|
{
|
|
|
|
|
wchar_t buf[128] = { 0 };
|
|
|
|
|
|
|
|
|
|
swprintf_s(buf + lstrlenW(buf), _countof(buf) - 1, L"%s: %04X:%04X %s\r\n", usb::now().c_str(),
|
|
|
|
|
pnp->vid, pnp->pid, pnp->arrive ? L"Arrive" : L"Left");
|
|
|
|
|
append_log(buf, IDC_EDIT_PNP_MSG);
|
2023-04-13 06:42:43 +00:00
|
|
|
|
log_cls::log(LOG_LEVEL_ALL, "%04X:%04X %s\r\n", pnp->vid, pnp->pid, pnp->arrive ? "Arrived" : "Left");
|
2023-04-08 00:56:20 +00:00
|
|
|
|
}
|
|
|
|
|
bool CusbtoolsDlg::endpoint_from_combo_text(wchar_t* text, BYTE& type, BYTE& addr)
|
|
|
|
|
{
|
|
|
|
|
wchar_t* ptr = wcsstr(text, L" ");
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (ptr)
|
|
|
|
|
{
|
|
|
|
|
*ptr++ = 0;
|
|
|
|
|
type = usb::ep_type(text);
|
|
|
|
|
if (type != -1)
|
|
|
|
|
{
|
|
|
|
|
ptr = wcsstr(ptr, L"-");
|
|
|
|
|
if (ptr++)
|
|
|
|
|
{
|
|
|
|
|
while (*ptr == L' ') ptr++;
|
|
|
|
|
addr = usb::from_hex_str(ptr, &ret);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::close_device(usb::LPUSBPNP pnp)
|
|
|
|
|
{
|
|
|
|
|
if (pnp->handle)
|
|
|
|
|
{
|
|
|
|
|
int face = -1;
|
|
|
|
|
for (auto& v : pnp->eps)
|
|
|
|
|
{
|
|
|
|
|
if (face != v.iface)
|
|
|
|
|
{
|
|
|
|
|
face = v.iface;
|
|
|
|
|
libusb_release_interface(pnp->handle, face);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
libusb_close(pnp->handle);
|
|
|
|
|
pnp->handle = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wchar_t msg[128] = { 0 };
|
|
|
|
|
|
|
|
|
|
swprintf_s(msg, _countof(msg) - 1, L"%s: %04X:%04X closed.\r\n", usb::now().c_str(), pnp->vid, pnp->pid);
|
|
|
|
|
append_log(msg, IDC_EDIT_PNP_MSG);
|
|
|
|
|
}
|
|
|
|
|
usb::LPUSBPNP CusbtoolsDlg::get_cur_device(void)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < devl_.GetItemCount(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (devl_.GetItemState(i, LVIS_SELECTED))
|
|
|
|
|
return (usb::LPUSBPNP)devl_.GetItemData(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::open_usb(usb::LPUSBPNP pnp, bool from_list)
|
|
|
|
|
{
|
|
|
|
|
wchar_t msg[256] = { 0 }, errb[40] = { 0 };
|
|
|
|
|
int face = -1, ret = 0;
|
|
|
|
|
|
|
|
|
|
//*
|
|
|
|
|
if (pnp->dlg == NULL)
|
|
|
|
|
{
|
|
|
|
|
pnp->dlg = new CDlgScanner(this); // new CDlgOpenning(this);
|
|
|
|
|
pnp->dlg->Create(IDD_SCANNER); // (IDD_OPENNING);
|
|
|
|
|
}
|
|
|
|
|
pnp->dlg->set_device(pnp);
|
|
|
|
|
pnp->dlg->ShowWindow(SW_SHOW);
|
|
|
|
|
/*/
|
|
|
|
|
ret = libusb_open(pnp->device, &pnp->handle);
|
|
|
|
|
if (ret == LIBUSB_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : pnp->eps)
|
|
|
|
|
{
|
|
|
|
|
if (face != v.iface)
|
|
|
|
|
{
|
|
|
|
|
face = v.iface;
|
|
|
|
|
ret = libusb_claim_interface(pnp->handle, face);
|
|
|
|
|
if (ret)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ret == LIBUSB_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
if (pnp->dlg == NULL)
|
|
|
|
|
{
|
|
|
|
|
pnp->dlg = new CDlgOpenning(this);
|
|
|
|
|
pnp->dlg->Create(IDD_OPENNING);
|
|
|
|
|
}
|
|
|
|
|
if (pnp->eps.empty())
|
|
|
|
|
usb::enum_endpoints(pnp->device, pnp->eps);
|
|
|
|
|
pnp->dlg->set_device(pnp);
|
|
|
|
|
pnp->dlg->ShowWindow(SW_SHOW);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swprintf_s(msg, _countof(msg) - 1, L"%s: Claim interface %d of %04X:%04X failed: %s\r\n", usb::now().c_str()
|
|
|
|
|
, face, pnp->vid, pnp->pid, usb::error_name(ret, errb));
|
|
|
|
|
for (auto& v : pnp->eps)
|
|
|
|
|
{
|
|
|
|
|
if (v.iface == face)
|
|
|
|
|
break;
|
|
|
|
|
if (ret != v.iface)
|
|
|
|
|
{
|
|
|
|
|
ret = v.iface;
|
|
|
|
|
libusb_release_interface(pnp->handle, v.iface);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
libusb_close(pnp->handle);
|
|
|
|
|
pnp->handle = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swprintf_s(msg, _countof(msg) - 1, L"%s: libusb_open(%04X:%04X) failed: %s\r\n", usb::now().c_str()
|
|
|
|
|
, pnp->vid, pnp->pid, usb::error_name(ret, errb));
|
|
|
|
|
}
|
|
|
|
|
////////////////////*///////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
if (!msg[0])
|
|
|
|
|
swprintf_s(msg, _countof(msg) - 1, L"%s: open %04X:%04X success\r\n", usb::now().c_str(), pnp->vid, pnp->pid);
|
|
|
|
|
else if (!from_list)
|
|
|
|
|
::MessageBoxW(m_hWnd, msg, L"Failed", MB_OK | MB_ICONERROR);
|
|
|
|
|
|
|
|
|
|
append_log(msg, IDC_EDIT_PNP_MSG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LRESULT CusbtoolsDlg::OnUsbPnp(WPARAM wp, LPARAM lp)
|
|
|
|
|
{
|
|
|
|
|
usb::LPUSBPNP pnp = (usb::LPUSBPNP)lp;
|
|
|
|
|
|
|
|
|
|
log_pnp(pnp);
|
2023-04-13 06:42:43 +00:00
|
|
|
|
if (pnp->pid == 0 && pnp->vid == 0)
|
|
|
|
|
{
|
|
|
|
|
delete pnp;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 00:56:20 +00:00
|
|
|
|
if (pnp->arrive)
|
|
|
|
|
{
|
|
|
|
|
////for (auto& v : pnp_que_)
|
|
|
|
|
////{
|
|
|
|
|
//// if (v->ctx == pnp->ctx && v->device == pnp->device)
|
|
|
|
|
//// {
|
|
|
|
|
//// libusb_unref_device(pnp->device);
|
|
|
|
|
//// v->arrive = true;
|
|
|
|
|
//// delete pnp;
|
|
|
|
|
//// pnp = NULL;
|
|
|
|
|
//// break;
|
|
|
|
|
//// }
|
|
|
|
|
////}
|
|
|
|
|
//if (pnp)
|
|
|
|
|
add_pnp_que(pnp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
remove_pnp_que(pnp);
|
|
|
|
|
// libusb_unref_device(pnp->device);
|
|
|
|
|
delete pnp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
LRESULT CusbtoolsDlg::OnRcvMsg(WPARAM wp, LPARAM lp)
|
|
|
|
|
{
|
|
|
|
|
std::wstring* msg = (std::wstring*)lp;
|
|
|
|
|
|
|
|
|
|
//append_log(msg->c_str(), IDC_EDIT_REPLY);
|
|
|
|
|
delete msg;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
LRESULT CusbtoolsDlg::OnDevDlgClosed(WPARAM wp, LPARAM lp)
|
|
|
|
|
{
|
|
|
|
|
CDlgScanner* dlg = (CDlgScanner*)lp;
|
|
|
|
|
//CDlgOpenning* dlg = (CDlgOpenning*)lp;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < pnp_que_.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (pnp_que_[i]->dlg == dlg)
|
|
|
|
|
{
|
|
|
|
|
pnp_que_[i]->dlg = NULL;
|
|
|
|
|
close_device(pnp_que_[i]);
|
|
|
|
|
if (!pnp_que_[i]->arrive)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < devl_.GetItemCount(); ++j)
|
|
|
|
|
{
|
|
|
|
|
if (devl_.GetItemData(i) == (DWORD_PTR)pnp_que_[i])
|
|
|
|
|
{
|
|
|
|
|
devl_.DeleteItem(i);
|
|
|
|
|
for (; j < devl_.GetItemCount(); ++j)
|
|
|
|
|
devl_.SetItemText(j, 0, std::to_wstring(j + 1).c_str());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete pnp_que_[i];
|
|
|
|
|
pnp_que_.erase(pnp_que_.begin() + i);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dlg->DestroyWindow();
|
|
|
|
|
delete dlg;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
LRESULT CusbtoolsDlg::OnTray(WPARAM wp, LPARAM lp)
|
|
|
|
|
{
|
|
|
|
|
UINT msg = (UINT)lp;
|
|
|
|
|
|
|
|
|
|
if (msg == WM_LBUTTONDBLCLK)
|
|
|
|
|
{
|
|
|
|
|
ShowWindow(SW_RESTORE);
|
|
|
|
|
SetForegroundWindow();
|
|
|
|
|
if (MAKELPARAM(MAKEWORD('P', 'O'), MAKEWORD('P', 'M')) == wp)
|
|
|
|
|
{
|
|
|
|
|
HWND taskwnd = ::FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL);
|
|
|
|
|
if (desktop_ != taskwnd && IsWindow(taskwnd))
|
|
|
|
|
{
|
|
|
|
|
usb::register_tray(m_hWnd, m_hIcon, true);
|
|
|
|
|
desktop_ = taskwnd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (msg == WM_RBUTTONDOWN)
|
|
|
|
|
{
|
|
|
|
|
// exit ...
|
|
|
|
|
POINT pt = { 0 };
|
|
|
|
|
HMENU hm = GetSubMenu(tray_, 0);
|
|
|
|
|
MENUITEMINFOW mi = { 0 };
|
|
|
|
|
|
|
|
|
|
mi.cbSize = sizeof(mi);
|
|
|
|
|
mi.fMask = MIIM_DATA;
|
|
|
|
|
while (GetMenuItemInfoW(hm, 0, TRUE, &mi) && mi.dwItemData)
|
|
|
|
|
DeleteMenu(hm, 0, MF_BYPOSITION);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < devl_.GetItemCount(); ++i)
|
|
|
|
|
{
|
|
|
|
|
usb::LPUSBPNP pnp = (usb::LPUSBPNP)devl_.GetItemData(i);
|
|
|
|
|
wchar_t id[40] = { 0 };
|
|
|
|
|
|
|
|
|
|
swprintf_s(id, _countof(id) - 1, L"%04X:%04X", pnp->vid, pnp->pid);
|
|
|
|
|
InsertMenuW(hm, i, MF_BYPOSITION, ID_TRAY_EXIT + 1 + i, id);
|
|
|
|
|
mi.dwItemData = (LONG)pnp;
|
|
|
|
|
SetMenuItemInfoW(hm, i, TRUE, &mi);
|
|
|
|
|
if (pnp->dlg)
|
|
|
|
|
CheckMenuItem(hm, i, MF_CHECKED | MF_BYPOSITION);
|
|
|
|
|
}
|
|
|
|
|
GetCursorPos(&pt);
|
|
|
|
|
TrackPopupMenu(hm, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, 0, m_hWnd, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnBnClickedCheckAutoMon()
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加控件通知处理程序代码
|
|
|
|
|
static libusb_hotplug_callback_handle handle = NULL;
|
|
|
|
|
|
|
|
|
|
if (ctx_)
|
|
|
|
|
{
|
|
|
|
|
libusb_context* cp = ctx_;
|
|
|
|
|
|
|
|
|
|
mon_ = false;
|
|
|
|
|
ctx_ = NULL;
|
|
|
|
|
if (mon_thrd_.get() && mon_thrd_->joinable())
|
|
|
|
|
mon_thrd_->join();
|
|
|
|
|
mon_thrd_.reset();
|
|
|
|
|
libusb_hotplug_deregister_callback(cp, handle);
|
|
|
|
|
libusb_exit(cp);
|
|
|
|
|
handle = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
libusb_init(&ctx_);
|
|
|
|
|
int ret = libusb_hotplug_register_callback(ctx_, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
|
|
|
|
|
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
|
|
|
|
|
LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY
|
|
|
|
|
LIBUSB_HOTPLUG_MATCH_ANY,//LIBUSB_HOTPLUG_MATCH_ANY,
|
|
|
|
|
LIBUSB_HOTPLUG_MATCH_ANY,
|
|
|
|
|
&usb::usb_pnp,
|
|
|
|
|
m_hWnd,
|
|
|
|
|
&handle);
|
|
|
|
|
mon_ = true;
|
|
|
|
|
mon_thrd_.reset(new std::thread(&CusbtoolsDlg::usb_monitor_thread, this));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnNMDblclkListDevices(NMHDR* pNMHDR, LRESULT* pResult)
|
|
|
|
|
{
|
|
|
|
|
LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
|
|
|
|
|
// TODO: 在此添加控件通知处理程序代码
|
|
|
|
|
*pResult = 0;
|
|
|
|
|
if (pNMItemActivate->iItem < 0 || pNMItemActivate->iItem >= devl_.GetItemCount())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
wchar_t msg[256] = { 0 }, unk[40] = { 0 };
|
|
|
|
|
usb::LPUSBPNP pnp = (usb::LPUSBPNP)devl_.GetItemData(pNMItemActivate->iItem);
|
|
|
|
|
int face = -1, ret = 0;
|
|
|
|
|
|
|
|
|
|
//CDlgScanner dlg;
|
|
|
|
|
//dlg.DoModal();
|
|
|
|
|
//return;
|
|
|
|
|
|
|
|
|
|
if (!pnp->dlg)
|
|
|
|
|
{
|
|
|
|
|
open_usb(pnp);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
RECT r = { 0 };
|
|
|
|
|
|
|
|
|
|
pnp->dlg->GetWindowRect(&r);
|
|
|
|
|
::SetWindowPos(pnp->dlg->m_hWnd, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOSENDCHANGING | SWP_SHOWWINDOW);
|
|
|
|
|
::SetTimer(pnp->dlg->m_hWnd, WM_TIMER_CANCEL_TOPMOST, 1000, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnBnClickedButtonClear()
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加控件通知处理程序代码
|
|
|
|
|
SetDlgItemText(IDC_EDIT_PNP_MSG, TEXT(""));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
|
|
|
|
if (nID == SC_CLOSE)
|
|
|
|
|
{
|
|
|
|
|
ShowWindow(SW_MINIMIZE);
|
|
|
|
|
ShowWindow(SW_HIDE);
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDialogEx::OnSysCommand(nID, lParam);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnTrayExit()
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加命令处理程序代码
|
|
|
|
|
usb::register_tray(m_hWnd, m_hIcon, false);
|
|
|
|
|
|
|
|
|
|
PostQuitMessage(0);
|
|
|
|
|
}
|
|
|
|
|
void CusbtoolsDlg::OnTrayDevice(UINT id)
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加命令处理程序代码
|
|
|
|
|
HMENU hm = GetSubMenu(tray_, 0);
|
|
|
|
|
MENUITEMINFOW mi = { 0 };
|
|
|
|
|
|
|
|
|
|
mi.cbSize = sizeof(mi);
|
|
|
|
|
mi.fMask = MIIM_DATA | MIIM_STATE;
|
|
|
|
|
GetMenuItemInfoW(hm, id, FALSE, &mi);
|
|
|
|
|
if (mi.dwItemData)
|
|
|
|
|
{
|
|
|
|
|
usb::LPUSBPNP pnp = (usb::LPUSBPNP)mi.dwItemData;
|
|
|
|
|
if (pnp->dlg)
|
|
|
|
|
pnp->dlg->OnBnClickedOk();
|
|
|
|
|
else
|
|
|
|
|
open_usb(pnp, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnBnClickedOk()
|
|
|
|
|
{
|
|
|
|
|
// TODO: 在此添加控件通知处理程序代码
|
|
|
|
|
OnTrayExit();
|
|
|
|
|
CDialogEx::OnOK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CusbtoolsDlg::OnSize(UINT nType, int cx, int cy)
|
|
|
|
|
{
|
|
|
|
|
CDialogEx::OnSize(nType, cx, cy);
|
|
|
|
|
|
|
|
|
|
// TODO: 在此处添加消息处理程序代码
|
|
|
|
|
//if (cx == 0 && cy == 0 && ::IsWindow(devl_.m_hWnd))
|
|
|
|
|
//{
|
|
|
|
|
// for (int i = 0; i < devl_.GetItemCount(); ++i)
|
|
|
|
|
// {
|
|
|
|
|
// usb::LPUSBPNP pnp = (usb::LPUSBPNP)devl_.GetItemData(i);
|
|
|
|
|
// if (pnp && pnp->dlg)
|
|
|
|
|
// pnp->dlg->ShowWindow(SW_SHOW);
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
}
|