KHMEXP khm_int32 KHMAPI kmm_get_module_info_i(kmm_module vm, kmm_module_info * info) { kmm_module_i * m; khm_int32 rv; EnterCriticalSection(&cs_kmm); if (!kmm_is_module(vm) || !info) rv = KHM_ERROR_INVALID_PARAM; else { m = kmm_module_from_handle(vm); ZeroMemory(info, sizeof(*info)); info->reg.name = m->name; info->reg.path = m->path; info->reg.vendor = m->vendor; info->reg.n_plugins = m->plugin_count; info->state = m->state; info->h_module = vm; info->file_version = m->file_version; info->product_version = m->prod_version; kmm_hold_module(vm); rv = KHM_ERROR_SUCCESS; } LeaveCriticalSection(&cs_kmm); return rv; }
KHMEXP HMODULE KHMAPI kmm_get_hmodule(kmm_module m) { if(!kmm_is_module(m)) return NULL; else return kmm_module_from_handle(m)->h_module; }
KHMEXP khm_int32 KHMAPI kmm_get_module_state(kmm_module m) { if(!kmm_is_module(m)) return KMM_MODULE_STATE_NONE; else return kmm_module_from_handle(m)->state; }
KHMEXP khm_int32 KHMAPI kmm_hold_module(kmm_module module) { if(!kmm_is_module(module)) return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); kmm_module_from_handle(module)->refcount++; LeaveCriticalSection(&cs_kmm); return KHM_ERROR_SUCCESS; }
KHMEXP khm_int32 KHMAPI kmm_unload_module(kmm_module module) { if(!kmm_is_module(module)) return KHM_ERROR_INVALID_PARAM; kmm_hold_module(module); kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_MODULE, (void *) kmm_module_from_handle(module)); return KHM_ERROR_SUCCESS; }
KHMEXP khm_int32 KHMAPI kmm_release_module(kmm_module vm) { kmm_module_i * m; if(!kmm_is_module(vm)) return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); m = kmm_module_from_handle(vm); if(! --(m->refcount)) { /* note that a 0 ref count means that there are no active plugins */ kmmint_free_module(m); } LeaveCriticalSection(&cs_kmm); return KHM_ERROR_SUCCESS; }
KHMEXP khm_int32 KHMAPI kmm_provide_plugin(kmm_module module, kmm_plugin_reg * plugin) { kmm_module_i * m; kmm_plugin_i * p; size_t cb_name = 0; size_t cb_desc = 0; size_t cb_dep = 0; m = kmm_module_from_handle(module); /* can only called when handing init_module() */ if(m->state != KMM_MODULE_STATE_INIT) return KHM_ERROR_INVALID_OPERATION; if(!plugin || FAILED(StringCbLength(plugin->name, KMM_MAXCB_NAME - sizeof(wchar_t), &cb_name)) || (plugin->description && FAILED(StringCbLength(plugin->description, KMM_MAXCB_DESC - sizeof(wchar_t), &cb_desc))) || (plugin->dependencies && KHM_FAILED(multi_string_length_cb(plugin->dependencies, KMM_MAXCB_DEPS, &cb_dep)))) { return KHM_ERROR_INVALID_PARAM; } cb_name += sizeof(wchar_t); cb_desc += sizeof(wchar_t); p = kmmint_get_plugin_i(plugin->name); /* released below or in kmmint_init_module() */ kmm_hold_plugin(kmm_handle_from_plugin(p)); if(p->state != KMM_PLUGIN_STATE_NONE && p->state != KMM_PLUGIN_STATE_PLACEHOLDER) { kmm_release_plugin(kmm_handle_from_plugin(p)); return KHM_ERROR_DUPLICATE; } /* released when the plugin quits */ kmm_hold_module(module); p->module = m; p->p.flags = plugin->flags; p->p.msg_proc = plugin->msg_proc; p->p.type = plugin->type; if(plugin->description) { p->p.description = PMALLOC(cb_desc); StringCbCopy(p->p.description, cb_desc, plugin->description); } else p->p.description = NULL; if(plugin->dependencies) { p->p.dependencies = PMALLOC(cb_dep); multi_string_copy_cb(p->p.dependencies, cb_dep, plugin->dependencies); } else p->p.dependencies = NULL; p->p.module = p->module->name; p->p.icon = plugin->icon; p->state = KMM_PLUGIN_STATE_REG; kmmint_delist_plugin(p); EnterCriticalSection(&cs_kmm); LPUSH(&(m->plugins), p); p->flags |= KMM_PLUGIN_FLAG_IN_MODLIST; LeaveCriticalSection(&cs_kmm); /* leave the plugin held because it is in the module's plugin list */ return KHM_ERROR_SUCCESS; }