#include "sane_helper.h" #include "huagao/brand.h" #include #include ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // win util #if OS_WIN namespace win_util { std::string get_registry_string(HKEY root, const char* path, const char* name) { HKEY key = NULL; RegOpenKeyA(root, path, &key); if (!key) return ""; char* buf = NULL; DWORD len = 0; DWORD type = REG_SZ; std::string ret(""); RegQueryValueExA(key, name, NULL, &type, (LPBYTE)buf, &len); if (len) { buf = new char[len + 4]; memset(buf, 0, (len + 4) * sizeof(*buf)); RegQueryValueExA(key, name, NULL, &type, (LPBYTE)buf, &len); ret = buf; delete[] buf; } RegCloseKey(key); return ret; } }; #else #include #endif ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // sane_helper sane_helper::sane_helper() { // find sane root directory ... #if OS_WIN std::string path(win_util::get_registry_string(HKEY_LOCAL_MACHINE, (std::string("Software\\") + PRODUCT_VENDOR + "Scan").c_str(), sizeof(void*) == 4 ? "DriverPath" : "DriverPath64")); dll_root_ = path + PATH_SEPARATOR; #else std::string path(utils::get_module_full_path("libc*.so*")); size_t pos = path.rfind(PATH_SEPARATOR[0]); if(pos++ != std::string::npos) { path.erase(pos); dll_root_ = std::move(path); dll_root_ += "sane/"; } #endif utils::to_log(1, "sane path is: %s\n", dll_root_.c_str()); } sane_helper::~sane_helper() { clear(); } void sane_helper::clear(void) { invoke_sane_init = nullptr; invoke_sane_exit = nullptr; invoke_sane_get_devices = nullptr; invoke_sane_open = nullptr; invoke_sane_close = nullptr; invoke_sane_get_option_descriptor = nullptr; invoke_sane_control_option = nullptr; invoke_sane_get_parameters = nullptr; invoke_sane_start = nullptr; invoke_sane_read = nullptr; invoke_sane_cancel = nullptr; invoke_sane_set_io_mode = nullptr; invoke_sane_get_select_fd = nullptr; invoke_sane_strstatus = nullptr; if(dll_handle_) { FreeLibrary(dll_handle_); dll_handle_ = nullptr; } } bool sane_helper::load_sane(const char* vendor) // libsane_hgsane.so.1, and vendor is 'hgsane' { bool ok = true; clear(); dll_handle_ = utils::load_dll((dll_root_ + MODULE_NAME_SANE).c_str(), LOAD_WITH_ALTERED_SEARCH_PATH); if(!dll_handle_) { utils::to_log(7, "load sane library(%s) = %s\n", MODULE_NAME_SANE, strerror(errno)); return false; } std::string func("sane_"); func += vendor; func += "sane_"; #define GET_PROC_ADDR(api) \ *(void**)&invoke_sane_##api = GetProcAddress(dll_handle_, (func + #api).c_str()); \ ok &= invoke_sane_##api != nullptr; GET_PROC_ADDR(init); GET_PROC_ADDR(init_ex); GET_PROC_ADDR(exit); GET_PROC_ADDR(get_devices); GET_PROC_ADDR(open); GET_PROC_ADDR(close); GET_PROC_ADDR(get_option_descriptor); GET_PROC_ADDR(control_option); GET_PROC_ADDR(get_parameters); GET_PROC_ADDR(start); GET_PROC_ADDR(read); GET_PROC_ADDR(cancel); GET_PROC_ADDR(set_io_mode); GET_PROC_ADDR(get_select_fd); GET_PROC_ADDR(strstatus); if(!ok) clear(); return ok; }