/*Deal with address*/ void search(Set *headSet, unsigned int address){ int tag = address >> (b+s); Set *curSet = _location(headSet, address); if(curSet == NULL) return; Line *curLine = curSet -> lineHead; Line *preLine = NULL; /*Check whether have exsiting tag*/ while(curLine != NULL){ if(curLine -> tag == tag){ numHits++; if(preLine != NULL){ preLine -> nextLine = curLine -> nextLine; curLine -> nextLine = curSet -> lineHead; curSet -> lineHead = curLine; } return; } preLine = curLine; curLine = curLine -> nextLine; } _append(tag, curSet); }
khm_int32 kmmint_read_module_info(kmm_module_i * m) { /* the only fields we can count on at this point are m->name and m->path */ DWORD t; size_t cb; WORD lang; khm_int32 rv = KHM_ERROR_SUCCESS; struct lang_code *languages; int n_languages; int i; wchar_t resname[256]; /* the resource names are a lot shorter */ wchar_t * r; VS_FIXEDFILEINFO *vff; UINT c; assert(m->name); assert(m->path); t = TRUE; cb = GetFileVersionInfoSize(m->path, &t); /* if successful, cb gets the size in bytes of the version info structure and sets t to zero */ if (t) { return KHM_ERROR_NOT_FOUND; } else if (cb == 0) { _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path)); return KHM_ERROR_INVALID_PARAM; } if (m->version_info) { PFREE(m->version_info); m->version_info = NULL; } m->version_info = PMALLOC(cb); #ifdef DEBUG assert(m->version_info); #endif if(!GetFileVersionInfo(m->path, t, (DWORD) cb, m->version_info)) { rv = KHM_ERROR_NOT_FOUND; _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path)); _location(L"GetFileVersionInfo"); goto _cleanup; } if(!VerQueryValue(m->version_info, L"\\VarFileInfo\\Translation", (LPVOID*) &languages, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_NO_TRANS, _dupstr(m->path)); _location(L"VerQueryValue"); goto _cleanup; } n_languages = (int) (c / sizeof(*languages)); /* Try searching for the user's default language first */ lang = GetUserDefaultLangID(); for (i = 0; i < n_languages; i++) { if(languages[i].language == lang) break; } /* If not, try the system default */ if (i >= n_languages) { lang = GetSystemDefaultLangID(); for (i=0; i<n_languages; i++) if (languages[i].language == lang) break; } /* Then try EN_US */ if (i >= n_languages) { lang = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); for (i=0; i<n_languages; i++) if (languages[i].language == lang) break; } /* Language neutral? */ if (i >= n_languages) { lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL); for (i=0; i<n_languages; i++) if (languages[i].language == lang) break; } /* Just use the first one? */ if (i >= n_languages) { i = 0; } if (i >= n_languages) { rv = KHM_ERROR_INVALID_PARAM; _report_mr0(KHERR_WARNING, MSG_RMI_NO_LOCAL); goto _cleanup; } /* check module name */ StringCbPrintf(resname, sizeof(resname), L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_MODULE), languages[i].language, languages[i].codepage); if (!VerQueryValue(m->version_info, resname, (LPVOID *) &r, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(TEXT(NIMV_MODULE))); goto _cleanup; } if (c > KMM_MAXCB_NAME || FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, _cstr(TEXT(NIMV_MODULE))); goto _cleanup; } if (wcscmp(r, m->name)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr2(KHERR_WARNING, MSG_RMI_MOD_MISMATCH, _dupstr(r), _dupstr(m->name)); goto _cleanup; } /* check API version */ StringCbPrintf(resname, sizeof(resname), L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_APIVER), languages[i].language, languages[i].codepage); if (!VerQueryValue(m->version_info, resname, (LPVOID *) &r, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(TEXT(NIMV_APIVER))); goto _cleanup; } if (c > KMM_MAXCB_NAME || FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, _cstr(TEXT(NIMV_APIVER))); goto _cleanup; } t = wcstol(r, NULL, 10); rv = kmmint_check_api_version(t); if (KHM_FAILED(rv)) { _report_mr2(KHERR_WARNING, MSG_RMI_API_MISMATCH, _int32(t), _int32(KH_VERSION_API)); goto _cleanup; } /* Looks good. Now load the description, copyright, support URI and file versions */ if (m->description) { PFREE(m->description); m->description = NULL; } StringCbPrintf(resname, sizeof(resname), L"\\StringFileInfo\\%04x%04x\\FileDescription", languages[i].language, languages[i].codepage); if (!VerQueryValue(m->version_info, resname, (LPVOID *) &r, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(L"FileDescription")); goto _cleanup; } if (c > KMM_MAXCB_DESC || FAILED(StringCbLength(r, KMM_MAXCB_DESC, &cb))) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, _cstr(L"FileDescription")); goto _cleanup; } cb += sizeof(wchar_t); m->description = PMALLOC(cb); #ifdef DEBUG assert(m->description); #endif StringCbCopy(m->description, cb, r); /* on to the support URI */ if (m->support) { PFREE(m->support); m->support = NULL; } StringCbPrintf(resname, sizeof(resname), L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_SUPPORT), languages[i].language, languages[i].codepage); if (!VerQueryValue(m->version_info, resname, (LPVOID *) &r, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(TEXT(NIMV_SUPPORT))); goto _cleanup; } if (c > KMM_MAXCB_SUPPORT || FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, _cstr(TEXT(NIMV_SUPPORT))); goto _cleanup; } cb += sizeof(wchar_t); m->support = PMALLOC(cb); #ifdef DEBUG assert(m->support); #endif StringCbCopy(m->support, cb, r); /* the vendor/copyright */ if (m->vendor) { PFREE(m->vendor); m->vendor = NULL; } StringCbPrintf(resname, sizeof(resname), L"\\StringFileInfo\\%04x%04x\\LegalCopyright", languages[i].language, languages[i].codepage); if (!VerQueryValue(m->version_info, resname, (LPVOID *) &r, &c)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(L"LegalCopyright")); goto _cleanup; } if (c > KMM_MAXCB_SUPPORT || FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, _cstr(L"LegalCopyright")); goto _cleanup; } cb += sizeof(wchar_t); m->vendor = PMALLOC(cb); #ifdef DEBUG assert(m->vendor); #endif StringCbCopy(m->vendor, cb, r); if (!VerQueryValue(m->version_info, L"\\", (LPVOID *) &vff, &c) || c != sizeof(*vff)) { rv = KHM_ERROR_INVALID_PARAM; _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, _cstr(L"Fixed Version Info")); goto _cleanup; } m->file_version.major = HIWORD(vff->dwFileVersionMS); m->file_version.minor = LOWORD(vff->dwFileVersionMS); m->file_version.patch = HIWORD(vff->dwFileVersionLS); m->file_version.aux = LOWORD(vff->dwFileVersionLS); m->prod_version.major = HIWORD(vff->dwProductVersionMS); m->prod_version.minor = LOWORD(vff->dwProductVersionMS); m->prod_version.patch = HIWORD(vff->dwProductVersionLS); m->prod_version.aux = LOWORD(vff->dwProductVersionLS); rv = KHM_ERROR_SUCCESS; _cleanup: if (KHM_FAILED(rv)) { if (m->version_info) { PFREE(m->version_info); m->version_info = NULL; } } return rv; }
/*! \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(); }