示例#1
0
/*! \internal
  \brief Message handler for the registrar thread. */
khm_boolean KHMAPI kmmint_reg_cb(khm_int32 msg_type, 
                                 khm_int32 msg_sub_type, 
                                 khm_ui_4 uparam,
                                 void *vparam)
{
    /* we should only be getting <KMSG_KMM,KMSG_KMM_I_REG> anyway */
    if(msg_type != KMSG_KMM || msg_sub_type != KMSG_KMM_I_REG)
        return FALSE;

    switch(uparam) {
        case KMM_REG_INIT_MODULE:
            kmmint_init_module((kmm_module_i *) vparam);
            kmm_release_module(kmm_handle_from_module((kmm_module_i *) vparam));
            break;

        case KMM_REG_EXIT_MODULE:
            kmmint_exit_module((kmm_module_i *) vparam);
            kmm_release_module(kmm_handle_from_module((kmm_module_i *) vparam));
            break;

        case KMM_REG_INIT_PLUGIN:
            kmmint_init_plugin((kmm_plugin_i *) vparam);
            kmm_release_plugin(kmm_handle_from_plugin((kmm_plugin_i *) vparam));
            break;

        case KMM_REG_EXIT_PLUGIN:
            kmmint_exit_plugin((kmm_plugin_i *) vparam);
            kmm_release_plugin(kmm_handle_from_plugin((kmm_plugin_i *) vparam));
            break;
    }
    return TRUE;
}
示例#2
0
/*! \internal
  \brief Uninitialize a plugin

  In addition to terminating the thread, and removing p from the
  linked list and hashtable, it also frees up p.
   
  \note Should only be called from the context of the registrar thread. */
void kmmint_exit_plugin(kmm_plugin_i * p) {
    int np;
    khm_boolean release_plugin = TRUE;

    if(p->state == KMM_PLUGIN_STATE_RUNNING ||
       p->state == KMM_PLUGIN_STATE_INIT) {

        kmq_post_thread_quit_message(p->tid_thread, 0, NULL);
        /* when we post the quit message to the plugin thread, the plugin
           broker terminates the plugin and posts a EXIT_PLUGIN message,
           which calls this function again.  We just exit here because
           the EXIT_PLUGIN message will end up calling us again momentarily */
        return;

    }

    if(p->ht_thread) {
        /* wait for the thread to terminate */
        WaitForSingleObject(p->ht_thread, INFINITE);
        p->ht_thread = NULL;
    }

    EnterCriticalSection(&cs_kmm);

    /* undo reference count done in kmmint_init_plugin() */
    if(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT) {

        np = --(p->module->plugin_count);
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;

    } else {
        /* the plugin was not included in the module's plugin_count.
           We can't base a decision to unload the module based on this
           plugin exiting. */
        np = TRUE;
    }

    /* The plugin is in an error state.  We need to keep the plugin
       record intact so that the failure information is kept around.
       Also, we shouldn't release the plugin if it appears that
       kmmint_init_plugin() was never called for it. */
    if (p->state < KMM_PLUGIN_STATE_HOLD) {
        release_plugin = FALSE;
    }

    LeaveCriticalSection(&cs_kmm);

    if(!np) {
        /*  if this is the last plugin to exit, then notify the
            registrar that the module should be removed as well */
        kmm_hold_module(kmm_handle_from_module(p->module));
        kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_MODULE, (void *) p->module);
    }

    /* release the hold obtained in kmmint_init_plugin() */
    if (release_plugin)
        kmm_release_plugin(kmm_handle_from_plugin(p));
}
示例#3
0
KHMEXP khm_int32   KHMAPI
kmm_release_plugin_info_i(kmm_plugin_info * info) {
    khm_int32 rv;

    if (!info || !info->h_plugin)
        return KHM_ERROR_INVALID_PARAM;

    rv = kmm_release_plugin(info->h_plugin);

    ZeroMemory(info, sizeof(info));

    return rv;
}
示例#4
0
文件: kmmmain.c 项目: aosm/Kerberos
KHMEXP void KHMAPI kmm_exit(void)
{
    kmm_module_i * m;
    kmm_plugin_i * p;

    EnterCriticalSection(&cs_kmm);

    p = kmm_listed_plugins;
    while(p) {
        kmm_plugin_i * pn;

        pn = LNEXT(p);
        /* plugins that were never resolved should be kicked off the
           list.  Flipping the refcount will do that if no other
           references exist for the plugin.  The plugins that were
           waiting for unresolved dependencies will automatically get
           freed when the placeholders and other plugins get freed. */
        if(p->state == KMM_PLUGIN_STATE_PLACEHOLDER) {
            kmm_hold_plugin(kmm_handle_from_plugin(p));
            kmm_release_plugin(kmm_handle_from_plugin(p));
        }

        p = pn;
    }

    m = kmm_all_modules;
    while(m) {
        kmm_unload_module(kmm_handle_from_module(m));
        m = LNEXT(m);
    }

    LeaveCriticalSection(&cs_kmm);
    WaitForSingleObject(evt_exit, INFINITE);
    EnterCriticalSection(&cs_kmm);

    kmq_post_thread_quit_message(tid_registrar, 0, NULL);

    hash_del_hashtable(hash_plugins);
    hash_del_hashtable(hash_modules);

    LeaveCriticalSection(&cs_kmm);

    TlsFree(tls_kmm);

    tls_kmm = 0;
}
示例#5
0
/* called with cs_identpro held */
static void
identpro_check_and_deleteL(kcdb_identpro_i * p)
{
    if (!(p->flags & KCDB_IDENTPRO_FLAG_DELETED) ||
        p->refcount > 0)
        return;

    p->magic = 0;
    if (p->name)
        PFREE(p->name);
    if (p->sub)
        kmq_delete_subscription(p->sub);
    if (p->plugin)
        kmm_release_plugin(p->plugin);
    LDELETE(&deleted_id_providers, p);
    ZeroMemory(p, sizeof(*p));
    PFREE(p);
}
示例#6
0
KHMEXP khm_int32 KHMAPI
kcdb_identity_set_type(khm_int32 cred_type)
{
    kmm_plugin plugin = NULL;
    kcdb_identpro_i * idp = NULL;
    khm_int32 rv = KHM_ERROR_SUCCESS;

    plugin = kmm_this_plugin();
    if (plugin == NULL) {
#ifdef DEBUG
        assert(FALSE);
#endif
        rv = KHM_ERROR_INVALID_OPERATION;
        goto _exit;
    }

    idp = identpro_find_by_plugin(plugin);
    if (idp == NULL) {
#ifdef DEBUG
        assert(FALSE);
#endif
        rv = KHM_ERROR_INVALID_OPERATION;
        goto _exit;
    }

    EnterCriticalSection(&cs_identpro);
    idp->cred_type = cred_type;

    identpro_release(idp);
    LeaveCriticalSection(&cs_identpro);

 _exit:

    if (plugin)
        kmm_release_plugin(plugin);

    return KHM_ERROR_SUCCESS;
}
示例#7
0
/* called with cs_cfgui held */
static void
cfgui_free_node(khui_config_node_i * node) {
    if (!cfgui_is_valid_node(node))
        return;

    if (node->reg.name)
        PFREE((void *) node->reg.name);

    if (node->reg.short_desc)
        PFREE((void *) node->reg.short_desc);

    if (node->reg.long_desc)
        PFREE((void *) node->reg.long_desc);

    node->magic = 0;

    if (node->owner)
        kmm_release_plugin(node->owner);

    ZeroMemory(node, sizeof(*node));

    PFREE(node);
}
示例#8
0
/* called with cs_kmm held */
void
kmmint_free_plugin(kmm_plugin_i * pi)
{
    int i;
    pi->magic = 0;

    hash_del(hash_plugins, (void *) pi->p.name);

    kmmint_delist_plugin(pi);

    for(i=0; i<pi->n_dependants; i++) {
        kmm_release_plugin(kmm_handle_from_plugin(pi->dependants[i]));
        pi->dependants[i] = NULL;
    }

    if(pi->module) {
        kmm_release_module(kmm_handle_from_module(pi->module));
    }

    pi->module = NULL;
    pi->p.module = NULL;

    if(pi->p.name)
        PFREE(pi->p.name);
    pi->p.name = NULL;

    if(pi->p.description)
        PFREE(pi->p.description);
    pi->p.description = NULL;

    if(pi->p.dependencies)
        PFREE(pi->p.dependencies);
    pi->p.dependencies = NULL;

    PFREE(pi);
}
示例#9
0
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;
}
示例#10
0
/*! \internal
  \brief Uninitializes a module

  \note Should only be called from the context of the registrar
  thread */
void kmmint_exit_module(kmm_module_i * m) {
    kmm_plugin_i * p;

    /*  Exiting a module happens in two stages.  

        If the module state is running (there are active plugins) then
        those plugins must be exited.  This has to be done from the
        plugin threads.  The signal for the plugins to exit must be
        issued from the registrar.  Therefore, we post messages to the
        registrar for each plugin we want to remove and exit
        kmmint_exit_module().

        When the last plugin is exited, the plugin management code
        automatically signalls the registrar to remove the module.
        kmmint_exit_module() gets called again.  This is the second
        stage, where we call exit_module() for the module and start
        unloading everything.
    */

    EnterCriticalSection(&cs_kmm);

    /* get rid of any dangling uninitialized plugins */
    LPOP(&(m->plugins), &p);
    while(p) {
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODLIST;
        kmmint_exit_plugin(p);

        /* release hold from kmm_provide_plugin() */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        LPOP(&(m->plugins), &p);
    }

    if(m->state == KMM_MODULE_STATE_RUNNING) {
        int np = 0;

        m->state = KMM_MODULE_STATE_EXITPLUG;

        p = kmm_listed_plugins;

        while(p) {
            if(p->module == m &&
               (p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT)) {

                kmm_hold_plugin(kmm_handle_from_plugin(p));
                kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, 
                                 KMM_REG_EXIT_PLUGIN, (void *) p);
                np++;

            }

            p = LNEXT(p);
        }

#ifdef DEBUG
        assert(np == m->plugin_count);
#endif

        if(np > 0) {
            /*  we have to go back and wait for the plugins to exit.
                when the last plugin exits, it automatically posts
                EXIT_MODULE. We can pick up from there when this
                happens. */
            LeaveCriticalSection(&cs_kmm);
            return;
        }

    } else {

#ifdef DEBUG
        assert(m->plugin_count == 0 ||
               m->state == KMM_MODULE_STATE_EXITPLUG);
#endif

        /* if there are still plug-ins waiting to be unloaded, then we
           have to go back and wait for them to finish.  Once they are
           done, kmmint_exit_module() will get called again. */
        if (m->plugin_count > 0) {
            LeaveCriticalSection(&cs_kmm);
            return;
        }
    }

    if(m->flags & KMM_MODULE_FLAG_INITP) {
        exit_module_t p_exit_module;

        if(m->state > 0)
            m->state = KMM_MODULE_STATE_EXIT;

        p_exit_module = 
            (exit_module_t) GetProcAddress(m->h_module, 
                                           EXP_EXIT_MODULE);
        if(p_exit_module) {
            LeaveCriticalSection(&cs_kmm);
            (*p_exit_module)(kmm_handle_from_module(m));
            EnterCriticalSection(&cs_kmm);
        }
    }

    if(m->state > 0)
        m->state = KMM_MODULE_STATE_EXITED;

    LeaveCriticalSection(&cs_kmm);

    if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) &&
       m->h_module) {
        FreeLibrary(m->h_module);
    }

    if(!(m->flags & KMM_MODULE_FLAG_NOUNLOAD) &&
       m->h_resource && (m->h_resource != m->h_module)) {
        FreeLibrary(m->h_resource);
    }

    m->h_module = NULL;
    m->h_resource = NULL;

    if (m->flags & KMM_MODULE_FLAG_LOADED) {
#ifdef DEBUG
        assert(kmm_active_modules > 0);
#endif
        kmm_active_modules--;
    }

    m->flags = 0;

    /* release the hold obtained in kmmint_init_module() */
    kmm_release_module(kmm_handle_from_module(m));

    /* Last but not least, now see if there are any modules left that
       are running. If not, we can safely signal an exit. */
    if (kmm_active_modules == 0) {
        SetEvent(evt_exit);
    }
}
示例#11
0
/*! \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();
}
示例#12
0
/*! \internal
  \brief Initialize a plugin

  \note If kmmint_init_plugin() is called on a plugin, then kmmint_exit_plugin()
      \b must be called for the plugin.

  \note Should only be called from the context of the registrar thread */
void kmmint_init_plugin(kmm_plugin_i * p) {
    DWORD dummy;
    khm_handle csp_plugin   = NULL;
    khm_handle csp_plugins  = NULL;
    khm_int32 t;

    /* the following will be undone in kmmint_exit_plugin() */
    kmm_hold_plugin(kmm_handle_from_plugin(p));

    EnterCriticalSection(&cs_kmm);
    if(p->state != KMM_PLUGIN_STATE_REG &&
        p->state != KMM_PLUGIN_STATE_HOLD)
    {
        LeaveCriticalSection(&cs_kmm);
        goto _exit;
    }

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_IP_TASK_DESC, _cstr(p->p.name));
    _describe();

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        /* if this plugin was held, then we already had a hold
           from the initial attempt to start the plugin.  Undo
           the hold we did a few lines earlier. */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        /* same for the plugin count for the module. */
#ifdef DEBUG
        assert(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT);
#endif
        p->module->plugin_count--;
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;
    }

    p->state = KMM_PLUGIN_STATE_PREINIT;

    kmmint_delist_plugin(p);
    kmmint_list_plugin(p);

    LeaveCriticalSection(&cs_kmm);

    if(KHM_FAILED(kmm_get_plugins_config(0, &csp_plugins))) {
        _report_mr0(KHERR_ERROR, MSG_IP_GET_CONFIG);

        p->state = KMM_PLUGIN_STATE_FAIL_UNKNOWN;
        goto _exit;
    }

    if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
        if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
        
        if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
    }

    if (KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"Disabled", &t)) && t) {
        p->flags |= KMM_PLUGIN_FLAG_DISABLED;
        p->state = KMM_PLUGIN_STATE_FAIL_DISABLED;
        goto _exit;
    }

#if 0
    /*TODO: check the failure count and act accordingly */
    if(KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"FailureCount", &t)) && (t > 0)) {
    }
#endif

    EnterCriticalSection(&cs_kmm);

    p->n_depends = 0;
    p->n_unresolved = 0;
    
    do {
        wchar_t * deps = NULL;
        wchar_t * d;
        khm_size sz = 0;

        if(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                 NULL, &sz) != KHM_ERROR_TOO_LONG)
            break;

        deps = PMALLOC(sz);
        if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                            deps, &sz))) {
            if(deps)
                PFREE(deps);
            break;
        }

        for(d = deps; d && *d; d = multi_string_next(d)) {
            kmm_plugin_i * pd;
            int i;

            pd = kmmint_get_plugin_i(d);

            if(pd->state == KMM_PLUGIN_STATE_NONE) {
                /* the dependant was not previously known */
                pd->state = KMM_PLUGIN_STATE_PLACEHOLDER;
            }

            for(i=0; i < pd->n_dependants; i++) {
                if(pd->dependants[i] == p)
                    break;
            }

            if(i >= pd->n_dependants) {
                if( pd->n_dependants >= KMM_MAX_DEPENDANTS ) {
                    /*TODO: handle this gracefully */
                    RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL);
                }

                /* released in kmmint_free_plugin() */
                kmm_hold_plugin(kmm_handle_from_plugin(p));
                pd->dependants[pd->n_dependants] = p;
                pd->n_dependants++;
            }

            p->n_depends++;

            if(pd->state != KMM_PLUGIN_STATE_RUNNING) {
                p->n_unresolved++;
            }
        }

        if(p->n_unresolved > 0) {
            p->state = KMM_PLUGIN_STATE_HOLD;
        }

        PFREE(deps);

    } while(FALSE);

#ifdef DEBUG
    assert(!(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT));
#endif
    p->flags |= KMM_PLUGIN_FLAG_IN_MODCOUNT;
    p->module->plugin_count++;

    LeaveCriticalSection(&cs_kmm);

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        _report_mr1(KHERR_INFO, MSG_IP_HOLD, _dupstr(p->p.name));

        goto _exit_post;
    }

    kmmint_add_to_plugin_queue(p);

    p->ht_thread = CreateThread(NULL,
                                0,
                                kmmint_plugin_broker,
                                (LPVOID) p,
                                CREATE_SUSPENDED,
                                &dummy);

    p->state = KMM_PLUGIN_STATE_INIT;

    ResumeThread(p->ht_thread);

_exit_post:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);

    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_INFO, MSG_IP_STATE, 
                _dupstr(p->p.name), _int32(p->state));

    _end_task();
    
    return;

    /* jump here if an error condition happens before the plugin
       broker thread starts and the plugin should be unloaded */

_exit:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);
    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_WARNING, MSG_IP_EXITING, 
                _dupstr(p->p.name), _int32(p->state));
    _end_task();


#ifdef ASYNC_PLUGIN_UNLOAD_ON_FAILURE

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p);

#else

    kmmint_exit_plugin(p);

#endif
}
示例#13
0
INT_PTR CALLBACK
khm_cfg_plugins_proc(HWND hwnd,
                     UINT uMsg,
                     WPARAM wParam,
                     LPARAM lParam) {

    plugin_dlg_data * d;

    switch(uMsg) {
    case WM_INITDIALOG:
        {
            kmm_plugin p;
            kmm_plugin pn;
            kmm_module m;
            khm_size i;
            LVCOLUMN lvc;
            RECT r;
            HWND hw;
            wchar_t buf[256];
            HIMAGELIST h_ilist;
            HICON h_icon;

            d = PMALLOC(sizeof(*d));
#ifdef DEBUG
            assert(d);
#endif
            ZeroMemory(d, sizeof(*d));
#pragma warning(push)
#pragma warning(disable: 4244)
            SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);
#pragma warning(pop)

            p = NULL;
            i = 0;
            do {
                if (KHM_FAILED(kmm_get_next_plugin(p, &pn)))
                    break;

                if (p)
                    kmm_release_plugin(p);
                p = pn;

#ifdef DEBUG
                assert(d->info[i] == NULL);
#endif
                d->info[i] = PMALLOC(sizeof(*(d->info[i])));
#ifdef DEBUG
                assert(d->info[i]);
#endif
                ZeroMemory(&d->info[i]->plugin,
                           sizeof(d->info[i]->plugin));

                if (KHM_FAILED(kmm_get_plugin_info_i(p, &d->info[i]->plugin))) {
                    PFREE(d->info[i]);
                    d->info[i] = NULL;
                    break;
                }

                ZeroMemory(&d->info[i]->module,
                           sizeof(d->info[i]->module));

                if (KHM_SUCCEEDED(kmm_load_module(d->info[i]->plugin.reg.module,
                                                  KMM_LM_FLAG_NOLOAD,
                                                  &m))) {
                    kmm_get_module_info_i(m, &d->info[i]->module);
                    kmm_release_module(m);
                }

                i ++;

                if (i == MAX_PLUGINS)
                    break;
            } while(p);

            if (p)
                kmm_release_plugin(p);

            d->n_info = i;

            /* now populate the list view */
            hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS);
#ifdef DEBUG
            assert(hw);
#endif

            h_ilist = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
                                       GetSystemMetrics(SM_CYSMICON),
                                       ILC_COLOR8,
                                       4, 4);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN_DIS),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            h_icon = LoadImage(khm_hInstance,
                               MAKEINTRESOURCE(IDI_CFG_PLUGIN_ERR),
                               IMAGE_ICON,
                               GetSystemMetrics(SM_CXSMICON),
                               GetSystemMetrics(SM_CYSMICON),
                               LR_DEFAULTCOLOR);
#ifdef DEBUG
            assert(h_icon);
#endif
            ImageList_AddIcon(h_ilist, h_icon);
            DestroyIcon(h_icon);

            ListView_SetImageList(hw, h_ilist, LVSIL_STATE);

            ZeroMemory(&lvc, sizeof(lvc));

            lvc.mask = LVCF_TEXT | LVCF_WIDTH;
            GetWindowRect(hw, &r);
            lvc.cx = ((r.right - r.left) * 95) / 100;
            lvc.pszText = buf;

            LoadString(khm_hInstance, IDS_CFG_PI_COL_PLUGINS,
                       buf, ARRAYLENGTH(buf));

            ListView_InsertColumn(hw, 0, &lvc);

            for(i=0; i<d->n_info; i++) {
                LVITEM lvi;

                ZeroMemory(&lvi, sizeof(lvi));

                lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
                lvi.lParam = (LPARAM) d->info[i];
                lvi.pszText = d->info[i]->plugin.reg.name;

                if (d->info[i]->plugin.flags & KMM_PLUGIN_FLAG_DISABLED) {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_DISABLED);
                } else if (d->info[i]->plugin.state < 0) {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_ERROR);
                } else {
                    lvi.state = INDEXTOSTATEIMAGEMASK(IDX_PLUGIN_NORMAL);
                }

                ListView_InsertItem(hw, &lvi);
            }

            d->plugin_ico =
                (HICON) LoadImage(khm_hInstance,
                                  MAKEINTRESOURCE(IDI_CFG_PLUGIN),
                                  IMAGE_ICON,
                                  GetSystemMetrics(SM_CXICON),
                                  GetSystemMetrics(SM_CYICON),
                                  LR_DEFAULTCOLOR);
        }
        return FALSE;

    case WM_NOTIFY:
        {
            LPNMHDR lpnm;
            HWND hw;

            d = (plugin_dlg_data *) (LONG_PTR) 
                GetWindowLongPtr(hwnd, DWLP_USER);
            if (d == NULL)
                return FALSE;

            if (wParam == IDC_CFG_PLUGINS &&
                (lpnm = (LPNMHDR) lParam) &&
                lpnm->code == LVN_ITEMCHANGED) {

                LVITEM lvi;

                hw = GetDlgItem(hwnd, IDC_CFG_PLUGINS);
#ifdef DEBUG
                assert(hw);
#endif
                if (ListView_GetSelectedCount(hw) != 1) {
                    SetDlgItemText(hwnd, IDC_CFG_DESC, L"");
                    SetDlgItemText(hwnd, IDC_CFG_STATE, L"");
                    SetDlgItemText(hwnd, IDC_CFG_MODULE, L"");
                    SetDlgItemText(hwnd, IDC_CFG_VENDOR, L"");
                    SetDlgItemText(hwnd, IDC_CFG_VERSION, L"");
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_ENABLE), FALSE);
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_DISABLE), FALSE);
                    EnableWindow(GetDlgItem(hwnd, IDC_CFG_UNREGISTER), FALSE);
                    SendDlgItemMessage(hwnd, IDC_CFG_DEPS, 
                                       LB_RESETCONTENT, 0, 0);
                    SendDlgItemMessage(hwnd, IDC_CFG_ICON, STM_SETICON,
                                       (WPARAM) d->plugin_ico, 0);
                    d->selected = NULL;
                } else {
                    int idx;
                    plugin_data * info;

                    idx = ListView_GetNextItem(hw, -1, LVNI_SELECTED);
#ifdef DEBUG
                    assert(idx != -1);
#endif
                    ZeroMemory(&lvi, sizeof(lvi));
                    lvi.iItem = idx;
                    lvi.iSubItem = 0;
                    lvi.mask = LVIF_PARAM;

                    ListView_GetItem(hw, &lvi);
#ifdef DEBUG
                    assert(lvi.lParam != 0);
#endif
                    info = (plugin_data *) lvi.lParam;

                    update_dialog_fields(hwnd, d, info);
                }
            }
        }
        return TRUE;

    case WM_COMMAND:
        {

            d = (plugin_dlg_data *) (LONG_PTR)
                GetWindowLongPtr(hwnd, DWLP_USER);
            if (d == NULL)
                return FALSE;

            switch (wParam) {
            case MAKEWPARAM(IDC_CFG_ENABLE, BN_CLICKED):
                if (d->selected != NULL) {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    kmm_plugin p;

                    khui_alert_create_empty(&alert);

                    LoadString(khm_hInstance, IDS_CFG_P_ENBCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_ENBCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_message(alert, buf);

                    khui_alert_set_severity(alert, KHERR_INFO);

                    khui_alert_show_modal(alert);

                    kmm_enable_plugin(d->selected->plugin.h_plugin, TRUE);

                    khui_alert_release(alert);

                    p = d->selected->plugin.h_plugin;
                    kmm_hold_plugin(p);
                    kmm_release_plugin_info_i(&d->selected->plugin);
                    kmm_get_plugin_info_i(p, &d->selected->plugin);
                    kmm_release_plugin(p);

                    update_dialog_fields(hwnd, d, d->selected);
                }
                break;

            case MAKEWPARAM(IDC_CFG_DISABLE, BN_CLICKED):
                if (d->selected != NULL) {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    wchar_t depends[KHUI_MAXCCH_MESSAGE];
                    khm_size i;
                    kmm_plugin p;

                    khui_alert_create_empty(&alert);
#ifdef DEBUG
                    assert(alert);
#endif
                    if (alert == NULL)
                        break;

                    LoadString(khm_hInstance, IDS_CFG_P_DELCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_DELCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, d->selected->plugin.reg.name);
                    khui_alert_set_message(alert, buf);

                    depends[0] = L'\0';

                    for (i=0; i<d->n_info; i++) {
                        wchar_t * t;

                        t = d->info[i]->plugin.reg.dependencies;

                        while(t) {
                            if (!wcscmp(t, d->selected->plugin.reg.name)) {
                                if (depends[0])
                                    StringCbCat(depends, sizeof(depends), L", ");
                                StringCbCat(depends, sizeof(depends),
                                            d->info[i]->plugin.reg.name);
                                break;
                            }
                            t = multi_string_next(t);
                        }
                    }

                    if (depends[0]) {
                        LoadString(khm_hInstance, IDS_CFG_P_DELCNFS,
                                   fmt, ARRAYLENGTH(fmt));
                        StringCbPrintf(buf, sizeof(buf), fmt, depends);
                        khui_alert_set_suggestion(alert, buf);
                    } else {
                        LoadString(khm_hInstance, IDS_CFG_P_DELNDEP,
                                   buf, ARRAYLENGTH(buf));
                        khui_alert_set_suggestion(alert, buf);
                    }

                    khui_alert_add_command(alert, KHUI_PACTION_YES);
                    khui_alert_add_command(alert, KHUI_PACTION_NO);

                    khui_alert_set_severity(alert, KHERR_WARNING);

                    if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) &&
                        alert->response == KHUI_PACTION_YES) {
                        kmm_enable_plugin(d->selected->plugin.h_plugin, FALSE);
                    }

                    khui_alert_release(alert);

                    p = d->selected->plugin.h_plugin;
                    kmm_hold_plugin(p);
                    kmm_release_plugin_info_i(&d->selected->plugin);
                    kmm_get_plugin_info_i(p, &d->selected->plugin);
                    kmm_release_plugin(p);

                    update_dialog_fields(hwnd, d, d->selected);
                }
                break;

            case MAKEWPARAM(IDC_CFG_UNREGISTER, BN_CLICKED):
                {
                    khui_alert * alert = NULL;
                    wchar_t buf[KHUI_MAXCCH_MESSAGE];
                    wchar_t fmt[KHUI_MAXCCH_MESSAGE];
                    wchar_t plist[KHUI_MAXCCH_MESSAGE];
                    khm_size i;

                    if (d->selected == NULL) {
#ifdef DEBUG
                        assert(FALSE);
#endif
                        break;
                    }

                    khui_alert_create_empty(&alert);

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFT,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt,
                                   d->selected->plugin.reg.name);

                    khui_alert_set_title(alert, buf);

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFM,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt,
                                   d->selected->plugin.reg.name);

                    khui_alert_set_message(alert, buf);

                    plist[0] = L'\0';
                    for (i=0; i < d->n_info; i++) {
                        if (!wcscmp(d->info[i]->module.reg.name,
                                    d->selected->module.reg.name)) {
                            if (plist[0])
                                StringCbCat(plist, sizeof(plist), L", ");
                            StringCbCat(plist, sizeof(plist),
                                        d->info[i]->plugin.reg.name);
                        }
                    }

#ifdef DEBUG
                    /* there should have been at least one plugin */
                    assert(plist[0]);
#endif

                    LoadString(khm_hInstance, IDS_CFG_P_UNRCNFS,
                               fmt, ARRAYLENGTH(fmt));
                    StringCbPrintf(buf, sizeof(buf), fmt, plist);
                    khui_alert_set_suggestion(alert, buf);

                    khui_alert_add_command(alert, KHUI_PACTION_YES);
                    khui_alert_add_command(alert, KHUI_PACTION_NO);

                    khui_alert_set_severity(alert, KHERR_WARNING);

                    if (KHM_SUCCEEDED(khui_alert_show_modal(alert)) &&
                        alert->response == KHUI_PACTION_YES) {
                        kmm_unregister_module(d->selected->module.reg.name, 0);

                        update_dialog_fields(hwnd, d, d->selected);
                    }
                }
                break;

            case MAKEWPARAM(IDC_CFG_REGISTER, BN_CLICKED):
                {
                    
                }
                break;
            }
        }
        return TRUE;

    case WM_DESTROY:
        {
            khm_size i;

            d = (plugin_dlg_data *) (LONG_PTR) 
                GetWindowLongPtr(hwnd, DWLP_USER);
#ifdef DEBUG
            assert(d);
#endif
            if (d == NULL)
                return TRUE;

            for (i=0; i<d->n_info; i++) {
#ifdef DEBUG
                assert(d->info[i]);
#endif
                kmm_release_plugin_info_i(&d->info[i]->plugin);
                kmm_release_module_info_i(&d->info[i]->module);
                PFREE(d->info[i]);
            }

            PFREE(d);
            SetWindowLongPtr(hwnd, DWLP_USER, 0);

            khm_set_dialog_result(hwnd, 0);
        }
        return TRUE;
    }
    return FALSE;
}
示例#14
0
KHMEXP khm_int32 KHMAPI
kcdb_identity_set_provider(khm_handle sub)
{
    kmm_plugin plugin = NULL;
    kcdb_identpro_i * p;
    khm_int32 rv = KHM_ERROR_SUCCESS;

    plugin = kmm_this_plugin();
    if (plugin == NULL) {
#ifdef DEBUG
        assert(FALSE);
#endif
        return KHM_ERROR_INVALID_OPERATION;
    }

    p = identpro_find_by_plugin(plugin);
    if (p != NULL && sub != NULL) {
        rv = KHM_ERROR_DUPLICATE;
#ifdef DEBUG
        assert(FALSE);
#endif
        goto _exit;
    }

#ifdef DEBUG
    assert(sub != NULL || p != NULL);
#endif

    if (p == NULL)
        p = identpro_create_with_plugin(plugin, sub);

    if (p == NULL) {
        rv = KHM_ERROR_UNKNOWN;
        goto _exit;
    }

    if (sub) {
        rv = kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_INIT, 0, 0);

        if (KHM_FAILED(rv)) {
            kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_EXIT, 0, 0);
            identpro_mark_for_deletion(p);
        } else {
	    EnterCriticalSection(&cs_identpro);
	    p->flags |= KCDB_IDENTPRO_FLAG_READY;
	    LeaveCriticalSection(&cs_identpro);
	}
    } else {
        EnterCriticalSection(&cs_identpro);
        sub = p->sub;
        LeaveCriticalSection(&cs_identpro);
        kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_EXIT, 0, 0);
        identpro_mark_for_deletion(p);
    }

 _exit:
    if (p)
        identpro_release(p);

    if (plugin)
        kmm_release_plugin(plugin);

    return rv;
}