KHMEXP kherr_event * __cdecl kherr_reportf(const wchar_t * long_desc_fmt, ...) { va_list vl; wchar_t buf[1024]; kherr_event * e; va_start(vl, long_desc_fmt); StringCbVPrintf(buf, sizeof(buf), long_desc_fmt, vl); va_end(vl); e = kherr_report(KHERR_DEBUG_1, NULL, NULL, NULL, buf, NULL, 0, KHERR_SUGGEST_NONE, _vnull(), _vnull(), _vnull(), _vnull(), KHERR_RF_CSTR_LONG_DESC #ifdef _WIN32 ,NULL #endif ); if (IS_KHERR_EVENT(e)) { kherr_evaluate_event(e); } return e; }
KHMEXP kherr_event * __cdecl kherr_reportf_ex(enum kherr_severity severity, const wchar_t * facility, khm_int32 facility_id, #ifdef _WIN32 HMODULE hModule, #endif const wchar_t * long_desc_fmt, ...) { va_list vl; wchar_t buf[1024]; kherr_event * e; va_start(vl, long_desc_fmt); StringCbVPrintf(buf, sizeof(buf), long_desc_fmt, vl); #ifdef DEBUG if (IsDebuggerPresent()) OutputDebugString(buf); #endif va_end(vl); e = kherr_report(severity, NULL, facility, NULL, buf, NULL, facility_id, KHERR_SUGGEST_NONE, _vnull(), _vnull(), _vnull(), _vnull(), KHERR_RF_CSTR_LONG_DESC #ifdef _WIN32 ,hModule #endif ); if (IS_KHERR_EVENT(e)) { kherr_evaluate_event(e); } return e; }
KHMEXP kherr_param kherr_dup_string(const wchar_t * s) { wchar_t * dest; size_t cb_s; if (s == NULL) return _vnull(); if (FAILED(StringCbLength(s, KHERR_MAXCB_STRING, &cb_s))) cb_s = KHERR_MAXCB_STRING; else cb_s += sizeof(wchar_t); dest = PMALLOC(cb_s); assert(dest != NULL); dest[0] = L'\0'; StringCbCopy(dest, cb_s, s); return _tstr(dest); }
/*! \internal \brief Initialize a module \a m is not in the linked list yet. \note Should only be called from the context of the registrar thread. */ void kmmint_init_module(kmm_module_i * m) { HMODULE hm; init_module_t p_init_module; kmm_plugin_i * pi; khm_int32 rv; khm_handle csp_mod = NULL; khm_handle csp_mods = NULL; khm_size sz; khm_int32 i; /* error condition handling */ BOOL exit_module = FALSE; BOOL release_module = TRUE; BOOL record_failure = FALSE; /* failure handling */ khm_int32 max_fail_count = 0; khm_int64 fail_reset_time = 0; _begin_task(0); _report_mr1(KHERR_NONE, MSG_INIT_MODULE, _cstr(m->name)); _describe(); kmm_hold_module(kmm_handle_from_module(m)); if(KHM_FAILED(kmm_get_modules_config(0, &csp_mods))) { _report_mr0(KHERR_ERROR, MSG_IM_GET_CONFIG); _location(L"kmm_get_modules_config()"); m->state = KMM_MODULE_STATE_FAIL_UNKNOWN; goto _exit; } khc_read_int32(csp_mods, L"ModuleMaxFailureCount", &max_fail_count); khc_read_int64(csp_mods, L"ModuleFailureCountResetTime", &fail_reset_time); /* If the module is not in the pre-init state, we can't initialize it. */ if(m->state != KMM_MODULE_STATE_PREINIT) { _report_mr1(KHERR_INFO, MSG_IM_NOT_PREINIT, _int32(m->state)); goto _exit; } if(KHM_FAILED(kmm_get_module_config(m->name, 0, &csp_mod))) { _report_mr0(KHERR_ERROR, MSG_IM_NOT_REGISTERED); m->state = KMM_MODULE_STATE_FAIL_NOT_REGISTERED; goto _exit; } if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"Disabled", &i)) && i) { _report_mr0(KHERR_INFO, MSG_IM_DISABLED); m->state = KMM_MODULE_STATE_FAIL_DISABLED; goto _exit; } if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"NoUnload", &i)) && i) { m->flags |= KMM_MODULE_FLAG_NOUNLOAD; } if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"FailureCount", &i))) { khm_int64 tm; khm_int64 ct; FILETIME fct; khm_int32 last_reason = 0; /* reset the failure count if the failure count reset time period has elapsed */ tm = 0; khc_read_int64(csp_mod, L"FailureTime", &tm); GetSystemTimeAsFileTime(&fct); ct = (FtToInt(&fct) - tm) / 10000000i64; if(tm > 0 && ct > fail_reset_time) { i = 0; khc_write_int32(csp_mod, L"FailureCount", 0); khc_write_int64(csp_mod, L"FailureTime", 0); } khc_read_int32(csp_mod, L"FailureReason", &last_reason); /* did we exceed the max failure count? However, we ignore the max failure count if the reason why it didn't load the last time was because the module wasn't found. */ if(i > max_fail_count && last_reason != KMM_MODULE_STATE_FAIL_NOT_FOUND) { /* failed too many times */ _report_mr0(KHERR_INFO, MSG_IM_MAX_FAIL); m->state = KMM_MODULE_STATE_FAIL_MAX_FAILURE; goto _exit; } } if(khc_read_string(csp_mod, L"ImagePath", NULL, &sz) == KHM_ERROR_TOO_LONG) { if(m->path) PFREE(m->path); m->path = PMALLOC(sz); khc_read_string(csp_mod, L"ImagePath", m->path, &sz); } else { _report_mr0(KHERR_ERROR, MSG_IM_NOT_REGISTERED); m->state = KMM_MODULE_STATE_FAIL_NOT_REGISTERED; goto _exit; } rv = kmmint_read_module_info(m); if (KHM_FAILED(rv)) { if (rv == KHM_ERROR_INCOMPATIBLE) { _report_mr0(KHERR_ERROR, MSG_IM_INCOMPATIBLE); m->state = KMM_MODULE_STATE_FAIL_INCOMPAT; } else if (rv == KHM_ERROR_NOT_FOUND) { _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path)); m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND; } else { _report_mr0(KHERR_ERROR, MSG_IM_INVALID_MODULE); m->state = KMM_MODULE_STATE_FAIL_INV_MODULE; } goto _exit; } /* check again */ if(m->state != KMM_MODULE_STATE_PREINIT) { _report_mr0(KHERR_ERROR, MSG_IM_NOT_PREINIT); goto _exit; } /* from this point on, we must record any failure codes */ record_failure = TRUE; hm = LoadLibrary(m->path); if(!hm) { m->h_module = NULL; m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND; _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path)); goto _exit; } /* from this point on, we need to discard the module through exit_module */ ResetEvent(evt_exit); kmm_active_modules++; release_module = FALSE; exit_module = TRUE; m->flags |= KMM_MODULE_FLAG_LOADED; m->h_module = hm; /* TODO: check signatures */ p_init_module = (init_module_t) GetProcAddress(hm, EXP_INIT_MODULE); if(!p_init_module) { _report_mr1(KHERR_ERROR, MSG_IM_NO_ENTRY, _cstr(EXP_INIT_MODULE)); m->state = KMM_MODULE_STATE_FAIL_INVALID; goto _exit; } m->state = KMM_MODULE_STATE_INIT; /* call init_module() */ rv = (*p_init_module)(kmm_handle_from_module(m)); m->flags |= KMM_MODULE_FLAG_INITP; if(KHM_FAILED(rv)) { _report_mr1(KHERR_ERROR, MSG_IM_INIT_FAIL, _int32(rv)); m->state = KMM_MODULE_STATE_FAIL_LOAD; goto _exit; } if(!m->plugins) { _report_mr0(KHERR_ERROR, MSG_IM_NO_PLUGINS); m->state = KMM_MODULE_STATE_FAIL_NO_PLUGINS; record_failure = FALSE; goto _exit; } m->state = KMM_MODULE_STATE_INITPLUG; do { LPOP(&(m->plugins), &pi); if(pi) { pi->flags &= ~KMM_PLUGIN_FLAG_IN_MODLIST; kmmint_init_plugin(pi); /* release the hold obtained in kmm_provide_plugin() */ kmm_release_plugin(kmm_handle_from_plugin(pi)); } } while(pi); if(!m->plugin_count) { /* We don't want to report this case. This usually means that the plugins that were provided by the module were disabled. */ #ifdef REPORT_EMPTY_MODULES _report_mr0(KHERR_ERROR, MSG_IM_NO_PLUGINS); m->state = KMM_MODULE_STATE_FAIL_NO_PLUGINS; #endif record_failure = FALSE; goto _exit; } m->state = KMM_MODULE_STATE_RUNNING; exit_module = FALSE; record_failure = FALSE; _exit: if(csp_mod) { if(record_failure) { FILETIME fct; i = 0; khc_read_int32(csp_mod, L"FailureCount", &i); i++; khc_write_int32(csp_mod, L"FailureCount", i); if(i==1) { /* first fault */ GetSystemTimeAsFileTime(&fct); khc_write_int64(csp_mod, L"FailureTime", FtToInt(&fct)); } khc_write_int32(csp_mod, L"FailureReason", m->state); } khc_close_space(csp_mod); } if(csp_mods) khc_close_space(csp_mods); _report_mr2(KHERR_INFO, MSG_IM_MOD_STATE, _dupstr(m->name), _int32(m->state)); kmmint_remove_from_module_queue(); /* if something went wrong after init_module was called on the module code, we need to call exit_module */ if(exit_module) kmmint_exit_module(m); if(release_module) kmm_release_module(kmm_handle_from_module(m)); if (kherr_is_error()) { kherr_context * c; kherr_event * err_e = NULL; kherr_event * warn_e = NULL; kherr_event * e; c = kherr_peek_context(); err_e = kherr_get_err_event(c); for(e = kherr_get_first_event(c); e; e = kherr_get_next_event(e)) { if (e != err_e && e->severity == KHERR_WARNING) { warn_e = e; break; } } kherr_evaluate_event(err_e); if (warn_e) kherr_evaluate_event(warn_e); kherr_clear_error(); e = kherr_report(KHERR_ERROR, (wchar_t *) MSG_IMERR_TITLE, KHERR_FACILITY, NULL, err_e->long_desc, ((warn_e)? (wchar_t *)MSG_IMERR_SUGGEST: NULL), KHERR_FACILITY_ID, KHERR_SUGGEST_NONE, _cstr(m->name), ((warn_e)? _cstr(warn_e->long_desc):_vnull()), _vnull(),_vnull(), KHERR_RF_MSG_SHORT_DESC | ((warn_e)? KHERR_RF_MSG_SUGGEST: 0), KHERR_HMODULE); kherr_evaluate_event(e); kherr_release_context(c); } _end_task(); }