void khm_hide_main_window(void) { khm_handle csp_notices = NULL; khm_int32 show_warning = FALSE; if (khm_nCmdShow != SW_MINIMIZE && KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow\\Notices", KHM_PERM_WRITE, &csp_notices)) && KHM_SUCCEEDED(khc_read_int32(csp_notices, L"MinimizeWarning", &show_warning)) && show_warning != 0) { khui_alert * alert; wchar_t title[KHUI_MAXCCH_TITLE]; wchar_t msg[KHUI_MAXCCH_MESSAGE]; LoadString(khm_hInstance, IDS_WARN_WM_TITLE, title, ARRAYLENGTH(title)); LoadString(khm_hInstance, IDS_WARN_WM_MSG, msg, ARRAYLENGTH(msg)); khui_alert_create_simple(title, msg, KHERR_INFO, &alert); khui_alert_set_flags(alert, KHUI_ALERT_FLAG_REQUEST_BALLOON, KHUI_ALERT_FLAG_REQUEST_BALLOON); khui_alert_show(alert); khc_write_int32(csp_notices, L"MinimizeWarning", 0); } if (csp_notices != NULL) khc_close_space(csp_notices); ShowWindow(khm_hwnd_main, SW_HIDE); }
/* Completion handler for KMSG_CRED messages. We control the overall logic of credentials acquisition and other operations here. Once a credentials operation is triggered, each successive message completion notification will be used to dispatch the messages for the next step in processing the operation. */ void KHMAPI kmsg_cred_completion(kmq_message *m) { khui_new_creds * nc; #ifdef DEBUG assert(m->type == KMSG_CRED); #else if(m->type != KMSG_CRED) return; /* huh? */ #endif switch(m->subtype) { case KMSG_CRED_PASSWORD: /* fallthrough */ case KMSG_CRED_NEW_CREDS: /* Cred types have attached themselves. Trigger the next phase. */ kmq_post_message(KMSG_CRED, KMSG_CRED_DIALOG_SETUP, 0, m->vparam); break; case KMSG_CRED_RENEW_CREDS: nc = (khui_new_creds *) m->vparam; /* khm_cred_dispatch_process_message() deals with the case where there are no credential types that wants to participate in this operation. */ khm_cred_dispatch_process_message(nc); break; case KMSG_CRED_DIALOG_SETUP: nc = (khui_new_creds *) m->vparam; khm_prep_newcredwnd(nc->hwnd); /* all the controls have been created. Now initialize them */ if (nc->n_types > 0) { kmq_post_subs_msg(nc->type_subs, nc->n_types, KMSG_CRED, KMSG_CRED_DIALOG_PRESTART, 0, m->vparam); } else { PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0); } break; case KMSG_CRED_DIALOG_PRESTART: /* all prestart stuff is done. Now to activate the dialog */ nc = (khui_new_creds *) m->vparam; khm_show_newcredwnd(nc->hwnd); kmq_post_subs_msg(nc->type_subs, nc->n_types, KMSG_CRED, KMSG_CRED_DIALOG_START, 0, m->vparam); /* at this point, the dialog window takes over. We let it run the show until KMSG_CRED_DIALOG_END is posted by the dialog procedure. */ break; case KMSG_CRED_PROCESS: /* a wave of these messages have completed. We should check if there's more */ nc = (khui_new_creds *) m->vparam; /* if we are done processing all the plug-ins, then check if there were any errors reported. Otherwise we dispatch another set of messages. */ if(!khm_cred_dispatch_process_level(nc)) { if(kherr_is_error()) { khui_alert * alert; kherr_event * evt; kherr_context * ctx; wchar_t ws_tfmt[512]; wchar_t w_idname[KCDB_IDENT_MAXCCH_NAME]; wchar_t ws_title[ARRAYLENGTH(ws_tfmt) + KCDB_IDENT_MAXCCH_NAME]; khm_size cb; /* For renewals, we suppress the error message for the following case: - The renewal was for an identity - There are no identity credentials for the identity (no credentials that have the same type as the identity provider). */ if (nc->subtype == KMSG_CRED_RENEW_CREDS && nc->ctx.scope == KHUI_SCOPE_IDENT && nc->ctx.identity != NULL) { khm_handle tcs = NULL; /* credential set */ khm_size count = 0; khm_int32 id_ctype = KCDB_CREDTYPE_INVALID; khm_int32 delta = 0; kcdb_identity_get_type(&id_ctype); kcdb_credset_create(&tcs); kcdb_credset_collect(tcs, NULL, nc->ctx.identity, id_ctype, &delta); kcdb_credset_get_size(tcs, &count); kcdb_credset_delete(tcs); if (count == 0) { goto done_with_op; } } ctx = kherr_peek_context(); evt = kherr_get_err_event(ctx); kherr_evaluate_event(evt); khui_alert_create_empty(&alert); if (nc->subtype == KMSG_CRED_NEW_CREDS) { khui_alert_set_type(alert, KHUI_ALERTTYPE_ACQUIREFAIL); cb = sizeof(w_idname); if (nc->n_identities == 0 || KHM_FAILED(kcdb_identity_get_name(nc->identities[0], w_idname, &cb))) { /* an identity could not be determined */ LoadString(khm_hInstance, IDS_NC_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->identities[0], KCDB_CREDTYPE_INVALID, NULL); } } else if (nc->subtype == KMSG_CRED_PASSWORD) { khui_alert_set_type(alert, KHUI_ALERTTYPE_CHPW); cb = sizeof(w_idname); if (nc->n_identities == 0 || KHM_FAILED(kcdb_identity_get_name(nc->identities[0], w_idname, &cb))) { LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->identities[0], KCDB_CREDTYPE_INVALID, NULL); } } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { khui_alert_set_type(alert, KHUI_ALERTTYPE_RENEWFAIL); cb = sizeof(w_idname); if (nc->ctx.identity == NULL || KHM_FAILED(kcdb_identity_get_name(nc->ctx.identity, w_idname, &cb))) { LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE, ws_title, ARRAYLENGTH(ws_title)); } else { LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE_I, ws_tfmt, ARRAYLENGTH(ws_tfmt)); StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_ctx(alert, KHUI_SCOPE_IDENT, nc->ctx.identity, KCDB_CREDTYPE_INVALID, NULL); } } else { #ifdef DEBUG assert(FALSE); #endif } khui_alert_set_title(alert, ws_title); khui_alert_set_severity(alert, evt->severity); if(!evt->long_desc) khui_alert_set_message(alert, evt->short_desc); else khui_alert_set_message(alert, evt->long_desc); if(evt->suggestion) khui_alert_set_suggestion(alert, evt->suggestion); if (nc->subtype == KMSG_CRED_RENEW_CREDS && nc->ctx.identity != NULL) { khm_int32 n_cmd; n_cmd = khm_get_identity_new_creds_action(nc->ctx.identity); if (n_cmd != 0) { khui_alert_add_command(alert, n_cmd); khui_alert_add_command(alert, KHUI_PACTION_CLOSE); khui_alert_set_flags(alert, KHUI_ALERT_FLAG_DISPATCH_CMD, KHUI_ALERT_FLAG_DISPATCH_CMD); } } khui_alert_show(alert); khui_alert_release(alert); kherr_release_context(ctx); kherr_clear_error(); } done_with_op: if (nc->subtype == KMSG_CRED_RENEW_CREDS) { kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, m->vparam); } else { PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0); } } break; case KMSG_CRED_END: /* all is done. */ { khui_new_creds * nc; khm_boolean continue_cmdline = TRUE; nc = (khui_new_creds *) m->vparam; if (nc->subtype == KMSG_CRED_NEW_CREDS || nc->subtype == KMSG_CRED_PASSWORD) { khm_cred_end_dialog(nc); } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { /* if this is a renewal that was triggered while we were processing the commandline, then we need to update the pending renewal count. */ if (khm_startup.processing) { LONG renewals; renewals = InterlockedDecrement(&khm_startup.pending_renewals); if (renewals != 0) { continue_cmdline = FALSE; } } } khui_cw_destroy_cred_blob(nc); kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); if (continue_cmdline) kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); } break; /* property sheet stuff */ case KMSG_CRED_PP_BEGIN: /* all the pages should have been added by now. Just send out the precreate message */ kmq_post_message(KMSG_CRED, KMSG_CRED_PP_PRECREATE, 0, m->vparam); break; case KMSG_CRED_PP_END: kmq_post_message(KMSG_CRED, KMSG_CRED_PP_DESTROY, 0, m->vparam); break; case KMSG_CRED_DESTROY_CREDS: #ifdef DEBUG assert(m->vparam != NULL); #endif khui_context_release((khui_action_context *) m->vparam); PFREE(m->vparam); kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); break; case KMSG_CRED_IMPORT: { khm_boolean continue_cmdline = FALSE; LONG pending_renewals; /* once an import operation ends, we have to trigger a renewal so that other plug-ins that didn't participate in the import operation can have a chance at getting the necessary credentials. If we are in the middle of processing the commandline, we have to be a little bit careful. We can't issue a commandline conituation message right now because the import action is still ongoing (since the renewals are part of the action). Once the renewals have completed, the completion handler will automatically issue a commandline continuation message. However, if there were no identities to renew, then we have to issue the message ourselves. */ InterlockedIncrement(&khm_startup.pending_renewals); khm_cred_renew_all_identities(); pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals); if (pending_renewals == 0 && khm_startup.processing) kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0); } break; case KMSG_CRED_REFRESH: kcdb_identity_refresh_all(); break; } }