#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h" #include "../wrapper/hg_log.h" #include "../hgdev/scanner_manager.h" #include #include #include "../hgdev/common_setting.h" #if defined(WIN32) || defined(_WIN64) #include #else #include #include #endif #include #define MAKE_VERSION(a, b, c, d) \ ((((unsigned long long)(a) & 0x0ffff) << 48) \ | (((unsigned long long)(b) & 0x0ffff) << 32) \ | (((unsigned long long)(c) & 0x0ffff) << 16) \ | (((unsigned long long)(d) & 0x0ffff) << 0)) std::string g_scanner_path = ""; static std::string g_sane_name = ""; static std::string g_sane_ver = ""; namespace err_map { struct { int sane; int scanner; }g_err_map[] = { {SANE_STATUS_GOOD, SCANNER_ERR_OK} , {SANE_STATUS_UNSUPPORTED, SCANNER_ERR_DEVICE_NOT_SUPPORT} , {SANE_STATUS_CANCELLED, SCANNER_ERR_USER_CANCELED} , {SANE_STATUS_DEVICE_BUSY, SCANNER_ERR_DEVICE_BUSY} , {SANE_STATUS_INVAL, SCANNER_ERR_INVALID_PARAMETER} , {SANE_STATUS_EOF, SCANNER_ERR_NO_DATA} , {SANE_STATUS_JAMMED, SCANNER_ERR_DEVICE_PAPER_JAMMED} , {SANE_STATUS_NO_DOCS, SCANNER_ERR_DEVICE_NO_PAPER} , {SANE_STATUS_COVER_OPEN, SCANNER_ERR_DEVICE_COVER_OPENNED} , {SANE_STATUS_IO_ERROR, SCANNER_ERR_IO} , {SANE_STATUS_NO_MEM, SCANNER_ERR_INSUFFICIENT_MEMORY} , {SANE_STATUS_ACCESS_DENIED, SCANNER_ERR_ACCESS_DENIED} }; static int sane_2_scanner(int sane) { for (size_t i = 0; i < _countof(g_err_map); ++i) { if (g_err_map[i].sane == sane) return g_err_map[i].scanner; } return sane; } static int scanner_2_sane(int scanner) { for (size_t i = 0; i < _countof(g_err_map); ++i) { if (g_err_map[i].scanner == scanner) return g_err_map[i].sane; } return scanner; } } extern "C" { static void language_changed(int cp, void* param) { reload_setting_string_from_pak(cp, nullptr); hg_scanner_mgr::instance()->on_language_changed(); } scanner_err hg_scanner_initialize(sane_callback callback, void* reserve) { std::string name(""), pe(hg_log::pe_path(&name)), path(PATH_SEPARATOR), scanner(g_scanner_path), sane(hg_log::get_module_full_path((g_sane_name + DLL_EXTESION).c_str())); #if defined(WIN32) || defined(_WIN64) size_t pos = g_scanner_path.rfind('\\'); if (pos++ != std::string::npos) g_scanner_path.erase(pos); #else size_t pos = 0; g_scanner_path = hg_log::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str()); scanner = g_scanner_path; pos = g_scanner_path.rfind('/'); if (pos++ != std::string::npos) g_scanner_path.erase(pos); #endif hg_log::init(); VLOG_MINI_5(LOG_LEVEL_DEBUG_INFO, "Module device: [%u.%u.%u.%u] - %s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER, scanner.c_str()); VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Module sane : [%s] - %s\n", g_sane_ver.c_str(), sane.c_str()); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Module exe : %s\n", (pe + path + name).c_str()); hg_scanner_mgr::set_version(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER); hg_scanner_mgr::set_exe_name(pe.c_str(), name.c_str()); hg_scanner_mgr::instance(callback); register_language_changed_notify(language_changed, true); std::string lang(hg_log::ini_get("language", "code-page")); if (lang.empty() && STRICMP(name.c_str(), "qtsane") == 0) { lang = "20127"; // qtsane can not support chinese !!! we change language to English :( hg_log::log(LOG_LEVEL_DEBUG_INFO, "Change the default language to English while qtsane does not support Chinese!\n"); } if (!lang.empty()) { lang_set_code_page(atoi(lang.c_str())); VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Found the language specified by user: %s, code-page after set = %d\n", lang.c_str(), lang_get_cur_code_page()); } return SCANNER_ERR_OK; } void hg_scanner_uninitialize(void) { register_language_changed_notify(language_changed, false); hg_scanner_mgr::clear(); hg_log::unint(); } unsigned long long hg_scanner_get_version(void) { return MAKE_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER); } scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only) { return hg_scanner_mgr::instance()->hg_scanner_enum(scanner_list, count, local_only); } scanner_err hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc) { return hg_scanner_mgr::instance()->hg_scanner_open(h, name, shared, user, pwd, check, rsc); } scanner_err hg_scanner_close(scanner_handle h, bool force) { return hg_scanner_mgr::instance()->hg_scanner_close(h, force); } scanner_err hg_scanner_get_parameter(scanner_handle h, const char* name, char* data, long* len, SANE_Int* id) { return hg_scanner_mgr::instance()->hg_scanner_get_parameter(h, name, data, len, id); } scanner_err hg_scanner_set_parameter(scanner_handle h, const char* name, void* data, long* len) { return hg_scanner_mgr::instance()->hg_scanner_set_parameter(h, name, data, len); } scanner_err hg_scanner_start(scanner_handle h, void* async_event, int num) { return hg_scanner_mgr::instance()->hg_scanner_start(h, async_event, num); } scanner_err hg_scanner_stop(scanner_handle h) { return hg_scanner_mgr::instance()->hg_scanner_stop(h); } scanner_err hg_scanner_get_img_info(scanner_handle h, SANE_Parameters* bmi, long len) { return hg_scanner_mgr::instance()->hg_scanner_get_img_info(h, bmi, len); } scanner_err hg_scanner_read_img_data(scanner_handle h, unsigned char* data, long* len) { return hg_scanner_mgr::instance()->hg_scanner_read_img_data(h, data, len); } scanner_err hg_scanner_get_status(scanner_handle h, int setstutas) { return hg_scanner_mgr::instance()->hg_scanner_get_status(h, setstutas); } scanner_err hg_scanner_reset(scanner_handle h) { return hg_scanner_mgr::instance()->hg_scanner_reset(h); } scanner_err hg_scanner_control(scanner_handle h, unsigned long code, void* data, unsigned* len) { return hg_scanner_mgr::instance()->hg_scanner_control(h, code, data, len); } void hg_scanner_set_sane_info(const char* name, const char* ver) { g_sane_name = name; g_sane_ver = ver; } const char* hg_scanner_err_name(int err) { RETURN_IF(err, SANE_STATUS_GOOD); RETURN_IF(err, SANE_STATUS_UNSUPPORTED); RETURN_IF(err, SANE_STATUS_CANCELLED); RETURN_IF(err, SANE_STATUS_DEVICE_BUSY); RETURN_IF(err, SANE_STATUS_INVAL); RETURN_IF(err, SANE_STATUS_EOF); RETURN_IF(err, SANE_STATUS_JAMMED); RETURN_IF(err, SANE_STATUS_NO_DOCS); RETURN_IF(err, SANE_STATUS_COVER_OPEN); RETURN_IF(err, SANE_STATUS_IO_ERROR); RETURN_IF(err, SANE_STATUS_NO_MEM); RETURN_IF(err, SANE_STATUS_ACCESS_DENIED); RETURN_IF(err, SCANNER_ERR_INVALID_PARAMETER); RETURN_IF(err, SCANNER_ERR_USER_CANCELED); RETURN_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY); RETURN_IF(err, SCANNER_ERR_ACCESS_DENIED); RETURN_IF(err, SCANNER_ERR_IO_PENDING); RETURN_IF(err, SCANNER_ERR_NOT_EXACT); RETURN_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED); RETURN_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM); RETURN_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM); RETURN_IF(err, SCANNER_ERR_NOT_OPEN); RETURN_IF(err, SCANNER_ERR_NOT_START); RETURN_IF(err, SCANNER_ERR_NOT_ANY_MORE); RETURN_IF(err, SCANNER_ERR_NO_DATA); RETURN_IF(err, SCANNER_ERR_HAS_DATA_YET); RETURN_IF(err, SCANNER_ERR_OUT_OF_RANGE); RETURN_IF(err, SCANNER_ERR_IO); RETURN_IF(err, SCANNER_ERR_TIMEOUT); RETURN_IF(err, SCANNER_ERR_OPEN_FILE_FAILED); RETURN_IF(err, SCANNER_ERR_CREATE_FILE_FAILED); RETURN_IF(err, SCANNER_ERR_WRITE_FILE_FAILED); RETURN_IF(err, SCANNER_ERR_DATA_DAMAGED); RETURN_IF(err, SCANNER_ERR_OPENED_BY_OTHER_PROCESS); RETURN_IF(err, SCANNER_ERR_USB_INIT_FAILED); RETURN_IF(err, SCANNER_ERR_USB_REGISTER_PNP_FAILED); RETURN_IF(err, SCANNER_ERR_USB_CLAIM_INTERFACE_FAILED); RETURN_IF(err, SCANNER_ERR_DEVICE_NOT_FOUND); RETURN_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT); RETURN_IF(err, SCANNER_ERR_DEVICE_BUSY); RETURN_IF(err, SCANNER_ERR_DEVICE_SLEEPING); RETURN_IF(err, SCANNER_ERR_DEVICE_COUNT_MODE); RETURN_IF(err, SCANNER_ERR_DEVICE_STOPPED); RETURN_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED); RETURN_IF(err, SCANNER_ERR_DEVICE_NO_PAPER); RETURN_IF(err, SCANNER_ERR_DEVICE_FEEDING_PAPER); RETURN_IF(err, SCANNER_ERR_DEVICE_DOUBLE_FEEDING); RETURN_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED); RETURN_IF(err, SCANNER_ERR_DEVICE_STAPLE_ON); RETURN_IF(err, SCANNER_ERR_DEVICE_PAPER_SKEW); RETURN_IF(err, SCANNER_ERR_DEVICE_SIZE_CHECK); RETURN_IF(err, SCANNER_ERR_DEVICE_DOGEAR); RETURN_IF(err, SCANNER_ERR_DEVICE_NO_IMAGE); RETURN_IF(err, SCANNER_ERR_DEVICE_SCANN_ERROR); RETURN_IF(err, SCANNER_ERR_DEVICE_PC_BUSY); RETURN_IF(err, SCANNER_ERR_DEVICE_ISLOCK); RETURN_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE); RETURN_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING); RETURN_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS); if (err == SCANNER_ERR_LANG_PAK_LOST) return "SCANNER_ERR_LANG_PAK_LOST"; // NOTE: multi-thread unsafe here static char g_unk_err[80] = { 0 }; sprintf(g_unk_err, "Unknown error: 0x%X", err); return g_unk_err; } const char* hg_scanner_err_description(int err) { if (err < 0x100) err = err_map::sane_2_scanner(err); if (err == SCANNER_ERR_OPENED_BY_OTHER_PROCESS && *hg_scanner_mgr::instance()->last_open_message()) return hg_scanner_mgr::instance()->last_open_message(); RETURN_DESC_IF(err, SCANNER_ERR_OK); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT); RETURN_DESC_IF(err, SCANNER_ERR_USER_CANCELED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_BUSY); RETURN_DESC_IF(err, SCANNER_ERR_INVALID_PARAMETER); RETURN_DESC_IF(err, SCANNER_ERR_NO_DATA); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_PAPER); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED); RETURN_DESC_IF(err, SCANNER_ERR_IO); RETURN_DESC_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY); RETURN_DESC_IF(err, SCANNER_ERR_ACCESS_DENIED); RETURN_DESC_IF(err, SCANNER_ERR_INSUFFICIENT_MEMORY); RETURN_DESC_IF(err, SCANNER_ERR_ACCESS_DENIED); RETURN_DESC_IF(err, SCANNER_ERR_IO_PENDING); RETURN_DESC_IF(err, SCANNER_ERR_NOT_EXACT); RETURN_DESC_IF(err, SCANNER_ERR_CONFIGURATION_CHANGED); RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_IMAGE_PARAM); RETURN_DESC_IF(err, SCANNER_ERR_RELOAD_OPT_PARAM); RETURN_DESC_IF(err, SCANNER_ERR_NOT_OPEN); RETURN_DESC_IF(err, SCANNER_ERR_NOT_START); RETURN_DESC_IF(err, SCANNER_ERR_NOT_ANY_MORE); RETURN_DESC_IF(err, SCANNER_ERR_NO_DATA); RETURN_DESC_IF(err, SCANNER_ERR_HAS_DATA_YET); RETURN_DESC_IF(err, SCANNER_ERR_OUT_OF_RANGE); RETURN_DESC_IF(err, SCANNER_ERR_IO); RETURN_DESC_IF(err, SCANNER_ERR_TIMEOUT); RETURN_DESC_IF(err, SCANNER_ERR_OPEN_FILE_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_CREATE_FILE_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_WRITE_FILE_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_DATA_DAMAGED); RETURN_DESC_IF(err, SCANNER_ERR_OPENED_BY_OTHER_PROCESS); RETURN_DESC_IF(err, SCANNER_ERR_USB_INIT_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_USB_REGISTER_PNP_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_USB_CLAIM_INTERFACE_FAILED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_FOUND); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NOT_SUPPORT); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_BUSY); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SLEEPING); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COUNT_MODE); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_STOPPED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_COVER_OPENNED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_PAPER); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_FEEDING_PAPER); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DOUBLE_FEEDING); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_JAMMED); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_STAPLE_ON); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PAPER_SKEW); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SIZE_CHECK); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DOGEAR); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_NO_IMAGE); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_SCANN_ERROR); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_PC_BUSY); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_ISLOCK); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_MAYBE_IS_HOLE); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_DEVS_BOOTING); RETURN_DESC_IF(err, SCANNER_ERR_DEVICE_UNKNOWN_STATUS); if (err == SCANNER_ERR_LANG_PAK_LOST) return "SCANNER_ERR_LANG_PAK_LOST"; // NOTE: multi-thread unsafe here static char g_unk_err[80] = { 0 }; strcpy(g_unk_err, hg_log::lang_load(ID_STATU_DESC_SCANNER_ERR_DEVICE_UNKNOWN_ERROR)); sprintf(g_unk_err + strlen(g_unk_err), ":0x%x", err); return g_unk_err; } bool hg_scanner_log_is_enable(int level) { return hg_log::is_log_level_enabled(level); } void hg_scanner_log(const char* info) { hg_log::log(info); } char* get_file_path(const char* name, char* buf) { std::string fp(hg_log::get_module_full_path(name)); if (fp.empty()) *buf = 0; else strcpy(buf, fp.c_str()); return buf; } int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block) { int ret = SCANNER_ERR_OK; #if defined(WIN32) || defined(_WIN64) ULARGE_INTEGER av = { 0 }, all = { 0 }; if (GetDiskFreeSpaceExA(path, &av, &all, NULL)) { if (total) *total = all.QuadPart; if (avail) *avail = av.QuadPart; if (block) { DWORD sec = 0, clu = 0; std::string root(path); size_t pos = root.find(":\\"); if (pos != std::string::npos) root.erase(pos + 2); if (GetDiskFreeSpaceA(root.c_str(), &clu, &sec, NULL, NULL)) { *block = clu * sec; } } } else ret = GetLastError(); #else struct statfs fs = { 0 }; ret = statfs(path, &fs); if (ret == 0) { VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, " Total: %lld, Free: %lld, Avail: %lld, block size: %lld\n", fs.f_blocks, fs.f_bfree, fs.f_bavail, fs.f_bsize); if (total) *total = fs.f_blocks * fs.f_bsize; if (avail) *avail = fs.f_bavail * fs.f_bsize; if (block) *block = fs.f_bsize; } #endif return ret; } const char* hg_scanner_image_statu_name(int img_statu) { RETURN_IF(img_statu, IMG_STATUS_OK); RETURN_IF(img_statu, IMG_STATUS_BLANK); RETURN_IF(img_statu, IMG_STATUS_DOUBLE); RETURN_IF(img_statu, IMG_STATUS_JAM); // NOTE: multi-thread unsafe here static char g_unk_statu[80] = { 0 }; sprintf(g_unk_statu, "Unknowned image statu: 0x%X", img_statu); return g_unk_statu; } void hg_get_current_time(char* tmbuf, struct tm* t) { #if defined(WIN32) || defined(_WIN64) static long bias = -1; static bool as_start = true; if (bias == -1) { _get_timezone(&bias); as_start = hg_log::ini_get("time", "adjust") != "no"; } #endif time_t now = time(nullptr); struct tm* l = localtime(&now); #if defined(WIN32) || defined(_WIN64) long after = 0; if (as_start && _get_timezone(&after) == 0 && (after != bias && after != -bias)) { now += bias; l = localtime(&now); } #endif if (t) *t = *l; if (tmbuf) sprintf(tmbuf, "%04d-%02d-%02d %02d:%02d:%02d--->", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday, l->tm_hour, l->tm_min, l->tm_sec); } void hg_get_current_time_w(wchar_t* tmbuf, struct tm* t) { struct tm tmp = { 0 }, * l = &tmp; hg_get_current_time(nullptr, l); if (t) *t = *l; if (tmbuf) swprintf(tmbuf, 40, L"%04d-%02d-%02d %02d:%02d:%02d--->", l->tm_year + 1900, l->tm_mon + 1, l->tm_mday, l->tm_hour, l->tm_min, l->tm_sec); } } #if defined(WIN32) || defined(_WIN64) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { if (reason == DLL_PROCESS_ATTACH) { if (g_scanner_path.empty()) { char path[MAX_PATH] = { 0 }; GetModuleFileNameA(inst, path, _countof(path) - 1); // if (strrchr(path, '\\')) { // strrchr(path, '\\')[1] = 0; g_scanner_path = path; } } } else if (reason == DLL_PROCESS_DETACH) { g_scanner_path.clear(); } return TRUE; } #endif