Beispiel #1
0
void
khm_show_identity_config_pane(khm_handle identity) {
    khui_config_node cfg_ids = NULL;
    khui_config_node cfg_id = NULL;
    wchar_t cfgname[KHUI_MAXCCH_NAME];
    khm_size cb;

    cb = sizeof(cfgname);
    if (KHM_FAILED(kcdb_identity_get_short_name(identity, FALSE, cfgname, &cb)))
        goto exit;

    if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cfg_ids)))
        goto exit;

    if (KHM_FAILED(khui_cfg_open(cfg_ids, cfgname, &cfg_id)))
        goto exit;

    khm_show_config_pane(cfg_id);

 exit:
    if (cfg_id)
        khui_cfg_release(cfg_id);
    if (cfg_ids)
        khui_cfg_release(cfg_ids);
}
Beispiel #2
0
khm_int32
handle_kmsg_system_exit(void)
{
    khui_config_node cnode;
    khui_config_node cn_idents;

    /* It should not be assumed that initialization of the plugin went
       well at this point since we receive a KMSG_SYSTEM_EXIT even if
       the initialization failed. */

    if (credtype_id != KCDB_CREDTYPE_INVALID) {
        kcdb_credtype_unregister(credtype_id);
        credtype_id = KCDB_CREDTYPE_INVALID;
    }

    if (g_credset) {
        kcdb_credset_delete(g_credset);
        g_credset = NULL;
    }

    /* Now unregister any configuration nodes we registered. */

    if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
        khui_cfg_remove(cnode);
        khui_cfg_release(cnode);
    }

    if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
        if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                        CONFIGNODE_ALL_ID,
                                        &cnode))) {
            khui_cfg_remove(cnode);
            khui_cfg_release(cnode);
        }

        if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                        CONFIGNODE_PER_ID,
                                        &cnode))) {
            khui_cfg_remove(cnode);
            khui_cfg_release(cnode);
        }

        khui_cfg_release(cn_idents);
    }

    if (h_idprov_event != NULL) {
	CloseHandle(h_idprov_event);
	h_idprov_event = NULL;
    }

    /* TODO: Perform additional uninitialization operations. */

    return KHM_ERROR_SUCCESS;
}
Beispiel #3
0
static HWND
cfgui_create_config_node_window(HWND hwnd, khui_config_node node) {
    khui_config_node_reg reg;
    khm_int32 rv;
    HWND hw_new;

    khui_config_node parent;

    if (KHM_SUCCEEDED(khui_cfg_get_parent(node, &parent))) {
        HWND hwp;

        hwp = khui_cfg_get_hwnd(parent);

        if (hwp == NULL)
            cfgui_create_config_node_window(hwnd, parent);

        khui_cfg_release(parent);
    }

    rv = khui_cfg_get_reg(node, &reg);
#ifdef DEBUG
    assert(KHM_SUCCEEDED(rv));
#endif
    hw_new = CreateDialogParam(reg.h_module,
                               reg.dlg_template,
                               hwnd,
                               reg.dlg_proc,
                               (LPARAM) node);
#ifdef DEBUG
    assert(hw_new);
#endif
    khui_cfg_set_hwnd(node, hw_new);

    return hw_new;
}
Beispiel #4
0
/* dialog procedure for individual identity configuration nodes */
INT_PTR CALLBACK
khm_cfg_identity_proc(HWND hwnd,
                      UINT uMsg,
                      WPARAM wParam,
                      LPARAM lParam) {
    HWND hw;

    switch(uMsg) {
    case WM_INITDIALOG:
        {
            khui_config_node refnode = NULL;

            set_window_node(hwnd, (khui_config_node) lParam);

            khui_cfg_open(NULL, L"KhmIdentities", &refnode);
#ifdef DEBUG
            assert(refnode != NULL);
#endif
            add_subpanels(hwnd,
                          (khui_config_node) lParam,
                          refnode);

            hw = GetDlgItem(hwnd, IDC_CFG_TAB);

            show_tab_panel(hwnd,
                           (khui_config_node) lParam,
                           hw,
                           TabCtrl_GetCurSel(hw),
                           TRUE);

            khui_cfg_release(refnode);
        }
        return FALSE;

    case WM_DESTROY:
        return 0;

    case KHUI_WM_CFG_NOTIFY:
        return handle_cfg_notify(hwnd, wParam, lParam);

    case WM_NOTIFY:
        return handle_notify(hwnd, wParam, lParam);
    }
    return FALSE;
}
Beispiel #5
0
static void
cfgui_remove_item(HWND hwtv,
                  HTREEITEM hItem) {
    khui_config_node node;
    HTREEITEM hChild;
    TVITEMEX itemex;

    for (hChild = TreeView_GetChild(hwtv, hItem);
         hChild;
         hChild = TreeView_GetChild(hwtv, hItem)) {

        cfgui_remove_item(hwtv, hChild);

    }

    ZeroMemory(&itemex, sizeof(itemex));

    itemex.mask = TVIF_PARAM;
    itemex.hItem = hItem;

    TreeView_GetChild(hwtv, &itemex);

    node = (khui_config_node) itemex.lParam;

    if (node) {
        HWND hw;
        hw = khui_cfg_get_hwnd(node);

        if (hw)
            DestroyWindow(hw);

        khui_cfg_release(node);
    }

    TreeView_DeleteItem(hwtv, hItem);
}
Beispiel #6
0
static void
cfgui_free_node(HWND hwtv, HTREEITEM hItem) {
    TVITEMEX iex;
    HTREEITEM hChItem;

    ZeroMemory(&iex, sizeof(iex));

    iex.mask = TVIF_PARAM;
    iex.hItem = hItem;

    if (TreeView_GetItem(hwtv, &iex)) {
        khui_config_node node;

        node = (khui_config_node) iex.lParam;
        khui_cfg_release(node);
    }

    hChItem = TreeView_GetChild(hwtv, hItem);
    while(hChItem) {
        cfgui_free_node(hwtv, hChItem);

        hChItem = TreeView_GetNextSibling(hwtv, hChItem);
    }
}
Beispiel #7
0
static void
refresh_identity_config_panels(void) {
    khm_handle ident = NULL;
    kcdb_enumeration e = NULL;

    khui_config_node cfg_iter = NULL;
    khui_config_node cfg_ids = NULL;

    if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cfg_ids)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_identity_begin_enum(KCDB_IDENT_FLAG_CONFIG,
                                            KCDB_IDENT_FLAG_CONFIG,
                                            &e, NULL)))
        goto _done_adding;

    while (KHM_SUCCEEDED(kcdb_enum_next(e, &ident))) {
        khui_config_node cfg_id;
        wchar_t cfgname[KCDB_MAXCCH_NAME];
        khm_size cb;

        cb = sizeof(cfgname);
        if (KHM_FAILED(kcdb_identity_get_short_name(ident, FALSE, cfgname, &cb)))
            continue;

        if (KHM_SUCCEEDED(khui_cfg_open(cfg_ids, cfgname, &cfg_id))) {
            /* it's already there */
            khui_cfg_release(cfg_id);
            continue;
        } else {
            khui_config_node_reg reg;
            wchar_t wshort[KHUI_MAXCCH_SHORT_DESC];
            wchar_t wlong[KHUI_MAXCCH_LONG_DESC];

            wchar_t wfmt[KHUI_MAXCCH_NAME];
            wchar_t widname[KHUI_MAXCCH_SHORT_DESC];
            khm_size cb;

            ZeroMemory(&reg, sizeof(reg));

            reg.name = cfgname;
            reg.short_desc = wshort;
            reg.long_desc = wlong;
            reg.h_module = khm_hInstance;
            reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDENTITY);
            reg.dlg_proc = khm_cfg_identity_proc;
            reg.flags = 0;

            cb = sizeof(widname);
            kcdb_get_resource(ident, KCDB_RES_DISPLAYNAME, KCDB_RFS_SHORT,
                              NULL, NULL, widname, &cb);

            LoadString(khm_hInstance, IDS_CFG_IDENTITY_SHORT,
                       wfmt, ARRAYLENGTH(wfmt));
            StringCbPrintf(wshort, sizeof(wshort), wfmt, widname);

            LoadString(khm_hInstance, IDS_CFG_IDENTITY_LONG,
                       wfmt, ARRAYLENGTH(wfmt));
            StringCbPrintf(wlong, sizeof(wlong), wfmt, widname);

            khui_cfg_register(cfg_ids, &reg);

            if (KHM_SUCCEEDED(khui_cfg_open(cfg_ids, cfgname, &cfg_id))) {
                khui_cfg_set_data(cfg_id, ident);
                kcdb_identity_hold(ident);
                khui_cfg_release(cfg_id);
            }
        }
    } /* while enumerating through e */

    kcdb_enum_end(e);

 _done_adding:

    for (khui_cfg_get_first_child(cfg_ids, &cfg_iter);
         cfg_iter;
         khui_cfg_get_next_release(&cfg_iter)) {

        khm_int32 flags = 0;

        ident = khui_cfg_get_data(cfg_iter);

        if (ident == NULL ||
            KHM_FAILED(kcdb_identity_get_flags(ident, &flags)) ||
            (flags & (KCDB_IDENT_FLAG_ACTIVE|
                      KCDB_IDENT_FLAG_CONFIG)) != (KCDB_IDENT_FLAG_ACTIVE |
                                                   KCDB_IDENT_FLAG_CONFIG)) {
            /* this configuration node needs to be removed */

            if (ident)          /* undo the hold done above for for
                                   configuration node data */
                kcdb_identity_release(ident);
            khui_cfg_set_data(cfg_iter, NULL);
            khui_cfg_remove(cfg_iter);
        }
    }

 _cleanup:
    if (cfg_ids) {
        khui_cfg_release(cfg_ids);
    }
}
Beispiel #8
0
static void
cfgui_add_node(cfgui_wnd_data * d,
               HWND hwtv,
               khui_config_node node,
               khui_config_node parent,
               BOOL sorted) {

    khui_config_node_reg reg;
    khui_config_node c;
    wchar_t wbuf[256];
    const wchar_t * short_desc;
    TVINSERTSTRUCT s;
    HTREEITEM hItem;

    if (node) {
        khui_cfg_get_reg(node, &reg);
        short_desc = reg.short_desc;
    } else {
        short_desc = wbuf;
        LoadString(khm_hInstance, IDS_CFG_ROOT_NAME,
                   wbuf, ARRAYLENGTH(wbuf));
        reg.flags = 0;
    }

    ZeroMemory(&s, sizeof(s));

    s.hParent = (node)?
        (HTREEITEM) khui_cfg_get_param(parent):
        TVI_ROOT;

    s.hInsertAfter = (sorted)? TVI_SORT: TVI_FIRST;

    s.itemex.mask =
        TVIF_CHILDREN |
        TVIF_PARAM |
        TVIF_TEXT |
        TVIF_STATE;

    {
        khui_config_node n;

        if (KHM_SUCCEEDED(khui_cfg_get_first_child(node,
                                                   &n))) {
            s.itemex.cChildren = 1;
            s.itemex.state = TVIS_EXPANDED;
            s.itemex.stateMask = TVIS_EXPANDED;
            khui_cfg_release(n);
        } else {
            s.itemex.cChildren = 0;
            s.itemex.state = 0;
            s.itemex.stateMask = TVIS_EXPANDED;
        }

        s.itemex.state |= INDEXTOSTATEIMAGEMASK(d->idx_default);
        s.itemex.stateMask |= TVIS_STATEIMAGEMASK;
    }

    s.itemex.lParam = (LPARAM) node;
    khui_cfg_hold(node);

    s.itemex.pszText = (LPWSTR) short_desc;

    hItem = TreeView_InsertItem(hwtv, &s);

    khui_cfg_set_param(node, (LPARAM) hItem);

    if (KHM_SUCCEEDED(khui_cfg_get_first_child(node,
                                               &c))) {
        do {
            cfgui_add_node(d, hwtv, c, node,
                           !!(reg.flags & KHUI_CNFLAG_SORT_CHILDREN));
        } while (KHM_SUCCEEDED(khui_cfg_get_next_release(&c)));
    }
}
Beispiel #9
0
static void
cfgui_sync_node(cfgui_wnd_data * d,
                HWND hwtv,
                khui_config_node c,
                HTREEITEM hItem) {
    khui_config_node child;
    HTREEITEM hChild;
    struct cfgui_child_info * childinfo = NULL;
    khm_size n_childinfo = 0;
    khm_size nc_childinfo = 0;
    khm_size i;

    /* first, get the list of children from the treeview control */
    for (hChild = TreeView_GetChild(hwtv, hItem);
         hChild;
         hChild = TreeView_GetNextSibling(hwtv, hChild)) {

        if (n_childinfo >= nc_childinfo) {
            nc_childinfo = UBOUNDSS(n_childinfo + 1,
                                    CI_ALLOC_INCR, CI_ALLOC_INCR);
#ifdef DEBUG
            assert(nc_childinfo > n_childinfo);
#endif
            childinfo = PREALLOC(childinfo,
                                 sizeof(*childinfo) * nc_childinfo);
#ifdef DEBUG
            assert(childinfo);
#endif
        }

        ZeroMemory(&childinfo[n_childinfo],
                   sizeof(childinfo[n_childinfo]));

        childinfo[n_childinfo].hItem = hChild;
        childinfo[n_childinfo].checked = FALSE;
        n_childinfo++;
    }

    /* now, go through the list of actual nodes and make sure they
       match up */
    child = NULL;
    for (khui_cfg_get_first_child(c, &child);
         child;
         khui_cfg_get_next_release(&child)) {

        hChild = (HTREEITEM) khui_cfg_get_param(child);

        for (i=0; i < n_childinfo; i++) {
            if (childinfo[i].hItem == hChild)
                break;
        }

        if (i < n_childinfo) {
            childinfo[i].checked = TRUE;
        } else {
            /* add it to the list, so we can create the node in the
               tree view control later. */
            if (n_childinfo >= nc_childinfo) {
                nc_childinfo = UBOUNDSS(n_childinfo + 1,
                                        CI_ALLOC_INCR, CI_ALLOC_INCR);
#ifdef DEBUG
                assert(nc_childinfo > n_childinfo);
#endif
                childinfo = PREALLOC(childinfo,
                                     sizeof(*childinfo) * nc_childinfo);
#ifdef DEBUG
                assert(childinfo);
#endif
            }

            ZeroMemory(&childinfo[n_childinfo],
                       sizeof(childinfo[n_childinfo]));

            childinfo[n_childinfo].node = child;
            khui_cfg_hold(child);
            n_childinfo++;
        }
    }

    /* by this point, the childinfo list contains items of the
       following forms:

       1. childinfo[i].hItem != NULL && childinfo[i].checked == TRUE

          Corresponds to a tree view item that has a matching
          configuration node.  Nothing to do here.

       2. childinfo[i].hItem != NULL && childinfo[i].checked == FALSE

          Corresponds to a tree view item that has no matching
          configuration node.  These should be removed.

       3. childinfo[i].hItem == NULL && childinfo[i].node != NULL

          Corresponds to a configuration node that has no matching
          tree view item.  These nodes should be added.
    */

    /* first do the removals */
    for (i=0; i < n_childinfo; i++) {
        if (childinfo[i].hItem == NULL)
            break;              /* nothing more to see from this point
                                   on */
        if (!childinfo[i].checked) {
            /* remove! */
            cfgui_remove_item(hwtv, childinfo[i].hItem);
        }
    }

    /* continue from where the previous loop left off */
    for (; i < n_childinfo; i++) {
#ifdef DEBUG
        assert(childinfo[i].hItem == NULL);
        assert(childinfo[i].node != NULL);
#endif

        cfgui_add_node(d, hwtv, childinfo[i].node, c, FALSE);

        khui_cfg_release(childinfo[i].node);
        childinfo[i].node = NULL;
    }

    if (childinfo)
        PFREE(childinfo);

    /* finally recurse through to the next level */
    for (hChild = TreeView_GetChild(hwtv, hItem);
         hChild;
         hChild = TreeView_GetNextSibling(hwtv, hChild)) {

        TVITEMEX itemex;

        ZeroMemory(&itemex, sizeof(itemex));

        itemex.mask = TVIF_PARAM;
        itemex.hItem = hChild;

        TreeView_GetItem(hwtv, &itemex);

        if (itemex.lParam) {
            child = (khui_config_node) itemex.lParam;

            cfgui_sync_node(d, hwtv, child, hChild);
        }
    }
}
Beispiel #10
0
void khm_init_config(void) {
    wchar_t wshort[KHUI_MAXCCH_SHORT_DESC];
    wchar_t wlong[KHUI_MAXCCH_LONG_DESC];
    khui_config_node_reg reg;
    khui_config_node node;

    reg.short_desc = wshort;
    reg.long_desc = wlong;
    reg.h_module = khm_hInstance;
    reg.flags = KHUI_CNFLAG_SYSTEM;

    reg.name = L"KhmGeneral";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_GENERAL);
    reg.dlg_proc = khm_cfg_general_proc;
    LoadString(khm_hInstance, IDS_CFG_GENERAL_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_GENERAL_LONG,
               wlong, ARRAYLENGTH(wlong));

    khui_cfg_register(NULL, &reg);

    reg.name = L"KhmAppear";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_APPEAR);
    reg.dlg_proc = khm_cfg_appearance_proc;
    LoadString(khm_hInstance, IDS_CFG_APPEAR_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_APPEAR_LONG,
               wlong, ARRAYLENGTH(wlong));

    khui_cfg_register(NULL, &reg);

    reg.name = L"KhmIdentities";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDENTITIES);
    reg.dlg_proc = khm_cfg_identities_proc;
    LoadString(khm_hInstance, IDS_CFG_IDENTITIES_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_IDENTITIES_LONG,
               wlong, ARRAYLENGTH(wlong));

    khui_cfg_register(NULL, &reg);

    node = NULL;
    khui_cfg_open(NULL, L"KhmIdentities", &node);
    assert(node);

    reg.name = L"KhmIdentitiesTab";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_TAB);
    reg.dlg_proc = khm_cfg_ids_tab_proc;
    LoadString(khm_hInstance, IDS_CFG_IDS_TAB_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_IDS_TAB_LONG,
               wlong, ARRAYLENGTH(wlong));
    reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_SYSTEM;

    khui_cfg_register(node, &reg);

    reg.name = L"KhmIdentitiesTabPlural";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_TAB);
    reg.dlg_proc = khm_cfg_id_tab_proc;
    LoadString(khm_hInstance, IDS_CFG_ID_TAB_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_ID_TAB_LONG,
               wlong, ARRAYLENGTH(wlong));
    reg.flags = KHUI_CNFLAG_INSTANCE | KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_SYSTEM;

    khui_cfg_register(node, &reg);

    reg.flags = KHUI_CNFLAG_SYSTEM;
    khui_cfg_release(node);

    reg.name = L"KhmNotifications";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_NOTIF);
    reg.dlg_proc = khm_cfg_notifications_proc;
    LoadString(khm_hInstance, IDS_CFG_NOTIF_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_NOTIF_LONG,
               wlong, ARRAYLENGTH(wlong));

    khui_cfg_register(NULL, &reg);

    reg.name = L"KhmPlugins";
    reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_PLUGINS);
    reg.dlg_proc = khm_cfg_plugins_proc;
    LoadString(khm_hInstance, IDS_CFG_PLUGINS_SHORT,
               wshort, ARRAYLENGTH(wshort));
    LoadString(khm_hInstance, IDS_CFG_PLUGINS_LONG,
               wlong, ARRAYLENGTH(wlong));

    khui_cfg_register(NULL, &reg);
}
Beispiel #11
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

        /* This is the first message that will be received by a
           plugin.  We use it to perform initialization operations
           such as registering any credential types, data types and
           attributes. */
    case KMSG_SYSTEM_INIT:
        {
            wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
            wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
#ifdef USE_CONFIGURATION_PANELS
            khui_config_node_reg creg;
#endif
            afs_msg_announce announce;

            if (KHM_FAILED(kmq_find_type(AFS_MSG_TYPENAME, &msg_type_afs))) {
                return KHM_ERROR_UNKNOWN;
            }

            /* We must first announce our extension plug-in, so that
               the AFS plug-in will know we exist */
            announce.cbsize = sizeof(announce);
            announce.version = AFS_PLUGIN_VERSION;
            announce.name = MYPLUGIN_NAMEW;

            kmq_create_subscription(handle_AFS_MSG, &announce.sub);

            /* Set to TRUE if we are providing a token acquisition
               method */
            announce.provide_token_acq = TRUE;

            LoadString(hResModule, IDS_TKMETHOD_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            announce.token_acq.short_desc = short_desc;

            LoadString(hResModule, IDS_TKMETHOD_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            announce.token_acq.long_desc = long_desc;

            if (KHM_FAILED(kmq_send_message(msg_type_afs,
                                            AFS_MSG_ANNOUNCE, 0, &announce))) {
                kmq_delete_subscription(announce.sub);
                announce.sub = NULL;

                return KHM_ERROR_UNKNOWN;
            }

            tk_method = announce.token_acq.method_id;

#ifdef USE_CONFIGURATION_PANELS

            /* Register our configuration panels. */

            /* Registering configuration panels is not required for
               extension plug-in.  As such, this bit of code is
               commented out.  However, if you wish to provide a
               configuration panel, you should uncomment this block
               and fill in the stub functions in config_main.c */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_MAIN;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
            creg.dlg_proc = config_dlgproc;
            creg.flags = 0;

            khui_cfg_register(NULL, &creg);
#endif
        }
        break;

        /* This is the last message that will be received by the
           plugin. */
    case KMSG_SYSTEM_EXIT:
        {
            khui_config_node cnode;

            /* It should not be assumed that initialization of the
               plugin went well at this point since we receive a
               KMSG_SYSTEM_EXIT even if the initialization failed. */

            /* Now unregister any configuration nodes we registered. */

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            /* TODO: Perform additional uninitialization
               operations. */
        }
        break;
    }

    return rv;
}
Beispiel #12
0
khm_int32
handle_kmsg_system_init(void)
{
    kcdb_credtype ct;
    wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
    wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
    khui_config_node cnode;
    khui_config_node_reg creg;
    khm_int32 rv;

    assert (h_idprov_event == NULL);

    h_idprov_event = CreateEvent(NULL, TRUE, FALSE, L"Local\\" IDPROV_NAMEW L"Waiter");

    /* First and foremost, we need to register a credential type. */
    ZeroMemory(&ct, sizeof(ct));
    ct.id = KCDB_CREDTYPE_AUTO;
    ct.name = CREDTYPE_NAMEW;
    ct.short_desc = short_desc;
    ct.long_desc = long_desc;

    short_desc[0] = L'\0';
    LoadString(hResModule, IDS_CT_SHORT_DESC,
               short_desc, ARRAYLENGTH(short_desc));

    long_desc[0] = L'\0';
    LoadString(hResModule, IDS_CT_LONG_DESC,
               long_desc, ARRAYLENGTH(long_desc));

    ct.icon = NULL;     /* We skip the icon for now, but you can
                           assign a handle to an icon here.  The icon
                           will be used to represent the credentials
                           type.*/

    kmq_create_subscription(credprov_msg_proc, &ct.sub);

    ct.is_equal = cred_is_equal;

    rv = kcdb_credtype_register(&ct, &credtype_id);
    if (KHM_FAILED(rv))
        return rv;

    /* We create a global credential set that we use in the plug-in
       thread.  This alleviates the need to create one everytime we
       need one. Keep in mind that this should only be used in the
       plug-in thread and should not be touched from the UI thread or
       any other thread. */
    kcdb_credset_create(&g_credset);

    /* Now we register our configuration panels. */

    /* This configuration panel is the one that controls general
       options.  We leave the identity specific and identity defaults
       for other configuration panels. */

    ZeroMemory(&creg, sizeof(creg));

    short_desc[0] = L'\0';

    LoadString(hResModule, IDS_CFG_SHORT_DESC,
               short_desc, ARRAYLENGTH(short_desc));

    long_desc[0] = L'\0';

    LoadString(hResModule, IDS_CFG_LONG_DESC,
               long_desc, ARRAYLENGTH(long_desc));

    creg.name = CONFIGNODE_MAIN;
    creg.short_desc = short_desc;
    creg.long_desc = long_desc;
    creg.h_module = hResModule;
    creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
    creg.dlg_proc = config_dlgproc;
    creg.flags = 0;

    khui_cfg_register(NULL, &creg);

    /* Now we do the identity specific and identity default
       configuration panels. "KhmIdentities" is a predefined
       configuration node under which all the identity spcific
       configuration is managed. */

    if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
        /* this should always work */
        assert(FALSE);
        return KHM_ERROR_NOT_FOUND;
    }

    /* First the tab panel for defaults for all identities */

    ZeroMemory(&creg, sizeof(creg));

    short_desc[0] = L'\0';
    LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
               short_desc, ARRAYLENGTH(short_desc));
    long_desc[0] = L'\0';
    LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
               long_desc, ARRAYLENGTH(long_desc));

    creg.name = CONFIGNODE_ALL_ID;
    creg.short_desc = short_desc;
    creg.long_desc = long_desc;
    creg.h_module = hResModule;
    creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
    creg.dlg_proc = config_ids_dlgproc;
    creg.flags = KHUI_CNFLAG_SUBPANEL;

    khui_cfg_register(cnode, &creg);

    /* Now the panel for per identity configuration */

    ZeroMemory(&creg, sizeof(creg));

    short_desc[0] = L'\0';
    LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
               short_desc, ARRAYLENGTH(short_desc));
    long_desc[0] = L'\0';
    LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
               long_desc, ARRAYLENGTH(long_desc));

    creg.name = CONFIGNODE_PER_ID;
    creg.short_desc = short_desc;
    creg.long_desc = long_desc;
    creg.h_module = hResModule;
    creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
    creg.dlg_proc = config_id_dlgproc;
    creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

    khui_cfg_register(cnode, &creg);

    khui_cfg_release(cnode);

    /* TODO: Perform additional initialization operations. */

    /* TODO: Also list out the credentials of this type that already
       exist. */

    return KHM_ERROR_SUCCESS;
}
Beispiel #13
0
KHMEXP khm_int32 KHMAPI
khui_cfg_register(khui_config_node vparent,
                  const khui_config_node_reg * reg) {

    size_t cb_name;
    size_t cb_short_desc;
    size_t cb_long_desc;
    khui_config_node_i * node;
    khui_config_node_i * parent;
    khui_config_node t;
    wchar_t * name;
    wchar_t * short_desc;
    wchar_t * long_desc;

    cfgui_init_once();

    if (!reg ||
        FAILED(StringCbLength(reg->name,
                              KHUI_MAXCB_NAME,
                              &cb_name)) ||
        FAILED(StringCbLength(reg->short_desc,
                              KHUI_MAXCB_SHORT_DESC,
                              &cb_short_desc)) ||
        FAILED(StringCbLength(reg->long_desc,
                              KHUI_MAXCB_LONG_DESC,
                              &cb_long_desc)) ||
        (vparent &&
         !cfgui_is_valid_node_handle(vparent)))
        return KHM_ERROR_INVALID_PARAM;

    if (KHM_SUCCEEDED(khui_cfg_open(vparent,
                                  reg->name,
                                  &t))) {
        khui_cfg_release(t);
        return KHM_ERROR_DUPLICATE;
    }

    cb_name += sizeof(wchar_t);
    cb_short_desc += sizeof(wchar_t);
    cb_long_desc += sizeof(wchar_t);

    node = cfgui_create_new_node();

    node->reg = *reg;
    node->reg.flags &= KHUI_CNFLAGMASK_STATIC;

    name = PMALLOC(cb_name);
    StringCbCopy(name, cb_name, reg->name);
    short_desc = PMALLOC(cb_short_desc);
    StringCbCopy(short_desc, cb_short_desc, reg->short_desc);
    long_desc = PMALLOC(cb_long_desc);
    StringCbCopy(long_desc, cb_long_desc, reg->long_desc);

    node->reg.name = name;
    node->reg.short_desc = short_desc;
    node->reg.long_desc = long_desc;
    node->flags = node->reg.flags;

    if (vparent == NULL) {
        parent = cfgui_root_config;
    } else {
        parent = cfgui_node_i_from_handle(vparent);
    }

    /* plugin handles should not be obtained lightly.  For the moment,
       the cleanup of nodes doesn't happen until module unload and
       module unload doesn't happen until all the plugin and module
       handles have been freed. */
    /* node->owner = kmm_this_plugin(); */

    EnterCriticalSection(&cs_cfgui);
    TADDCHILD(parent, node);

    if (hwnd_cfgui) {
        SendMessage(hwnd_cfgui, KHUI_WM_CFG_NOTIFY,
                    MAKEWPARAM(0, WMCFG_SYNC_NODE_LIST), 0);
    }

    LeaveCriticalSection(&cs_cfgui);

    /* when the root config list changes, we need to notify the UI.
       this way, the Options menu can be kept in sync. */
    if (parent == cfgui_root_config) {
        kmq_post_message(KMSG_ACT, KMSG_ACT_SYNC_CFG, 0, 0);
    }

    return KHM_ERROR_SUCCESS;
}
Beispiel #14
0
LRESULT CALLBACK
khm_main_wnd_proc(HWND hwnd,
                  UINT uMsg,
                  WPARAM wParam,
                  LPARAM lParam)
{
    LPNMHDR lpnm;

    switch(uMsg) {
    case WM_CREATE:
        khm_create_main_window_controls(hwnd);
        kmq_subscribe_hwnd(KMSG_CRED, hwnd);
        kmq_subscribe_hwnd(KMSG_ACT, hwnd);
        kmq_subscribe_hwnd(KMSG_KMM, hwnd);
        mw_restart_refresh_timer(hwnd);

        /* if the plug-ins finished loading before the window was
           created, we would have missed the KMSG_KMM_I_DONE message.
           So we check if the module load is complete and if so, fire
           off KMSG_ACT_BEGIN_CMDLINE. */
        if (!kmm_load_pending())
            kmq_post_message(KMSG_ACT, KMSG_ACT_BEGIN_CMDLINE, 0, 0);
        break;

    case WM_DESTROY:
        khm_pre_shutdown();
        kmq_unsubscribe_hwnd(KMSG_ACT, hwnd);
        kmq_unsubscribe_hwnd(KMSG_CRED, hwnd);
        kmq_unsubscribe_hwnd(KMSG_KMM, hwnd);
        HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0);
        PostQuitMessage(0);
        break;

    case WM_NOTIFY:
        lpnm = (LPNMHDR) lParam;
        if(lpnm->hwndFrom == khui_main_menu_toolbar) {
            return khm_menu_notify_main(lpnm);
        } else if(lpnm->hwndFrom == khui_hwnd_standard_toolbar) {
            return khm_toolbar_notify(lpnm);
        } else if(lpnm->hwndFrom == khm_hwnd_rebar) {
            return khm_rebar_notify(lpnm);
        } else if(lpnm->hwndFrom == khm_hwnd_statusbar) {
            return khm_statusbar_notify(lpnm);
        }
        break;

    case WM_HELP:
        khm_html_help(khm_hwnd_main, NULL, HH_HELP_CONTEXT, IDH_WELCOME);
        break;

    case WM_COMMAND:
        switch(LOWORD(wParam)) {
            /* general actions */
        case KHUI_ACTION_VIEW_REFRESH:
            khm_cred_refresh();
            InvalidateRect(khm_hwnd_main_cred, NULL, FALSE);
            return 0;

        case KHUI_ACTION_PASSWD_ID:
            if (khm_startup.processing)
                return 0;

            khm_cred_change_password(NULL);
            return 0;

        case KHUI_ACTION_NEW_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_obtain_new_creds(NULL);
            return 0;

        case KHUI_ACTION_RENEW_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_renew_creds();
            return 0;

        case KHUI_ACTION_DESTROY_CRED:
            if (khm_startup.processing)
                return 0;

            khm_cred_destroy_creds(FALSE, FALSE);
            return 0;

        case KHUI_ACTION_SET_DEF_ID:
            if (khm_startup.processing)
                return 0;

            khm_cred_set_default();
            return 0;

        case KHUI_ACTION_EXIT:
            DestroyWindow(hwnd);
            return 0;

        case KHUI_ACTION_OPEN_APP:
            khm_show_main_window();
            return 0;

        case KHUI_ACTION_CLOSE_APP:
            khm_hide_main_window();
            return 0;

        case KHUI_ACTION_OPT_KHIM: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmGeneral", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_IDENTS: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmIdentities", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_APPEAR: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmAppear", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_NOTIF: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmNotifications", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_OPT_PLUGINS: {
            khui_config_node node = NULL;

            khui_cfg_open(NULL, L"KhmPlugins", &node);
            khm_show_config_pane(node);
        }
            return 0;

        case KHUI_ACTION_HELP_CTX:
            khm_html_help(khm_hwnd_main, NULL, HH_HELP_CONTEXT, IDH_WELCOME);
            return 0;

        case KHUI_ACTION_HELP_CONTENTS:
            khm_html_help(khm_hwnd_main, NULL, HH_DISPLAY_TOC, 0);
            return 0;

        case KHUI_ACTION_HELP_INDEX:
            khm_html_help(khm_hwnd_main, NULL, HH_DISPLAY_INDEX, (DWORD_PTR) L"");
            return 0;

        case KHUI_ACTION_HELP_ABOUT:
            khm_create_about_window();
            return 0;

        case KHUI_ACTION_IMPORT:
            khm_cred_import();
            return 0;

        case KHUI_ACTION_PROPERTIES:
            /* properties are not handled by the main window.
               Just bounce it to credwnd.  However, use SendMessage
               instead of PostMessage so we don't lose context */
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_UICB:
            khm_ui_cb(lParam);
            return 0;

            /* layout control */

        case KHUI_ACTION_VIEW_ALL_IDS:
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_MINI:

            if (khm_main_wnd_mode == KHM_MAIN_WND_MINI) {
                khm_set_main_window_mode(KHM_MAIN_WND_NORMAL);
            } else {
                khm_set_main_window_mode(KHM_MAIN_WND_MINI);
            }
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_RELOAD:
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        case KHUI_ACTION_LAYOUT_ID:
        case KHUI_ACTION_LAYOUT_TYPE:
        case KHUI_ACTION_LAYOUT_LOC:
        case KHUI_ACTION_LAYOUT_CUST:
            khm_set_main_window_mode(KHM_MAIN_WND_NORMAL);
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

            /* menu commands */
        case KHUI_PACTION_MENU:
            if(HIWORD(lParam) == 1)
                mm_last_hot_item = LOWORD(lParam);
            return khm_menu_activate(MENU_ACTIVATE_DEFAULT);

        case KHUI_PACTION_ESC:
            /* if esc is pressed while no menu is active, we close the
               main window */
            if (mm_last_hot_item == -1) {
                khm_close_main_window();
                return 0;
            }

            /* generic, retargetting */
        case KHUI_PACTION_UP:
        case KHUI_PACTION_UP_TOGGLE:
        case KHUI_PACTION_UP_EXTEND:
        case KHUI_PACTION_PGUP:
        case KHUI_PACTION_PGUP_EXTEND:
        case KHUI_PACTION_DOWN:
        case KHUI_PACTION_DOWN_TOGGLE:
        case KHUI_PACTION_DOWN_EXTEND:
        case KHUI_PACTION_PGDN:
        case KHUI_PACTION_PGDN_EXTEND:
        case KHUI_PACTION_LEFT:
        case KHUI_PACTION_RIGHT:
        case KHUI_PACTION_ENTER:
            /* menu tracking */
            if(mm_last_hot_item != -1) {
                switch(LOWORD(wParam)) {
                case KHUI_PACTION_LEFT:
                    khm_menu_activate(MENU_ACTIVATE_LEFT);
                    break;

                case KHUI_PACTION_RIGHT:
                    khm_menu_activate(MENU_ACTIVATE_RIGHT);
                    break;

                case KHUI_PACTION_ESC:
                case KHUI_PACTION_ENTER:
                    khm_menu_activate(MENU_ACTIVATE_NONE);
                    break;

                case KHUI_PACTION_DOWN:
                    khm_menu_track_current();
                    break;
                }
                return 0;
            }

            /*FALLTHROUGH*/
        case KHUI_PACTION_DELETE:

        case KHUI_PACTION_SELALL:
            /* otherwise fallthrough and bounce to the creds window */
            return SendMessage(khm_hwnd_main_cred, uMsg,
                               wParam, lParam);

        default:
            /* handle custom actions here */
            {
                khui_action * act;

                /* check if this is an identity menu action.  (custom
                   actions that were created for renewing or
                   destroying specific identities). */
                if (khm_check_identity_menu_action(LOWORD(wParam)))
                    break;

                act = khui_find_action(LOWORD(wParam));
                if (act && act->listener) {
                    kmq_post_sub_msg(act->listener, KMSG_ACT, KMSG_ACT_ACTIVATE, act->cmd, NULL);
                    return 0;
                }
            }
        }
        break;              /* WM_COMMAND */

    case WM_SYSCOMMAND:
        switch(wParam & 0xfff0) {
        case SC_MINIMIZE:
            khm_hide_main_window();
            return 0;

        case SC_CLOSE:
            khm_close_main_window();
            return 0;
        }
        break;

    case WM_MEASUREITEM:
        /* sent to measure the bitmaps associated with a menu item */
        if(!wParam) /* sent by menu */
            return khm_menu_measure_item(wParam, lParam);
        break;

    case WM_DRAWITEM:
        /* sent to draw a menu item */
        if(!wParam)
            return khm_menu_draw_item(wParam, lParam);
        break;

    case WM_ERASEBKGND:
        /* Don't erase the background.  The whole client area is
           covered with children.  It doesn't need to be erased */
        return TRUE;
        break;

    case WM_SIZE:
        if(hwnd == khm_hwnd_main &&
           (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED)) {
            int cwidth, cheight;
            RECT r_rebar, r_status;

            cwidth = LOWORD(lParam);
            cheight = HIWORD(lParam);

            /* resize the rebar control */
            SendMessage(khm_hwnd_rebar, WM_SIZE, 0, 0);

            khm_update_statusbar(hwnd);

            GetWindowRect(khm_hwnd_rebar, &r_rebar);
            GetWindowRect(khm_hwnd_statusbar, &r_status);

            /* the cred window fills the area between the rebar
               and the status bar */
            MoveWindow(khm_hwnd_main_cred, 0,
                       r_rebar.bottom - r_rebar.top,
                       r_status.right - r_status.left,
                       r_status.top - r_rebar.bottom, TRUE);

            SetTimer(hwnd,
                     MW_RESIZE_TIMER,
                     MW_RESIZE_TIMEOUT,
                     NULL);
            return 0;
        }
        break;

    case WM_MOVE:
        {
            SetTimer(hwnd,
                     MW_RESIZE_TIMER,
                     MW_RESIZE_TIMEOUT,
                     NULL);

            return 0;
        }
        break;

    case WM_MOVING:
        {
            RECT * r;

            r = (RECT *) lParam;
            khm_adjust_window_dimensions_for_display(r,
                                                     KHM_DOCK_AUTO | KHM_DOCKF_XBORDER);
        }
        return TRUE;

    case WM_TIMER:
        if (wParam == MW_RESIZE_TIMER) {
            main_wnd_save_sizepos();

            return 0;

        } else if (wParam == MW_REFRESH_TIMER) {
            kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

            return 0;

        }
        break;

    case WM_MENUSELECT:
        return khm_menu_handle_select(wParam, lParam);

    case KMQ_WM_DISPATCH:
        {
            kmq_message * m;
            khm_int32 rv = KHM_ERROR_SUCCESS;

            kmq_wm_begin(lParam, &m);
            if (m->type == KMSG_ACT &&
                m->subtype == KMSG_ACT_REFRESH) {
                khm_menu_refresh_items();
                khm_update_standard_toolbar();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_BEGIN_CMDLINE) {
                khm_cred_begin_startup_actions();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_CONTINUE_CMDLINE) {
                khm_cred_process_startup_actions();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_END_CMDLINE) {
                /* nothing yet */
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_SYNC_CFG) {
                khm_refresh_config();
            } else if (m->type == KMSG_ACT &&
                       m->subtype == KMSG_ACT_ACTIVATE) {
                /* some custom action fired */

                khm_int32 action;
                khui_action * paction;

                action = m->uparam;
                paction = khui_find_action(action);
                if (paction && paction->data == (void *) CFGACTION_MAGIC) {
                    /* a custom configuration needs to be invoked */
                    khui_config_node node;

                    if (KHM_SUCCEEDED(khui_cfg_open(NULL, paction->name, &node))) {
                        khm_show_config_pane(node);
                        khui_cfg_release(node);
                    }
                }
            } else if (m->type == KMSG_CRED &&
                  m->subtype == KMSG_CRED_REFRESH) {
                mw_restart_refresh_timer(hwnd);
            } else if (m->type == KMSG_CRED &&
                       m->subtype == KMSG_CRED_ADDR_CHANGE) {
                khm_cred_addr_change();
            } else if (m->type == KMSG_CRED &&
                       m->subtype == KMSG_CRED_ROOTDELTA) {
                khm_refresh_identity_menus();
            } else if (m->type == KMSG_KMM &&
                       m->subtype == KMSG_KMM_I_DONE) {
                kmq_post_message(KMSG_ACT, KMSG_ACT_BEGIN_CMDLINE, 0, 0);
            }

            return kmq_wm_end(m, rv);
        }

    case WM_KHUI_ASSIGN_COMMANDLINE_V1:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];
            khm_startup_options_v1 * pv1opt;
            int code = KHM_ERROR_SUCCESS;

            StringCbPrintf(mapname, sizeof(mapname),
                           COMMANDLINE_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_READ, FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0,
                                 sizeof(*pv1opt));

            if (xfer) {
                pv1opt = (khm_startup_options_v1 *) xfer;

                khm_startup.init = pv1opt->init;
                khm_startup.import = pv1opt->import;
                khm_startup.renew = pv1opt->renew;
                khm_startup.destroy = pv1opt->destroy;

                khm_startup.autoinit = pv1opt->autoinit;
                khm_startup.error_exit = FALSE;

                khm_startup.no_main_window = FALSE;
                khm_startup.remote_exit = FALSE;
                khm_startup.display = 0;

                UnmapViewOfFile(xfer);
            } else {
                code = KHM_ERROR_NOT_FOUND;
            }

            CloseHandle(hmap);

            if(InSendMessage())
                ReplyMessage(code);

            if (code == KHM_ERROR_SUCCESS) {
                khm_startup.exit = FALSE;

                khm_startup.seen = FALSE;
                khm_startup.remote = TRUE;
#ifdef DEBUG
                assert(!khm_startup.processing);
#endif
                khm_startup.processing = FALSE;

                khm_cred_begin_startup_actions();
            }

            return code;
        }

    case WM_KHUI_ASSIGN_COMMANDLINE_V2:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];
            khm_startup_options_v2 *pv2opt = NULL;
            khm_startup_options_v3 *pv3opt = NULL;
            int code = KHM_ERROR_SUCCESS;

            StringCbPrintf(mapname, sizeof(mapname),
                           COMMANDLINE_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_WRITE, FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0,
                                 sizeof(*pv2opt));

            if (xfer) {
                pv2opt = (khm_startup_options_v2 *) xfer;

                if (pv2opt->magic != STARTUP_OPTIONS_MAGIC ||
                    (pv2opt->cb_size != sizeof(*pv2opt) &&
                     pv2opt->cb_size != sizeof(*pv3opt))) {
                    code = KHM_ERROR_INVALID_PARAM;
                    goto done_with_v2_opt;
                }

                khm_startup.init = pv2opt->init;
                khm_startup.import = pv2opt->import;
                khm_startup.renew = pv2opt->renew;
                khm_startup.destroy = pv2opt->destroy;

                khm_startup.autoinit = pv2opt->autoinit;
                khm_startup.exit = pv2opt->remote_exit;

                pv2opt->code = KHM_ERROR_SUCCESS;

                if (pv2opt->cb_size == sizeof(*pv3opt)) {
                    pv3opt = (khm_startup_options_v3 *) xfer;

                    khm_startup.display = pv3opt->remote_display;
                } else {
                    khm_startup.display = 0;
                }

            done_with_v2_opt:
                UnmapViewOfFile(xfer);
            } else {
                code = KHM_ERROR_NOT_FOUND;
            }

            CloseHandle(hmap);

            if(InSendMessage())
                ReplyMessage(code);

            if (code == KHM_ERROR_SUCCESS) {
                khm_startup.seen = FALSE;
                khm_startup.remote = TRUE;
#ifdef DEBUG
                assert(!khm_startup.processing);
#endif
                khm_startup.processing = FALSE;

                khm_cred_begin_startup_actions();
            }

            return code;
        }

    case WM_KHUI_QUERY_APP_VERSION:
        {
            HANDLE hmap;
            void * xfer;
            wchar_t mapname[256];

            StringCbPrintf(mapname, sizeof(mapname),
                           QUERY_APP_VER_MAP_FMT, (DWORD) lParam);

            hmap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE,
                                   FALSE, mapname);

            if (hmap == NULL)
                return 1;

            xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0,
                                 sizeof(khm_query_app_version));

            if (xfer) {
                khm_process_query_app_ver((khm_query_app_version *) xfer);

                UnmapViewOfFile(xfer);
            }

            CloseHandle(hmap);
        }
        return 0;

    }
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
Beispiel #15
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

    /* This is the first message that will be received by a
       plugin.  We use it to perform initialization operations
       such as registering any credential types, data types and
       attributes. */
    case KMSG_SYSTEM_INIT:
    {
        kcdb_credtype ct;
        wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
        wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
        khui_config_node cnode;
        khui_config_node_reg creg;

        /* First and foremost, we need to register a credential
           type. */
        ZeroMemory(&ct, sizeof(ct));
        ct.id = KCDB_CREDTYPE_AUTO;
        ct.name = MYCREDTYPE_NAMEW;

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CT_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));

        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CT_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        ct.icon = NULL;     /* We skip the icon for now, but you
                               can assign a handle to an icon
                               here.  The icon will be used to
                               represent the credentials type.*/

        kmq_create_subscription(plugin_msg_proc, &ct.sub);

        ct.is_equal = cred_is_equal;

        rv = kcdb_credtype_register(&ct, &credtype_id);

        /* We create a global credential set that we use in the
           plug-in thread.  This alleviates the need to create one
           everytime we need one. Keep in mind that this should
           only be used in the plug-in thread and should not be
           touched from the UI thread or any other thread. */
        kcdb_credset_create(&g_credset);

        /* TODO: Perform additional initialization operations. */

        /* TODO: Also list out the credentials of this type that
           already exist. */

        /* Now we register our configuration panels. */


        /* This configuration panel is the one that controls
           general options.  We leave the identity specific and
           identity defaults for other configuration panels. */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';

        LoadString(hResModule, IDS_CFG_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));

        long_desc[0] = L'\0';

        LoadString(hResModule, IDS_CFG_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_MAIN;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
        creg.dlg_proc = config_dlgproc;
        creg.flags = 0;

        khui_cfg_register(NULL, &creg);

        /* Now we do the identity specific and identity default
           configuration panels. "KhmIdentities" is a predefined
           configuration node under which all the identity spcific
           configuration is managed. */

        if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
            /* this should always work */
            assert(FALSE);
            rv = KHM_ERROR_NOT_FOUND;
            break;
        }

        /* First the tab panel for defaults for all identities */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));
        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_ALL_ID;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
        creg.dlg_proc = config_ids_dlgproc;
        creg.flags = KHUI_CNFLAG_SUBPANEL;

        khui_cfg_register(cnode, &creg);

        /* Now the panel for per identity configuration */

        ZeroMemory(&creg, sizeof(creg));

        short_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
                   short_desc, ARRAYLENGTH(short_desc));
        long_desc[0] = L'\0';
        LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
                   long_desc, ARRAYLENGTH(long_desc));

        creg.name = CONFIGNODE_PER_ID;
        creg.short_desc = short_desc;
        creg.long_desc = long_desc;
        creg.h_module = hResModule;
        creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
        creg.dlg_proc = config_id_dlgproc;
        creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

        khui_cfg_register(cnode, &creg);

        khui_cfg_release(cnode);

        /* get IdentProvider handle to which this plugin belongs
           it is possible to use kcdb_identity_create_ex() function with
           proper h_idprov */
        if (KHM_FAILED(kcdb_identpro_find(IDPROV_NAMEW, &h_idprov))) {
            return KHM_ERROR_UNKNOWN;
        }
    }
    break;

    /* This is the last message that will be received by the
       plugin. */
    case KMSG_SYSTEM_EXIT:
    {
        khui_config_node cnode;
        khui_config_node cn_idents;

        /* It should not be assumed that initialization of the
           plugin went well at this point since we receive a
           KMSG_SYSTEM_EXIT even if the initialization failed. */

        if (credtype_id != KCDB_CREDTYPE_INVALID) {
            kcdb_credtype_unregister(credtype_id);
            credtype_id = KCDB_CREDTYPE_INVALID;
        }

        if (g_credset) {
            kcdb_credset_delete(g_credset);
            g_credset = NULL;
        }

        /* Now unregister any configuration nodes we registered. */

        if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
            khui_cfg_remove(cnode);
            khui_cfg_release(cnode);
        }

        if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
            if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                            CONFIGNODE_ALL_ID,
                                            &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                            CONFIGNODE_PER_ID,
                                            &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            khui_cfg_release(cn_idents);
        }

        /* TODO: Perform additional uninitialization
           operations. */

        kcdb_identpro_release(h_idprov);
    }
    break;
    }

    return rv;
}
Beispiel #16
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

        /* This is the first message that will be received by a
           plugin.  We use it to perform initialization operations
           such as registering any credential types, data types and
           attributes. */
    case KMSG_SYSTEM_INIT:
        {
            kcdb_credtype ct;
            wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
            wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
            khui_config_node cnode;
            khui_config_node_reg creg;
            kcdb_attrib attr;
            khm_handle csp_plugin = NULL;
            khm_handle csp_plugins = NULL;

#ifdef BUILD_KRBCOMPAT
            /* If we don't have a Kerberos backend, then we can't
             * function. */
            if (!DelayLoadHeimdal()) {
		_reportf("Can't initialize a Kerberos backend.  LastError=%d", GetLastError());
                return KHM_ERROR_NOT_FOUND;
            }
#endif

#if KH_VERSION_API < 12

            do {
                khm_version libver;
                khm_ui_4 apiver;

                khm_get_lib_version(&libver, &apiver);

                if (apiver < 7)
                    break;

                hm_netidmgr = LoadLibrary(NIMDLLNAME);

                if (hm_netidmgr == NULL)
                    break;

#if KH_VERSION_API < 7
                pkhui_action_lock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_lock);
                pkhui_action_unlock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_unlock);
                pkhui_refresh_actions = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_refresh_actions);
                pkhui_request_UI_callback = (khm_int32 (KHMAPI *)(khm_ui_callback, void *))
                    GetProcAddress(hm_netidmgr, API_khui_request_UI_callback);
#endif
                pkhui_cw_get_primary_id = (khm_int32 (KHMAPI *)(khui_new_creds *, khm_handle *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_primary_id);
                pkhui_cw_get_result = (khm_int32 (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_result);
                pkhui_cw_get_subtype = (khui_nc_subtype (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_subtype);
                pkhui_cw_get_ctx = (khui_action_context * (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_ctx);
                pkcdb_get_resource = (khm_int32 (KHMAPI *)(khm_handle, kcdb_resource_id,
                                                           khm_int32, khm_int32 *,
                                                           void *, void *, khm_size *))
                    GetProcAddress(hm_netidmgr, API_kcdb_get_resource);
            } while (FALSE);

            if (pkhui_cw_get_primary_id == NULL)
              pkhui_cw_get_primary_id = int_khui_cw_get_primary_id;

            if (pkhui_cw_get_result == NULL)
                pkhui_cw_get_result = int_khui_cw_get_result;

            if (pkhui_cw_get_subtype == NULL)
                pkhui_cw_get_subtype = int_khui_cw_get_subtype;

            if (pkhui_cw_get_ctx == NULL)
                pkhui_cw_get_ctx = int_khui_cw_get_ctx;

            if (pkcdb_get_resource == NULL)
                pkcdb_get_resource = int_kcdb_get_resource;
#endif

            /* Add the icon now.  On NIM v2.x, doing so after tokens
               were reported may result in a deadlock as we try to
               switch to the UI thread and the UI thread is blocked on
               a resource request to this plug-in. */
            kca_icon_set_state(NULL);

            /* First and foremost, we need to register a credential
               type. */
            ZeroMemory(&ct, sizeof(ct));
            ct.id = KCDB_CREDTYPE_AUTO;
            ct.name = MYCREDTYPE_NAMEW;
            ct.short_desc = short_desc;
            ct.long_desc = long_desc;

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            ct.icon = NULL;     /* We skip the icon for now, but you
                                   can assign a handle to an icon
                                   here.  The icon will be used to
                                   represent the credentials type.*/

            kmq_create_subscription(plugin_msg_proc, &ct.sub);

            ct.is_equal = cred_is_equal;

            rv = kcdb_credtype_register(&ct, &credtype_id);

            /* We create a global credential set that we use in the
               plug-in thread.  This alleviates the need to create one
               everytime we need one. Keep in mind that this should
               only be used in the plug-in thread and should not be
               touched from the UI thread or any other thread. */
            kcdb_credset_create(&g_credset);

            /* TODO: Perform additional initialization operations. */

            /* Register our attributes */

            ZeroMemory(&attr, sizeof(attr));

            attr.name = ATTRNAME_KCA_AUTHREALM;
            attr.id = KCDB_ATTR_INVALID;
            attr.alt_id = KCDB_ATTR_INVALID;
            attr.flags = 0;
            attr.type = KCDB_TYPE_STRING;
            attr.short_desc = short_desc;
            attr.long_desc = long_desc;
            attr.compute_cb = NULL;
            attr.compute_min_cbsize = 0;
            attr.compute_max_cbsize = 0;

            LoadString(hResModule, IDS_ATTR_REALM_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_REALM_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_auth_realm);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_EMAIL;

            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_email);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_DISPLAY;

            LoadString(hResModule, IDS_ATTR_SUBJECT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_DISPLAY;

            LoadString(hResModule, IDS_ATTR_ISSUER_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_ISSUER_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_NAME;
            attr.flags = KCDB_ATTR_FLAG_HIDDEN;
            attr.type = KCDB_TYPE_DATA;
            attr.short_desc = NULL;
            attr.long_desc = NULL;

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_name);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SERIAL;

            rv = kcdb_attrib_register(&attr, &attr_id_serial_number);
            if (KHM_FAILED(rv))
                break;

            /* List the credentials that are already here */
            kca_list_creds();

            /* Now we register our configuration panels. */

#ifdef GENERAL_CONFIG_PANEL
            /* This configuration panel is the one that controls
               general options.  We leave the identity specific and
               identity defaults for other configuration panels. */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_MAIN;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
            creg.dlg_proc = config_dlgproc;
            creg.flags = 0;

            khui_cfg_register(NULL, &creg);
#endif

            /* Now we do the identity specific and identity default
               configuration panels. "KhmIdentities" is a predefined
               configuration node under which all the identity spcific
               configuration is managed. */

            if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
                /* this should always work */
                assert(FALSE);
                rv = KHM_ERROR_NOT_FOUND;
                break;
            }

            /* First the tab panel for defaults for all identities */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_ALL_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
            creg.dlg_proc = config_ids_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL;

            khui_cfg_register(cnode, &creg);

            /* Now the panel for per identity configuration */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_PER_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
            creg.dlg_proc = config_id_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

            khui_cfg_register(cnode, &creg);

            khui_cfg_release(cnode);

            /* load the schema */
            if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
                khc_load_schema(csp_plugins, plugin_schema);
                khc_close_space(csp_plugins);
            }

            /* open the plug-in and parameter configuration spaces */
            if (KHM_SUCCEEDED(kmm_get_plugin_config(MYPLUGIN_NAMEW,
                                                    KHM_FLAG_CREATE,
                                                    &csp_plugin))) {
                khc_open_space(csp_plugin, L"Parameters", KHM_FLAG_CREATE,
                               &csp_params);

                khc_close_space(csp_plugin);
            }

            /* try to install the kpkcs11 plugin now */
            install_kpkcs11_plugin();

            /* register the "KCA Help" menu item, so that we can add
               the plug-in menu item to the Help menu. */
            {
                khm_handle h_sub = NULL;

#if KH_VERSION_API < 7

                if (pkhui_action_lock == NULL ||
                    pkhui_action_unlock == NULL ||
                    pkhui_refresh_actions == NULL ||
                    pkhui_request_UI_callback == NULL)

                    goto no_custom_help;

#endif

                kmq_create_subscription(plugin_msg_proc, &h_sub);

                LoadString(hResModule, IDS_ACTION_KCA_HELP,
                           short_desc, ARRAYLENGTH(short_desc));
                LoadString(hResModule, IDS_ACTION_KCA_HELP_TT,
                           long_desc, ARRAYLENGTH(long_desc));

                action_id_kca_help = khui_action_create(NULL,
                                                        short_desc,
                                                        long_desc,
                                                        NULL,
                                                        KHUI_ACTIONTYPE_TRIGGER,
                                                        h_sub);

                if (action_id_kca_help != 0) {
                    khm_size s;
                    khm_size i;
                    khui_menu_def * help_menu;
                    khm_boolean refresh = FALSE;

                    khui_action_lock();

                    help_menu = khui_find_menu(KHUI_MENU_HELP);
                    if (help_menu) {
                        s = khui_menu_get_size(help_menu);

                        for (i=0; i < s; i++) {
                            khui_action_ref * aref;

                            aref = khui_menu_get_action(help_menu, i);

                            if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                                aref->action == KHUI_ACTION_HELP_INDEX) {

                                khui_menu_insert_action(help_menu,
                                                        i + 1,
                                                        action_id_kca_help,
                                                        0);
                                refresh = TRUE;
                                break;
                            }
                        }
                    }

                    khui_action_unlock();

                    if (refresh)
                        khui_refresh_actions();
                }

#if KH_VERSION_API < 7
            no_custom_help:
                ;
#endif
            }
        }
        break;

        /* This is the last message that will be received by the
           plugin. */
    case KMSG_SYSTEM_EXIT:
        {
            khui_config_node cnode;
            khui_config_node cn_idents;
            khm_int32 attr_id;

            kca_remove_icon();

            /* It should not be assumed that initialization of the
               plugin went well at this point since we receive a
               KMSG_SYSTEM_EXIT even if the initialization failed. */

            /* Try to remove the KCA plug-in action from Help menu if
               it was successfully registered.  Also, delete the
               action. */
            if (action_id_kca_help != 0) {

                khui_menu_def * help_menu;
                khm_boolean menu_changed = FALSE;

                khui_action_lock();

                help_menu = khui_find_menu(KHUI_MENU_HELP);
                if (help_menu) {
                    khm_size s;
                    khm_size i;

                    s = khui_menu_get_size(help_menu);
                    for (i=0; i < s; i++) {
                        khui_action_ref * aref = khui_menu_get_action(help_menu, i);

                        if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                            aref->action == action_id_kca_help) {

                            khui_menu_remove_action(help_menu, i);
                            menu_changed = TRUE;
                            break;

                        }
                    }
                }

                khui_action_delete(action_id_kca_help);

                khui_action_unlock();

                if (menu_changed)
                    khui_refresh_actions();

                action_id_kca_help = 0;
            }

            if (credtype_id != KCDB_CREDTYPE_INVALID) {
                kcdb_credtype_unregister(credtype_id);
                credtype_id = KCDB_CREDTYPE_INVALID;
            }

            if (g_credset) {
                kcdb_credset_delete(g_credset);
                g_credset = NULL;
            }

            /* Now unregister any configuration nodes we registered. */

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_ALL_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_PER_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                khui_cfg_release(cn_idents);
            }

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_KCA_AUTHREALM,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_EMAIL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_NAME,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SERIAL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (csp_params) {
                khc_close_space(csp_params);
                csp_params = NULL;
            }

#if KH_VERSION_API < 12
            if (hm_netidmgr)
                FreeLibrary(hm_netidmgr);

            pkhui_cw_get_primary_id = NULL;
#endif

#if KH_VERSION_API < 7
            pkhui_action_lock = NULL;
            pkhui_action_unlock = NULL;
            pkhui_refresh_actions = NULL;
            pkhui_request_UI_callback = NULL;
#endif

            /* TODO: Perform additional uninitialization
               operations. */
        }
        break;
    }

    return rv;
}