code_twain/twain/load_sane.cpp

177 lines
3.8 KiB
C++

#include "pch.h"
#include "load_sane.h"
#include <string>
namespace load_sane_util
{
static std::wstring sane_path(L"");
static HMODULE sane_module(NULL);
static int (__stdcall* sane_inst)(SCANNERID, ISaneInvoker**) = NULL;
static int(__stdcall* is_on)(SCANNERID) = NULL;
static int(__stdcall* init)(void*) = NULL;
static int(__stdcall* uninit)(void*) = NULL;
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(void)
{
#ifdef OEM_HANWANG
std::wstring path(L"SOFTWARE\\HanvonScan");
#elif defined(OEM_LISICHENG)
std::wstring path(L"SOFTWARE\\LanxumScan");
#else
std::wstring path(L"SOFTWARE\\HuaGoScan");
#endif
return reg_read(HKEY_LOCAL_MACHINE, path.c_str(), L"AppDirectory");
}
static int load_dll(const wchar_t* path_dll, HMODULE* dll)
{
HMODULE h = LoadLibraryW(path_dll);
int ret = GetLastError();
if (!h && ret == ERROR_MOD_NOT_FOUND)
{
std::wstring dir(path_dll);
size_t pos = dir.rfind(L'\\');
wchar_t path[MAX_PATH] = { 0 };
GetCurrentDirectoryW(_countof(path) - 1, path);
if (pos != std::wstring::npos)
dir.erase(pos);
SetCurrentDirectoryW(dir.c_str());
h = LoadLibraryW(path_dll);
ret = GetLastError();
SetCurrentDirectoryW(path);
}
if (dll)
*dll = h;
return ret;
}
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;
}
bool initialize(HMODULE me)
{
bool ret = false;
sane_path = reg_get_app_installing_path();
if (!sane_path.empty())
{
sane_path += L"\\sane.dll";
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");
ret = is_ok();
if (ret)
ret = init(NULL) == 0;
}
}
return ret;
}
bool is_ok(void)
{
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)
{
ISaneInvoker* ret = NULL;
int code = 0;
if (!err)
err = &code;
if (sane_inst)
*err = sane_inst(guid, &ret);
return ret;
}
void uninitialize(void)
{
if (uninit)
uninit(NULL);
if (sane_module)
{
FreeLibrary(sane_module);
sane_module = NULL;
}
sane_path = L"";
sane_inst = NULL;
}
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);
}
};