#include "pch.h" #include "load_sane.h" #include 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); } };