code_device/twain/ds/sane_helper.cpp

141 lines
3.2 KiB
C++

#include "sane_helper.h"
#include "huagao/brand.h"
#include "../../sdk/hginclude/utils.h"
#include <string.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 <dlfcn.h>
#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;
}