KHMEXP khm_int32 KHMAPI kcdb_identpro_get_default_identity(khm_handle vidpro, khm_handle * pvident) { khm_int32 rv = KHM_ERROR_SUCCESS; if (!pvident) return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_identpro); if (kcdb_is_active_identpro(vidpro)) { kcdb_identpro_i * p; p = kcdb_identpro_from_handle(vidpro); *pvident = p->default_id; } else { *pvident = NULL; rv = KHM_ERROR_NO_PROVIDER; } LeaveCriticalSection(&cs_identpro); if (*pvident == NULL || KHM_FAILED(kcdb_identity_hold(*pvident))) rv = KHM_ERROR_NOT_FOUND; return rv; }
KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle record) { if(kcdb_cred_is_active_cred(record)) return kcdb_cred_hold(record); else if(kcdb_is_active_identity(record)) return kcdb_identity_hold(record); else return KHM_ERROR_INVALID_PARAM; }
khm_int32 KHMAPI int_khui_cw_get_primary_id(khui_new_creds * nc, khm_handle * h) { if (nc->n_identities > 0 && nc->identities[0] != NULL) { *h = nc->identities[0]; kcdb_identity_hold(*h); return KHM_ERROR_SUCCESS; } *h = NULL; return KHM_ERROR_NOT_FOUND; }
static void check_and_set_refresh_bit_for_identity(khm_handle cred, khm_handle * plast_identity) { khm_handle this_identity; if (KHM_SUCCEEDED(kcdb_cred_get_identity(cred, &this_identity))) { if (!kcdb_identity_is_equal(this_identity, *plast_identity)) { kcdb_identity_set_flags(this_identity, KCDB_IDENT_FLAG_NEEDREFRESH, KCDB_IDENT_FLAG_NEEDREFRESH); kcdb_identity_hold(this_identity); if (*plast_identity) kcdb_identity_release(*plast_identity); *plast_identity = this_identity; } kcdb_identity_release(this_identity); this_identity = NULL; } }
khm_int32 krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) { switch(msg_subtype) { case KMSG_CRED_NEW_CREDS: { khui_new_creds * nc; khui_new_creds_by_type * nct; khm_size cbsize; wchar_t wbuf[256]; nc = (khui_new_creds *) vparam; nct = PMALLOC(sizeof(*nct)); #ifdef DEBUG assert(nct); #endif ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb4; nct->ordinal = 3; LoadString(hResModule, IDS_NC_K4_SHORT, wbuf, ARRAYLENGTH(wbuf)); StringCbLength(wbuf, sizeof(wbuf), &cbsize); cbsize += sizeof(wchar_t); nct->name = PMALLOC(cbsize); StringCbCopy(nct->name, cbsize, wbuf); nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; nct->h_module = hResModule; nct->dlg_proc = k4_nc_dlg_proc; nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4); khui_cw_add_type(nc, nct); } break; case KMSG_CRED_RENEW_CREDS: { khui_new_creds * nc; khui_new_creds_by_type * nct; khm_size cbsize; wchar_t wbuf[256]; khui_action_context * pctx = NULL; nc = (khui_new_creds *) vparam; pctx = khui_cw_get_ctx(nc); if (!pctx->identity) break; nct = PMALLOC(sizeof(*nct)); #ifdef DEBUG assert(nct); #endif ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb4; nct->ordinal = 3; LoadString(hResModule, IDS_NC_K4_SHORT, wbuf, ARRAYLENGTH(wbuf)); StringCbLength(wbuf, sizeof(wbuf), &cbsize); cbsize += sizeof(wchar_t); nct->name = PMALLOC(cbsize); StringCbCopy(nct->name, cbsize, wbuf); nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; khui_cw_add_type(nc, nct); } break; case KMSG_CRED_DIALOG_SETUP: break; case KMSG_CRED_PROCESS: { khui_new_creds * nc; khui_new_creds_by_type * nct = NULL; khm_handle ident = NULL; khui_action_context * pctx = NULL; k4_dlg_data * d = NULL; long code = 0; wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; khm_size cb; khm_int32 subtype; nc = (khui_new_creds *) vparam; if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) break; subtype = khui_cw_get_subtype(nc); if (subtype == KMSG_CRED_NEW_CREDS || subtype == KMSG_CRED_RENEW_CREDS) { khm_int32 method; if (subtype == KMSG_CRED_NEW_CREDS) { d = (k4_dlg_data *) nct->aux; if (KHM_FAILED(khui_cw_get_primary_id(nc, &ident))) break; if (!d || khui_cw_get_result(nc) != KHUI_NC_RESULT_PROCESS) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } if (!d->k4_enabled) { k4_write_identity_data(d); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } method = d->method; cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); _begin_task(0); _report_sr0(KHERR_NONE, IDS_MSG_K4NEW); _resolve(); _describe(); } else if (subtype == KMSG_CRED_RENEW_CREDS) { pctx = khui_cw_get_ctx(nc); if ((pctx->scope == KHUI_SCOPE_IDENT && pctx->identity != NULL) || (pctx->scope == KHUI_SCOPE_CREDTYPE && pctx->cred_type == credtype_id_krb4 && pctx->identity != NULL) || (pctx->scope == KHUI_SCOPE_CRED && pctx->cred_type == credtype_id_krb4 && pctx->identity != NULL && pctx->cred != NULL)) { ident = pctx->identity; kcdb_identity_hold(ident); if (!k4_should_identity_get_k4(ident)) { _reportf(L"Kerberos 4 is not enabled for this identity. Skipping"); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); kcdb_identity_release(ident); break; } } else { _reportf(L"Kerberos 4 is not within renewal scope. Skipping"); khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); break; } method = K4_METHOD_K524; /* only k524 is supported for renewals */ _begin_task(0); cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); _report_sr0(KHERR_NONE, IDS_MSG_K4RENEW); _resolve(); _describe(); } else { assert(FALSE); break; } _progress(0,1); if ((method == K4_METHOD_AUTO || method == K4_METHOD_K524) && khui_cw_type_succeeded(nc, credtype_id_krb5)) { khm_handle tgt; FILETIME ft_prev; FILETIME ft_new; khm_size cb; _report_cs0(KHERR_INFO, L"Trying K524..."); tgt = khm_krb4_find_tgt(NULL, ident); _progress(1,3); if (tgt) { cb = sizeof(ft_prev); if (KHM_FAILED(kcdb_cred_get_attr(tgt, KCDB_ATTR_EXPIRE, NULL, &ft_prev, &cb))) ZeroMemory(&ft_prev, sizeof(ft_prev)); kcdb_cred_release(tgt); } code = khm_convert524(ident); _progress(2,3); _reportf(L"khm_convert524 returns code %d", code); if (code == 0) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_SUCCESS | KHUI_NC_RESPONSE_EXIT); if (subtype == KMSG_CRED_NEW_CREDS) { assert(d != NULL); k4_write_identity_data(d); } else if (subtype == KMSG_CRED_RENEW_CREDS && (pctx->scope == KHUI_SCOPE_CREDTYPE || pctx->scope == KHUI_SCOPE_CRED)) { khm_krb4_list_tickets(); tgt = khm_krb4_find_tgt(NULL, ident); if (tgt) { cb = sizeof(ft_new); ZeroMemory(&ft_new, sizeof(ft_new)); kcdb_cred_get_attr(tgt, KCDB_ATTR_EXPIRE, NULL, &ft_new, &cb); kcdb_cred_release(tgt); } if (!tgt || CompareFileTime(&ft_new, &ft_prev) <= 0) { /* The new TGT wasn't much of an improvement over what we already had. We should go out and try to renew the identity now. */ khui_action_context ctx; _reportf(L"Renewal of Krb4 creds failed to get a longer TGT. Triggering identity renewal"); khui_context_create(&ctx, KHUI_SCOPE_IDENT, pctx->identity, KCDB_CREDTYPE_INVALID, NULL); khui_action_trigger(KHUI_ACTION_RENEW_CRED, &ctx); khui_context_release(&ctx); } } _progress(1,1); _end_task(); if (ident) kcdb_identity_release(ident); break; } else if (method == K4_METHOD_K524) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_FAILED | KHUI_NC_RESPONSE_EXIT); if (subtype == KMSG_CRED_RENEW_CREDS && (pctx->scope == KHUI_SCOPE_CREDTYPE || pctx->scope == KHUI_SCOPE_CRED)) { /* We were trying to get a new Krb4 TGT for this identity. Sometimes this fails because of restrictions placed on K524d regarding the lifetime of the issued K4 TGT. In this case, we trigger a renewal of the identity in the hope that the new K5 TGT will allow us to successfully get a new K4 TGT next time over using the new K5 TGT. */ khui_action_context ctx; _reportf(L"Renewal of Krb4 creds failed using k524. Triggerring identity renewal."); khui_context_create(&ctx, KHUI_SCOPE_IDENT, pctx->identity, KCDB_CREDTYPE_INVALID, NULL); khui_action_trigger(KHUI_ACTION_RENEW_CRED, &ctx); khui_context_release(&ctx); } _progress(1,1); _end_task(); if (ident) kcdb_identity_release(ident); break; } } /* only supported for new credentials */ if (method == K4_METHOD_AUTO || method == K4_METHOD_PASSWORD) { khm_size n_prompts = 0; khm_size idx; khm_size cb; wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE]; char pwd[KHUI_MAXCCH_PROMPT_VALUE]; wchar_t widname[KCDB_IDENT_MAXCCH_NAME]; char idname[KCDB_IDENT_MAXCCH_NAME]; char * aname = NULL; char * inst = NULL; char * realm = NULL; assert(subtype == KMSG_CRED_NEW_CREDS); _report_cs0(KHERR_INFO, L"Trying password ..."); code = TRUE; /* just has to be non-zero */ khui_cw_get_prompt_count(nc, &n_prompts); if (n_prompts == 0) goto _skip_pwd; for (idx = 0; idx < n_prompts; idx++) { khui_new_creds_prompt * p; if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p))) continue; if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD) break; } if (idx >= n_prompts) { _reportf(L"Password prompt not found"); goto _skip_pwd; } khui_cw_sync_prompt_values(nc); cb = sizeof(wpwd); if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx, wpwd, &cb))) { _reportf(L"Failed to obtain password value"); goto _skip_pwd; } UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd); cb = sizeof(widname); kcdb_identity_get_name(ident, widname, &cb); UnicodeStrToAnsi(idname, sizeof(idname), widname); { char * atsign; atsign = strchr(idname, '@'); if (atsign == NULL) { _reportf(L"Identity name does not contain an '@'"); goto _skip_pwd; } *atsign++ = 0; realm = atsign; } { char * slash; slash = strchr(idname, '/'); if (slash != NULL) { *slash++ = 0; inst = slash; } else { inst = ""; } } aname = idname; code = khm_krb4_kinit(aname, inst, realm, (long) d->lifetime, pwd); _progress(2,3); _reportf(L"khm_krb4_kinit returns code %d", code); _skip_pwd: if (code) { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_EXIT | KHUI_NC_RESPONSE_FAILED); } else { khui_cw_set_response(nc, credtype_id_krb4, KHUI_NC_RESPONSE_EXIT | KHUI_NC_RESPONSE_SUCCESS); if (subtype == KMSG_CRED_NEW_CREDS) { assert(d != NULL); k4_write_identity_data(d); } } } _progress(1,1); _end_task(); } if (ident) kcdb_identity_release(ident); } break; case KMSG_CRED_END: { khui_new_creds * nc; khui_new_creds_by_type * nct = NULL; nc = (khui_new_creds *) vparam; if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) break; khui_cw_del_type(nc, credtype_id_krb4); if (nct->name) PFREE(nct->name); if (nct->credtext) PFREE(nct->credtext); PFREE(nct); } break; } return KHM_ERROR_SUCCESS; }
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(®, 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, ®); 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); } }
/* dialog box procedure for the "Add new identity" dialog */ INT_PTR CALLBACK khm_cfg_add_ident_proc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) { add_ident_data * d; switch(umsg) { case WM_INITDIALOG: /* we create a new credentials blob and pull in the identity selectors from the identity provider. */ d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); khui_cw_create_cred_blob(&d->nc); #ifdef DEBUG assert(d->nc != NULL); #endif if (d->nc == NULL) { PFREE(d); break; } if (KHM_FAILED(kcdb_identpro_get_ui_cb(&d->nc->ident_cb))) { /* this should have worked. The only reason it would fail is if there is no identity provider or if the identity provider does not support providing idnetity selectors. */ khui_cw_destroy_cred_blob(d->nc); PFREE(d); break; } #pragma warning(push) #pragma warning(disable: 4244) SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); #pragma warning(pop) /* get metrics for dynamic controls */ get_ctrl_row_metrics(&d->dim_small, GetDlgItem(hwnd, IDC_SM_LBL), GetDlgItem(hwnd, IDC_SM_CTL)); get_ctrl_row_metrics(&d->dim_medium, GetDlgItem(hwnd, IDC_MED_LBL), GetDlgItem(hwnd, IDC_MED_CTL)); get_ctrl_row_metrics(&d->dim_large, GetDlgItem(hwnd, IDC_LG_LBL), GetDlgItem(hwnd, IDC_LG_CTL)); { RECT rlbl; RECT rctl; RECT rwnd; GetWindowRect(GetDlgItem(hwnd, IDC_SM_LBL), &rlbl); GetWindowRect(GetDlgItem(hwnd, IDC_SM_CTL), &rctl); GetWindowRect(hwnd, &rwnd); OffsetRect(&rlbl, -rwnd.left, -rwnd.top); OffsetRect(&rctl, -rwnd.left, -rwnd.top); d->current_x = rlbl.left; d->current_y = rctl.top - GetSystemMetrics(SM_CYCAPTION); GetWindowRect(GetDlgItem(hwnd, IDC_MED_CTL), &rlbl); OffsetRect(&rlbl, -rwnd.left, -rwnd.top); d->row_gap = rlbl.top - rctl.bottom; } d->nc->hwnd = hwnd; /* now call the UI callback and make it create the controls. */ d->nc->ident_cb(d->nc, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) hwnd); break; case WM_DESTROY: d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d == NULL) break; d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0); khui_cw_destroy_cred_blob(d->nc); PFREE(d); break; case KHUI_WM_NC_NOTIFY: d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); switch(HIWORD(wParam)) { case WMNC_ADD_CONTROL_ROW: { khui_control_row * row; RECT r_lbl, r_inp, r_enc; struct ctrl_row_dimensions * dim; HFONT hf; row = (khui_control_row *) lParam; #ifdef DEBUG assert(row->label); assert(row->input); assert(d); #endif if (row->size == KHUI_CTRLSIZE_SMALL) { dim = &d->dim_small; } else if (row->size == KHUI_CTRLSIZE_HALF) { dim = &d->dim_medium; } else { dim = &d->dim_large; #ifdef DEBUG assert(row->size == KHUI_CTRLSIZE_FULL); #endif } CopyRect(&r_enc, &dim->enclosure); CopyRect(&r_lbl, &dim->label); CopyRect(&r_inp, &dim->control); OffsetRect(&r_enc, d->current_x, d->current_y); OffsetRect(&r_lbl, r_enc.left, r_enc.top); OffsetRect(&r_inp, r_enc.left, r_enc.top); d->current_y += r_enc.bottom - r_enc.top; hf = (HFONT) SendDlgItemMessage(hwnd, IDOK, WM_GETFONT, 0, 0); if (row->label) { SetWindowPos(row->label, ((d->hwnd_last_ctrl != NULL)? d->hwnd_last_ctrl : HWND_TOP), r_lbl.left, r_lbl.top, r_lbl.right - r_lbl.left, r_lbl.bottom - r_lbl.top, SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (hf) SendMessage(row->label, WM_SETFONT, (WPARAM) hf, TRUE); d->hwnd_last_ctrl = row->label; } if (row->input) { SetWindowPos(row->input, ((d->hwnd_last_ctrl != NULL)? d->hwnd_last_ctrl : HWND_TOP), r_inp.left, r_inp.top, r_inp.right - r_inp.left, r_inp.bottom - r_inp.top, SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER); if (hf) SendMessage(row->input, WM_SETFONT, (WPARAM) hf, TRUE); d->hwnd_last_ctrl = row->input; } } break; case WMNC_IDENTITY_CHANGE: break; } return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK) { wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; wchar_t err_msg[1024]; khm_handle ident = NULL; khm_handle csp_ident = NULL; khm_size cb; khm_int32 rv = KHM_ERROR_SUCCESS; d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (!d || !d->nc) break; /* check if there was an identity selected */ if (d->nc->n_identities == 0 || d->nc->identities[0] == NULL) { StringCbCopy(idname, sizeof(idname), L""); LoadString(khm_hInstance, IDS_CFG_IDNAME_NON, err_msg, ARRAYLENGTH(err_msg)); goto show_failure; } ident = d->nc->identities[0]; kcdb_identity_hold(ident); cb = sizeof(idname); kcdb_identity_get_name(ident, idname, &cb); /* now we have to create the identity configuration. */ if (KHM_FAILED(rv = kcdb_identity_get_config(ident, KHM_FLAG_CREATE, &csp_ident))) { wchar_t fmt[256]; LoadString(khm_hInstance, IDS_CFG_IDNAME_CCC, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(err_msg, sizeof(err_msg), fmt, rv); kcdb_identity_release(ident); goto show_failure; } /* create a value so that the configuration space will actually be created in the registry. We don't want this new identity to be sticky. */ khc_write_int32(csp_ident, L"Sticky", 0); khm_refresh_config(); kcdb_identity_release(ident); khc_close_space(csp_ident); EndDialog(hwnd, 0); break; show_failure: { wchar_t title[512]; wchar_t fmt[256]; if (!err_msg[0]) break; LoadString(khm_hInstance, IDS_CFG_IDNAME_PRB, fmt, ARRAYLENGTH(fmt)); StringCbPrintf(title, sizeof(title), fmt, idname); MessageBox(hwnd, err_msg, title, MB_OK | MB_ICONSTOP); /* don't end the dialog yet */ break; } break; } else if (LOWORD(wParam) == IDCANCEL) { EndDialog(hwnd, 1); } else { d = (add_ident_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER); if (d && d->nc && d->nc->ident_cb) { return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, umsg, wParam, lParam); } } break; } return FALSE; }
KHMEXP khm_int32 KHMAPI kcdb_identpro_set_default_identity(khm_handle videntity, khm_boolean ask_idpro) { khm_handle sub = NULL; khm_int32 rv = KHM_ERROR_SUCCESS; kcdb_identpro_i * p; if(!kcdb_is_identity(videntity)) return KHM_ERROR_INVALID_PARAM; p = identpro_get_provider_for_identity(videntity); EnterCriticalSection(&cs_identpro); if (!kcdb_is_active_identpro(p)) { rv = KHM_ERROR_INVALID_PARAM; } else { if (kcdb_identity_is_equal(videntity, p->default_id)) rv = KHM_ERROR_DUPLICATE; } LeaveCriticalSection(&cs_identpro); if (KHM_FAILED(rv)) { return (rv == KHM_ERROR_DUPLICATE)? KHM_ERROR_SUCCESS : rv; } if (ask_idpro) { sub = identpro_get_sub_for_identity(videntity); if(sub != NULL) { rv = kmq_send_sub_msg(sub, KMSG_IDENT, KMSG_IDENT_SET_DEFAULT, TRUE, (void *) videntity); } else { #ifdef DEBUG assert(FALSE); #endif rv = KHM_ERROR_NO_PROVIDER; } } if (KHM_SUCCEEDED(rv)) { khm_handle h_old_id = NULL; int new_default = FALSE; kcdb_identity * id; EnterCriticalSection(&cs_identpro); if (!kcdb_identity_is_equal(videntity, p->default_id)) { h_old_id = p->default_id; p->default_id = videntity; new_default = TRUE; } LeaveCriticalSection(&cs_identpro); EnterCriticalSection(&cs_ident); if (new_default) kcdb_identity_hold(videntity); id = (kcdb_identity *) videntity; id->flags |= KCDB_IDENT_FLAG_DEFAULT; if (h_old_id) { id = (kcdb_identity *) h_old_id; id->flags &= ~KCDB_IDENT_FLAG_DEFAULT; kcdb_identity_release(h_old_id); } LeaveCriticalSection(&cs_ident); if (new_default) { kcdb_identity_hold(videntity); kcdbint_ident_post_message(KCDB_OP_NEW_DEFAULT, (kcdb_identity *) videntity); } } return rv; }