#include "sane_hg_mdw.h" #include // for log-api #include // for log-level /// /// SANE API entrance ... /// extern "C" { // avoid compiler exporting name in C++ style !!! const char* inner_sane_err_desc(SANE_Status err) { return hg_scanner_err_description(local_utility::sane_statu_2_scanner_err(err)); } SANE_Status inner_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize) { hg_sane_middleware::set_app_callback((void*)authorize); if (!hg_sane_middleware::instance()->is_ready()) return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST; hg_sane_middleware::get_version(version_code); return SANE_STATUS_GOOD; } void inner_sane_exit(void) { hg_sane_middleware::clear(); } SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only) { SANE_Status code = hg_sane_middleware::instance()->get_devices(device_list, local_only); return code; } SANE_Status inner_sane_open(SANE_String_Const devicename, SANE_Handle* handle) { return hg_sane_middleware::instance()->open_device(devicename, handle); } void inner_sane_close(SANE_Handle handle) { hg_sane_middleware::instance()->close_device(handle); } const SANE_Option_Descriptor* inner_sane_get_option_descriptor(SANE_Handle handle, const void* option) { return hg_sane_middleware::instance()->get_option_descriptor(handle, option); } SANE_Status inner_sane_control_option(SANE_Handle handle, const void* option, SANE_Action action, void* value, SANE_Int* info) { return hg_sane_middleware::instance()->control_option(handle, option, action, value, info); } SANE_Status inner_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params) { return hg_sane_middleware::instance()->get_image_parameters(handle, params); } SANE_Status inner_sane_start(SANE_Handle handle) { utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_start\n"); return hg_sane_middleware::instance()->start(handle, NULL); } SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length) { if (!length) length = &max_length; else *length = max_length; return hg_sane_middleware::instance()->read(handle, data, length); } void inner_sane_cancel(SANE_Handle handle) { utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_cancel\n"); hg_sane_middleware::instance()->stop(handle); } SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking) { utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, LOG_LEVEL_ALL, "sane_set_io_mode\n"); return non_blocking ? SANE_STATUS_UNSUPPORTED : SANE_STATUS_GOOD; } SANE_Status inner_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd) { return SANE_STATUS_UNSUPPORTED; } SANE_String_Const inner_sane_strstatus(SANE_Status status) { // return hg_scanner_err_name(status); return inner_sane_err_desc(status); } void sanei_debug_msg(int level, int max_level, const char* be, const char* fmt, va_list ap) { } /// following are extensions for standard ... SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param) { hg_sane_middleware::set_app_callback((void*)cb, param, hg_sane_middleware::APP_CALLBACK_EX); if (!hg_sane_middleware::instance()->is_ready()) return (SANE_Status)SCANNER_ERR_LANG_PAK_LOST; hg_sane_middleware::get_version(version_code); return SANE_STATUS_GOOD; } SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len) { return hg_sane_middleware::instance()->ex_io_control(h, code, data, len); } SANE_Status inner_sane_read_ext(SANE_Img_Ext_Info* ext_info, SANE_Int* len) { return SANE_STATUS_UNSUPPORTED; } } #if defined(WIN32) || defined(_WIN64) #include #include #include typedef struct _jsn_obj { gb_json* jsn; int from; bool operator==(const gb_json* obj) { return jsn == obj; } }JSNOBJ; static std::vector g_jsn_objs; static int max_objs = 0; static void record_json(gb_json* jsn, bool add, void* param) { std::vector::iterator it = std::find(g_jsn_objs.begin(), g_jsn_objs.end(), jsn); if (it == g_jsn_objs.end()) { if (add) { JSNOBJ jo; DWORD base = 0; _asm { push eax mov eax, ebp mov base, eax pop eax } jo.jsn = jsn; jo.from = ((DWORD***)base)[0][0][1]; g_jsn_objs.push_back(jo); if (max_objs < g_jsn_objs.size()) max_objs = g_jsn_objs.size(); } } else if (!add) g_jsn_objs.erase(it); } BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { //static _CrtMemState state; if (reason == DLL_PROCESS_ATTACH) { //if (g_scanner_path.empty()) //{ // char path[MAX_PATH] = { 0 }; // GetModuleFileNameA(inst, path, _countof(path) - 1); //// if (strrchr(path, '\\')) // { //// strrchr(path, '\\')[1] = 0; // g_scanner_path = path; // } //} //_CrtMemCheckpoint(&state); #ifdef _DEBUG _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetBreakAlloc(-1); #endif } else if (reason == DLL_PROCESS_DETACH) { #ifdef _DEBUG OutputDebugStringA("\r\nsane module unloading ...\r\n"); #endif //_CrtMemDumpAllObjectsSince(&state); } return TRUE; } #endif