code_twain/twain/load_sane.cpp

268 lines
6.6 KiB
C++
Raw Normal View History

2022-06-15 03:04:40 +00:00
#include "pch.h"
#include "load_sane.h"
#include <string>
2022-09-20 04:41:32 +00:00
#include <shellapi.h> // for SHFileOperationW
#include "../../sdk/include/huagao/brand.h"
2022-06-15 03:04:40 +00:00
2022-09-20 04:41:32 +00:00
#pragma comment(lib, "shell32.lib")
2022-06-15 03:04:40 +00:00
namespace load_sane_util
{
static std::wstring sane_path(L"");
static HMODULE sane_module(NULL);
static int (__stdcall* sane_inst)(SCANNERID, ISaneInvoker**, bool) = NULL;
2022-06-15 03:04:40 +00:00
static int(__stdcall* is_on)(SCANNERID) = NULL;
static int(__stdcall* init)(void*) = NULL;
static int(__stdcall* uninit)(void*) = NULL;
2022-09-19 06:16:34 +00:00
static void(__stdcall* log)(const wchar_t*, int) = NULL;
2022-06-15 03:04:40 +00:00
static std::string u2m(const wchar_t* u, int page)
{
char* ansi = NULL;
int len = 0;
std::string mb("");
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), NULL, 0, NULL, NULL);
ansi = new char[len + 2];
len = WideCharToMultiByte(page, 0, u, lstrlenW(u), ansi, len, NULL, NULL);
ansi[len--] = 0;
mb = ansi;
delete[] ansi;
return mb;
}
static std::wstring m2u(const char* m, int page)
{
wchar_t* unic = NULL;
int len = 0;
std::wstring u(L"");
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), NULL, 0);
unic = new wchar_t[len + 2];
len = MultiByteToWideChar(page, 0, m, lstrlenA(m), unic, len);
unic[len--] = 0;
u = unic;
delete[] unic;
return u;
}
2022-06-15 03:04:40 +00:00
static std::wstring reg_read(HKEY root, const wchar_t* path, const wchar_t* name)
{
HKEY key = NULL;
RegOpenKeyW(root, path, &key);
if (!key)
return L"";
wchar_t* buf = NULL;
DWORD len = 0;
DWORD type = REG_SZ;
std::wstring ret(L"");
RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len);
if (len)
{
buf = new wchar_t[len + 4];
memset(buf, 0, (len + 4) * sizeof(*buf));
RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len);
ret = buf;
delete[] buf;
}
RegCloseKey(key);
return ret;
}
static std::wstring reg_get_app_installing_path(std::wstring* rp = NULL)
2022-06-15 03:04:40 +00:00
{
std::wstring path(m2u(PRODUCT_VENDOR, CP_ACP)), key(L"DriverPath");
path.insert(0, L"Software\\");
path += L"Scan";
if (sizeof(void*) != 4)
key += L"64";
if (rp)
*rp = path + L"\\" + key;
return reg_read(HKEY_LOCAL_MACHINE, path.c_str(), key.c_str());
2022-06-15 03:04:40 +00:00
}
std::string to_web_utf(const std::wstring& unic)
{
std::string webu("");
char buf[20] = { 0 };
for (size_t i = 0; i < unic.length(); ++i)
{
wchar_t v = unic[i];
if (v <= 0x7f)
webu.append(1, (char)v);
else
{
sprintf_s(buf, _countof(buf) - 1, "\\u%04X", v);
webu += buf;
}
}
return webu;
}
2022-06-15 03:04:40 +00:00
static int load_dll(const wchar_t* path_dll, HMODULE* dll)
{
HMODULE h = NULL; // LoadLibraryW(path_dll); // 3rd APP like Dynamsoft will treat the exception, so we force to SetDllDirectoryW first and load later
int ret = 0; // GetLastError();
wchar_t info[128] = { 0 };
2022-06-15 03:04:40 +00:00
// SetSearchPathMode(BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE);
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());
if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT || ret == 0))
2022-06-15 03:04:40 +00:00
{
std::wstring dir(path_dll);
size_t pos = dir.rfind(L'\\');
wchar_t path[MAX_PATH] = { 0 };
GetDllDirectoryW(_countof(path) - 1, path);
2022-06-15 03:04:40 +00:00
if (pos != std::wstring::npos)
dir.erase(pos);
OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str());
SetDllDirectoryW(dir.c_str());
2022-06-15 03:04:40 +00:00
h = LoadLibraryW(path_dll);
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
2022-06-15 03:04:40 +00:00
ret = GetLastError();
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());
OutputDebugStringW((L"[TWAIN]Load: restore directory to " + std::wstring(path) + L"\r\n").c_str());
SetDllDirectoryW(path);
2022-06-15 03:04:40 +00:00
}
if (dll)
*dll = h;
return ret;
}
bool initialize(HMODULE me)
{
std::wstring reg_path(L"");
2022-06-15 03:04:40 +00:00
bool ret = false;
sane_path = reg_get_app_installing_path(&reg_path);
2022-06-15 03:04:40 +00:00
if (!sane_path.empty())
{
sane_path += /*L"\\sane.dll";*/ L"\\" + m2u(MODULE_NAME_SANE, CP_UTF8);
2022-06-15 03:04:40 +00:00
load_dll(sane_path.c_str(), &sane_module);
if (sane_module)
{
*((FARPROC*)&init) = GetProcAddress(sane_module, "initialize");
*((FARPROC*)&sane_inst) = GetProcAddress(sane_module, "open_scanner");
*((FARPROC*)&is_on) = GetProcAddress(sane_module, "is_scanner_online");
*((FARPROC*)&uninit) = GetProcAddress(sane_module, "uninitialize");
2022-09-19 06:16:34 +00:00
*((FARPROC*)&log) = GetProcAddress(sane_module, "log_info");
2022-06-15 03:04:40 +00:00
ret = is_ok();
if (ret)
ret = init(NULL) == 0;
}
}
if (!ret)
MessageBoxW(NULL, (reg_path + L": " + sane_path).c_str(), L"Load scanner driver failed:", MB_OK);
2022-06-15 03:04:40 +00:00
return ret;
}
bool is_ok(void)
{
wchar_t info[128] = { 0 };
swprintf_s(info, _countof(info) - 1, L"[TWAIN]Load: sane_inst: %s, is_on: %s, init: %s, uninit: %s\r\n"
, sane_inst != NULL ? "ok" : "not found"
, is_on != NULL ? "ok" : "not found"
, init != NULL ? "ok" : "not found"
, uninit != NULL ? "ok" : "not found");
2022-06-15 03:04:40 +00:00
return sane_inst != NULL && is_on != NULL && init != NULL && uninit != NULL;
}
bool is_online(SCANNERID guid)
{
if (is_on)
return is_on(guid);
else
return false;
}
ISaneInvoker* open(SCANNERID guid, int* err, bool last_try)
2022-06-15 03:04:40 +00:00
{
ISaneInvoker* ret = NULL;
int code = 0;
if (!err)
err = &code;
if (sane_inst)
*err = sane_inst(guid, &ret, last_try);
2022-06-15 03:04:40 +00:00
return ret;
}
void uninitialize(void)
{
sane_inst = NULL;
is_on = NULL;
init = NULL;
log = NULL;
2022-06-15 03:04:40 +00:00
if (uninit)
uninit(NULL);
uninit = NULL;
2022-06-15 03:04:40 +00:00
if (sane_module)
{
FreeLibrary(sane_module);
sane_module = NULL;
}
sane_path = L"";
sane_inst = NULL;
}
2022-09-19 06:16:34 +00:00
void log_info(const wchar_t* info, int level)
{
if (log)
log(info, level);
}
2022-06-15 03:04:40 +00:00
std::string utf82ansi(const char* utf8)
{
return u2m(m2u(utf8, CP_UTF8).c_str(), CP_ACP);
}
std::string ansi2utf8(const char* ansi)
{
return u2m(m2u(ansi, CP_ACP).c_str(), CP_UTF8);
}
2022-09-19 06:16:34 +00:00
std::wstring ansi2unic(const char* ansi)
{
return m2u(ansi, CP_ACP);
}
2022-09-20 04:41:32 +00:00
int move_file(const char* from, const char* to)
{
return move_file(ansi2unic(from).c_str(), ansi2unic(to).c_str());
}
int move_file(const wchar_t* from, const wchar_t* to)
{
SHFILEOPSTRUCTW fo = { 0 };
int ret = 0;
std::wstring _from(from), _to(to ? to : L"");
if (wcsicmp(from, to) == 0)
return 0;
_from += std::wstring((wchar_t*)&ret, 2); // ended with double '\0'
fo.pFrom = &_from[0];
_to += std::wstring((wchar_t*)&ret, 2); // ended with double '\0'
fo.pTo = &_to[0];
fo.fFlags = FOF_NO_UI | FOF_NO_CONNECTED_ELEMENTS; // 614 | 2000
fo.wFunc = FO_MOVE;
ret = SHFileOperationW(&fo);
if (ret == /*DE_SAMEFILE*/0x71)
ret = 0;
return ret;
}
2022-06-15 03:04:40 +00:00
};