diff --git a/device/gxx-linux/usb/src/usbdevice.cpp b/device/gxx-linux/usb/src/usbdevice.cpp index f8798ed..13780a6 100644 --- a/device/gxx-linux/usb/src/usbdevice.cpp +++ b/device/gxx-linux/usb/src/usbdevice.cpp @@ -1465,22 +1465,27 @@ public: void dump_buf(uint8_t *data, int len) { uint32_t addr = 0; - std::string asc(""); + std::string cont(""), asc(""); + char buf[20] = { 0 }; for(int i = 0; i < len; ++i) { if((i % 16) == 0) { - printf(" %s\n0x%08x ", asc.c_str(), addr); + if (cont.length()) + log_cls::log(LOG_LEVEL_ALL, "%s %s\n", cont.c_str(), asc.c_str()); + sprintf(buf, "0x%08x ", addr); addr += 16; + cont = buf; asc = ""; } else if((i % 8) == 0) { - printf(" "); + cont += " "; } uint8_t v = data[i]; - printf("%02X ", v); + sprintf(buf, "%02X ", v); + cont += buf; if(v >= 0x20 && v < 0x7f) asc.append(1, v); else @@ -1495,10 +1500,8 @@ void dump_buf(uint8_t *data, int len) pad.erase((16 - asc.length()) * 3); else pad = ""; - printf("%s %s", pad.c_str(), asc.c_str()); - } - printf("\n"); - + log_cls::log(LOG_LEVEL_ALL, "%s%s %s\n", cont.c_str(), pad.c_str(), asc.c_str()); + } } dyn_mem_ptr UsbDevice::unhandled_ep0(struct usb_functionfs_event* pev) @@ -1659,6 +1662,14 @@ dyn_mem_ptr UsbDevice::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_ *required = dynamic_cast(reader); } break; + default: + log_cls::log(LOG_LEVEL_ALL, "Unhandled Packet with command %d:\n", pack->cmd); + dump_buf((uint8_t*)pack, *used); + reply = dyn_mem::memory(base_head_size); + LPPACK_BASE p = (LPPACK_BASE)reply->ptr(); + BASE_PACKET_REPLY(*p, pack->cmd + 1, pack->pack_id, EINVAL); + reply->set_len(base_head_size); + break; } return reply; diff --git a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe index c10964d..2f715ce 100644 Binary files a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe and b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe differ diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.cpp b/pc/code_twain/sln/usb_tools/DlgScanner.cpp index d9923ed..b20b220 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.cpp +++ b/pc/code_twain/sln/usb_tools/DlgScanner.cpp @@ -573,7 +573,7 @@ IMPLEMENT_DYNAMIC(CDlgScanner, CDialogEx) CDlgScanner::CDlgScanner(CWnd* pParent /*=nullptr*/) : CDialogEx(IDD_SCANNER, pParent) , scanner_(NULL), auto_tx_file_(-1), auto_tx_(false) - , setting_ui_(NULL) + , setting_ui_(NULL), img_cnt_(0) { g_my_inst = GetModuleHandle(NULL); @@ -627,6 +627,47 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) setting_ui_ = NULL; } + auto progresser = [&](uint64_t total, uint64_t cur, uint32_t err) -> int + { + if (err) + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (L"Receive image " + std::to_wstring(img_cnt_) + L" error: " + std::to_wstring(err)).c_str()); + else if (cur >= total) + SetDlgItemInt(IDC_EDIT_COUNT, img_cnt_); + + return 0; + }; + auto img_keeper = [&](LPPACKIMAGE img, uint64_t size) -> data_holder_ptr + { + if (img) + { + file_saver* saver = new file_saver(); + std::string root(usb::u2a(img_root_.c_str())); + char name[40] = { 0 }; + + sprintf_s(name, _countof(name) - 1, "scan_%03x.jpg", ++img_cnt_); + if (saver->open((root + name).c_str(), size)) + { + saver->release(); + saver = NULL; + } + else + saver->set_progress_notify(progresser); + + return dynamic_cast(saver); + } + else + { + // scan stopped ... + ::SetDlgItemTextW(m_hWnd, IDC_BUTTON_SCAN, L"Scan"); + + if (size) + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L" (Error: " + std::to_wstring(size) + L")").c_str()); + else + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_COUNT, (std::to_wstring(img_cnt_) + L" (Good)").c_str()); + return NULL; + } + }; + if (pnp) { int err = 0; @@ -638,6 +679,7 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) scanner_->release(); scanner_ = NULL; msg_box(m_hWnd, MB_OK, L"Error", L"Open %04X:%04X failed with error %d.", pnp->vid, pnp->pid, err); + enable_buttons(false); } else { @@ -651,9 +693,14 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp) if (err) { msg_box(m_hWnd, MB_OK, L"Unsupported Scanner", L"Failed to get protocol version with error %d.", err); + scanner_->release(); + scanner_ = NULL; + enable_buttons(false); } else { + scanner_->set_image_receiver(img_keeper); + swprintf_s(buf, _countof(buf) - 1, L"%u.%u", h, l); SetDlgItemTextW(IDC_EDIT_PROTOCOL_VER, buf); @@ -870,6 +917,26 @@ BOOL CDlgScanner::OnInitDialog() sane_api_.sane_init_api = &sane::sane_init_api; sane_api_.sane_exit_api = &sane::sane_exit_api; + wchar_t path[MAX_PATH] = { 0 }; + std::wstring root(L""); + + GetModuleFileNameW(NULL, path, _countof(path) - 1); + wcsrchr(path, L'\\')[1] = 0; + root = path; + if (GetPrivateProfileStringW(L"config", L"img-path", L"", path, _countof(path) - 1, (root + L"config.txt").c_str())) + { + img_root_ = path; + } + else + { + img_root_ = root + L"imgs"; + } + STR_SIMPLIFY_PATH(img_root_); + file_util::force_create_folder(img_root_.c_str(), NULL, false); + if(img_root_[img_root_.length() - 1] != L'\\') + img_root_ += L"\\"; + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_IMG_PATH, img_root_.c_str()); + return FALSE; // 除非将焦点设置到控件,否则返回 TRUE } BOOL CDlgScanner::PreTranslateMessage(MSG* pMsg) @@ -944,10 +1011,61 @@ void CDlgScanner::OnBnClickedButtonResetBulk() void CDlgScanner::OnBnClickedButtonBrowseSavingPath() { // TODO: 在此添加控件通知处理程序代码 + LPITEMIDLIST pidRoot = NULL; + BROWSEINFOW bi = { 0 }; + wchar_t path[MAX_PATH] = { 0 }; + + SHGetSpecialFolderLocation(m_hWnd, CSIDL_DRIVES, &pidRoot); + bi.hwndOwner = m_hWnd; + bi.pidlRoot = pidRoot; + bi.lpszTitle = L"Select folder to save scanning images"; + bi.pszDisplayName = path; + bi.ulFlags = BIF_RETURNONLYFSDIRS; + pidRoot = SHBrowseForFolderW(&bi); + if (pidRoot) + { + SHGetPathFromIDListW(pidRoot, path); + img_root_ = path; + img_root_ += L"\\"; + STR_SIMPLIFY_PATH(img_root_); + ::SetDlgItemTextW(m_hWnd, IDC_EDIT_IMG_PATH, img_root_.c_str()); + + std::wstring root(L""); + + GetModuleFileNameW(NULL, path, _countof(path) - 1); + wcsrchr(path, L'\\')[1] = 0; + root = path; + WritePrivateProfileStringW(L"config", L"img-path", img_root_.c_str(), (root + L"config.txt").c_str()); + } } void CDlgScanner::OnBnClickedButtonScan() { // TODO: 在此添加控件通知处理程序代码 + wchar_t title[40] = { 0 }; + + ::GetDlgItemTextW(m_hWnd, IDC_BUTTON_SCAN, title, _countof(title) - 1); + if (wcsicmp(title, L"Scan") == 0) + { + img_cnt_ = 0; + SetDlgItemInt(IDC_EDIT_COUNT, img_cnt_); + if (scanner_) + { + int err = scanner_->scan_start(); + if (err) + msg_box(m_hWnd, MB_OK, L"Error", L"Failed in startin scanning with code %d", err); + else + ::SetDlgItemTextW(m_hWnd, IDC_BUTTON_SCAN, L"Stop"); + } + } + else + { + if (scanner_) + { + int err = scanner_->scan_stop(); + if (err) + msg_box(m_hWnd, MB_OK, L"Error", L"Failed to stop scanning with code %d", err); + } + } } void CDlgScanner::OnBnClickedButtonBrowseFile() { diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.h b/pc/code_twain/sln/usb_tools/DlgScanner.h index 6127be5..675916a 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.h +++ b/pc/code_twain/sln/usb_tools/DlgScanner.h @@ -57,6 +57,8 @@ class CDlgScanner : public CDialogEx HANDLE auto_wait_; dlg_setting *setting_ui_; SANEAPI sane_api_; + std::wstring img_root_; + uint32_t img_cnt_; public: CDlgScanner(CWnd* pParent = nullptr); // 标准构造函数 diff --git a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp index e0116a9..a7c9858 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.cpp @@ -133,7 +133,7 @@ int cmd_result::clean(void) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // scanner_handler -scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_NOT_OPEN) +scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_NOT_OPEN), img_receiver_(std::function()) { auto on_reply = [&](dyn_mem_ptr reply, uint32_t* used, packet_data_base_ptr* more) ->dyn_mem_ptr { @@ -186,6 +186,15 @@ scanner_handler::scanner_handler(void) : usb_(nullptr), status_(SCANNER_STATUS_N *more = dynamic_cast(receiver); } } + else if (pack->cmd == PACK_CMD_SCAN_STOP_ROGER) + { + data_holder_ptr receiver = img_receiver_(NULL, pack->data); + if (receiver) + receiver->release(); + + *used = sizeof(PACK_BASE); + status_ = pack->data; + } else if (pack->cmd == PACK_CMD_STATUS_ROGER) { *used = sizeof(PACK_BASE); @@ -543,10 +552,12 @@ int scanner_handler::status_get(void) return status_; } -int scanner_handler::scan_start(std::function img) +void scanner_handler::set_image_receiver(std::function img) { img_receiver_ = img; - +} +int scanner_handler::scan_start(void) +{ auto call = [&](cmd_result* cmd) -> int { return usb_->scan_start(cmd->get_id()); diff --git a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h index 4fab72b..c95eed7 100644 --- a/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h +++ b/pc/code_twain/sln/usb_tools/scanner/scanner_handler.h @@ -110,7 +110,8 @@ public: int option_value_set(const char* name, uint32_t type, void* buf, uint32_t size/*buffer size of 'buf'*/, uint8_t* after); int status_get(void); - int scan_start(std::function img); + void set_image_receiver(std::function img); + int scan_start(void); int scan_stop(void); int file_transfer(const char* local_path, const char* remote_path, bool to_device