#include "pch.h" #include "load_sane.h" #include #include "../../sdk/include/huagao/brand.h" 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::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; } 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) { 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()); } 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) { std::wstring reg_path(L""); bool ret = false; sane_path = reg_get_app_installing_path(®_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; } } if (!ret) MessageBoxW(NULL, (reg_path + L": " + sane_path).c_str(), L"Load scanner driver failed:", MB_OK); 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); } };