2022-06-15 03:04:40 +00:00
|
|
|
|
#include "pch.h"
|
|
|
|
|
#include "load_sane.h"
|
|
|
|
|
#include <string>
|
2022-09-08 07:51:02 +00:00
|
|
|
|
#include "../../sdk/include/huagao/brand.h"
|
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**) = NULL;
|
|
|
|
|
static int(__stdcall* is_on)(SCANNERID) = NULL;
|
|
|
|
|
static int(__stdcall* init)(void*) = NULL;
|
|
|
|
|
static int(__stdcall* uninit)(void*) = NULL;
|
|
|
|
|
|
2022-09-08 07:51:02 +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;
|
|
|
|
|
}
|
2022-09-08 07:51:02 +00:00
|
|
|
|
static std::wstring reg_get_app_installing_path(std::wstring* rp = NULL)
|
2022-06-15 03:04:40 +00:00
|
|
|
|
{
|
2022-09-08 07:51:02 +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
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool initialize(HMODULE me)
|
|
|
|
|
{
|
2022-09-08 07:51:02 +00:00
|
|
|
|
std::wstring reg_path(L"");
|
2022-06-15 03:04:40 +00:00
|
|
|
|
bool ret = false;
|
2022-09-08 07:51:02 +00:00
|
|
|
|
sane_path = reg_get_app_installing_path(®_path);
|
2022-06-15 03:04:40 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-08 07:51:02 +00:00
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
};
|