aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>2007-04-12 21:30:33 +0000
committerTom Yu <tlyu@mit.edu>2007-04-12 21:30:33 +0000
commit4f91d87cb04653f3a33398a60f20d7e81d974791 (patch)
tree4262577811b2579928f781bc8ab5c1a71206443f /src
parente548cce8821cac458b369d29249b256e5af33d0b (diff)
downloadkrb5-4f91d87cb04653f3a33398a60f20d7e81d974791.zip
krb5-4f91d87cb04653f3a33398a60f20d7e81d974791.tar.gz
krb5-4f91d87cb04653f3a33398a60f20d7e81d974791.tar.bz2
pull up r19440 from trunk
r19440@cathode-dark-space: jaltman | 2007-04-12 17:19:33 -0400 ticket: new subject: NIM - Fix taskbar button visibility on Vista component: windows tags: pullup Although the Platform SDK docs suggest using ITaskbarList to add/remove a taskbar button on the fly, it doesn't work on Vista. Instead we will just set the window style to use WS_EX_APPWINDOW and be done with it. No change in the NIM version number. ticket: 5526 version_fixed: 1.6.1 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@19441 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/windows/identity/ui/mainwnd.c2722
-rw-r--r--src/windows/identity/ui/newcredwnd.c5820
-rw-r--r--src/windows/identity/ui/newcredwnd.h378
3 files changed, 4455 insertions, 4465 deletions
diff --git a/src/windows/identity/ui/mainwnd.c b/src/windows/identity/ui/mainwnd.c
index 159255f..d177b11 100644
--- a/src/windows/identity/ui/mainwnd.c
+++ b/src/windows/identity/ui/mainwnd.c
@@ -1,1364 +1,1358 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- * Copyright (c) 2007 Secure Endpoints Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#include<khmapp.h>
-#include<intaction.h>
-#include<assert.h>
-
-ATOM khm_main_window_class;
-ATOM khm_null_window_class;
-HWND khm_hwnd_null;
-HWND khm_hwnd_main;
-HWND khm_hwnd_rebar;
-HWND khm_hwnd_main_cred;
-
-int khm_main_wnd_mode = KHM_MAIN_WND_NORMAL;
-
-#define MW_RESIZE_TIMER 1
-#define MW_RESIZE_TIMEOUT 2000
-#define MW_REFRESH_TIMER 2
-#define MW_REFRESH_TIMEOUT 600
-
-void
-khm_set_dialog_result(HWND hwnd, LRESULT lr) {
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lr);
-#pragma warning(pop)
-}
-
-static void
-mw_restart_refresh_timer(HWND hwnd) {
- khm_handle csp_cw;
- khm_int32 timeout;
-
- KillTimer(hwnd, MW_REFRESH_TIMER);
- if (KHM_SUCCEEDED(khc_open_space(NULL,
- L"CredWindow",
- KHM_PERM_READ,
- &csp_cw))) {
- if (KHM_FAILED(khc_read_int32(csp_cw,
- L"RefreshTimeout",
- &timeout)))
- timeout = MW_REFRESH_TIMEOUT;
- khc_close_space(csp_cw);
- } else {
- timeout = MW_REFRESH_TIMEOUT;
- }
-
- timeout *= 1000; /* convert to milliseconds */
-
- SetTimer(hwnd, MW_REFRESH_TIMER, timeout, NULL);
-}
-
-khm_int32 KHMAPI
-mw_select_cred(khm_handle cred, void * rock) {
- if (cred)
- kcdb_cred_set_flags(cred,
- KCDB_CRED_FLAG_SELECTED,
- KCDB_CRED_FLAG_SELECTED);
-
- return KHM_ERROR_SUCCESS;
-}
-
-/* perform shutdown operations */
-static void
-khm_pre_shutdown(void) {
- khm_handle csp_cw = NULL;
- khm_handle credset = NULL;
- khm_int32 t;
- khm_size s;
-
- khm_taskbar_remove_window(khm_hwnd_main);
-
- /* Check if we should destroy all credentials on exit... */
-
- if (KHM_FAILED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw)))
- return;
-
- if (KHM_FAILED(khc_read_int32(csp_cw, L"DestroyCredsOnExit", &t)) ||
- !t)
- goto _cleanup;
-
- if (KHM_FAILED(kcdb_credset_create(&credset)))
- goto _cleanup;
-
- if (KHM_FAILED(kcdb_credset_extract(credset, NULL, NULL,
- KCDB_TYPE_INVALID)))
- goto _cleanup;
-
- if (KHM_FAILED(kcdb_credset_get_size(credset, &s)) ||
- s == 0)
- goto _cleanup;
-
- kcdb_credset_apply(credset, mw_select_cred, NULL);
-
- khui_context_set(KHUI_SCOPE_GROUP,
- NULL,
- KCDB_CREDTYPE_INVALID,
- NULL,
- NULL,
- 0,
- credset);
-
- khm_cred_destroy_creds(TRUE, TRUE);
-
- _cleanup:
-
- if (credset)
- kcdb_credset_delete(credset);
-
- if (csp_cw)
- khc_close_space(csp_cw);
-}
-
-void
-khm_process_query_app_ver(khm_query_app_version * papp_ver) {
-
- if (!papp_ver || papp_ver->magic != KHM_QUERY_APP_VER_MAGIC)
- return;
-
- papp_ver->ver_remote = app_version;
-
- /* the remote instance has requested swapping in. we check the
- version numbers and if the remote instance is newer than us,
- then we exit and let the remote instance take over. */
- if (papp_ver->request_swap) {
- khm_version ver_caller = papp_ver->ver_caller;
-
- if (ver_caller.major > app_version.major ||
-
- (ver_caller.major == app_version.major &&
- ver_caller.minor > app_version.minor) ||
-
- (ver_caller.major == app_version.major &&
- ver_caller.minor == app_version.minor &&
- ver_caller.aux > app_version.aux) ||
-
- (ver_caller.major == app_version.major &&
- ver_caller.minor == app_version.minor &&
- ver_caller.aux == app_version.aux &&
- ver_caller.patch > app_version.patch)) {
-
- papp_ver->request_swap = TRUE;
-
- if (khm_hwnd_main)
- DestroyWindow(khm_hwnd_main);
-
- } else {
-
- papp_ver->request_swap = FALSE;
-
- }
- }
-
- papp_ver->code = KHM_ERROR_SUCCESS;
-}
-
-static void
-khm_ui_cb(LPARAM lParam) {
- khui_ui_callback_data * pcbdata;
-
- pcbdata = (khui_ui_callback_data *) lParam;
-
- if (pcbdata == NULL || pcbdata->magic != KHUI_UICBDATA_MAGIC) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- return;
- }
-
-#ifdef DEBUG
- assert(pcbdata->cb);
-#endif
-
- /* make the call */
- if (!IsBadCodePtr(pcbdata->cb))
- pcbdata->rv = (*pcbdata->cb)(khm_hwnd_main, pcbdata->rock);
- else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- pcbdata->rv = KHM_ERROR_INVALID_PARAM;
- }
-}
-
-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_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) {
- RECT r;
- khm_handle csp_cw;
- khm_handle csp_mw;
- const wchar_t * wconfig;
-
- if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
- wconfig = L"Windows\\MainMini";
- else
- wconfig = L"Windows\\Main";
-
- KillTimer(hwnd, wParam);
-
- GetWindowRect(hwnd, &r);
-
- if (KHM_SUCCEEDED(khc_open_space(NULL,
- L"CredWindow",
- KHM_PERM_WRITE,
- &csp_cw))) {
- if (KHM_SUCCEEDED(khc_open_space(csp_cw,
- wconfig,
- KHM_PERM_WRITE,
- &csp_mw))) {
- khm_int32 t;
-
- khc_write_int32(csp_mw, L"XPos", r.left);
- khc_write_int32(csp_mw, L"YPos", r.top);
- khc_write_int32(csp_mw, L"Width",
- r.right - r.left);
- khc_write_int32(csp_mw, L"Height",
- r.bottom - r.top);
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)) &&
- t != KHM_DOCK_NONE) {
- khc_write_int32(csp_mw, L"Dock", KHM_DOCK_AUTO);
- }
-
- khc_close_space(csp_mw);
- }
- khc_close_space(csp_cw);
- }
-
- 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);
- }
- return 0;
-
- case WM_KHUI_ASSIGN_COMMANDLINE_V1:
- {
- HANDLE hmap;
- void * xfer;
- wchar_t mapname[256];
- struct tag_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 = (struct tag_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;
-
- 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];
- struct tag_khm_startup_options_v2 *pv2opt;
- 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 = (struct tag_khm_startup_options_v2 *) xfer;
-
- if (pv2opt->magic != STARTUP_OPTIONS_MAGIC ||
- pv2opt->cb_size != sizeof(*pv2opt)) {
- 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;
-
- 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);
-}
-
-LRESULT CALLBACK
-khm_null_wnd_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-LRESULT
-khm_rebar_notify(LPNMHDR lpnm) {
- switch(lpnm->code) {
-#if (_WIN32_WINNT >= 0x0501)
- case RBN_AUTOBREAK:
- {
- LPNMREBARAUTOBREAK lpra = (LPNMREBARAUTOBREAK) lpnm;
- lpra->fAutoBreak = TRUE;
- }
- break;
-#endif
- case RBN_BEGINDRAG:
- {
- LPNMREBAR lprb = (LPNMREBAR) lpnm;
- if ((lprb->dwMask & RBNM_ID) &&
- lprb->wID == 0)
- return 1;
- else
- return 0;
- }
- break;
-
- case NM_CUSTOMDRAW:
- return CDRF_DODEFAULT;
- break;
- }
-
- return 1;
-}
-
-void
-khm_create_main_window_controls(HWND hwnd_main) {
- REBARINFO rbi;
- HWND hwRebar;
-
- khm_menu_create_main(hwnd_main);
-
- hwRebar =
- CreateWindowEx(WS_EX_TOOLWINDOW,
- REBARCLASSNAME,
- L"Rebar",
- WS_CHILD |
- WS_VISIBLE|
- WS_CLIPSIBLINGS |
- WS_CLIPCHILDREN |
- CCS_NODIVIDER |
- RBS_VARHEIGHT |
- RBS_FIXEDORDER,
- 0,0,0,0,
- hwnd_main,
- NULL,
- khm_hInstance,
- NULL);
-
- if(!hwRebar) {
- DWORD dwe = GetLastError();
- return;
- }
-
- khm_hwnd_rebar = hwRebar;
-
- rbi.cbSize = sizeof(rbi);
- rbi.fMask = 0;
- rbi.himl = (HIMAGELIST) NULL;
- if(!SendMessage(hwRebar, RB_SETBARINFO, 0, (LPARAM) &rbi))
- return;
-
- /* self attach */
- khm_create_standard_toolbar(hwRebar);
- khm_create_statusbar(hwnd_main);
-
- /* manual attach */
- khm_hwnd_main_cred = khm_create_credwnd(hwnd_main);
-}
-
-void
-khm_adjust_window_dimensions_for_display(RECT * pr, int dock) {
-
- HMONITOR hmon;
- RECT rm;
- long x, y, width, height;
-
- x = pr->left;
- y = pr->top;
- width = pr->right - pr->left;
- height = pr->bottom - pr->top;
-
- /* if the rect doesn't intersect with the display area of any
- monitor, we just default to the primary monitor. */
- hmon = MonitorFromRect(pr, MONITOR_DEFAULTTOPRIMARY);
-
- if (hmon == NULL) {
- /* huh? we'll just center this on the primary screen */
- goto nomonitor;
- } else {
- MONITORINFO mi;
-
- ZeroMemory(&mi, sizeof(mi));
- mi.cbSize = sizeof(mi);
-
- if (!GetMonitorInfo(hmon, &mi))
- goto nomonitor;
-
- CopyRect(&rm, &mi.rcWork);
-
- goto adjust_dims;
- }
-
- nomonitor:
- /* for some reason we couldn't get a handle on a monitor or we
- couldn't get the metrics for that monitor. We default to
- setting things up on the primary monitor. */
-
- SetRectEmpty(&rm);
- if (!SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID) &rm, 0))
- goto done_with_monitor;
-
- adjust_dims:
-
- if (width > (rm.right - rm.left))
- width = rm.right - rm.left;
- if (height > (rm.bottom - rm.top))
- height = rm.bottom - rm.top;
-
- switch (dock & KHM_DOCKF_DOCKHINT) {
- case KHM_DOCK_TOPLEFT:
- x = rm.left;
- y = rm.top;
- break;
-
- case KHM_DOCK_TOPRIGHT:
- x = rm.right - width;
- y = rm.top;
- break;
-
- case KHM_DOCK_BOTTOMRIGHT:
- x = rm.right - width;
- y = rm.bottom - height;
- break;
-
- case KHM_DOCK_BOTTOMLEFT:
- x = rm.left;
- y = rm.bottom - height;
- break;
-
- case KHM_DOCK_AUTO:
- {
- int cxt, cyt;
-
- cxt = GetSystemMetrics(SM_CXDRAG);
- cyt = GetSystemMetrics(SM_CYDRAG);
-
- if (x > rm.left && (x - rm.left) < cxt)
- x = rm.left;
- else if ((x + width) < rm.right && (rm.right - (x + width)) < cxt)
- x = rm.right - width;
-
- if (y > rm.top && (y - rm.top) < cyt)
- y = rm.top;
- else if ((y + height) < rm.bottom && (rm.bottom - (y + height)) < cyt)
- y = rm.bottom - height;
- }
- break;
- }
-
- if (!(dock & KHM_DOCKF_XBORDER)) {
- if (x < rm.left)
- x = rm.left;
- if (x + width > rm.right)
- x = rm.right - width;
- if (y < rm.top)
- y = rm.top;
- if (y + height > rm.bottom)
- y = rm.bottom - height;
- }
-
- done_with_monitor:
- pr->left = x;
- pr->top = y;
- pr->right = x + width;
- pr->bottom = y + height;
-
-}
-
-void
-khm_get_main_window_rect(RECT * pr) {
- khm_handle csp_mw = NULL;
- int x,y,width,height,dock;
- RECT r;
- const wchar_t * wconfig;
-
- x = CW_USEDEFAULT;
- y = CW_USEDEFAULT;
- width = CW_USEDEFAULT;
- height = CW_USEDEFAULT;
- dock = KHM_DOCK_NONE;
-
- if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
- wconfig = L"CredWindow\\Windows\\MainMini";
- else
- wconfig = L"CredWindow\\Windows\\Main";
-
- if (KHM_SUCCEEDED(khc_open_space(NULL,
- wconfig,
- KHM_PERM_READ,
- &csp_mw))) {
- khm_int32 t;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"XPos", &t)))
- x = t;
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"YPos", &t)))
- y = t;
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Width", &t)))
- width = t;
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Height", &t)))
- height = t;
- if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)))
- dock = t;
-
- khc_close_space(csp_mw);
- }
-
- /* If there were no default values, we default to using 1/4 of the
- work area centered on the primary monitor. If there were any
- docking hints, then the next call to
- khm_adjust_window_dimensions_for_display() will reposition the
- window. */
- if (width == CW_USEDEFAULT || x == CW_USEDEFAULT) {
- RECT wr;
-
- SetRectEmpty(&wr);
- SystemParametersInfo(SPI_GETWORKAREA, 0, &wr, 0);
-
- if (width == CW_USEDEFAULT) {
- width = (wr.right - wr.left) / 2;
- height = (wr.bottom - wr.top) / 2;
- }
-
- if (x == CW_USEDEFAULT) {
- x = (wr.left + wr.right) / 2 - width / 2;
- y = (wr.top + wr.bottom) / 2 - height / 2;
- }
- }
-
- /* The saved dimensions might not actually be visible if the user
- has changed the resolution of the display or if it's a multiple
- monitor system where the monitor on which the Network Identity
- Manager window was on previously is no longer connected. We
- have to check for that and adjust the dimensions if needed. */
- SetRect(&r, x, y, x + width, y + height);
- khm_adjust_window_dimensions_for_display(&r, dock);
-
- *pr = r;
-}
-
-void
-khm_set_main_window_mode(int mode) {
-
- RECT r;
- khm_handle csp_cw;
-
- if (mode == khm_main_wnd_mode)
- return;
-
- khui_check_action(KHUI_ACTION_LAYOUT_MINI,
- ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
- khui_enable_action(KHUI_MENU_LAYOUT,
- ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
- khui_enable_action(KHUI_MENU_COLUMNS,
- ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
-
- khui_refresh_actions();
-
- khm_main_wnd_mode = mode;
- if (khm_hwnd_main) {
- khm_get_main_window_rect(&r);
-
- SetWindowPos(khm_hwnd_main,
- NULL,
- r.left, r.top,
- r.right - r.left, r.bottom - r.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER);
- }
-
- if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_WRITE,
- &csp_cw))) {
-
- khc_write_int32(csp_cw, L"DefaultWindowMode", mode);
- khc_close_space(csp_cw);
-
- }
-
- khm_cred_refresh();
-}
-
-void
-khm_create_main_window(void) {
- wchar_t buf[1024];
- khm_handle csp_cw = NULL;
- RECT r;
-
- LoadString(khm_hInstance, IDS_MAIN_WINDOW_TITLE,
- buf, ARRAYLENGTH(buf));
-
- khm_hwnd_null =
- CreateWindow(MAKEINTATOM(khm_null_window_class),
- buf,
- 0, /* Style */
- 0, 0, /* x, y */
- 100, 100, /* width, height */
- NULL, /* parent */
- NULL, /* menu */
- NULL, /* HINSTANCE */
- 0); /* lparam */
-
- if (!khm_hwnd_null)
- return;
-
- if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
- KHM_PERM_READ,
- &csp_cw))) {
- khm_int32 t;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultWindowMode", &t))) {
- khm_set_main_window_mode(t);
- }
-
- khc_close_space(csp_cw);
- }
-
- khm_get_main_window_rect(&r);
-
- khm_hwnd_main =
- CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
- MAKEINTATOM(khm_main_window_class),
- buf,
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
- WS_CLIPSIBLINGS,
- r.left, r.top,
- r.right - r.left,
- r.bottom - r.top,
- khm_hwnd_null,
- NULL,
- NULL,
- NULL);
-
- khui_set_main_window(khm_hwnd_main);
-}
-
-void
-khm_show_main_window(void) {
-
- if (khm_nCmdShow == SW_RESTORE) {
- HWND hw;
-
- hw = GetForegroundWindow();
- if (hw != khm_hwnd_main)
- SetForegroundWindow(khm_hwnd_main);
- }
-
- if (khm_nCmdShow == SW_SHOWMINIMIZED ||
- khm_nCmdShow == SW_SHOWMINNOACTIVE ||
- khm_nCmdShow == SW_MINIMIZE) {
- khm_hide_main_window();
- } else {
- ShowWindow(khm_hwnd_main, khm_nCmdShow);
- UpdateWindow(khm_hwnd_main);
-
- khm_taskbar_add_window(khm_hwnd_main);
-
- khm_cred_refresh();
- }
-
- khm_nCmdShow = SW_RESTORE;
-}
-
-void
-khm_activate_main_window(void) {
-
- if (!SetForegroundWindow(khm_hwnd_main)) {
- FLASHWINFO finfo;
-
- SetActiveWindow(khm_hwnd_main);
-
- ZeroMemory(&finfo, sizeof(finfo));
- finfo.cbSize = sizeof(finfo);
- finfo.hwnd = khm_hwnd_main;
- finfo.dwFlags = FLASHW_ALL;
- finfo.uCount = 3;
- finfo.dwTimeout = 0;
-
- FlashWindowEx(&finfo);
- }
-}
-
-void
-khm_close_main_window(void) {
- khm_handle csp_cw;
- BOOL keep_running = FALSE;
-
- if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
- KHM_PERM_READ, &csp_cw))) {
- khm_int32 t;
-
- if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"KeepRunning",
- &t))) {
- keep_running = t;
- } else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- }
-
- khc_close_space(csp_cw);
- } else {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- }
-
- if (keep_running)
- khm_hide_main_window();
- else
- DestroyWindow(khm_hwnd_main);
-}
-
-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);
-
- khm_taskbar_remove_window(khm_hwnd_main);
-}
-
-BOOL
-khm_is_main_window_visible(void) {
- return IsWindowVisible(khm_hwnd_main);
-}
-
-BOOL
-khm_is_main_window_active(void) {
- if (!IsWindowVisible(khm_hwnd_main))
- return FALSE;
- if (GetForegroundWindow() == khm_hwnd_main)
- return TRUE;
- return khm_is_dialog_active();
-}
-
-void
-khm_register_main_wnd_class(void) {
- WNDCLASSEX wc;
-
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = 0;
- wc.lpfnWndProc = khm_null_wnd_proc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = khm_hInstance;
- wc.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
- wc.hCursor = LoadCursor((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_ARROW));
- wc.hIconSm = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
- wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = KHUI_NULL_WINDOW_CLASS;
-
- khm_null_window_class = RegisterClassEx(&wc);
-
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = khm_main_wnd_proc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = khm_hInstance;
- wc.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
- wc.hCursor = LoadCursor((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_ARROW));
- wc.hIconSm = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
- wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = KHUI_MAIN_WINDOW_CLASS;
-
- khm_main_window_class = RegisterClassEx(&wc);
-}
-
-void
-khm_unregister_main_wnd_class(void) {
- UnregisterClass(MAKEINTATOM(khm_main_window_class),khm_hInstance);
- UnregisterClass(MAKEINTATOM(khm_null_window_class),khm_hInstance);
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ * Copyright (c) 2007 Secure Endpoints Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include<khmapp.h>
+#include<intaction.h>
+#include<assert.h>
+
+ATOM khm_main_window_class;
+ATOM khm_null_window_class;
+HWND khm_hwnd_null;
+HWND khm_hwnd_main;
+HWND khm_hwnd_rebar;
+HWND khm_hwnd_main_cred;
+
+int khm_main_wnd_mode = KHM_MAIN_WND_NORMAL;
+
+#define MW_RESIZE_TIMER 1
+#define MW_RESIZE_TIMEOUT 2000
+#define MW_REFRESH_TIMER 2
+#define MW_REFRESH_TIMEOUT 600
+
+void
+khm_set_dialog_result(HWND hwnd, LRESULT lr) {
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lr);
+#pragma warning(pop)
+}
+
+static void
+mw_restart_refresh_timer(HWND hwnd) {
+ khm_handle csp_cw;
+ khm_int32 timeout;
+
+ KillTimer(hwnd, MW_REFRESH_TIMER);
+ if (KHM_SUCCEEDED(khc_open_space(NULL,
+ L"CredWindow",
+ KHM_PERM_READ,
+ &csp_cw))) {
+ if (KHM_FAILED(khc_read_int32(csp_cw,
+ L"RefreshTimeout",
+ &timeout)))
+ timeout = MW_REFRESH_TIMEOUT;
+ khc_close_space(csp_cw);
+ } else {
+ timeout = MW_REFRESH_TIMEOUT;
+ }
+
+ timeout *= 1000; /* convert to milliseconds */
+
+ SetTimer(hwnd, MW_REFRESH_TIMER, timeout, NULL);
+}
+
+khm_int32 KHMAPI
+mw_select_cred(khm_handle cred, void * rock) {
+ if (cred)
+ kcdb_cred_set_flags(cred,
+ KCDB_CRED_FLAG_SELECTED,
+ KCDB_CRED_FLAG_SELECTED);
+
+ return KHM_ERROR_SUCCESS;
+}
+
+/* perform shutdown operations */
+static void
+khm_pre_shutdown(void) {
+ khm_handle csp_cw = NULL;
+ khm_handle credset = NULL;
+ khm_int32 t;
+ khm_size s;
+
+ /* Check if we should destroy all credentials on exit... */
+
+ if (KHM_FAILED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw)))
+ return;
+
+ if (KHM_FAILED(khc_read_int32(csp_cw, L"DestroyCredsOnExit", &t)) ||
+ !t)
+ goto _cleanup;
+
+ if (KHM_FAILED(kcdb_credset_create(&credset)))
+ goto _cleanup;
+
+ if (KHM_FAILED(kcdb_credset_extract(credset, NULL, NULL,
+ KCDB_TYPE_INVALID)))
+ goto _cleanup;
+
+ if (KHM_FAILED(kcdb_credset_get_size(credset, &s)) ||
+ s == 0)
+ goto _cleanup;
+
+ kcdb_credset_apply(credset, mw_select_cred, NULL);
+
+ khui_context_set(KHUI_SCOPE_GROUP,
+ NULL,
+ KCDB_CREDTYPE_INVALID,
+ NULL,
+ NULL,
+ 0,
+ credset);
+
+ khm_cred_destroy_creds(TRUE, TRUE);
+
+ _cleanup:
+
+ if (credset)
+ kcdb_credset_delete(credset);
+
+ if (csp_cw)
+ khc_close_space(csp_cw);
+}
+
+void
+khm_process_query_app_ver(khm_query_app_version * papp_ver) {
+
+ if (!papp_ver || papp_ver->magic != KHM_QUERY_APP_VER_MAGIC)
+ return;
+
+ papp_ver->ver_remote = app_version;
+
+ /* the remote instance has requested swapping in. we check the
+ version numbers and if the remote instance is newer than us,
+ then we exit and let the remote instance take over. */
+ if (papp_ver->request_swap) {
+ khm_version ver_caller = papp_ver->ver_caller;
+
+ if (ver_caller.major > app_version.major ||
+
+ (ver_caller.major == app_version.major &&
+ ver_caller.minor > app_version.minor) ||
+
+ (ver_caller.major == app_version.major &&
+ ver_caller.minor == app_version.minor &&
+ ver_caller.aux > app_version.aux) ||
+
+ (ver_caller.major == app_version.major &&
+ ver_caller.minor == app_version.minor &&
+ ver_caller.aux == app_version.aux &&
+ ver_caller.patch > app_version.patch)) {
+
+ papp_ver->request_swap = TRUE;
+
+ if (khm_hwnd_main)
+ DestroyWindow(khm_hwnd_main);
+
+ } else {
+
+ papp_ver->request_swap = FALSE;
+
+ }
+ }
+
+ papp_ver->code = KHM_ERROR_SUCCESS;
+}
+
+static void
+khm_ui_cb(LPARAM lParam) {
+ khui_ui_callback_data * pcbdata;
+
+ pcbdata = (khui_ui_callback_data *) lParam;
+
+ if (pcbdata == NULL || pcbdata->magic != KHUI_UICBDATA_MAGIC) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ return;
+ }
+
+#ifdef DEBUG
+ assert(pcbdata->cb);
+#endif
+
+ /* make the call */
+ if (!IsBadCodePtr(pcbdata->cb))
+ pcbdata->rv = (*pcbdata->cb)(khm_hwnd_main, pcbdata->rock);
+ else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ pcbdata->rv = KHM_ERROR_INVALID_PARAM;
+ }
+}
+
+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_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) {
+ RECT r;
+ khm_handle csp_cw;
+ khm_handle csp_mw;
+ const wchar_t * wconfig;
+
+ if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
+ wconfig = L"Windows\\MainMini";
+ else
+ wconfig = L"Windows\\Main";
+
+ KillTimer(hwnd, wParam);
+
+ GetWindowRect(hwnd, &r);
+
+ if (KHM_SUCCEEDED(khc_open_space(NULL,
+ L"CredWindow",
+ KHM_PERM_WRITE,
+ &csp_cw))) {
+ if (KHM_SUCCEEDED(khc_open_space(csp_cw,
+ wconfig,
+ KHM_PERM_WRITE,
+ &csp_mw))) {
+ khm_int32 t;
+
+ khc_write_int32(csp_mw, L"XPos", r.left);
+ khc_write_int32(csp_mw, L"YPos", r.top);
+ khc_write_int32(csp_mw, L"Width",
+ r.right - r.left);
+ khc_write_int32(csp_mw, L"Height",
+ r.bottom - r.top);
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)) &&
+ t != KHM_DOCK_NONE) {
+ khc_write_int32(csp_mw, L"Dock", KHM_DOCK_AUTO);
+ }
+
+ khc_close_space(csp_mw);
+ }
+ khc_close_space(csp_cw);
+ }
+
+ 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);
+ }
+ return 0;
+
+ case WM_KHUI_ASSIGN_COMMANDLINE_V1:
+ {
+ HANDLE hmap;
+ void * xfer;
+ wchar_t mapname[256];
+ struct tag_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 = (struct tag_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;
+
+ 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];
+ struct tag_khm_startup_options_v2 *pv2opt;
+ 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 = (struct tag_khm_startup_options_v2 *) xfer;
+
+ if (pv2opt->magic != STARTUP_OPTIONS_MAGIC ||
+ pv2opt->cb_size != sizeof(*pv2opt)) {
+ 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;
+
+ 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);
+}
+
+LRESULT CALLBACK
+khm_null_wnd_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+LRESULT
+khm_rebar_notify(LPNMHDR lpnm) {
+ switch(lpnm->code) {
+#if (_WIN32_WINNT >= 0x0501)
+ case RBN_AUTOBREAK:
+ {
+ LPNMREBARAUTOBREAK lpra = (LPNMREBARAUTOBREAK) lpnm;
+ lpra->fAutoBreak = TRUE;
+ }
+ break;
+#endif
+ case RBN_BEGINDRAG:
+ {
+ LPNMREBAR lprb = (LPNMREBAR) lpnm;
+ if ((lprb->dwMask & RBNM_ID) &&
+ lprb->wID == 0)
+ return 1;
+ else
+ return 0;
+ }
+ break;
+
+ case NM_CUSTOMDRAW:
+ return CDRF_DODEFAULT;
+ break;
+ }
+
+ return 1;
+}
+
+void
+khm_create_main_window_controls(HWND hwnd_main) {
+ REBARINFO rbi;
+ HWND hwRebar;
+
+ khm_menu_create_main(hwnd_main);
+
+ hwRebar =
+ CreateWindowEx(WS_EX_TOOLWINDOW,
+ REBARCLASSNAME,
+ L"Rebar",
+ WS_CHILD |
+ WS_VISIBLE|
+ WS_CLIPSIBLINGS |
+ WS_CLIPCHILDREN |
+ CCS_NODIVIDER |
+ RBS_VARHEIGHT |
+ RBS_FIXEDORDER,
+ 0,0,0,0,
+ hwnd_main,
+ NULL,
+ khm_hInstance,
+ NULL);
+
+ if(!hwRebar) {
+ DWORD dwe = GetLastError();
+ return;
+ }
+
+ khm_hwnd_rebar = hwRebar;
+
+ rbi.cbSize = sizeof(rbi);
+ rbi.fMask = 0;
+ rbi.himl = (HIMAGELIST) NULL;
+ if(!SendMessage(hwRebar, RB_SETBARINFO, 0, (LPARAM) &rbi))
+ return;
+
+ /* self attach */
+ khm_create_standard_toolbar(hwRebar);
+ khm_create_statusbar(hwnd_main);
+
+ /* manual attach */
+ khm_hwnd_main_cred = khm_create_credwnd(hwnd_main);
+}
+
+void
+khm_adjust_window_dimensions_for_display(RECT * pr, int dock) {
+
+ HMONITOR hmon;
+ RECT rm;
+ long x, y, width, height;
+
+ x = pr->left;
+ y = pr->top;
+ width = pr->right - pr->left;
+ height = pr->bottom - pr->top;
+
+ /* if the rect doesn't intersect with the display area of any
+ monitor, we just default to the primary monitor. */
+ hmon = MonitorFromRect(pr, MONITOR_DEFAULTTOPRIMARY);
+
+ if (hmon == NULL) {
+ /* huh? we'll just center this on the primary screen */
+ goto nomonitor;
+ } else {
+ MONITORINFO mi;
+
+ ZeroMemory(&mi, sizeof(mi));
+ mi.cbSize = sizeof(mi);
+
+ if (!GetMonitorInfo(hmon, &mi))
+ goto nomonitor;
+
+ CopyRect(&rm, &mi.rcWork);
+
+ goto adjust_dims;
+ }
+
+ nomonitor:
+ /* for some reason we couldn't get a handle on a monitor or we
+ couldn't get the metrics for that monitor. We default to
+ setting things up on the primary monitor. */
+
+ SetRectEmpty(&rm);
+ if (!SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID) &rm, 0))
+ goto done_with_monitor;
+
+ adjust_dims:
+
+ if (width > (rm.right - rm.left))
+ width = rm.right - rm.left;
+ if (height > (rm.bottom - rm.top))
+ height = rm.bottom - rm.top;
+
+ switch (dock & KHM_DOCKF_DOCKHINT) {
+ case KHM_DOCK_TOPLEFT:
+ x = rm.left;
+ y = rm.top;
+ break;
+
+ case KHM_DOCK_TOPRIGHT:
+ x = rm.right - width;
+ y = rm.top;
+ break;
+
+ case KHM_DOCK_BOTTOMRIGHT:
+ x = rm.right - width;
+ y = rm.bottom - height;
+ break;
+
+ case KHM_DOCK_BOTTOMLEFT:
+ x = rm.left;
+ y = rm.bottom - height;
+ break;
+
+ case KHM_DOCK_AUTO:
+ {
+ int cxt, cyt;
+
+ cxt = GetSystemMetrics(SM_CXDRAG);
+ cyt = GetSystemMetrics(SM_CYDRAG);
+
+ if (x > rm.left && (x - rm.left) < cxt)
+ x = rm.left;
+ else if ((x + width) < rm.right && (rm.right - (x + width)) < cxt)
+ x = rm.right - width;
+
+ if (y > rm.top && (y - rm.top) < cyt)
+ y = rm.top;
+ else if ((y + height) < rm.bottom && (rm.bottom - (y + height)) < cyt)
+ y = rm.bottom - height;
+ }
+ break;
+ }
+
+ if (!(dock & KHM_DOCKF_XBORDER)) {
+ if (x < rm.left)
+ x = rm.left;
+ if (x + width > rm.right)
+ x = rm.right - width;
+ if (y < rm.top)
+ y = rm.top;
+ if (y + height > rm.bottom)
+ y = rm.bottom - height;
+ }
+
+ done_with_monitor:
+ pr->left = x;
+ pr->top = y;
+ pr->right = x + width;
+ pr->bottom = y + height;
+
+}
+
+void
+khm_get_main_window_rect(RECT * pr) {
+ khm_handle csp_mw = NULL;
+ int x,y,width,height,dock;
+ RECT r;
+ const wchar_t * wconfig;
+
+ x = CW_USEDEFAULT;
+ y = CW_USEDEFAULT;
+ width = CW_USEDEFAULT;
+ height = CW_USEDEFAULT;
+ dock = KHM_DOCK_NONE;
+
+ if (khm_main_wnd_mode == KHM_MAIN_WND_MINI)
+ wconfig = L"CredWindow\\Windows\\MainMini";
+ else
+ wconfig = L"CredWindow\\Windows\\Main";
+
+ if (KHM_SUCCEEDED(khc_open_space(NULL,
+ wconfig,
+ KHM_PERM_READ,
+ &csp_mw))) {
+ khm_int32 t;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"XPos", &t)))
+ x = t;
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"YPos", &t)))
+ y = t;
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Width", &t)))
+ width = t;
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Height", &t)))
+ height = t;
+ if (KHM_SUCCEEDED(khc_read_int32(csp_mw, L"Dock", &t)))
+ dock = t;
+
+ khc_close_space(csp_mw);
+ }
+
+ /* If there were no default values, we default to using 1/4 of the
+ work area centered on the primary monitor. If there were any
+ docking hints, then the next call to
+ khm_adjust_window_dimensions_for_display() will reposition the
+ window. */
+ if (width == CW_USEDEFAULT || x == CW_USEDEFAULT) {
+ RECT wr;
+
+ SetRectEmpty(&wr);
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &wr, 0);
+
+ if (width == CW_USEDEFAULT) {
+ width = (wr.right - wr.left) / 2;
+ height = (wr.bottom - wr.top) / 2;
+ }
+
+ if (x == CW_USEDEFAULT) {
+ x = (wr.left + wr.right) / 2 - width / 2;
+ y = (wr.top + wr.bottom) / 2 - height / 2;
+ }
+ }
+
+ /* The saved dimensions might not actually be visible if the user
+ has changed the resolution of the display or if it's a multiple
+ monitor system where the monitor on which the Network Identity
+ Manager window was on previously is no longer connected. We
+ have to check for that and adjust the dimensions if needed. */
+ SetRect(&r, x, y, x + width, y + height);
+ khm_adjust_window_dimensions_for_display(&r, dock);
+
+ *pr = r;
+}
+
+void
+khm_set_main_window_mode(int mode) {
+
+ RECT r;
+ khm_handle csp_cw;
+
+ if (mode == khm_main_wnd_mode)
+ return;
+
+ khui_check_action(KHUI_ACTION_LAYOUT_MINI,
+ ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
+ khui_enable_action(KHUI_MENU_LAYOUT,
+ ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
+ khui_enable_action(KHUI_MENU_COLUMNS,
+ ((mode == KHM_MAIN_WND_MINI)? FALSE : TRUE));
+
+ khui_refresh_actions();
+
+ khm_main_wnd_mode = mode;
+ if (khm_hwnd_main) {
+ khm_get_main_window_rect(&r);
+
+ SetWindowPos(khm_hwnd_main,
+ NULL,
+ r.left, r.top,
+ r.right - r.left, r.bottom - r.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER);
+ }
+
+ if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_WRITE,
+ &csp_cw))) {
+
+ khc_write_int32(csp_cw, L"DefaultWindowMode", mode);
+ khc_close_space(csp_cw);
+
+ }
+
+ khm_cred_refresh();
+}
+
+void
+khm_create_main_window(void) {
+ wchar_t buf[1024];
+ khm_handle csp_cw = NULL;
+ RECT r;
+
+ LoadString(khm_hInstance, IDS_MAIN_WINDOW_TITLE,
+ buf, ARRAYLENGTH(buf));
+
+ khm_hwnd_null =
+ CreateWindow(MAKEINTATOM(khm_null_window_class),
+ buf,
+ 0, /* Style */
+ 0, 0, /* x, y */
+ 100, 100, /* width, height */
+ NULL, /* parent */
+ NULL, /* menu */
+ NULL, /* HINSTANCE */
+ 0); /* lparam */
+
+ if (!khm_hwnd_null)
+ return;
+
+ if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
+ KHM_PERM_READ,
+ &csp_cw))) {
+ khm_int32 t;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"DefaultWindowMode", &t))) {
+ khm_set_main_window_mode(t);
+ }
+
+ khc_close_space(csp_cw);
+ }
+
+ khm_get_main_window_rect(&r);
+
+ khm_hwnd_main =
+ CreateWindowEx(WS_EX_OVERLAPPEDWINDOW | WS_EX_APPWINDOW,
+ MAKEINTATOM(khm_main_window_class),
+ buf,
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
+ WS_CLIPSIBLINGS,
+ r.left, r.top,
+ r.right - r.left,
+ r.bottom - r.top,
+ khm_hwnd_null,
+ NULL,
+ NULL,
+ NULL);
+
+ khui_set_main_window(khm_hwnd_main);
+}
+
+void
+khm_show_main_window(void) {
+
+ if (khm_nCmdShow == SW_RESTORE) {
+ HWND hw;
+
+ hw = GetForegroundWindow();
+ if (hw != khm_hwnd_main)
+ SetForegroundWindow(khm_hwnd_main);
+ }
+
+ if (khm_nCmdShow == SW_SHOWMINIMIZED ||
+ khm_nCmdShow == SW_SHOWMINNOACTIVE ||
+ khm_nCmdShow == SW_MINIMIZE) {
+ khm_hide_main_window();
+ } else {
+ ShowWindow(khm_hwnd_main, khm_nCmdShow);
+ UpdateWindow(khm_hwnd_main);
+
+ khm_cred_refresh();
+ }
+
+ khm_nCmdShow = SW_RESTORE;
+}
+
+void
+khm_activate_main_window(void) {
+
+ if (!SetForegroundWindow(khm_hwnd_main)) {
+ FLASHWINFO finfo;
+
+ SetActiveWindow(khm_hwnd_main);
+
+ ZeroMemory(&finfo, sizeof(finfo));
+ finfo.cbSize = sizeof(finfo);
+ finfo.hwnd = khm_hwnd_main;
+ finfo.dwFlags = FLASHW_ALL;
+ finfo.uCount = 3;
+ finfo.dwTimeout = 0;
+
+ FlashWindowEx(&finfo);
+ }
+}
+
+void
+khm_close_main_window(void) {
+ khm_handle csp_cw;
+ BOOL keep_running = FALSE;
+
+ if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",
+ KHM_PERM_READ, &csp_cw))) {
+ khm_int32 t;
+
+ if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"KeepRunning",
+ &t))) {
+ keep_running = t;
+ } else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ }
+
+ khc_close_space(csp_cw);
+ } else {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ }
+
+ if (keep_running)
+ khm_hide_main_window();
+ else
+ DestroyWindow(khm_hwnd_main);
+}
+
+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);
+}
+
+BOOL
+khm_is_main_window_visible(void) {
+ return IsWindowVisible(khm_hwnd_main);
+}
+
+BOOL
+khm_is_main_window_active(void) {
+ if (!IsWindowVisible(khm_hwnd_main))
+ return FALSE;
+ if (GetForegroundWindow() == khm_hwnd_main)
+ return TRUE;
+ return khm_is_dialog_active();
+}
+
+void
+khm_register_main_wnd_class(void) {
+ WNDCLASSEX wc;
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = 0;
+ wc.lpfnWndProc = khm_null_wnd_proc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = khm_hInstance;
+ wc.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
+ wc.hCursor = LoadCursor((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_ARROW));
+ wc.hIconSm = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = KHUI_NULL_WINDOW_CLASS;
+
+ khm_null_window_class = RegisterClassEx(&wc);
+
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = khm_main_wnd_proc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = khm_hInstance;
+ wc.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
+ wc.hCursor = LoadCursor((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_ARROW));
+ wc.hIconSm = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE);
+ wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = KHUI_MAIN_WINDOW_CLASS;
+
+ khm_main_window_class = RegisterClassEx(&wc);
+}
+
+void
+khm_unregister_main_wnd_class(void) {
+ UnregisterClass(MAKEINTATOM(khm_main_window_class),khm_hInstance);
+ UnregisterClass(MAKEINTATOM(khm_null_window_class),khm_hInstance);
+}
diff --git a/src/windows/identity/ui/newcredwnd.c b/src/windows/identity/ui/newcredwnd.c
index d4d9a78..6c8ea60 100644
--- a/src/windows/identity/ui/newcredwnd.c
+++ b/src/windows/identity/ui/newcredwnd.c
@@ -1,2912 +1,2908 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- * Copyright (c) 2007 Secure Endpoints Inc.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-/* Include the OEMRESOURCE constants for locating standard icon
- resources. */
-#define OEMRESOURCE
-
-#include<khmapp.h>
-#include<assert.h>
-
-ATOM khui_newcredwnd_cls;
-
-/* forward dcl */
-static void
-nc_position_credtext(khui_nc_wnd_data * d);
-
-/* Common dialog procedure used by the main credential panel
- (IDD_NC_NEWCRED) and the button bar (IDC_NC_BBAR). */
-
-static void
-nc_layout_main_panel(khui_nc_wnd_data * d);
-
-static void
-nc_layout_new_cred_window(khui_nc_wnd_data * d);
-
-static INT_PTR CALLBACK
-nc_common_dlg_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch(uMsg) {
- case WM_INITDIALOG:
- {
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *) lParam;
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, DWLP_USER, lParam);
-#pragma warning(pop)
-
- if (d->nc->subtype == KMSG_CRED_PASSWORD) {
- ShowWindow(GetDlgItem(hwnd, IDC_NC_ADVANCED),
- SW_HIDE);
- }
- }
- return TRUE;
-
- case WM_COMMAND:
- {
- int ctrl_id;
-
- ctrl_id = LOWORD(wParam);
- if (ctrl_id < KHUI_CW_ID_MIN ||
- ctrl_id > KHUI_CW_ID_MAX) {
- /* pump it to the parent */
- PostMessage(GetParent(hwnd), WM_COMMAND, wParam, lParam);
- return TRUE;
- } /* else we allow the message to fall through and get
- passed into the identity provider's message
- handler. */
- }
- break;
-
- case KHUI_WM_NC_NOTIFY:
- {
- khui_nc_wnd_data * d;
- d = (khui_nc_wnd_data *)(LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- /* message sent by parent to notify us of something */
- switch(HIWORD(wParam)) {
- case WMNC_DIALOG_EXPAND:
- /* fallthrough */
- case WMNC_UPDATE_LAYOUT:
- if(hwnd == d->dlg_main) {
-
- nc_layout_main_panel(d);
-
- return TRUE;
- }
- break; /* nop */
- }
- }
- return TRUE;
- }
-
- /* check if we have a wnd_data, and if so pass the message on to
- the identity provider callback. */
- {
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *) (LONG_PTR)
- GetWindowLongPtr(hwnd, DWLP_USER);
-
- /* TODO: filter out and forward only the messages that
- originated or pertain to the identity selection
- controls. */
- if (d && d->nc && d->nc->ident_cb) {
- return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, uMsg,
- wParam, lParam);
- }
- }
-
- return FALSE;
-}
-
-static void
-nc_notify_clear(khui_nc_wnd_data * d) {
-
- if (d->notif_type == NC_NOTIFY_NONE)
- /* there are no notifications anyway. */
- return;
-
- if (d->hwnd_notif_label)
- DestroyWindow(d->hwnd_notif_label);
-
- if (d->hwnd_notif_aux)
- DestroyWindow(d->hwnd_notif_aux);
-
- d->hwnd_notif_label = NULL;
- d->hwnd_notif_aux = NULL;
-
- SetRectEmpty(&d->r_notif);
-
- d->notif_type = NC_NOTIFY_NONE;
-
- /* Note that we must call nc_layout_main_panel() after calling
- this to adjust the layout of the main panel. However we aren't
- calling it here since we might want to add another set of
- notifications or make other changes to the main panel content
- before calling nc_layout_main_panel(). */
-}
-
-static void
-nc_notify_marquee(khui_nc_wnd_data * d, const wchar_t * label) {
-
-#if (_WIN32_IE >= 0x0600)
- HDC hdc;
- size_t length;
- SIZE label_size;
-#endif
-
- RECT r_label;
- RECT r_mq;
- RECT r_row;
- HFONT hfont;
- HWND hwnd;
- HDWP hdefer;
-
- /* Clear the notification area. We only support one notification
- at a time. */
- nc_notify_clear(d);
-
-#ifdef DEBUG
- assert(d->dlg_main);
-#endif
-
-#if (_WIN32_IE >= 0x0600)
-
- /* We can only show the marquee control if the comctl32 DLL is
- version 6.0 or later. Otherwise we only show the label. */
-
- if (FAILED(StringCchLength(label, KHUI_MAXCCH_SHORT_DESC, &length))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- length = KHUI_MAXCCH_SHORT_DESC;
- }
-
- /* See how big the notification control needs to be. */
-
- hdc = GetDC(d->dlg_main);
-#ifdef DEBUG
- assert(hdc != NULL);
-#endif
-
- GetTextExtentPoint32(hdc, label, (int) length, &label_size);
-
- ReleaseDC(d->dlg_main, hdc);
-
- CopyRect(&r_row, &d->r_row);
-
- if (label_size.cx > d->r_e_label.right - d->r_e_label.left) {
- /* using an entire row */
- CopyRect(&r_label, &d->r_row);
- CopyRect(&r_mq, &d->r_n_input);
- OffsetRect(&r_mq, 0, r_row.bottom - r_row.top);
- r_row.bottom += r_row.bottom - r_row.top;
- } else if (label_size.cx > d->r_n_label.right - d->r_n_label.left) {
- /* using large labels */
- CopyRect(&r_label, &d->r_e_label);
- CopyRect(&r_mq, &d->r_e_input);
- } else {
- /* normal labels */
- CopyRect(&r_label, &d->r_n_label);
- CopyRect(&r_mq, &d->r_n_input);
- }
-
- InflateRect(&r_mq, 0, - ((r_mq.bottom - r_mq.top) / 4));
-
-#else /* _WIN32_IE < 0x0600 */
-
- /* We are just showing the label */
- CopyRect(&r_row, &d->r_row);
- CopyRect(&r_label, &r_row);
- SetRectEmpty(&r_mq);
-
-#endif /* _WIN32_IE >= 0x0600 */
-
- {
- long y;
-
- if (IsRectEmpty(&d->r_custprompt)) {
- y = d->r_idspec.bottom;
- } else {
- y = d->r_custprompt.bottom;
- }
-
- OffsetRect(&r_row, d->r_area.left, y);
- OffsetRect(&r_label, r_row.left, r_row.top);
- OffsetRect(&r_mq, r_row.left, r_row.top);
- }
-
- hfont = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
-
- hdefer = BeginDeferWindowPos(2);
-
- /* the label */
- hwnd = CreateWindowEx(0,
- L"STATIC",
- label,
- WS_CHILD | SS_ENDELLIPSIS,
- r_label.left, r_label.top,
- r_label.right - r_label.left,
- r_label.bottom - r_label.top,
- d->dlg_main,
- NULL, NULL, NULL);
-#ifdef DEBUG
- assert(hwnd != NULL);
-#endif
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hfont, (LPARAM) TRUE);
-
- DeferWindowPos(hdefer, hwnd, NULL,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_SHOWWINDOW);
-
- d->hwnd_notif_label = hwnd;
-
- /* and the marquee */
-
-#if (_WIN32_IE >= 0x0600)
-
- /* unfortunately, the marquee is only available on comctl32
- version 6.0 or later. On previous versions, we only display
- the message label. */
-
- hwnd = CreateWindowEx(0,
- PROGRESS_CLASS,
- L"",
- WS_CHILD | PBS_MARQUEE,
- r_mq.left, r_mq.top,
- r_mq.right - r_mq.left,
- r_mq.bottom - r_mq.top,
- d->dlg_main,
- NULL, NULL, NULL);
-#ifdef DEBUG
- assert(hwnd != NULL);
-#endif
-
- SendMessage(hwnd, PBM_SETMARQUEE, TRUE, 100);
-
- DeferWindowPos(hdefer, hwnd, NULL,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_SHOWWINDOW);
-
- d->hwnd_notif_aux = hwnd;
-
-#endif /* _WIN32_IE >= 0x0600 */
-
- EndDeferWindowPos(hdefer);
-
- CopyRect(&d->r_notif, &r_row);
-
- d->notif_type = NC_NOTIFY_MARQUEE;
-
- /* Note that we must call nc_layout_main_panel() after calling
- this to adjust the layout of the main panel. However we aren't
- calling it here since we might want to add another set of
- notifications or make other changes to the main panel content
- before calling nc_layout_main_panel(). */
-}
-
-static void
-nc_notify_message(khui_nc_wnd_data * d,
- kherr_severity severity,
- const wchar_t * message) {
-
- SIZE icon_size;
- LPCTSTR icon_res;
- HICON h_icon;
- HWND hwnd;
- HFONT hfont;
- HDWP hdefer;
-
- RECT r_row;
- RECT r_label;
- RECT r_icon;
-
- nc_notify_clear(d);
-
- icon_size.cx = GetSystemMetrics(SM_CXSMICON);
- icon_size.cy = GetSystemMetrics(SM_CYSMICON);
-
- switch(severity) {
- case KHERR_INFO:
- icon_res = MAKEINTRESOURCE(OIC_INFORMATION);
- break;
-
- case KHERR_WARNING:
- icon_res = MAKEINTRESOURCE(OIC_WARNING);
- break;
-
- case KHERR_ERROR:
- icon_res = MAKEINTRESOURCE(OIC_ERROR);
- break;
-
- default:
- icon_res = NULL;
- }
-
- if (icon_res != NULL) {
- h_icon = (HICON) LoadImage(NULL,
- icon_res,
- IMAGE_ICON,
- icon_size.cx,
- icon_size.cy,
- LR_DEFAULTCOLOR | LR_SHARED);
- } else {
- h_icon = NULL;
- }
-
- CopyRect(&r_row, &d->r_row);
-
-#define CENTERVALUE(w,v) ((w)/2 - (v)/2)
-
- SetRect(&r_icon,
- 0, CENTERVALUE(r_row.bottom - r_row.top, icon_size.cy),
- icon_size.cx,
- CENTERVALUE(r_row.bottom - r_row.top, icon_size.cy) + icon_size.cy);
-
-#undef CENTERVALUE
-
- CopyRect(&r_label, &r_row);
- OffsetRect(&r_label, -r_label.left, -r_label.top);
- r_label.left += (icon_size.cx * 3) / 2;
-
- {
- long y;
-
- if (IsRectEmpty(&d->r_custprompt)) {
- y = d->r_idspec.bottom;
- } else {
- y = d->r_custprompt.bottom;
- }
-
- OffsetRect(&r_row, d->r_area.left, y);
- OffsetRect(&r_label, r_row.left, r_row.top);
- OffsetRect(&r_icon, r_row.left, r_row.top);
- }
-
- hfont = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
-
- hdefer = BeginDeferWindowPos(2);
-
- hwnd = CreateWindowEx(0,
- L"STATIC",
- message,
- WS_CHILD | SS_ENDELLIPSIS | SS_CENTER,
- r_label.left, r_label.top,
- r_label.right - r_label.left,
- r_label.bottom - r_label.top,
- d->dlg_main,
- NULL, NULL, NULL);
-#ifdef DEBUG
- assert(hwnd != NULL);
-#endif
- SendMessage(hwnd, WM_SETFONT, (WPARAM) hfont, (LPARAM) TRUE);
-
- DeferWindowPos(hdefer, hwnd, NULL,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_SHOWWINDOW);
-
- d->hwnd_notif_label = hwnd;
-
- hwnd = CreateWindowEx(0,
- L"STATIC",
- NULL,
- WS_CHILD | SS_ICON |
-#if (_WIN32_IE >= 0x0600)
- SS_REALSIZECONTROL
-#else
- 0
-#endif
- ,
- r_icon.left, r_icon.top,
- r_icon.right - r_icon.left,
- r_icon.bottom - r_icon.top,
- d->dlg_main,
- NULL, NULL, NULL);
-#ifdef DEBUG
- assert(hwnd != NULL);
-#endif
-
- if (h_icon && hwnd)
- SendMessage(hwnd, STM_SETICON, (WPARAM) h_icon, 0);
-
- DeferWindowPos(hdefer, hwnd, NULL,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOZORDER);
-
- d->hwnd_notif_aux = hwnd;
-
- EndDeferWindowPos(hdefer);
-
- CopyRect(&d->r_notif, &r_row);
-
- d->notif_type = NC_NOTIFY_MESSAGE;
-
- /* Note that we must call nc_layout_main_panel() after calling
- this to adjust the layout of the main panel. However we aren't
- calling it here since we might want to add another set of
- notifications or make other changes to the main panel content
- before calling nc_layout_main_panel(). */
-}
-
-static void
-nc_layout_main_panel(khui_nc_wnd_data * d)
-{
- RECT r_main;
- HWND hw_ct;
- HWND hw_ct_label;
- HDWP hdwp;
- RECT r_used; /* extent used by identity specifiers,
- custom prompts and notificaiton
- controls. */
-
- RECT r_wmain; /* extents of the main window in screen
- coordinates. */
-
- r_main.left = 0;
- r_main.top = 0;
- r_main.bottom = NCDLG_HEIGHT;
- r_main.right = NCDLG_WIDTH;
-
- MapDialogRect(d->dlg_main, &r_main);
-
- CopyRect(&r_used, &d->r_idspec);
-
- GetWindowRect(d->dlg_main, &r_wmain);
-
- hdwp = BeginDeferWindowPos(7);
-
- /* check if the notification area and the custom prompt area are
- overlapping. */
-
- if (d->notif_type != NC_NOTIFY_NONE) {
- long delta_y = 0;
- RECT r;
-
- CopyRect(&r, &d->r_custprompt);
-
- if (IsRectEmpty(&d->r_custprompt)) {
- /* if there are no custom prompts, then the notification
- area should be immediately below the identitify
- specifers. */
-
- delta_y = d->r_idspec.bottom - d->r_notif.top;
- } else {
- /* otherwise, the notification area should be immediately
- below the custom prompt area */
-
- delta_y = d->r_custprompt.bottom - d->r_notif.top;
- }
-
- if (delta_y != 0) {
- RECT r_lbl;
- RECT r_aux;
-
- if (d->hwnd_notif_label) {
- GetWindowRect(d->hwnd_notif_label, &r_lbl);
- OffsetRect(&r_lbl, -r_wmain.left, delta_y - r_wmain.top);
-
- DeferWindowPos(hdwp, d->hwnd_notif_label, NULL,
- r_lbl.left, r_lbl.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOSIZE);
- }
-
- if (d->hwnd_notif_aux) {
- GetWindowRect(d->hwnd_notif_aux, &r_aux);
- OffsetRect(&r_aux, -r_wmain.left, delta_y - r_wmain.top);
-
- DeferWindowPos(hdwp, d->hwnd_notif_aux, NULL,
- r_aux.left, r_aux.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOSIZE);
- }
-
- OffsetRect(&d->r_notif, 0, delta_y);
- }
- }
-
- if (!IsRectEmpty(&d->r_custprompt)) {
- r_used.bottom = max(d->r_custprompt.bottom,
- r_used.bottom);
- }
-
- if (!IsRectEmpty(&d->r_notif)) {
- r_used.bottom = max(d->r_notif.bottom,
- r_used.bottom);
- }
-
- if (d->nc->mode == KHUI_NC_MODE_MINI) {
- RECT r_ok;
- RECT r_cancel;
- RECT r_advanced;
- HWND hw;
-
- hw = GetDlgItem(d->dlg_main, IDOK);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- GetWindowRect(hw, &r_ok);
- OffsetRect(&r_ok, -r_wmain.left, -r_ok.top + r_used.bottom);
-
- DeferWindowPos(hdwp, hw, NULL,
- r_ok.left, r_ok.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
-
- hw = GetDlgItem(d->dlg_main, IDCANCEL);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- GetWindowRect(hw, &r_cancel);
- OffsetRect(&r_cancel, -r_wmain.left, -r_cancel.top + r_used.bottom);
-
- DeferWindowPos(hdwp, hw, NULL,
- r_cancel.left, r_cancel.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
-
- hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- GetWindowRect(hw, &r_advanced);
- OffsetRect(&r_advanced, -r_wmain.left, -r_advanced.top + r_used.bottom);
-
- DeferWindowPos(hdwp, hw, NULL,
- r_advanced.left, r_advanced.top, 0, 0,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
-
- /* and now update the extents of the main panel */
- r_main.bottom = r_used.bottom + (r_ok.bottom - r_ok.top) + d->r_area.top;
-
- CopyRect(&d->r_main, &r_main);
-
- } else {
-
- HWND hw;
-
- hw = GetDlgItem(d->dlg_main, IDOK);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- if (IsWindowVisible(hw))
- DeferWindowPos(hdwp, hw, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
- SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- hw = GetDlgItem(d->dlg_main, IDCANCEL);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- if (IsWindowVisible(hw))
- DeferWindowPos(hdwp, hw, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
- SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
-#ifdef DEBUG
- assert(hw != NULL);
-#endif
- if (IsWindowVisible(hw))
- DeferWindowPos(hdwp, hw, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
- SWP_NOOWNERZORDER | SWP_NOZORDER);
-
- d->r_credtext.top = r_used.bottom;
-
- CopyRect(&d->r_main, &r_main);
- }
-
- /* now update the layout of the credentials text window */
-
- hw_ct = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT);
- hw_ct_label = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT_LABEL);
-#ifdef DEBUG
- assert(hw_ct != NULL);
- assert(hw_ct_label != NULL);
-#endif
-
- if (d->nc->mode == KHUI_NC_MODE_MINI ||
- d->r_credtext.bottom < d->r_credtext.top + d->r_row.bottom * 2) {
-
- /* either we aren't supposed to show the credentials text
- window, or we don't have enough room. */
- if (IsWindowVisible(hw_ct) || IsWindowVisible(hw_ct_label)) {
-
- DeferWindowPos(hdwp, hw_ct, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
-
- DeferWindowPos(hdwp, hw_ct_label, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
-
- }
-
- } else {
-
- DeferWindowPos(hdwp,
- hw_ct, NULL,
- d->r_credtext.left + d->r_n_input.left, /* x */
- d->r_credtext.top, /* y */
- d->r_n_input.right - d->r_n_input.left, /* width */
- d->r_credtext.bottom - d->r_credtext.top, /* height */
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_SHOWWINDOW);
-
- DeferWindowPos(hdwp,
- hw_ct_label, NULL,
- d->r_credtext.left + d->r_n_label.left, /* x */
- d->r_credtext.top, /* y */
- d->r_n_label.right - d->r_n_label.left, /* width */
- d->r_n_label.bottom - d->r_n_label.top, /* height */
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_SHOWWINDOW);
- }
-
- EndDeferWindowPos(hdwp);
-
- /* NOTE: although we updated d->r_main, if the new credentials
- window is in mini mode, we must call
- nc_layout_new_cred_window() to adjust the size of the new
- credentials window to fit the main panel. We don't do it here
- because we need to keep these two operations separate. */
-}
-
-/* Credential type panel comparison function. Tabs are sorted based
- on the following criteria:
-
- 1) By ordinal - Panels with ordinal -1 will be ranked after panels
- whose ordinal is not -1.
-
- 2) By name - Case insensitive comparison of the name. If the panel
- does not have a name (i.e. the ->name member is NULL, it will be
- ranked after panels which have a name.
- */
-static int __cdecl
-nc_tab_sort_func(const void * v1, const void * v2)
-{
- /* v1 and v2 and of type : khui_new_creds_by_type ** */
- khui_new_creds_by_type *t1, *t2;
-
- t1 = *((khui_new_creds_by_type **) v1);
- t2 = *((khui_new_creds_by_type **) v2);
-
- if(t1->ordinal != -1) {
- if(t2->ordinal != -1) {
- if(t1->ordinal == t2->ordinal) {
- if (t1->name && t2->name)
- return _wcsicmp(t1->name, t2->name);
- else if (t1->name)
- return -1;
- else if (t2->name)
- return 1;
- else
- return 0;
- } else {
- /* safe to convert to an int here */
- return (int) (t1->ordinal - t2->ordinal);
- }
- } else
- return -1;
- } else {
- if(t2->ordinal != -1)
- return 1;
- else if (t1->name && t2->name)
- return wcscmp(t1->name, t2->name);
- else if (t1->name)
- return -1;
- else if (t2->name)
- return 1;
- else
- return 0;
- }
-}
-
-static void
-nc_notify_types(khui_new_creds * c, UINT uMsg,
- WPARAM wParam, LPARAM lParam, BOOL sync)
-{
- khm_size i;
-
- for(i=0; i<c->n_types; i++) {
-
- if (c->types[i]->hwnd_panel == NULL)
- continue;
-
- if (sync)
- SendMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
- else
- PostMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
- }
-}
-
-static void
-nc_clear_password_fields(khui_nc_wnd_data * d)
-{
- khm_size i;
- khm_boolean need_sync = FALSE;
-
- khui_cw_lock_nc(d->nc);
-
- for (i=0; i < d->nc->n_prompts; i++) {
- if ((d->nc->prompts[i]->flags & KHUI_NCPROMPT_FLAG_HIDDEN) &&
- d->nc->prompts[i]->hwnd_edit) {
- SetWindowText(d->nc->prompts[i]->hwnd_edit,
- L"");
- need_sync = TRUE;
- }
- }
-
- khui_cw_unlock_nc(d->nc);
-
- if (need_sync) {
- khui_cw_sync_prompt_values(d->nc);
- }
-}
-
-/* used by nc_enable_controls */
-
-struct nc_enum_wnd_data {
- khui_nc_wnd_data * d;
- khm_boolean enable;
-};
-
-static
-BOOL CALLBACK
-nc_enum_wnd_proc(HWND hwnd,
- LPARAM lParam)
-{
- struct nc_enum_wnd_data * wd;
-
- wd = (struct nc_enum_wnd_data *) lParam;
-
- EnableWindow(hwnd, wd->enable);
-
- return TRUE;
-}
-
-static void
-nc_enable_controls(khui_nc_wnd_data * d, khm_boolean enable)
-{
- struct nc_enum_wnd_data wd;
-
- ZeroMemory(&wd, sizeof(wd));
-
- wd.d = d;
- wd.enable = enable;
-
- EnumChildWindows(d->dlg_main, nc_enum_wnd_proc, (LPARAM) &wd);
-}
-
-#define NC_MAXCCH_CREDTEXT 16384
-#define NC_MAXCB_CREDTEXT (NC_MAXCCH_CREDTEXT * sizeof(wchar_t))
-
-static void
-nc_update_credtext(khui_nc_wnd_data * d)
-{
- wchar_t * ctbuf = NULL;
- wchar_t * buf;
- BOOL okEnable = FALSE;
- BOOL validId = FALSE;
- HWND hw = NULL;
- size_t cch = 0;
-
- ctbuf = PMALLOC(NC_MAXCB_CREDTEXT);
-
- assert(ctbuf != NULL);
-
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_TABS, ctbuf, NC_MAXCCH_CREDTEXT);
- StringCchLength(ctbuf, NC_MAXCCH_CREDTEXT, &cch);
- buf = ctbuf + cch;
- nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), (LPARAM) d->nc, TRUE);
-
- /* hopefully all the types have updated their credential texts */
-
- /* if the dialog is in the mini mode, we have to display
- exceptions using a notification. */
- if (d->nc->mode == KHUI_NC_MODE_MINI) {
- BOOL need_layout = FALSE;
- if (d->nc->n_identities == 0) {
-
- /* There are no identities selected. We don't show any
- notifications here. */
- if (d->notif_type != NC_NOTIFY_NONE) {
- nc_notify_clear(d);
- need_layout = TRUE;
- }
-
- } else {
-
- wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
- wchar_t format[256];
- wchar_t msg[ARRAYLENGTH(format) + ARRAYLENGTH(id_name)];
- khm_size cbbuf;
- khm_int32 flags;
-
- kcdb_identity_get_flags(d->nc->identities[0], &flags);
-
- cbbuf = sizeof(id_name);
- kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
-
- if (flags & KCDB_IDENT_FLAG_INVALID) {
-
- /* identity is invalid */
- LoadString(khm_hInstance, IDS_NCN_IDENT_INVALID,
- format, ARRAYLENGTH(format));
- StringCbPrintf(msg, sizeof(msg), format, id_name);
-
- nc_notify_message(d, KHERR_ERROR, msg);
-
- need_layout = TRUE;
-
- } else if ((flags & KCDB_IDENT_FLAG_VALID) ||
- d->nc->subtype == KMSG_CRED_PASSWORD) {
- /* special case: If we are going to change the
- password, we don't expect the identity provider to
- validate the identity in real time. As such, we
- assume that the identity is valid. */
-
- /* identity is valid */
- if (d->notif_type != NC_NOTIFY_NONE) {
- nc_notify_clear(d);
- need_layout = TRUE;
- }
-
- } else if (flags & KCDB_IDENT_FLAG_UNKNOWN) {
-
- /* unknown state */
- LoadString(khm_hInstance, IDS_NCN_IDENT_UNKNOWN,
- format, ARRAYLENGTH(format));
- StringCbPrintf(msg, sizeof(msg), format, id_name);
-
- nc_notify_message(d, KHERR_WARNING, msg);
-
- need_layout = TRUE;
-
- } else {
-
- /* still checking */
- LoadString(khm_hInstance, IDS_NCN_IDENT_CHECKING,
- format, ARRAYLENGTH(format));
- StringCbPrintf(msg, sizeof(msg), format, id_name);
-
- nc_notify_marquee(d, msg);
-
- need_layout = TRUE;
-
- }
- }
-
- if (need_layout) {
- nc_layout_main_panel(d);
- nc_layout_new_cred_window(d);
- }
- }
-
- if(d->nc->n_identities == 1) {
- wchar_t main_fmt[256];
- wchar_t id_fmt[256];
- wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
- wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
- khm_size cbbuf;
- khm_int32 flags;
-
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_ONE,
- main_fmt, (int) ARRAYLENGTH(main_fmt));
-
- cbbuf = sizeof(id_name);
- kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
-
- kcdb_identity_get_flags(d->nc->identities[0], &flags);
-
- if (flags & KCDB_IDENT_FLAG_INVALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else if(flags & KCDB_IDENT_FLAG_VALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else if(flags & KCDB_IDENT_FLAG_UNKNOWN) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else if(d->nc->subtype == KMSG_CRED_NEW_CREDS) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_CHECKING,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- }
-
- StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
-
- StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
- main_fmt, id_string);
-
- if (flags & KCDB_IDENT_FLAG_VALID) {
- if (flags & KCDB_IDENT_FLAG_DEFAULT)
- LoadString(khm_hInstance, IDS_NC_ID_DEF,
- id_string, ARRAYLENGTH(id_string));
- else if (d->nc->set_default)
- LoadString(khm_hInstance, IDS_NC_ID_WDEF,
- id_string, ARRAYLENGTH(id_string));
- else
- LoadString(khm_hInstance, IDS_NC_ID_NDEF,
- id_string, ARRAYLENGTH(id_string));
-
- StringCbCat(buf, NC_MAXCB_CREDTEXT - cch * sizeof(wchar_t),
- id_string);
- }
-
- } else if(d->nc->n_identities > 1) {
- wchar_t *ids_string;
- khm_size cb_ids_string;
-
- wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
- wchar_t id_fmt[256];
- wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
-
- wchar_t main_fmt[256];
- khm_size cbbuf;
-
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_MANY,
- main_fmt, (int) ARRAYLENGTH(main_fmt));
-
- /* we are going to concatenate all the identity names into
- a comma separated string */
-
- /* d->nc->n_identities is at least 2 */
- ids_string = PMALLOC((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
- (d->nc->n_identities - 1));
- cb_ids_string =
- (KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
- (d->nc->n_identities - 1);
-
- assert(ids_string != NULL);
-
- ids_string[0] = 0;
-
- {
- khm_size i;
- khm_int32 flags;
-
- for(i=1; i<d->nc->n_identities; i++) {
- if(i>1) {
- StringCbCat(ids_string, cb_ids_string, L",");
- }
-
- flags = 0;
-
- cbbuf = sizeof(id_name);
- kcdb_identity_get_name(d->nc->identities[i], id_name, &cbbuf);
- kcdb_identity_get_flags(d->nc->identities[i], &flags);
- if(flags & KCDB_IDENT_FLAG_INVALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else if(flags & KCDB_IDENT_FLAG_VALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- }
-
- StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
- StringCbCat(ids_string, cb_ids_string, id_string);
- }
-
- cbbuf = sizeof(id_name);
- kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
- kcdb_identity_get_flags(d->nc->identities[0], &flags);
- if(flags & KCDB_IDENT_FLAG_INVALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else if(flags & KCDB_IDENT_FLAG_VALID) {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- } else {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
- id_fmt, (int) ARRAYLENGTH(id_fmt));
- }
- StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
-
- StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
- main_fmt, id_string, ids_string);
-
- PFREE(ids_string);
- }
- } else {
- LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_NONE,
- buf, (int)(NC_MAXCCH_CREDTEXT - cch));
- }
-
- /* now, append the credtext string from each of the cred types */
- {
- khm_size i;
- size_t cb;
- wchar_t * buf;
-
- cb = NC_MAXCB_CREDTEXT;
- buf = ctbuf;
-
- for(i=0; i<d->nc->n_types; i++) {
- if(d->nc->types[i]->credtext != NULL) {
- StringCbCatEx(buf, cb,
- d->nc->types[i]->credtext,
- &buf, &cb,
- 0);
- }
- }
- }
-
- SetDlgItemText(d->dlg_main, IDC_NC_CREDTEXT, ctbuf);
-
- PFREE(ctbuf);
-
- /* so depending on whether the primary identity was found to be
- invalid, we need to disable the Ok button and set the title to
- reflect this */
-
- if(d->nc->n_identities > 0) {
- khm_int32 flags = 0;
-
- if(KHM_SUCCEEDED(kcdb_identity_get_flags(d->nc->identities[0],
- &flags)) &&
- (flags & KCDB_IDENT_FLAG_VALID)) {
- validId = TRUE;
- }
- }
-
- if (d->nc->window_title == NULL) {
- if(validId) {
- wchar_t wpostfix[256];
- wchar_t wtitle[KCDB_IDENT_MAXCCH_NAME + 256];
- khm_size cbsize;
-
- cbsize = sizeof(wtitle);
- kcdb_identity_get_name(d->nc->identities[0], wtitle, &cbsize);
-
- if (d->nc->subtype == KMSG_CRED_PASSWORD)
- LoadString(khm_hInstance, IDS_WTPOST_PASSWORD,
- wpostfix, (int) ARRAYLENGTH(wpostfix));
- else
- LoadString(khm_hInstance, IDS_WTPOST_NEW_CREDS,
- wpostfix, (int) ARRAYLENGTH(wpostfix));
-
- StringCbCat(wtitle, sizeof(wtitle), wpostfix);
-
- SetWindowText(d->nc->hwnd, wtitle);
- } else {
- wchar_t wtitle[256];
-
- if (d->nc->subtype == KMSG_CRED_PASSWORD)
- LoadString(khm_hInstance, IDS_WT_PASSWORD,
- wtitle, (int) ARRAYLENGTH(wtitle));
- else
- LoadString(khm_hInstance, IDS_WT_NEW_CREDS,
- wtitle, (int) ARRAYLENGTH(wtitle));
-
- SetWindowText(d->nc->hwnd, wtitle);
- }
- }
-
- if (!(d->nc->response & KHUI_NC_RESPONSE_PROCESSING)) {
- if(validId ||
- d->nc->subtype == KMSG_CRED_PASSWORD) {
- /* TODO: check if all the required fields have valid values
- before enabling the Ok button */
- okEnable = TRUE;
- }
-
- hw = GetDlgItem(d->dlg_main, IDOK);
- EnableWindow(hw, okEnable);
- hw = GetDlgItem(d->dlg_bb, IDOK);
- EnableWindow(hw, okEnable);
- }
-}
-
-static void
-nc_layout_new_cred_window(khui_nc_wnd_data * ncd) {
- khui_new_creds * c;
- RECT r_main;
- RECT r_ncdialog;
- HDWP hdefer;
-
- c = ncd->nc;
-
- r_main.left = 0;
- r_main.top = 0;
- r_main.right = NCDLG_WIDTH;
- r_main.bottom = NCDLG_HEIGHT;
-
- MapDialogRect(ncd->dlg_main, &r_main);
-
- hdefer = BeginDeferWindowPos(5);
-
- if (c->mode == KHUI_NC_MODE_MINI) {
-
- if (IsWindowVisible(ncd->tab_wnd)) {
- DeferWindowPos(hdefer,
- ncd->tab_wnd, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW |
- SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_NOZORDER);
- }
-
- if (IsWindowVisible(ncd->dlg_bb)) {
- DeferWindowPos(hdefer,
- ncd->dlg_bb, NULL,
- 0, 0, 0, 0,
- SWP_HIDEWINDOW |
- SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOSIZE | SWP_NOZORDER);
- }
-
- DeferWindowPos(hdefer, ncd->dlg_main, NULL,
- r_main.left, r_main.top,
- r_main.right - r_main.left,
- r_main.bottom - r_main.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_SHOWWINDOW);
-
- /* note that the ncd->r_main.bottom may not be the same as
- r_main.bottom because ncd->r_main.bottom is set dynamically
- depending on custom controls. ncd->r_main is valid only
- once nc_layout_main_panel() is called.*/
- CopyRect(&ncd->r_required, &ncd->r_main);
-
- } else {
- RECT r_tabctrl;
- RECT r_displayarea;
- RECT r_bbar;
- khm_size i;
-
- /* calculate the size of the tab control so that it fits
- snugly around the expanded main panel. */
- CopyRect(&r_tabctrl, &r_main);
- TabCtrl_AdjustRect(ncd->tab_wnd, TRUE, &r_tabctrl);
-
- if (r_tabctrl.left < 0 ||
- r_tabctrl.top < 0) {
-
- OffsetRect(&r_tabctrl,
- (r_tabctrl.left < 0)? -r_tabctrl.left : 0,
- (r_tabctrl.top < 0)? -r_tabctrl.top : 0);
-
- }
-
-#ifdef DEBUG
- assert(r_tabctrl.left == 0);
- assert(r_tabctrl.top == 0);
-#endif
-
- OffsetRect(&r_tabctrl, 0, ncd->r_area.top);
-
- /* and now calculate the rectangle where the main panel should
- be inside the tab control. */
- CopyRect(&r_displayarea, &r_tabctrl);
- TabCtrl_AdjustRect(ncd->tab_wnd, FALSE, &r_displayarea);
-
- DeferWindowPos(hdefer,
- ncd->tab_wnd, HWND_BOTTOM,
- r_tabctrl.left, r_tabctrl.top,
- r_tabctrl.right - r_tabctrl.left,
- r_tabctrl.bottom - r_tabctrl.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_SHOWWINDOW);
-
- /* we have to place the button bar just to the right of the
- tab panel. */
- r_bbar.left = 0;
- r_bbar.top = 0;
- r_bbar.right = NCDLG_BBAR_WIDTH;
- r_bbar.bottom = NCDLG_BBAR_HEIGHT;
-
- MapDialogRect(ncd->dlg_main, &r_bbar);
-
- OffsetRect(&r_bbar, r_tabctrl.right, 0);
-
- DeferWindowPos(hdefer,
- ncd->dlg_bb, NULL,
- r_bbar.left, r_bbar.top,
- r_bbar.right - r_bbar.left,
- r_bbar.bottom - r_bbar.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER | SWP_SHOWWINDOW);
-
- /* move the main panel inside the tab control... */
- DeferWindowPos(hdefer,
- ncd->dlg_main, NULL,
- r_displayarea.left, r_displayarea.top,
- r_displayarea.right - r_displayarea.left,
- r_displayarea.bottom - r_displayarea.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER |
- (ncd->current_panel == 0 ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
-
- /* and also move all the credential type panels (if they have
- been created) inside the tab control too. */
- khui_cw_lock_nc(c);
-
- for (i=0; i < c->n_types; i++) {
- if (c->types[i]->hwnd_panel != NULL) {
- DeferWindowPos(hdefer,
- c->types[i]->hwnd_panel, NULL,
- r_displayarea.left, r_displayarea.top,
- r_displayarea.right - r_displayarea.left,
- r_displayarea.bottom - r_displayarea.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER |
- SWP_NOZORDER |
- (ncd->current_panel == c->types[i]->ordinal ?
- SWP_SHOWWINDOW : SWP_HIDEWINDOW));
- }
- }
-
- khui_cw_unlock_nc(c);
-
- /* then update the required size of the new credentials
- dialog. */
- ncd->r_required.left = 0;
- ncd->r_required.top = 0;
- ncd->r_required.right = r_bbar.right;
- ncd->r_required.bottom = max(r_tabctrl.bottom, r_bbar.bottom) + ncd->r_area.top;
- }
-
- /* commit all the window moves, resizes and hides/shows we did*/
- EndDeferWindowPos(hdefer);
-
- /* now we have to see if the client area of the new credentials
- window is the right size. */
-
- GetClientRect(c->hwnd, &r_ncdialog);
-
- if (
-
- ((r_ncdialog.right - r_ncdialog.left !=
- ncd->r_required.right - ncd->r_required.left)
-
- ||
-
- (r_ncdialog.bottom - r_ncdialog.top !=
- ncd->r_required.bottom - ncd->r_required.top))
-
- &&
-
- /* we don't bother if the new creds window is already in the
- process of changing the size. */
- !ncd->size_changing) {
-
- /* if not, notify the window that the size needs adjusting. */
- if (IsWindowVisible(c->hwnd))
- PostMessage(c->hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_LAYOUT), 0);
- else
- SendMessage(c->hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_UPDATE_LAYOUT), 0);
- }
-}
-
-#define CW_PARAM DWLP_USER
-
-static LRESULT
-nc_handle_wm_create(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- LPCREATESTRUCT lpc;
- khui_new_creds * c;
- khui_nc_wnd_data * ncd;
- int x, y;
- int width, height;
- RECT r;
- HFONT hf_main;
-
- lpc = (LPCREATESTRUCT) lParam;
-
- ncd = PMALLOC(sizeof(*ncd));
- ZeroMemory(ncd, sizeof(*ncd));
-
- c = (khui_new_creds *) lpc->lpCreateParams;
- ncd->nc = c;
- c->hwnd = hwnd;
-
-#ifdef DEBUG
- assert(c->subtype == KMSG_CRED_NEW_CREDS ||
- c->subtype == KMSG_CRED_PASSWORD);
-#endif
-
-#pragma warning(push)
-#pragma warning(disable: 4244)
- SetWindowLongPtr(hwnd, CW_PARAM, (LONG_PTR) ncd);
-#pragma warning(pop)
-
- /* first, create the tab control that will house the main dialog
- panel as well as the plug-in specific panels */
- ncd->tab_wnd = CreateWindowEx(0, /* extended style */
- WC_TABCONTROL,
- L"TabControloxxrz", /* window name */
- TCS_HOTTRACK | TCS_RAGGEDRIGHT |
- TCS_SINGLELINE | TCS_TABS |
- WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS,
- 0, 0, 100, 100, /* x,y,width height.
- We'll be changing
- these later
- anyway. */
- hwnd,
- (HMENU) IDC_NC_TABS,
- NULL,
- 0);
-
-#ifdef DEBUG
- assert(ncd->tab_wnd != NULL);
-#endif
-
- /* try to create the main dialog panel */
-
- ncd->dlg_main = CreateDialogParam(khm_hInstance,
- MAKEINTRESOURCE(IDD_NC_NEWCRED),
- hwnd,
- nc_common_dlg_proc,
- (LPARAM) ncd);
-#ifdef DEBUG
- assert(ncd->dlg_main != NULL);
-#endif
-
- hf_main = (HFONT) SendMessage(ncd->dlg_main, WM_GETFONT, 0, 0);
- if (hf_main)
- SendMessage(ncd->tab_wnd, WM_SETFONT, (WPARAM) hf_main, FALSE);
-
- {
- RECT r_main;
- RECT r_area;
- RECT r_row;
- HWND hw;
-
- /* During the operation of the new credentials window, we will
- need to dynamically change the layout of the controls as a
- result of custom prompting from credentials providers and
- identity selectors from identity providers. In order to
- guide the dynamic layout, we pick out a few metrics from
- the dialog template for the main panel. The metrics come
- from hidden STATIC controls in the dialog template. */
-
- GetWindowRect(ncd->dlg_main, &r_main);
-
- /* IDC_NC_TPL_PANEL spans the full extent of the dialog that
- we can populate with custom controls. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_PANEL);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r_area);
- OffsetRect(&r_area,-r_main.left, -r_main.top);
- CopyRect(&ncd->r_area, &r_area);
-
- /* IDC_NC_TPL_ROW spans the extent of a row of normal sized
- custom controls. A row of custom controls typicall consist
- of a text label and an input control. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- CopyRect(&r_row, &r);
- OffsetRect(&r,-r.left, -r.top);
- CopyRect(&ncd->r_row, &r);
-
- /* IDC_NC_TPL_LABEL spans the extent that a normal sized
- label. The control overlaps IDC_NC_TPL_ROW so we can get
- coordinates relative to the row extents. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- OffsetRect(&r,-r_row.left, -r_row.top);
- CopyRect(&ncd->r_n_label, &r);
-
- /* IDC_NC_TPL_INPUT spans the extent of a normal sized input
- control in a custom control row. The control overlaps
- IDC_NC_TPL_ROW so we can get relative coordinates. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- OffsetRect(&r, -r_row.left, -r_row.top);
- CopyRect(&ncd->r_n_input, &r);
-
- /* IDC_NC_TPL_ROW_LG spans the extent of a row of large sized
- controls. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW_LG);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r_row);
-
- /* IDC_NC_TPL_LABEL_LG is a large sized label. The control
- overlaps IDC_NC_TPL_ROW_LG. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL_LG);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- OffsetRect(&r, -r_row.left, -r_row.top);
- CopyRect(&ncd->r_e_label, &r);
-
- /* IDC_NC_TPL_INPUT_LG is a large sized input control.
- Overlaps IDC_NC_TPL_ROW_LG. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT_LG);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- OffsetRect(&r, -r_row.left, -r_row.top);
- CopyRect(&ncd->r_e_input, &r);
-
- CopyRect(&ncd->r_credtext, &ncd->r_area);
- CopyRect(&ncd->r_idspec, &ncd->r_area);
-
- ncd->r_idspec.bottom = ncd->r_idspec.top;
-
- /* And finally the credential text window. The only metric we
- take from here is the Y coordinate of the bottom of the
- control since the actual size and position of the
- credentials window will change depending on the custom
- controls being displayed. */
- hw = GetDlgItem(ncd->dlg_main, IDC_NC_CREDTEXT);
-#ifdef DEBUG
- assert(hw);
-#endif
- GetWindowRect(hw, &r);
- OffsetRect(&r, -r_main.left, -r_main.top);
- ncd->r_credtext.bottom = r.bottom;
- }
-
- /* if the mode is 'mini'*/
- r.left = 0;
- r.top = 0;
-
- if(c->mode == KHUI_NC_MODE_MINI) {
- r.right = NCDLG_WIDTH;
- r.bottom = NCDLG_HEIGHT;
- } else {
- r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;
- r.bottom = NCDLG_BBAR_HEIGHT;
- }
-
- MapDialogRect(ncd->dlg_main, &r);
-
- /* position the new credentials dialog */
- width = r.right - r.left;
- height = r.bottom - r.top;
-
- /* adjust width and height to accomodate NC area */
- {
- RECT wr,cr;
-
- GetWindowRect(hwnd, &wr);
- GetClientRect(hwnd, &cr);
-
- /* the non-client and client areas have already been calculated
- at this point. We just use the difference to adjust the width
- and height */
- width += (wr.right - wr.left) - (cr.right - cr.left);
- height += (wr.bottom - wr.top) - (cr.bottom - cr.top);
- }
-
- /* if the parent window is visible, we center the new credentials
- dialog over the parent. Otherwise, we center it on the primary
- display. */
-
- if (IsWindowVisible(lpc->hwndParent)) {
- GetWindowRect(lpc->hwndParent, &r);
- } else {
- if(!SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID) &r, 0)) {
- /* failover to the window coordinates */
- GetWindowRect(lpc->hwndParent, &r);
- }
- }
- x = (r.right + r.left)/2 - width / 2;
- y = (r.top + r.bottom)/2 - height / 2;
-
- MoveWindow(hwnd, x, y, width, height, FALSE);
-
- ncd->dlg_bb = CreateDialogParam(khm_hInstance,
- MAKEINTRESOURCE(IDD_NC_BBAR),
- hwnd,
- nc_common_dlg_proc,
- (LPARAM) ncd);
-
-#ifdef DEBUG
- assert(ncd->dlg_bb);
-#endif
-
- /* Call the identity provider callback to set the identity
- selector controls. These controls need to be there before we
- layout the main panel. */
- c->ident_cb(c, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) ncd->dlg_main);
-
- if (c->mode == KHUI_NC_MODE_EXPANDED) {
- SendMessage(ncd->dlg_main, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
- } else {
- /* we don't call nc_layout_main_panel() if the dialog is
- expanded because posting WMNC_DIALOG_EXPAND to the main
- panel results in it getting called anyway. */
- nc_layout_main_panel(ncd);
- }
-
- nc_layout_new_cred_window(ncd);
-
- /* add this to the dialog chain */
- khm_add_dialog(hwnd);
-
- khm_taskbar_add_window(hwnd);
-
- return TRUE;
-}
-
-/* add a control row supplied by an identity provider */
-static void
-nc_add_control_row(khui_nc_wnd_data * d,
- HWND label,
- HWND input,
- khui_control_size size)
-{
- RECT r_row;
- RECT r_label;
- RECT r_input;
- HFONT hf;
- HDWP hdefer;
-
- hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
- SendMessage(label, WM_SETFONT, (WPARAM) hf, FALSE);
- SendMessage(input, WM_SETFONT, (WPARAM) hf, FALSE);
-
- CopyRect(&r_row, &d->r_row);
- OffsetRect(&r_row, d->r_idspec.left, d->r_idspec.bottom);
-
- if (size == KHUI_CTRLSIZE_SMALL) {
- CopyRect(&r_label, &d->r_n_label);
- CopyRect(&r_input, &d->r_n_input);
- OffsetRect(&r_label, r_row.left, r_row.top);
- OffsetRect(&r_input, r_row.left, r_row.top);
- } else if (size == KHUI_CTRLSIZE_HALF) {
- CopyRect(&r_label, &d->r_e_label);
- CopyRect(&r_input, &d->r_e_input);
- OffsetRect(&r_label, r_row.left, r_row.top);
- OffsetRect(&r_input, r_row.left, r_row.top);
- } else if (size == KHUI_CTRLSIZE_FULL) {
- CopyRect(&r_label, &d->r_n_label);
- r_label.right = d->r_row.right;
- CopyRect(&r_input, &d->r_n_input);
- OffsetRect(&r_input, r_row.left, r_row.top);
- OffsetRect(&r_input, 0, r_input.bottom);
- r_row.bottom += r_input.bottom;
- OffsetRect(&r_label, r_row.left, r_row.top);
- } else {
- SetRectEmpty(&r_label);
- SetRectEmpty(&r_input);
-#ifdef DEBUG
- assert(FALSE);
-#endif
- return;
- }
-
- hdefer = BeginDeferWindowPos(2);
-
- if (label)
- DeferWindowPos(hdefer, label,
- ((d->hwnd_last_idspec != NULL)?
- d->hwnd_last_idspec:
- HWND_TOP),
- r_label.left, r_label.top,
- r_label.right - r_label.left,
- r_label.bottom - r_label.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER);
-
- if (input)
- DeferWindowPos(hdefer, input,
- (label ? label : ((d->hwnd_last_idspec != NULL)?
- d->hwnd_last_idspec:
- HWND_TOP)),
- r_input.left, r_input.top,
- r_input.right - r_input.left,
- r_input.bottom - r_input.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER);
-
- EndDeferWindowPos(hdefer);
-
- d->hwnd_last_idspec = (input ? input : label);
-
- d->r_idspec.bottom = r_row.bottom;
-
- /* we don't update the layout of the main panel yet, since these
- control additions happen before the main panel is displayed. A
- call to nc_layout_main_panel() will be made before the main
- panel is shown anyway. */
-
-}
-
-
-static LRESULT
-nc_handle_wm_destroy(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- khui_nc_wnd_data * d;
-
- /* remove self from dialog chain */
- khm_del_dialog(hwnd);
-
- khm_taskbar_remove_window(hwnd);
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);
-
- if (d->hwnd_notif_label)
- DestroyWindow(d->hwnd_notif_label);
- if (d->hwnd_notif_aux)
- DestroyWindow(d->hwnd_notif_aux);
-
- if(d->dlg_bb)
- DestroyWindow(d->dlg_bb);
- if(d->dlg_main)
- DestroyWindow(d->dlg_main);
-
- d->dlg_bb = NULL;
- d->dlg_main = NULL;
-
- PFREE(d);
-
- return TRUE;
-}
-
-static LRESULT
-nc_handle_wm_command(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- switch(HIWORD(wParam)) {
- case BN_CLICKED:
- switch(LOWORD(wParam)) {
-
- case IDOK:
- d->nc->result = KHUI_NC_RESULT_PROCESS;
-
- /* fallthrough */
-
- case IDCANCEL:
- /* the default value for d->nc->result is set to
- KHUI_NC_RESULT_CANCEL */
- d->nc->response = KHUI_NC_RESPONSE_PROCESSING;
-
- nc_enable_controls(d, FALSE);
-
- nc_notify_types(d->nc,
- KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0,WMNC_DIALOG_PREPROCESS),
- (LPARAM) d->nc,
- TRUE);
-
- khui_cw_sync_prompt_values(d->nc);
-
- khm_cred_dispatch_process_message(d->nc);
-
- /* we won't know whether to abort or not until we get
- feedback from the plugins, even if the command was
- to cancel */
- {
- HWND hw;
-
- hw = GetDlgItem(d->dlg_main, IDOK);
- EnableWindow(hw, FALSE);
- hw = GetDlgItem(d->dlg_main, IDCANCEL);
- EnableWindow(hw, FALSE);
- hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
- EnableWindow(hw, FALSE);
- hw = GetDlgItem(d->dlg_bb, IDOK);
- EnableWindow(hw, FALSE);
- hw = GetDlgItem(d->dlg_bb, IDCANCEL);
- EnableWindow(hw, FALSE);
- }
- return FALSE;
-
- case IDC_NC_HELP:
- khm_html_help(hwnd, NULL, HH_HELP_CONTEXT, IDH_ACTION_NEW_ID);
- return FALSE;
-
- case IDC_NC_BASIC:
- case IDC_NC_ADVANCED:
- /* the Options button in the main window was clicked. we
- respond by expanding the dialog. */
- PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
- return FALSE;
-
- case IDC_NC_CREDTEXT: /* credtext link activated */
- {
- khui_htwnd_link * l;
- wchar_t sid[KHUI_MAXCCH_HTLINK_FIELD];
- wchar_t sparam[KHUI_MAXCCH_HTLINK_FIELD];
- wchar_t * colon;
-
- l = (khui_htwnd_link *) lParam;
-
- /* do we have a valid link? */
- if(l->id == NULL || l->id_len >= ARRAYLENGTH(sid))
- return TRUE; /* nope */
-
- StringCchCopyN(sid, ARRAYLENGTH(sid), l->id, l->id_len);
- sid[l->id_len] = L'\0'; /* just make sure */
-
- if(l->param != NULL &&
- l->param_len < ARRAYLENGTH(sparam) &&
- l->param_len > 0) {
-
- StringCchCopyN(sparam, ARRAYLENGTH(sparam),
- l->param, l->param_len);
- sparam[l->param_len] = L'\0';
-
- } else {
- sparam[0] = L'\0';
- }
-
- /* If the ID is of the form '<credtype>:<link_tag>'
- and <credtype> is a valid name of a credentials
- type that is participating in the credentials
- acquisition process, then we forward the message to
- the panel that is providing the UI for that cred
- type. We also switch to that panel first, unless
- the link is of the form '<credtype>:!<link_tag>'. */
-
- colon = wcschr(sid, L':');
- if (colon != NULL) {
- khm_int32 credtype;
- khui_new_creds_by_type * t;
-
- *colon = L'\0';
- if (KHM_SUCCEEDED(kcdb_credtype_get_id(sid, &credtype)) &&
- KHM_SUCCEEDED(khui_cw_find_type(d->nc, credtype, &t))){
- *colon = L':';
-
- if (t->ordinal != d->current_panel &&
- *(colon + 1) != L'!')
- PostMessage(hwnd,
- KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(t->ordinal,
- WMNC_DIALOG_SWITCH_PANEL),
- 0);
-
- return SendMessage(t->hwnd_panel,
- KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_CREDTEXT_LINK),
- lParam);
- } else {
- *colon = L':';
- }
- }
-
- /* if it was for us, then we need to process the message */
- if(!_wcsicmp(sid, CTLINKID_SWITCH_PANEL)) {
- khm_int32 credtype;
- khui_new_creds_by_type * t;
-
- if (KHM_SUCCEEDED(kcdb_credtype_get_id(sparam,
- &credtype)) &&
- KHM_SUCCEEDED(khui_cw_find_type(d->nc,
- credtype, &t))) {
- if (t->ordinal != d->current_panel)
- PostMessage(hwnd,
- KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(t->ordinal,
- WMNC_DIALOG_SWITCH_PANEL),
- 0);
- }
- } else if (!_wcsicmp(sid, L"NotDef")) {
- d->nc->set_default = FALSE;
- nc_update_credtext(d);
- } else if (!_wcsicmp(sid, L"MakeDef")) {
- d->nc->set_default = TRUE;
- nc_update_credtext(d);
- }
- }
- return FALSE;
-
-#if 0
- case NC_BN_SET_DEF_ID:
- {
- d->nc->set_default =
- (IsDlgButtonChecked(d->dlg_main, NC_BN_SET_DEF_ID)
- == BST_CHECKED);
- }
- return FALSE;
-#endif
- }
- break;
- }
-
- return TRUE;
-}
-
-static LRESULT nc_handle_wm_moving(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_DIALOG_MOVE), (LPARAM) d->nc, TRUE);
-
- return FALSE;
-}
-
-static LRESULT nc_handle_wm_nc_notify(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- khui_nc_wnd_data * d;
- int id;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- switch(HIWORD(wParam)) {
-
- case WMNC_DIALOG_SWITCH_PANEL:
- id = LOWORD(wParam);
- if(id >= 0 && id <= (int) d->nc->n_types) {
- /* one of the tab buttons were pressed */
- if(d->current_panel == id) {
- return TRUE; /* nothing to do */
- }
-
- d->current_panel = id;
-
- TabCtrl_SetCurSel(d->tab_wnd, id);
- }
-
- if(d->nc->mode == KHUI_NC_MODE_EXPANDED) {
- nc_layout_new_cred_window(d);
- return TRUE;
- }
- /*else*/
- /* fallthrough */
-
- case WMNC_DIALOG_EXPAND:
- /* we are switching from basic to advanced or vice versa */
-
- if (d->nc->mode == KHUI_NC_MODE_EXPANDED) {
- d->nc->mode = KHUI_NC_MODE_MINI;
- } else {
- d->nc->mode = KHUI_NC_MODE_EXPANDED;
- }
-
- /* if we are switching to the advanced mode, we clear any
- notifications because we now have a credential text area
- for that. */
- if (d->nc->mode == KHUI_NC_MODE_EXPANDED)
- nc_notify_clear(d);
-
- nc_layout_main_panel(d);
-
- nc_layout_new_cred_window(d);
-
- break;
-
- case WMNC_DIALOG_SETUP:
-
- if(d->nc->n_types > 0) {
- khm_size i;
- for(i=0; i < d->nc->n_types;i++) {
-
- if (d->nc->types[i]->dlg_proc == NULL) {
- d->nc->types[i]->hwnd_panel = NULL;
- } else {
- /* Create the dialog panel */
- d->nc->types[i]->hwnd_panel =
- CreateDialogParam(d->nc->types[i]->h_module,
- d->nc->types[i]->dlg_template,
- d->nc->hwnd,
- d->nc->types[i]->dlg_proc,
- (LPARAM) d->nc);
-
-#ifdef DEBUG
- assert(d->nc->types[i]->hwnd_panel);
-#endif
- }
- }
- }
-
- break;
-
- case WMNC_DIALOG_ACTIVATE:
- {
- wchar_t wname[KCDB_MAXCCH_NAME];
- TCITEM tabitem;
- khm_int32 t;
-
- /* About to activate the window. We should add all the
- panels to the tab control. */
-
-#ifdef DEBUG
- assert(d->tab_wnd != NULL);
-#endif
-
- ZeroMemory(&tabitem, sizeof(tabitem));
-
- tabitem.mask = TCIF_PARAM | TCIF_TEXT;
-
- LoadString(khm_hInstance, IDS_NC_IDENTITY,
- wname, ARRAYLENGTH(wname));
-
- tabitem.pszText = wname;
- tabitem.lParam = 0; /* ordinal */
-
- TabCtrl_InsertItem(d->tab_wnd, 0, &tabitem);
-
- khui_cw_lock_nc(d->nc);
-
- if(d->nc->n_types > 0) {
- khm_size i;
-
- /* We should sort the tabs first. See
- nc_tab_sort_func() for sort criteria. */
- qsort(d->nc->types,
- d->nc->n_types,
- sizeof(*(d->nc->types)),
- nc_tab_sort_func);
-
- for(i=0; i < d->nc->n_types;i++) {
-
- d->nc->types[i]->ordinal = i + 1;
-
- if(d->nc->types[i]->name)
- tabitem.pszText = d->nc->types[i]->name;
- else {
- khm_size cbsize;
-
- cbsize = sizeof(wname);
-
- if(KHM_FAILED
- (kcdb_credtype_describe
- (d->nc->types[i]->type,
- wname,
- &cbsize,
- KCDB_TS_SHORT))) {
-
-#ifdef DEBUG
- assert(FALSE);
-#endif
- wname[0] = L'\0';
-
- }
-
- tabitem.pszText = wname;
-
- }
-
- tabitem.lParam = d->nc->types[i]->ordinal;
-
- TabCtrl_InsertItem(d->tab_wnd, d->nc->types[i]->ordinal,
- &tabitem);
- }
- }
-
- khui_cw_unlock_nc(d->nc);
-
- nc_update_credtext(d);
-
- TabCtrl_SetCurSel(d->tab_wnd, 0); /* the first selected
- tab is the main
- panel. */
-
- /* bring the window to the top, if necessary */
- if (KHM_SUCCEEDED(khc_read_int32(NULL,
- L"CredWindow\\Windows\\NewCred\\ForceToTop",
- &t)) &&
-
- t != 0) {
- /* it used to be that the above condition also called
- !khm_is_dialog_active() to find out whether there
- was a dialog active. If there was, we wouldn't try
- to bring the new cred window to the foreground. But
- that was not the behavior we want. */
-
- /* if the main window is not visible, then the SetWindowPos()
- call is sufficient to bring the new creds window to the
- top. However, if the main window is visible but not
- active, the main window needs to be activated before a
- child window can be activated. */
- khm_activate_main_window();
-
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
- (SWP_NOMOVE | SWP_NOSIZE));
- }
-
- ShowWindow(hwnd, SW_SHOWNOACTIVATE);
-
- /* we don't enable animations until a specific timeout
- elapses after showing the window. We don't need to
- animate any size changes if the user has barely had a
- chance to notice the original size. This prevents the
- new cred window from appearing in an animated state. */
- SetTimer(hwnd, NC_TIMER_ENABLEANIMATE, ENABLEANIMATE_TIMEOUT, NULL);
-
- SetFocus(hwnd);
-
- if (d->nc->n_identities == 0)
- break;
- /* else */
- /* fallthrough */
- }
-
- case WMNC_IDENTITY_CHANGE:
- {
- BOOL okEnable = FALSE;
-
- nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_IDENTITY_CHANGE), (LPARAM) d->nc,
- TRUE);
-
- if (d->nc->subtype == KMSG_CRED_NEW_CREDS &&
- d->nc->n_identities > 0 &&
- d->nc->identities[0]) {
- khm_int32 f = 0;
-
- kcdb_identity_get_flags(d->nc->identities[0], &f);
-
- if (!(f & KCDB_IDENT_FLAG_DEFAULT)) {
- d->nc->set_default = FALSE;
- }
- }
-
- nc_update_credtext(d);
-
- }
- break;
-
- case WMNC_TYPE_STATE:
- /* fallthrough */
- case WMNC_UPDATE_CREDTEXT:
- nc_update_credtext(d);
- break;
-
- case WMNC_CLEAR_PROMPTS:
- {
- khm_size i;
-
- khui_cw_lock_nc(d->nc);
-
- if(d->hwnd_banner != NULL) {
- DestroyWindow(d->hwnd_banner);
- d->hwnd_banner = NULL;
- }
-
- if(d->hwnd_name != NULL) {
- DestroyWindow(d->hwnd_name);
- d->hwnd_name = NULL;
- }
-
- for(i=0;i<d->nc->n_prompts;i++) {
- if(!(d->nc->prompts[i]->flags &
- KHUI_NCPROMPT_FLAG_STOCK)) {
- if(d->nc->prompts[i]->hwnd_static != NULL)
- DestroyWindow(d->nc->prompts[i]->hwnd_static);
-
- if(d->nc->prompts[i]->hwnd_edit != NULL)
- DestroyWindow(d->nc->prompts[i]->hwnd_edit);
- }
-
- d->nc->prompts[i]->hwnd_static = NULL;
- d->nc->prompts[i]->hwnd_edit = NULL;
- }
-
- khui_cw_unlock_nc(d->nc);
-
- SetRectEmpty(&d->r_custprompt);
-
- nc_layout_main_panel(d);
-
- nc_layout_new_cred_window(d);
- }
- break;
-
- case WMNC_SET_PROMPTS:
- {
- khm_size i;
- int y;
- HWND hw, hw_prev;
- HFONT hf, hfold;
- HDC hdc;
- BOOL use_large_lables = FALSE;
-
- /* we assume that WMNC_CLEAR_PROMPTS has already been
- received */
-
-#ifdef DEBUG
- assert(IsRectEmpty(&d->r_custprompt));
-#endif
-
- khui_cw_lock_nc(d->nc);
-
-#if 0
- /* special case, we have one prompt and it is a password
- prompt. very common */
- if(d->nc->n_prompts == 1 &&
- d->nc->prompts[0]->type == KHUI_NCPROMPT_TYPE_PASSWORD) {
-
- hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD);
- EnableWindow(hw, TRUE);
-
- d->nc->prompts[0]->flags |= KHUI_NCPROMPT_FLAG_STOCK;
- d->nc->prompts[0]->hwnd_edit = hw;
- d->nc->prompts[0]->hwnd_static = NULL; /* don't care */
-
- khui_cw_unlock_nc(d->nc);
- break;
- }
-#endif
- /* for everything else */
-
- y = d->r_idspec.bottom;
-
- d->r_custprompt.left = d->r_area.left;
- d->r_custprompt.right = d->r_area.right;
- d->r_custprompt.top = y;
-
- hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
-
- if (d->nc->pname != NULL) {
- hw =
- CreateWindowEx
- (0,
- L"STATIC",
- d->nc->pname,
- SS_SUNKEN | WS_CHILD,
- d->r_area.left, y,
- d->r_row.right,
- d->r_n_label.bottom - d->r_n_label.top,
- d->dlg_main,
- NULL,
- khm_hInstance,
- NULL);
-
-#ifdef DEBUG
- assert(hw);
-#endif
- d->hwnd_name = hw;
- SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM) TRUE);
- ShowWindow(hw, SW_SHOW);
-
- y += d->r_n_label.bottom - d->r_n_label.top;
- }
-
- if (d->nc->banner != NULL) {
- hw =
- CreateWindowEx
- (0,
- L"STATIC",
- d->nc->banner,
- WS_CHILD,
- d->r_area.left, y,
- d->r_row.right, d->r_row.bottom,
- d->dlg_main,
- NULL,
- khm_hInstance,
- NULL);
-#ifdef DEBUG
- assert(hw);
-#endif
- d->hwnd_banner = hw;
- SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM)TRUE);
- ShowWindow(hw, SW_SHOW);
- y += d->r_row.bottom;
- }
-
- hw_prev = d->hwnd_last_idspec;
-
- hdc = GetWindowDC(d->dlg_main);
- hfold = SelectObject(hdc,hf);
-
- /* first do a trial run and see if we should use the
- larger text labels or not. This is so that all the
- labels and input controls align properly. */
- for (i=0; i < d->nc->n_prompts; i++) {
- if (d->nc->prompts[i]->prompt != NULL) {
- SIZE s;
-
- GetTextExtentPoint32(hdc,
- d->nc->prompts[i]->prompt,
- (int) wcslen(d->nc->prompts[i]->prompt),
- &s);
-
- if(s.cx >= d->r_n_label.right - d->r_n_label.left) {
- use_large_lables = TRUE;
- break;
- }
- }
- }
-
- for(i=0; i<d->nc->n_prompts; i++) {
- RECT pr, er;
- SIZE s;
- int dy;
-
- if(d->nc->prompts[i]->prompt != NULL) {
- GetTextExtentPoint32(hdc,
- d->nc->prompts[i]->prompt,
- (int) wcslen(d->nc->prompts[i]->prompt),
- &s);
- if(s.cx < d->r_n_label.right - d->r_n_label.left &&
- !use_large_lables) {
- CopyRect(&pr, &d->r_n_label);
- CopyRect(&er, &d->r_n_input);
- dy = d->r_row.bottom;
- } else if(s.cx <
- d->r_e_label.right - d->r_e_label.left) {
- CopyRect(&pr, &d->r_e_label);
- CopyRect(&er, &d->r_e_input);
- dy = d->r_row.bottom;
- } else {
- /* oops. the prompt doesn't fit in our
- controls. we need to use up two lines */
- pr.left = 0;
- pr.right = d->r_row.right;
- pr.top = 0;
- pr.bottom = d->r_n_label.bottom -
- d->r_n_label.top;
- CopyRect(&er, &d->r_n_input);
- OffsetRect(&er, 0, pr.bottom);
- dy = er.bottom + (d->r_row.bottom -
- d->r_n_input.bottom);
- }
- } else {
- SetRectEmpty(&pr);
- CopyRect(&er, &d->r_n_input);
- dy = d->r_row.bottom;
- }
-
- if(IsRectEmpty(&pr)) {
- d->nc->prompts[i]->hwnd_static = NULL;
- } else {
- OffsetRect(&pr, d->r_area.left, y);
-
- hw = CreateWindowEx
- (0,
- L"STATIC",
- d->nc->prompts[i]->prompt,
- WS_CHILD,
- pr.left, pr.top,
- pr.right - pr.left, pr.bottom - pr.top,
- d->dlg_main,
- NULL,
- khm_hInstance,
- NULL);
-#ifdef DEBUG
- assert(hw);
-#endif
-
- SendMessage(hw, WM_SETFONT,
- (WPARAM) hf, (LPARAM) TRUE);
-
- SetWindowPos(hw, hw_prev,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE |
- SWP_NOOWNERZORDER | SWP_NOSIZE |
- SWP_SHOWWINDOW);
-
- d->nc->prompts[i]->hwnd_static = hw;
- hw_prev = hw;
- }
-
- OffsetRect(&er, d->r_area.left, y);
-
- hw = CreateWindowEx
- (0,
- L"EDIT",
- (d->nc->prompts[i]->def ?
- d->nc->prompts[i]->def : L""),
- WS_CHILD | WS_TABSTOP |
- WS_BORDER |
- ((d->nc->prompts[i]->flags &
- KHUI_NCPROMPT_FLAG_HIDDEN)? ES_PASSWORD:0),
- er.left, er.top,
- er.right - er.left, er.bottom - er.top,
- d->dlg_main,
- NULL,
- khm_hInstance,
- NULL);
-
-#ifdef DEBUG
- assert(hw);
-#endif
-
- SendMessage(hw, WM_SETFONT,
- (WPARAM) hf, (LPARAM) TRUE);
-
- SetWindowPos(hw, hw_prev,
- 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE |
- SWP_NOOWNERZORDER | SWP_NOSIZE |
- SWP_SHOWWINDOW);
-
- SendMessage(hw, EM_SETLIMITTEXT,
- KHUI_MAXCCH_PROMPT_VALUE -1,
- 0);
-
- d->nc->prompts[i]->hwnd_edit = hw;
-
- hw_prev = hw;
-
- y += dy;
- }
-
- if (d->nc->n_prompts > 0 &&
- d->nc->prompts[0]->hwnd_edit) {
-
- PostMessage(d->dlg_main, WM_NEXTDLGCTL,
- (WPARAM) d->nc->prompts[0]->hwnd_edit,
- MAKELPARAM(TRUE, 0));
-
- }
-
- SelectObject(hdc, hfold);
- ReleaseDC(d->dlg_main, hdc);
-
- khui_cw_unlock_nc(d->nc);
-
- d->r_custprompt.bottom = y;
-
- if (d->r_custprompt.bottom == d->r_custprompt.top)
- SetRectEmpty(&d->r_custprompt);
-
- nc_layout_main_panel(d);
-
- nc_layout_new_cred_window(d);
- }
- break;
-
- case WMNC_DIALOG_PROCESS_COMPLETE:
- {
- khui_new_creds * nc;
-
- nc = d->nc;
-
- nc->response &= ~KHUI_NC_RESPONSE_PROCESSING;
-
- if(nc->response & KHUI_NC_RESPONSE_NOEXIT) {
- HWND hw;
-
- nc_enable_controls(d, TRUE);
-
- /* reset state */
- nc->result = KHUI_NC_RESULT_CANCEL;
-
- hw = GetDlgItem(d->dlg_main, IDOK);
- EnableWindow(hw, TRUE);
- hw = GetDlgItem(d->dlg_main, IDCANCEL);
- EnableWindow(hw, TRUE);
- hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
- EnableWindow(hw, TRUE);
- hw = GetDlgItem(d->dlg_bb, IDOK);
- EnableWindow(hw, TRUE);
- hw = GetDlgItem(d->dlg_bb, IDCANCEL);
- EnableWindow(hw, TRUE);
-
- nc_clear_password_fields(d);
-
- return TRUE;
- }
-
- DestroyWindow(hwnd);
-
- kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, (void *) nc);
- }
- break;
-
- /* MUST be called with SendMessage */
- case WMNC_ADD_CONTROL_ROW:
- {
- khui_control_row * row;
-
- row = (khui_control_row *) lParam;
-
-#ifdef DEBUG
- assert(row->label);
- assert(row->input);
-#endif
-
- nc_add_control_row(d, row->label, row->input, row->size);
- }
- break;
-
- case WMNC_UPDATE_LAYOUT:
- {
-
- RECT r_client;
- khm_int32 animate;
- khm_int32 steps;
- khm_int32 timeout;
-
- /* We are already adjusting the size of the window. The
- next time the timer fires, it will notice if the target
- size has changed. */
- if (d->size_changing)
- return TRUE;
-
- GetClientRect(hwnd, &r_client);
-
- if ((r_client.right - r_client.left ==
- d->r_required.right - d->r_required.left) &&
- (r_client.bottom - r_client.top ==
- d->r_required.bottom - d->r_required.top)) {
-
- /* the window is already at the right size */
- return TRUE;
-
- }
-
- if (!IsWindowVisible(hwnd)) {
- /* The window is not visible yet. There's no need to
- animate anything. */
-
- animate = FALSE;
-
- } else if (KHM_FAILED(khc_read_int32(NULL,
- L"CredWindow\\Windows\\NewCred\\AnimateSizeChanges",
- &animate))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- animate = TRUE;
- }
-
- /* if we aren't animating the window resize, then we just
- do it in one call. */
- if (!animate || !d->animation_enabled) {
- RECT r_window;
-
- CopyRect(&r_window, &d->r_required);
- AdjustWindowRectEx(&r_window, NC_WINDOW_STYLES, FALSE,
- NC_WINDOW_EX_STYLES);
-
- SetWindowPos(hwnd, NULL, 0, 0,
- r_window.right - r_window.left,
- r_window.bottom - r_window.top,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOZORDER);
-
- return TRUE;
- }
-
- if (KHM_FAILED(khc_read_int32(NULL,
- L"CredWindow\\Windows\\NewCred\\AnimationSteps",
- &steps))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- steps = NC_SZ_STEPS_DEF;
- } else {
-
- if (steps < NC_SZ_STEPS_MIN)
- steps = NC_SZ_STEPS_MIN;
- else if (steps > NC_SZ_STEPS_MAX)
- steps = NC_SZ_STEPS_MAX;
-
- }
-
- if (KHM_FAILED(khc_read_int32(NULL,
- L"CredWindow\\Windows\\NewCred\\AnimationStepTimeout",
- &timeout))) {
-#ifdef DEBUG
- assert(FALSE);
-#endif
- timeout = NC_SZ_TIMEOUT_DEF;
- } else {
-
- if (timeout < NC_SZ_TIMEOUT_MIN)
- timeout = NC_SZ_TIMEOUT_MIN;
- else if (timeout > NC_SZ_TIMEOUT_MAX)
- timeout = NC_SZ_TIMEOUT_MAX;
-
- }
-
- CopyRect(&d->sz_ch_source, &r_client);
- OffsetRect(&d->sz_ch_source, -d->sz_ch_source.left, -d->sz_ch_source.top);
- CopyRect(&d->sz_ch_target, &d->r_required);
- OffsetRect(&d->sz_ch_target, -d->sz_ch_target.left, -d->sz_ch_target.top);
- d->sz_ch_increment = 0;
- d->sz_ch_max = steps;
- d->sz_ch_timeout = timeout;
- d->size_changing = TRUE;
-
- SetTimer(hwnd, NC_TIMER_SIZER, timeout, NULL);
- }
- break;
- } /* switch(HIWORD(wParam)) */
-
- return TRUE;
-}
-
-static LRESULT nc_handle_wm_timer(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- if (wParam == NC_TIMER_SIZER) {
-
- RECT r_now;
-
- /* are we done with this sizing operation? */
- if (!d->size_changing ||
- d->sz_ch_increment >= d->sz_ch_max) {
-
- d->size_changing = FALSE;
- KillTimer(hwnd, NC_TIMER_SIZER);
- return 0;
- }
-
- /* have the requirements changed while we were processing the
- sizing operation? */
- if ((d->r_required.right - d->r_required.left !=
- d->sz_ch_target.right)
-
- ||
-
- (d->r_required.bottom - d->r_required.top !=
- d->sz_ch_target.bottom)) {
-
- /* the target size has changed. we need to restart the
- sizing operation. */
-
- RECT r_client;
-
- GetClientRect(hwnd, &r_client);
-
- CopyRect(&d->sz_ch_source, &r_client);
- OffsetRect(&d->sz_ch_source, -d->sz_ch_source.left, -d->sz_ch_source.top);
- CopyRect(&d->sz_ch_target, &d->r_required);
- OffsetRect(&d->sz_ch_target, -d->sz_ch_target.left, -d->sz_ch_target.top);
- d->sz_ch_increment = 0;
-
- /* leave the other fields alone */
-
-#ifdef DEBUG
- assert(d->sz_ch_max >= NC_SZ_STEPS_MIN);
- assert(d->sz_ch_max <= NC_SZ_STEPS_MAX);
- assert(d->sz_ch_timeout >= NC_SZ_TIMEOUT_MIN);
- assert(d->sz_ch_timeout <= NC_SZ_TIMEOUT_MAX);
- assert(d->size_changing);
-#endif
- }
-
- /* we are going to do the next increment */
- d->sz_ch_increment ++;
-
- /* now, figure out the size of the client area for this
- step */
-
- r_now.left = 0;
- r_now.top = 0;
-
-#define PROPORTION(v1, v2, i, s) (((v1) * ((s) - (i)) + (v2) * (i)) / (s))
-
- r_now.right = PROPORTION(d->sz_ch_source.right, d->sz_ch_target.right,
- d->sz_ch_increment, d->sz_ch_max);
-
- r_now.bottom = PROPORTION(d->sz_ch_source.bottom, d->sz_ch_target.bottom,
- d->sz_ch_increment, d->sz_ch_max);
-
-#undef PROPORTION
-
-#ifdef DEBUG
- {
- long dx = (r_now.right - d->sz_ch_target.right) *
- (d->sz_ch_source.right - d->sz_ch_target.right);
-
- long dy = (r_now.bottom - d->sz_ch_target.bottom) *
- (d->sz_ch_source.bottom - d->sz_ch_target.bottom);
-
- if (dx < 0 || dy < 0) {
- KillTimer(hwnd, NC_TIMER_SIZER);
- assert(dx >= 0);
- assert(dy >= 0);
- SetTimer(hwnd, NC_TIMER_SIZER, d->sz_ch_timeout, NULL);
- }
- }
-#endif
-
- AdjustWindowRectEx(&r_now, NC_WINDOW_STYLES, FALSE,
- NC_WINDOW_EX_STYLES);
-
- SetWindowPos(hwnd, NULL,
- 0, 0,
- r_now.right - r_now.left,
- r_now.bottom - r_now.top,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
- SWP_NOZORDER);
-
- /* and now we wait for the next timer message */
-
- return 0;
- } else if (wParam == NC_TIMER_ENABLEANIMATE) {
-
- d->animation_enabled = TRUE;
- KillTimer(hwnd, NC_TIMER_ENABLEANIMATE);
- }
-
- return 0;
-}
-
-static LRESULT nc_handle_wm_notify(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
-
- LPNMHDR nmhdr;
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
- nmhdr = (LPNMHDR) lParam;
-
- if (nmhdr->code == TCN_SELCHANGE) {
- /* the current tab has changed. */
- int idx;
- TCITEM tcitem;
-
- idx = TabCtrl_GetCurSel(d->tab_wnd);
- ZeroMemory(&tcitem, sizeof(tcitem));
-
- tcitem.mask = TCIF_PARAM;
- TabCtrl_GetItem(d->tab_wnd, idx, &tcitem);
-
- d->current_panel = (int) tcitem.lParam;
-
- nc_layout_new_cred_window(d);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static LRESULT nc_handle_wm_help(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam) {
- static DWORD ctxids[] = {
- NC_TS_CTRL_ID_MIN, IDH_NC_TABMAIN,
- NC_TS_CTRL_ID_MIN + 1, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 2, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 3, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 4, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 5, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 6, IDH_NC_TABBUTTON,
- NC_TS_CTRL_ID_MIN + 7, IDH_NC_TABBUTTON,
- IDOK, IDH_NC_OK,
- IDCANCEL, IDH_NC_CANCEL,
- IDC_NC_HELP, IDH_NC_HELP,
- IDC_NC_ADVANCED, IDH_NC_ADVANCED,
- IDC_NC_CREDTEXT, IDH_NC_CREDWND,
- 0
- };
-
- HELPINFO * hlp;
- HWND hw = NULL;
- HWND hw_ctrl;
- khui_nc_wnd_data * d;
-
- d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
-
- hlp = (HELPINFO *) lParam;
-
- if (d->nc->subtype != KMSG_CRED_NEW_CREDS &&
- d->nc->subtype != KMSG_CRED_PASSWORD)
- return TRUE;
-
- if (hlp->iContextType != HELPINFO_WINDOW)
- return TRUE;
-
- if (hlp->hItemHandle != NULL &&
- hlp->hItemHandle != hwnd) {
- DWORD id;
- int i;
-
- hw_ctrl =hlp->hItemHandle;
-
- id = GetWindowLong(hw_ctrl, GWL_ID);
- for (i=0; ctxids[i] != 0; i += 2)
- if (ctxids[i] == id)
- break;
-
- if (ctxids[i] != 0)
- hw = khm_html_help(hw_ctrl,
- ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
- L"::popups_newcreds.txt":
- L"::popups_password.txt"),
- HH_TP_HELP_WM_HELP,
- (DWORD_PTR) ctxids);
- }
-
- if (hw == NULL) {
- khm_html_help(hwnd, NULL, HH_HELP_CONTEXT,
- ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
- IDH_ACTION_NEW_ID: IDH_ACTION_PASSWD_ID));
- }
-
- return TRUE;
-}
-
-static LRESULT CALLBACK nc_window_proc(HWND hwnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch(uMsg) {
- case WM_CREATE:
- return nc_handle_wm_create(hwnd, uMsg, wParam, lParam);
-
- case WM_DESTROY:
- return nc_handle_wm_destroy(hwnd, uMsg, wParam, lParam);
-
- case WM_COMMAND:
- return nc_handle_wm_command(hwnd, uMsg, wParam, lParam);
-
- case WM_NOTIFY:
- return nc_handle_wm_notify(hwnd, uMsg, wParam, lParam);
-
- case WM_MOVE:
- case WM_MOVING:
- return nc_handle_wm_moving(hwnd, uMsg, wParam, lParam);
-
- case WM_TIMER:
- return nc_handle_wm_timer(hwnd, uMsg, wParam, lParam);
-
- case WM_HELP:
- return nc_handle_wm_help(hwnd, uMsg, wParam, lParam);
-
- case KHUI_WM_NC_NOTIFY:
- return nc_handle_wm_nc_notify(hwnd, uMsg, wParam, lParam);
- }
-
- /* Note that this is technically a dialog box */
- return DefDlgProc(hwnd, uMsg, wParam, lParam);
-}
-
-void khm_register_newcredwnd_class(void)
-{
- WNDCLASSEX wcx;
-
- wcx.cbSize = sizeof(wcx);
- wcx.style = CS_DBLCLKS | CS_OWNDC;
- wcx.lpfnWndProc = nc_window_proc;
- wcx.cbClsExtra = 0;
- wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR);
- wcx.hInstance = khm_hInstance;
- wcx.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
- wcx.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
- wcx.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
- wcx.lpszMenuName = NULL;
- wcx.lpszClassName = KHUI_NEWCREDWND_CLASS;
- wcx.hIconSm = NULL;
-
- khui_newcredwnd_cls = RegisterClassEx(&wcx);
-}
-
-void khm_unregister_newcredwnd_class(void)
-{
- UnregisterClass((LPWSTR) khui_newcredwnd_cls, khm_hInstance);
-}
-
-HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c)
-{
- wchar_t wtitle[256];
- HWND hwnd;
-
- if (c->window_title == NULL) {
- if (c->subtype == KMSG_CRED_PASSWORD)
- LoadString(khm_hInstance,
- IDS_WT_PASSWORD,
- wtitle,
- ARRAYLENGTH(wtitle));
- else
- LoadString(khm_hInstance,
- IDS_WT_NEW_CREDS,
- wtitle,
- ARRAYLENGTH(wtitle));
- }
-
- hwnd = CreateWindowEx(NC_WINDOW_EX_STYLES,
- MAKEINTATOM(khui_newcredwnd_cls),
- ((c->window_title)?c->window_title: wtitle),
- NC_WINDOW_STYLES,
- 0,0,400,400, /* bogus values. the window
- is going to resize and
- reposition itself
- anyway */
- parent,
- NULL,
- khm_hInstance,
- (LPVOID) c);
-
-#ifdef DEBUG
- assert(hwnd != NULL);
-#endif
-
- /* note that the window is not visible yet. That's because, at
- this point we don't know what the panels are */
-
- return hwnd;
-}
-
-void khm_prep_newcredwnd(HWND hwnd)
-{
- SendMessage(hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_DIALOG_SETUP), 0);
-}
-
-void khm_show_newcredwnd(HWND hwnd)
-{
- /* add all the panels in and prep UI */
- PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
- MAKEWPARAM(0, WMNC_DIALOG_ACTIVATE), 0);
-}
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ * Copyright (c) 2007 Secure Endpoints Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* Include the OEMRESOURCE constants for locating standard icon
+ resources. */
+#define OEMRESOURCE
+
+#include<khmapp.h>
+#include<assert.h>
+
+ATOM khui_newcredwnd_cls;
+
+/* forward dcl */
+static void
+nc_position_credtext(khui_nc_wnd_data * d);
+
+/* Common dialog procedure used by the main credential panel
+ (IDD_NC_NEWCRED) and the button bar (IDC_NC_BBAR). */
+
+static void
+nc_layout_main_panel(khui_nc_wnd_data * d);
+
+static void
+nc_layout_new_cred_window(khui_nc_wnd_data * d);
+
+static INT_PTR CALLBACK
+nc_common_dlg_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch(uMsg) {
+ case WM_INITDIALOG:
+ {
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *) lParam;
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, DWLP_USER, lParam);
+#pragma warning(pop)
+
+ if (d->nc->subtype == KMSG_CRED_PASSWORD) {
+ ShowWindow(GetDlgItem(hwnd, IDC_NC_ADVANCED),
+ SW_HIDE);
+ }
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ {
+ int ctrl_id;
+
+ ctrl_id = LOWORD(wParam);
+ if (ctrl_id < KHUI_CW_ID_MIN ||
+ ctrl_id > KHUI_CW_ID_MAX) {
+ /* pump it to the parent */
+ PostMessage(GetParent(hwnd), WM_COMMAND, wParam, lParam);
+ return TRUE;
+ } /* else we allow the message to fall through and get
+ passed into the identity provider's message
+ handler. */
+ }
+ break;
+
+ case KHUI_WM_NC_NOTIFY:
+ {
+ khui_nc_wnd_data * d;
+ d = (khui_nc_wnd_data *)(LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ /* message sent by parent to notify us of something */
+ switch(HIWORD(wParam)) {
+ case WMNC_DIALOG_EXPAND:
+ /* fallthrough */
+ case WMNC_UPDATE_LAYOUT:
+ if(hwnd == d->dlg_main) {
+
+ nc_layout_main_panel(d);
+
+ return TRUE;
+ }
+ break; /* nop */
+ }
+ }
+ return TRUE;
+ }
+
+ /* check if we have a wnd_data, and if so pass the message on to
+ the identity provider callback. */
+ {
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *) (LONG_PTR)
+ GetWindowLongPtr(hwnd, DWLP_USER);
+
+ /* TODO: filter out and forward only the messages that
+ originated or pertain to the identity selection
+ controls. */
+ if (d && d->nc && d->nc->ident_cb) {
+ return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, uMsg,
+ wParam, lParam);
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+nc_notify_clear(khui_nc_wnd_data * d) {
+
+ if (d->notif_type == NC_NOTIFY_NONE)
+ /* there are no notifications anyway. */
+ return;
+
+ if (d->hwnd_notif_label)
+ DestroyWindow(d->hwnd_notif_label);
+
+ if (d->hwnd_notif_aux)
+ DestroyWindow(d->hwnd_notif_aux);
+
+ d->hwnd_notif_label = NULL;
+ d->hwnd_notif_aux = NULL;
+
+ SetRectEmpty(&d->r_notif);
+
+ d->notif_type = NC_NOTIFY_NONE;
+
+ /* Note that we must call nc_layout_main_panel() after calling
+ this to adjust the layout of the main panel. However we aren't
+ calling it here since we might want to add another set of
+ notifications or make other changes to the main panel content
+ before calling nc_layout_main_panel(). */
+}
+
+static void
+nc_notify_marquee(khui_nc_wnd_data * d, const wchar_t * label) {
+
+#if (_WIN32_IE >= 0x0600)
+ HDC hdc;
+ size_t length;
+ SIZE label_size;
+#endif
+
+ RECT r_label;
+ RECT r_mq;
+ RECT r_row;
+ HFONT hfont;
+ HWND hwnd;
+ HDWP hdefer;
+
+ /* Clear the notification area. We only support one notification
+ at a time. */
+ nc_notify_clear(d);
+
+#ifdef DEBUG
+ assert(d->dlg_main);
+#endif
+
+#if (_WIN32_IE >= 0x0600)
+
+ /* We can only show the marquee control if the comctl32 DLL is
+ version 6.0 or later. Otherwise we only show the label. */
+
+ if (FAILED(StringCchLength(label, KHUI_MAXCCH_SHORT_DESC, &length))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ length = KHUI_MAXCCH_SHORT_DESC;
+ }
+
+ /* See how big the notification control needs to be. */
+
+ hdc = GetDC(d->dlg_main);
+#ifdef DEBUG
+ assert(hdc != NULL);
+#endif
+
+ GetTextExtentPoint32(hdc, label, (int) length, &label_size);
+
+ ReleaseDC(d->dlg_main, hdc);
+
+ CopyRect(&r_row, &d->r_row);
+
+ if (label_size.cx > d->r_e_label.right - d->r_e_label.left) {
+ /* using an entire row */
+ CopyRect(&r_label, &d->r_row);
+ CopyRect(&r_mq, &d->r_n_input);
+ OffsetRect(&r_mq, 0, r_row.bottom - r_row.top);
+ r_row.bottom += r_row.bottom - r_row.top;
+ } else if (label_size.cx > d->r_n_label.right - d->r_n_label.left) {
+ /* using large labels */
+ CopyRect(&r_label, &d->r_e_label);
+ CopyRect(&r_mq, &d->r_e_input);
+ } else {
+ /* normal labels */
+ CopyRect(&r_label, &d->r_n_label);
+ CopyRect(&r_mq, &d->r_n_input);
+ }
+
+ InflateRect(&r_mq, 0, - ((r_mq.bottom - r_mq.top) / 4));
+
+#else /* _WIN32_IE < 0x0600 */
+
+ /* We are just showing the label */
+ CopyRect(&r_row, &d->r_row);
+ CopyRect(&r_label, &r_row);
+ SetRectEmpty(&r_mq);
+
+#endif /* _WIN32_IE >= 0x0600 */
+
+ {
+ long y;
+
+ if (IsRectEmpty(&d->r_custprompt)) {
+ y = d->r_idspec.bottom;
+ } else {
+ y = d->r_custprompt.bottom;
+ }
+
+ OffsetRect(&r_row, d->r_area.left, y);
+ OffsetRect(&r_label, r_row.left, r_row.top);
+ OffsetRect(&r_mq, r_row.left, r_row.top);
+ }
+
+ hfont = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
+
+ hdefer = BeginDeferWindowPos(2);
+
+ /* the label */
+ hwnd = CreateWindowEx(0,
+ L"STATIC",
+ label,
+ WS_CHILD | SS_ENDELLIPSIS,
+ r_label.left, r_label.top,
+ r_label.right - r_label.left,
+ r_label.bottom - r_label.top,
+ d->dlg_main,
+ NULL, NULL, NULL);
+#ifdef DEBUG
+ assert(hwnd != NULL);
+#endif
+ SendMessage(hwnd, WM_SETFONT, (WPARAM) hfont, (LPARAM) TRUE);
+
+ DeferWindowPos(hdefer, hwnd, NULL,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ d->hwnd_notif_label = hwnd;
+
+ /* and the marquee */
+
+#if (_WIN32_IE >= 0x0600)
+
+ /* unfortunately, the marquee is only available on comctl32
+ version 6.0 or later. On previous versions, we only display
+ the message label. */
+
+ hwnd = CreateWindowEx(0,
+ PROGRESS_CLASS,
+ L"",
+ WS_CHILD | PBS_MARQUEE,
+ r_mq.left, r_mq.top,
+ r_mq.right - r_mq.left,
+ r_mq.bottom - r_mq.top,
+ d->dlg_main,
+ NULL, NULL, NULL);
+#ifdef DEBUG
+ assert(hwnd != NULL);
+#endif
+
+ SendMessage(hwnd, PBM_SETMARQUEE, TRUE, 100);
+
+ DeferWindowPos(hdefer, hwnd, NULL,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ d->hwnd_notif_aux = hwnd;
+
+#endif /* _WIN32_IE >= 0x0600 */
+
+ EndDeferWindowPos(hdefer);
+
+ CopyRect(&d->r_notif, &r_row);
+
+ d->notif_type = NC_NOTIFY_MARQUEE;
+
+ /* Note that we must call nc_layout_main_panel() after calling
+ this to adjust the layout of the main panel. However we aren't
+ calling it here since we might want to add another set of
+ notifications or make other changes to the main panel content
+ before calling nc_layout_main_panel(). */
+}
+
+static void
+nc_notify_message(khui_nc_wnd_data * d,
+ kherr_severity severity,
+ const wchar_t * message) {
+
+ SIZE icon_size;
+ LPCTSTR icon_res;
+ HICON h_icon;
+ HWND hwnd;
+ HFONT hfont;
+ HDWP hdefer;
+
+ RECT r_row;
+ RECT r_label;
+ RECT r_icon;
+
+ nc_notify_clear(d);
+
+ icon_size.cx = GetSystemMetrics(SM_CXSMICON);
+ icon_size.cy = GetSystemMetrics(SM_CYSMICON);
+
+ switch(severity) {
+ case KHERR_INFO:
+ icon_res = MAKEINTRESOURCE(OIC_INFORMATION);
+ break;
+
+ case KHERR_WARNING:
+ icon_res = MAKEINTRESOURCE(OIC_WARNING);
+ break;
+
+ case KHERR_ERROR:
+ icon_res = MAKEINTRESOURCE(OIC_ERROR);
+ break;
+
+ default:
+ icon_res = NULL;
+ }
+
+ if (icon_res != NULL) {
+ h_icon = (HICON) LoadImage(NULL,
+ icon_res,
+ IMAGE_ICON,
+ icon_size.cx,
+ icon_size.cy,
+ LR_DEFAULTCOLOR | LR_SHARED);
+ } else {
+ h_icon = NULL;
+ }
+
+ CopyRect(&r_row, &d->r_row);
+
+#define CENTERVALUE(w,v) ((w)/2 - (v)/2)
+
+ SetRect(&r_icon,
+ 0, CENTERVALUE(r_row.bottom - r_row.top, icon_size.cy),
+ icon_size.cx,
+ CENTERVALUE(r_row.bottom - r_row.top, icon_size.cy) + icon_size.cy);
+
+#undef CENTERVALUE
+
+ CopyRect(&r_label, &r_row);
+ OffsetRect(&r_label, -r_label.left, -r_label.top);
+ r_label.left += (icon_size.cx * 3) / 2;
+
+ {
+ long y;
+
+ if (IsRectEmpty(&d->r_custprompt)) {
+ y = d->r_idspec.bottom;
+ } else {
+ y = d->r_custprompt.bottom;
+ }
+
+ OffsetRect(&r_row, d->r_area.left, y);
+ OffsetRect(&r_label, r_row.left, r_row.top);
+ OffsetRect(&r_icon, r_row.left, r_row.top);
+ }
+
+ hfont = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
+
+ hdefer = BeginDeferWindowPos(2);
+
+ hwnd = CreateWindowEx(0,
+ L"STATIC",
+ message,
+ WS_CHILD | SS_ENDELLIPSIS | SS_CENTER,
+ r_label.left, r_label.top,
+ r_label.right - r_label.left,
+ r_label.bottom - r_label.top,
+ d->dlg_main,
+ NULL, NULL, NULL);
+#ifdef DEBUG
+ assert(hwnd != NULL);
+#endif
+ SendMessage(hwnd, WM_SETFONT, (WPARAM) hfont, (LPARAM) TRUE);
+
+ DeferWindowPos(hdefer, hwnd, NULL,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ d->hwnd_notif_label = hwnd;
+
+ hwnd = CreateWindowEx(0,
+ L"STATIC",
+ NULL,
+ WS_CHILD | SS_ICON |
+#if (_WIN32_IE >= 0x0600)
+ SS_REALSIZECONTROL
+#else
+ 0
+#endif
+ ,
+ r_icon.left, r_icon.top,
+ r_icon.right - r_icon.left,
+ r_icon.bottom - r_icon.top,
+ d->dlg_main,
+ NULL, NULL, NULL);
+#ifdef DEBUG
+ assert(hwnd != NULL);
+#endif
+
+ if (h_icon && hwnd)
+ SendMessage(hwnd, STM_SETICON, (WPARAM) h_icon, 0);
+
+ DeferWindowPos(hdefer, hwnd, NULL,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOZORDER);
+
+ d->hwnd_notif_aux = hwnd;
+
+ EndDeferWindowPos(hdefer);
+
+ CopyRect(&d->r_notif, &r_row);
+
+ d->notif_type = NC_NOTIFY_MESSAGE;
+
+ /* Note that we must call nc_layout_main_panel() after calling
+ this to adjust the layout of the main panel. However we aren't
+ calling it here since we might want to add another set of
+ notifications or make other changes to the main panel content
+ before calling nc_layout_main_panel(). */
+}
+
+static void
+nc_layout_main_panel(khui_nc_wnd_data * d)
+{
+ RECT r_main;
+ HWND hw_ct;
+ HWND hw_ct_label;
+ HDWP hdwp;
+ RECT r_used; /* extent used by identity specifiers,
+ custom prompts and notificaiton
+ controls. */
+
+ RECT r_wmain; /* extents of the main window in screen
+ coordinates. */
+
+ r_main.left = 0;
+ r_main.top = 0;
+ r_main.bottom = NCDLG_HEIGHT;
+ r_main.right = NCDLG_WIDTH;
+
+ MapDialogRect(d->dlg_main, &r_main);
+
+ CopyRect(&r_used, &d->r_idspec);
+
+ GetWindowRect(d->dlg_main, &r_wmain);
+
+ hdwp = BeginDeferWindowPos(7);
+
+ /* check if the notification area and the custom prompt area are
+ overlapping. */
+
+ if (d->notif_type != NC_NOTIFY_NONE) {
+ long delta_y = 0;
+ RECT r;
+
+ CopyRect(&r, &d->r_custprompt);
+
+ if (IsRectEmpty(&d->r_custprompt)) {
+ /* if there are no custom prompts, then the notification
+ area should be immediately below the identitify
+ specifers. */
+
+ delta_y = d->r_idspec.bottom - d->r_notif.top;
+ } else {
+ /* otherwise, the notification area should be immediately
+ below the custom prompt area */
+
+ delta_y = d->r_custprompt.bottom - d->r_notif.top;
+ }
+
+ if (delta_y != 0) {
+ RECT r_lbl;
+ RECT r_aux;
+
+ if (d->hwnd_notif_label) {
+ GetWindowRect(d->hwnd_notif_label, &r_lbl);
+ OffsetRect(&r_lbl, -r_wmain.left, delta_y - r_wmain.top);
+
+ DeferWindowPos(hdwp, d->hwnd_notif_label, NULL,
+ r_lbl.left, r_lbl.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOSIZE);
+ }
+
+ if (d->hwnd_notif_aux) {
+ GetWindowRect(d->hwnd_notif_aux, &r_aux);
+ OffsetRect(&r_aux, -r_wmain.left, delta_y - r_wmain.top);
+
+ DeferWindowPos(hdwp, d->hwnd_notif_aux, NULL,
+ r_aux.left, r_aux.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOSIZE);
+ }
+
+ OffsetRect(&d->r_notif, 0, delta_y);
+ }
+ }
+
+ if (!IsRectEmpty(&d->r_custprompt)) {
+ r_used.bottom = max(d->r_custprompt.bottom,
+ r_used.bottom);
+ }
+
+ if (!IsRectEmpty(&d->r_notif)) {
+ r_used.bottom = max(d->r_notif.bottom,
+ r_used.bottom);
+ }
+
+ if (d->nc->mode == KHUI_NC_MODE_MINI) {
+ RECT r_ok;
+ RECT r_cancel;
+ RECT r_advanced;
+ HWND hw;
+
+ hw = GetDlgItem(d->dlg_main, IDOK);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ GetWindowRect(hw, &r_ok);
+ OffsetRect(&r_ok, -r_wmain.left, -r_ok.top + r_used.bottom);
+
+ DeferWindowPos(hdwp, hw, NULL,
+ r_ok.left, r_ok.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ hw = GetDlgItem(d->dlg_main, IDCANCEL);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ GetWindowRect(hw, &r_cancel);
+ OffsetRect(&r_cancel, -r_wmain.left, -r_cancel.top + r_used.bottom);
+
+ DeferWindowPos(hdwp, hw, NULL,
+ r_cancel.left, r_cancel.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ GetWindowRect(hw, &r_advanced);
+ OffsetRect(&r_advanced, -r_wmain.left, -r_advanced.top + r_used.bottom);
+
+ DeferWindowPos(hdwp, hw, NULL,
+ r_advanced.left, r_advanced.top, 0, 0,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
+
+ /* and now update the extents of the main panel */
+ r_main.bottom = r_used.bottom + (r_ok.bottom - r_ok.top) + d->r_area.top;
+
+ CopyRect(&d->r_main, &r_main);
+
+ } else {
+
+ HWND hw;
+
+ hw = GetDlgItem(d->dlg_main, IDOK);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ if (IsWindowVisible(hw))
+ DeferWindowPos(hdwp, hw, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
+ SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+ hw = GetDlgItem(d->dlg_main, IDCANCEL);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ if (IsWindowVisible(hw))
+ DeferWindowPos(hdwp, hw, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
+ SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+ hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
+#ifdef DEBUG
+ assert(hw != NULL);
+#endif
+ if (IsWindowVisible(hw))
+ DeferWindowPos(hdwp, hw, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE |
+ SWP_NOOWNERZORDER | SWP_NOZORDER);
+
+ d->r_credtext.top = r_used.bottom;
+
+ CopyRect(&d->r_main, &r_main);
+ }
+
+ /* now update the layout of the credentials text window */
+
+ hw_ct = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT);
+ hw_ct_label = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT_LABEL);
+#ifdef DEBUG
+ assert(hw_ct != NULL);
+ assert(hw_ct_label != NULL);
+#endif
+
+ if (d->nc->mode == KHUI_NC_MODE_MINI ||
+ d->r_credtext.bottom < d->r_credtext.top + d->r_row.bottom * 2) {
+
+ /* either we aren't supposed to show the credentials text
+ window, or we don't have enough room. */
+ if (IsWindowVisible(hw_ct) || IsWindowVisible(hw_ct_label)) {
+
+ DeferWindowPos(hdwp, hw_ct, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
+
+ DeferWindowPos(hdwp, hw_ct_label, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE);
+
+ }
+
+ } else {
+
+ DeferWindowPos(hdwp,
+ hw_ct, NULL,
+ d->r_credtext.left + d->r_n_input.left, /* x */
+ d->r_credtext.top, /* y */
+ d->r_n_input.right - d->r_n_input.left, /* width */
+ d->r_credtext.bottom - d->r_credtext.top, /* height */
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_SHOWWINDOW);
+
+ DeferWindowPos(hdwp,
+ hw_ct_label, NULL,
+ d->r_credtext.left + d->r_n_label.left, /* x */
+ d->r_credtext.top, /* y */
+ d->r_n_label.right - d->r_n_label.left, /* width */
+ d->r_n_label.bottom - d->r_n_label.top, /* height */
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_SHOWWINDOW);
+ }
+
+ EndDeferWindowPos(hdwp);
+
+ /* NOTE: although we updated d->r_main, if the new credentials
+ window is in mini mode, we must call
+ nc_layout_new_cred_window() to adjust the size of the new
+ credentials window to fit the main panel. We don't do it here
+ because we need to keep these two operations separate. */
+}
+
+/* Credential type panel comparison function. Tabs are sorted based
+ on the following criteria:
+
+ 1) By ordinal - Panels with ordinal -1 will be ranked after panels
+ whose ordinal is not -1.
+
+ 2) By name - Case insensitive comparison of the name. If the panel
+ does not have a name (i.e. the ->name member is NULL, it will be
+ ranked after panels which have a name.
+ */
+static int __cdecl
+nc_tab_sort_func(const void * v1, const void * v2)
+{
+ /* v1 and v2 and of type : khui_new_creds_by_type ** */
+ khui_new_creds_by_type *t1, *t2;
+
+ t1 = *((khui_new_creds_by_type **) v1);
+ t2 = *((khui_new_creds_by_type **) v2);
+
+ if(t1->ordinal != -1) {
+ if(t2->ordinal != -1) {
+ if(t1->ordinal == t2->ordinal) {
+ if (t1->name && t2->name)
+ return _wcsicmp(t1->name, t2->name);
+ else if (t1->name)
+ return -1;
+ else if (t2->name)
+ return 1;
+ else
+ return 0;
+ } else {
+ /* safe to convert to an int here */
+ return (int) (t1->ordinal - t2->ordinal);
+ }
+ } else
+ return -1;
+ } else {
+ if(t2->ordinal != -1)
+ return 1;
+ else if (t1->name && t2->name)
+ return wcscmp(t1->name, t2->name);
+ else if (t1->name)
+ return -1;
+ else if (t2->name)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+static void
+nc_notify_types(khui_new_creds * c, UINT uMsg,
+ WPARAM wParam, LPARAM lParam, BOOL sync)
+{
+ khm_size i;
+
+ for(i=0; i<c->n_types; i++) {
+
+ if (c->types[i]->hwnd_panel == NULL)
+ continue;
+
+ if (sync)
+ SendMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
+ else
+ PostMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
+ }
+}
+
+static void
+nc_clear_password_fields(khui_nc_wnd_data * d)
+{
+ khm_size i;
+ khm_boolean need_sync = FALSE;
+
+ khui_cw_lock_nc(d->nc);
+
+ for (i=0; i < d->nc->n_prompts; i++) {
+ if ((d->nc->prompts[i]->flags & KHUI_NCPROMPT_FLAG_HIDDEN) &&
+ d->nc->prompts[i]->hwnd_edit) {
+ SetWindowText(d->nc->prompts[i]->hwnd_edit,
+ L"");
+ need_sync = TRUE;
+ }
+ }
+
+ khui_cw_unlock_nc(d->nc);
+
+ if (need_sync) {
+ khui_cw_sync_prompt_values(d->nc);
+ }
+}
+
+/* used by nc_enable_controls */
+
+struct nc_enum_wnd_data {
+ khui_nc_wnd_data * d;
+ khm_boolean enable;
+};
+
+static
+BOOL CALLBACK
+nc_enum_wnd_proc(HWND hwnd,
+ LPARAM lParam)
+{
+ struct nc_enum_wnd_data * wd;
+
+ wd = (struct nc_enum_wnd_data *) lParam;
+
+ EnableWindow(hwnd, wd->enable);
+
+ return TRUE;
+}
+
+static void
+nc_enable_controls(khui_nc_wnd_data * d, khm_boolean enable)
+{
+ struct nc_enum_wnd_data wd;
+
+ ZeroMemory(&wd, sizeof(wd));
+
+ wd.d = d;
+ wd.enable = enable;
+
+ EnumChildWindows(d->dlg_main, nc_enum_wnd_proc, (LPARAM) &wd);
+}
+
+#define NC_MAXCCH_CREDTEXT 16384
+#define NC_MAXCB_CREDTEXT (NC_MAXCCH_CREDTEXT * sizeof(wchar_t))
+
+static void
+nc_update_credtext(khui_nc_wnd_data * d)
+{
+ wchar_t * ctbuf = NULL;
+ wchar_t * buf;
+ BOOL okEnable = FALSE;
+ BOOL validId = FALSE;
+ HWND hw = NULL;
+ size_t cch = 0;
+
+ ctbuf = PMALLOC(NC_MAXCB_CREDTEXT);
+
+ assert(ctbuf != NULL);
+
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_TABS, ctbuf, NC_MAXCCH_CREDTEXT);
+ StringCchLength(ctbuf, NC_MAXCCH_CREDTEXT, &cch);
+ buf = ctbuf + cch;
+ nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), (LPARAM) d->nc, TRUE);
+
+ /* hopefully all the types have updated their credential texts */
+
+ /* if the dialog is in the mini mode, we have to display
+ exceptions using a notification. */
+ if (d->nc->mode == KHUI_NC_MODE_MINI) {
+ BOOL need_layout = FALSE;
+ if (d->nc->n_identities == 0) {
+
+ /* There are no identities selected. We don't show any
+ notifications here. */
+ if (d->notif_type != NC_NOTIFY_NONE) {
+ nc_notify_clear(d);
+ need_layout = TRUE;
+ }
+
+ } else {
+
+ wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t format[256];
+ wchar_t msg[ARRAYLENGTH(format) + ARRAYLENGTH(id_name)];
+ khm_size cbbuf;
+ khm_int32 flags;
+
+ kcdb_identity_get_flags(d->nc->identities[0], &flags);
+
+ cbbuf = sizeof(id_name);
+ kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
+
+ if (flags & KCDB_IDENT_FLAG_INVALID) {
+
+ /* identity is invalid */
+ LoadString(khm_hInstance, IDS_NCN_IDENT_INVALID,
+ format, ARRAYLENGTH(format));
+ StringCbPrintf(msg, sizeof(msg), format, id_name);
+
+ nc_notify_message(d, KHERR_ERROR, msg);
+
+ need_layout = TRUE;
+
+ } else if ((flags & KCDB_IDENT_FLAG_VALID) ||
+ d->nc->subtype == KMSG_CRED_PASSWORD) {
+ /* special case: If we are going to change the
+ password, we don't expect the identity provider to
+ validate the identity in real time. As such, we
+ assume that the identity is valid. */
+
+ /* identity is valid */
+ if (d->notif_type != NC_NOTIFY_NONE) {
+ nc_notify_clear(d);
+ need_layout = TRUE;
+ }
+
+ } else if (flags & KCDB_IDENT_FLAG_UNKNOWN) {
+
+ /* unknown state */
+ LoadString(khm_hInstance, IDS_NCN_IDENT_UNKNOWN,
+ format, ARRAYLENGTH(format));
+ StringCbPrintf(msg, sizeof(msg), format, id_name);
+
+ nc_notify_message(d, KHERR_WARNING, msg);
+
+ need_layout = TRUE;
+
+ } else {
+
+ /* still checking */
+ LoadString(khm_hInstance, IDS_NCN_IDENT_CHECKING,
+ format, ARRAYLENGTH(format));
+ StringCbPrintf(msg, sizeof(msg), format, id_name);
+
+ nc_notify_marquee(d, msg);
+
+ need_layout = TRUE;
+
+ }
+ }
+
+ if (need_layout) {
+ nc_layout_main_panel(d);
+ nc_layout_new_cred_window(d);
+ }
+ }
+
+ if(d->nc->n_identities == 1) {
+ wchar_t main_fmt[256];
+ wchar_t id_fmt[256];
+ wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
+ khm_size cbbuf;
+ khm_int32 flags;
+
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_ONE,
+ main_fmt, (int) ARRAYLENGTH(main_fmt));
+
+ cbbuf = sizeof(id_name);
+ kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
+
+ kcdb_identity_get_flags(d->nc->identities[0], &flags);
+
+ if (flags & KCDB_IDENT_FLAG_INVALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else if(flags & KCDB_IDENT_FLAG_VALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else if(flags & KCDB_IDENT_FLAG_UNKNOWN) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else if(d->nc->subtype == KMSG_CRED_NEW_CREDS) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_CHECKING,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ }
+
+ StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
+
+ StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
+ main_fmt, id_string);
+
+ if (flags & KCDB_IDENT_FLAG_VALID) {
+ if (flags & KCDB_IDENT_FLAG_DEFAULT)
+ LoadString(khm_hInstance, IDS_NC_ID_DEF,
+ id_string, ARRAYLENGTH(id_string));
+ else if (d->nc->set_default)
+ LoadString(khm_hInstance, IDS_NC_ID_WDEF,
+ id_string, ARRAYLENGTH(id_string));
+ else
+ LoadString(khm_hInstance, IDS_NC_ID_NDEF,
+ id_string, ARRAYLENGTH(id_string));
+
+ StringCbCat(buf, NC_MAXCB_CREDTEXT - cch * sizeof(wchar_t),
+ id_string);
+ }
+
+ } else if(d->nc->n_identities > 1) {
+ wchar_t *ids_string;
+ khm_size cb_ids_string;
+
+ wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
+ wchar_t id_fmt[256];
+ wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
+
+ wchar_t main_fmt[256];
+ khm_size cbbuf;
+
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_MANY,
+ main_fmt, (int) ARRAYLENGTH(main_fmt));
+
+ /* we are going to concatenate all the identity names into
+ a comma separated string */
+
+ /* d->nc->n_identities is at least 2 */
+ ids_string = PMALLOC((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
+ (d->nc->n_identities - 1));
+ cb_ids_string =
+ (KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
+ (d->nc->n_identities - 1);
+
+ assert(ids_string != NULL);
+
+ ids_string[0] = 0;
+
+ {
+ khm_size i;
+ khm_int32 flags;
+
+ for(i=1; i<d->nc->n_identities; i++) {
+ if(i>1) {
+ StringCbCat(ids_string, cb_ids_string, L",");
+ }
+
+ flags = 0;
+
+ cbbuf = sizeof(id_name);
+ kcdb_identity_get_name(d->nc->identities[i], id_name, &cbbuf);
+ kcdb_identity_get_flags(d->nc->identities[i], &flags);
+ if(flags & KCDB_IDENT_FLAG_INVALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else if(flags & KCDB_IDENT_FLAG_VALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ }
+
+ StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
+ StringCbCat(ids_string, cb_ids_string, id_string);
+ }
+
+ cbbuf = sizeof(id_name);
+ kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
+ kcdb_identity_get_flags(d->nc->identities[0], &flags);
+ if(flags & KCDB_IDENT_FLAG_INVALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else if(flags & KCDB_IDENT_FLAG_VALID) {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ } else {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
+ id_fmt, (int) ARRAYLENGTH(id_fmt));
+ }
+ StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
+
+ StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
+ main_fmt, id_string, ids_string);
+
+ PFREE(ids_string);
+ }
+ } else {
+ LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_NONE,
+ buf, (int)(NC_MAXCCH_CREDTEXT - cch));
+ }
+
+ /* now, append the credtext string from each of the cred types */
+ {
+ khm_size i;
+ size_t cb;
+ wchar_t * buf;
+
+ cb = NC_MAXCB_CREDTEXT;
+ buf = ctbuf;
+
+ for(i=0; i<d->nc->n_types; i++) {
+ if(d->nc->types[i]->credtext != NULL) {
+ StringCbCatEx(buf, cb,
+ d->nc->types[i]->credtext,
+ &buf, &cb,
+ 0);
+ }
+ }
+ }
+
+ SetDlgItemText(d->dlg_main, IDC_NC_CREDTEXT, ctbuf);
+
+ PFREE(ctbuf);
+
+ /* so depending on whether the primary identity was found to be
+ invalid, we need to disable the Ok button and set the title to
+ reflect this */
+
+ if(d->nc->n_identities > 0) {
+ khm_int32 flags = 0;
+
+ if(KHM_SUCCEEDED(kcdb_identity_get_flags(d->nc->identities[0],
+ &flags)) &&
+ (flags & KCDB_IDENT_FLAG_VALID)) {
+ validId = TRUE;
+ }
+ }
+
+ if (d->nc->window_title == NULL) {
+ if(validId) {
+ wchar_t wpostfix[256];
+ wchar_t wtitle[KCDB_IDENT_MAXCCH_NAME + 256];
+ khm_size cbsize;
+
+ cbsize = sizeof(wtitle);
+ kcdb_identity_get_name(d->nc->identities[0], wtitle, &cbsize);
+
+ if (d->nc->subtype == KMSG_CRED_PASSWORD)
+ LoadString(khm_hInstance, IDS_WTPOST_PASSWORD,
+ wpostfix, (int) ARRAYLENGTH(wpostfix));
+ else
+ LoadString(khm_hInstance, IDS_WTPOST_NEW_CREDS,
+ wpostfix, (int) ARRAYLENGTH(wpostfix));
+
+ StringCbCat(wtitle, sizeof(wtitle), wpostfix);
+
+ SetWindowText(d->nc->hwnd, wtitle);
+ } else {
+ wchar_t wtitle[256];
+
+ if (d->nc->subtype == KMSG_CRED_PASSWORD)
+ LoadString(khm_hInstance, IDS_WT_PASSWORD,
+ wtitle, (int) ARRAYLENGTH(wtitle));
+ else
+ LoadString(khm_hInstance, IDS_WT_NEW_CREDS,
+ wtitle, (int) ARRAYLENGTH(wtitle));
+
+ SetWindowText(d->nc->hwnd, wtitle);
+ }
+ }
+
+ if (!(d->nc->response & KHUI_NC_RESPONSE_PROCESSING)) {
+ if(validId ||
+ d->nc->subtype == KMSG_CRED_PASSWORD) {
+ /* TODO: check if all the required fields have valid values
+ before enabling the Ok button */
+ okEnable = TRUE;
+ }
+
+ hw = GetDlgItem(d->dlg_main, IDOK);
+ EnableWindow(hw, okEnable);
+ hw = GetDlgItem(d->dlg_bb, IDOK);
+ EnableWindow(hw, okEnable);
+ }
+}
+
+static void
+nc_layout_new_cred_window(khui_nc_wnd_data * ncd) {
+ khui_new_creds * c;
+ RECT r_main;
+ RECT r_ncdialog;
+ HDWP hdefer;
+
+ c = ncd->nc;
+
+ r_main.left = 0;
+ r_main.top = 0;
+ r_main.right = NCDLG_WIDTH;
+ r_main.bottom = NCDLG_HEIGHT;
+
+ MapDialogRect(ncd->dlg_main, &r_main);
+
+ hdefer = BeginDeferWindowPos(5);
+
+ if (c->mode == KHUI_NC_MODE_MINI) {
+
+ if (IsWindowVisible(ncd->tab_wnd)) {
+ DeferWindowPos(hdefer,
+ ncd->tab_wnd, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW |
+ SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_NOZORDER);
+ }
+
+ if (IsWindowVisible(ncd->dlg_bb)) {
+ DeferWindowPos(hdefer,
+ ncd->dlg_bb, NULL,
+ 0, 0, 0, 0,
+ SWP_HIDEWINDOW |
+ SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOSIZE | SWP_NOZORDER);
+ }
+
+ DeferWindowPos(hdefer, ncd->dlg_main, NULL,
+ r_main.left, r_main.top,
+ r_main.right - r_main.left,
+ r_main.bottom - r_main.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_SHOWWINDOW);
+
+ /* note that the ncd->r_main.bottom may not be the same as
+ r_main.bottom because ncd->r_main.bottom is set dynamically
+ depending on custom controls. ncd->r_main is valid only
+ once nc_layout_main_panel() is called.*/
+ CopyRect(&ncd->r_required, &ncd->r_main);
+
+ } else {
+ RECT r_tabctrl;
+ RECT r_displayarea;
+ RECT r_bbar;
+ khm_size i;
+
+ /* calculate the size of the tab control so that it fits
+ snugly around the expanded main panel. */
+ CopyRect(&r_tabctrl, &r_main);
+ TabCtrl_AdjustRect(ncd->tab_wnd, TRUE, &r_tabctrl);
+
+ if (r_tabctrl.left < 0 ||
+ r_tabctrl.top < 0) {
+
+ OffsetRect(&r_tabctrl,
+ (r_tabctrl.left < 0)? -r_tabctrl.left : 0,
+ (r_tabctrl.top < 0)? -r_tabctrl.top : 0);
+
+ }
+
+#ifdef DEBUG
+ assert(r_tabctrl.left == 0);
+ assert(r_tabctrl.top == 0);
+#endif
+
+ OffsetRect(&r_tabctrl, 0, ncd->r_area.top);
+
+ /* and now calculate the rectangle where the main panel should
+ be inside the tab control. */
+ CopyRect(&r_displayarea, &r_tabctrl);
+ TabCtrl_AdjustRect(ncd->tab_wnd, FALSE, &r_displayarea);
+
+ DeferWindowPos(hdefer,
+ ncd->tab_wnd, HWND_BOTTOM,
+ r_tabctrl.left, r_tabctrl.top,
+ r_tabctrl.right - r_tabctrl.left,
+ r_tabctrl.bottom - r_tabctrl.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_SHOWWINDOW);
+
+ /* we have to place the button bar just to the right of the
+ tab panel. */
+ r_bbar.left = 0;
+ r_bbar.top = 0;
+ r_bbar.right = NCDLG_BBAR_WIDTH;
+ r_bbar.bottom = NCDLG_BBAR_HEIGHT;
+
+ MapDialogRect(ncd->dlg_main, &r_bbar);
+
+ OffsetRect(&r_bbar, r_tabctrl.right, 0);
+
+ DeferWindowPos(hdefer,
+ ncd->dlg_bb, NULL,
+ r_bbar.left, r_bbar.top,
+ r_bbar.right - r_bbar.left,
+ r_bbar.bottom - r_bbar.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER | SWP_SHOWWINDOW);
+
+ /* move the main panel inside the tab control... */
+ DeferWindowPos(hdefer,
+ ncd->dlg_main, NULL,
+ r_displayarea.left, r_displayarea.top,
+ r_displayarea.right - r_displayarea.left,
+ r_displayarea.bottom - r_displayarea.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER |
+ (ncd->current_panel == 0 ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
+
+ /* and also move all the credential type panels (if they have
+ been created) inside the tab control too. */
+ khui_cw_lock_nc(c);
+
+ for (i=0; i < c->n_types; i++) {
+ if (c->types[i]->hwnd_panel != NULL) {
+ DeferWindowPos(hdefer,
+ c->types[i]->hwnd_panel, NULL,
+ r_displayarea.left, r_displayarea.top,
+ r_displayarea.right - r_displayarea.left,
+ r_displayarea.bottom - r_displayarea.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER |
+ (ncd->current_panel == c->types[i]->ordinal ?
+ SWP_SHOWWINDOW : SWP_HIDEWINDOW));
+ }
+ }
+
+ khui_cw_unlock_nc(c);
+
+ /* then update the required size of the new credentials
+ dialog. */
+ ncd->r_required.left = 0;
+ ncd->r_required.top = 0;
+ ncd->r_required.right = r_bbar.right;
+ ncd->r_required.bottom = max(r_tabctrl.bottom, r_bbar.bottom) + ncd->r_area.top;
+ }
+
+ /* commit all the window moves, resizes and hides/shows we did*/
+ EndDeferWindowPos(hdefer);
+
+ /* now we have to see if the client area of the new credentials
+ window is the right size. */
+
+ GetClientRect(c->hwnd, &r_ncdialog);
+
+ if (
+
+ ((r_ncdialog.right - r_ncdialog.left !=
+ ncd->r_required.right - ncd->r_required.left)
+
+ ||
+
+ (r_ncdialog.bottom - r_ncdialog.top !=
+ ncd->r_required.bottom - ncd->r_required.top))
+
+ &&
+
+ /* we don't bother if the new creds window is already in the
+ process of changing the size. */
+ !ncd->size_changing) {
+
+ /* if not, notify the window that the size needs adjusting. */
+ if (IsWindowVisible(c->hwnd))
+ PostMessage(c->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_LAYOUT), 0);
+ else
+ SendMessage(c->hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_UPDATE_LAYOUT), 0);
+ }
+}
+
+#define CW_PARAM DWLP_USER
+
+static LRESULT
+nc_handle_wm_create(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ LPCREATESTRUCT lpc;
+ khui_new_creds * c;
+ khui_nc_wnd_data * ncd;
+ int x, y;
+ int width, height;
+ RECT r;
+ HFONT hf_main;
+
+ lpc = (LPCREATESTRUCT) lParam;
+
+ ncd = PMALLOC(sizeof(*ncd));
+ ZeroMemory(ncd, sizeof(*ncd));
+
+ c = (khui_new_creds *) lpc->lpCreateParams;
+ ncd->nc = c;
+ c->hwnd = hwnd;
+
+#ifdef DEBUG
+ assert(c->subtype == KMSG_CRED_NEW_CREDS ||
+ c->subtype == KMSG_CRED_PASSWORD);
+#endif
+
+#pragma warning(push)
+#pragma warning(disable: 4244)
+ SetWindowLongPtr(hwnd, CW_PARAM, (LONG_PTR) ncd);
+#pragma warning(pop)
+
+ /* first, create the tab control that will house the main dialog
+ panel as well as the plug-in specific panels */
+ ncd->tab_wnd = CreateWindowEx(0, /* extended style */
+ WC_TABCONTROL,
+ L"TabControloxxrz", /* window name */
+ TCS_HOTTRACK | TCS_RAGGEDRIGHT |
+ TCS_SINGLELINE | TCS_TABS |
+ WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS,
+ 0, 0, 100, 100, /* x,y,width height.
+ We'll be changing
+ these later
+ anyway. */
+ hwnd,
+ (HMENU) IDC_NC_TABS,
+ NULL,
+ 0);
+
+#ifdef DEBUG
+ assert(ncd->tab_wnd != NULL);
+#endif
+
+ /* try to create the main dialog panel */
+
+ ncd->dlg_main = CreateDialogParam(khm_hInstance,
+ MAKEINTRESOURCE(IDD_NC_NEWCRED),
+ hwnd,
+ nc_common_dlg_proc,
+ (LPARAM) ncd);
+#ifdef DEBUG
+ assert(ncd->dlg_main != NULL);
+#endif
+
+ hf_main = (HFONT) SendMessage(ncd->dlg_main, WM_GETFONT, 0, 0);
+ if (hf_main)
+ SendMessage(ncd->tab_wnd, WM_SETFONT, (WPARAM) hf_main, FALSE);
+
+ {
+ RECT r_main;
+ RECT r_area;
+ RECT r_row;
+ HWND hw;
+
+ /* During the operation of the new credentials window, we will
+ need to dynamically change the layout of the controls as a
+ result of custom prompting from credentials providers and
+ identity selectors from identity providers. In order to
+ guide the dynamic layout, we pick out a few metrics from
+ the dialog template for the main panel. The metrics come
+ from hidden STATIC controls in the dialog template. */
+
+ GetWindowRect(ncd->dlg_main, &r_main);
+
+ /* IDC_NC_TPL_PANEL spans the full extent of the dialog that
+ we can populate with custom controls. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_PANEL);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r_area);
+ OffsetRect(&r_area,-r_main.left, -r_main.top);
+ CopyRect(&ncd->r_area, &r_area);
+
+ /* IDC_NC_TPL_ROW spans the extent of a row of normal sized
+ custom controls. A row of custom controls typicall consist
+ of a text label and an input control. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ CopyRect(&r_row, &r);
+ OffsetRect(&r,-r.left, -r.top);
+ CopyRect(&ncd->r_row, &r);
+
+ /* IDC_NC_TPL_LABEL spans the extent that a normal sized
+ label. The control overlaps IDC_NC_TPL_ROW so we can get
+ coordinates relative to the row extents. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ OffsetRect(&r,-r_row.left, -r_row.top);
+ CopyRect(&ncd->r_n_label, &r);
+
+ /* IDC_NC_TPL_INPUT spans the extent of a normal sized input
+ control in a custom control row. The control overlaps
+ IDC_NC_TPL_ROW so we can get relative coordinates. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ OffsetRect(&r, -r_row.left, -r_row.top);
+ CopyRect(&ncd->r_n_input, &r);
+
+ /* IDC_NC_TPL_ROW_LG spans the extent of a row of large sized
+ controls. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW_LG);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r_row);
+
+ /* IDC_NC_TPL_LABEL_LG is a large sized label. The control
+ overlaps IDC_NC_TPL_ROW_LG. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL_LG);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ OffsetRect(&r, -r_row.left, -r_row.top);
+ CopyRect(&ncd->r_e_label, &r);
+
+ /* IDC_NC_TPL_INPUT_LG is a large sized input control.
+ Overlaps IDC_NC_TPL_ROW_LG. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT_LG);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ OffsetRect(&r, -r_row.left, -r_row.top);
+ CopyRect(&ncd->r_e_input, &r);
+
+ CopyRect(&ncd->r_credtext, &ncd->r_area);
+ CopyRect(&ncd->r_idspec, &ncd->r_area);
+
+ ncd->r_idspec.bottom = ncd->r_idspec.top;
+
+ /* And finally the credential text window. The only metric we
+ take from here is the Y coordinate of the bottom of the
+ control since the actual size and position of the
+ credentials window will change depending on the custom
+ controls being displayed. */
+ hw = GetDlgItem(ncd->dlg_main, IDC_NC_CREDTEXT);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ GetWindowRect(hw, &r);
+ OffsetRect(&r, -r_main.left, -r_main.top);
+ ncd->r_credtext.bottom = r.bottom;
+ }
+
+ /* if the mode is 'mini'*/
+ r.left = 0;
+ r.top = 0;
+
+ if(c->mode == KHUI_NC_MODE_MINI) {
+ r.right = NCDLG_WIDTH;
+ r.bottom = NCDLG_HEIGHT;
+ } else {
+ r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;
+ r.bottom = NCDLG_BBAR_HEIGHT;
+ }
+
+ MapDialogRect(ncd->dlg_main, &r);
+
+ /* position the new credentials dialog */
+ width = r.right - r.left;
+ height = r.bottom - r.top;
+
+ /* adjust width and height to accomodate NC area */
+ {
+ RECT wr,cr;
+
+ GetWindowRect(hwnd, &wr);
+ GetClientRect(hwnd, &cr);
+
+ /* the non-client and client areas have already been calculated
+ at this point. We just use the difference to adjust the width
+ and height */
+ width += (wr.right - wr.left) - (cr.right - cr.left);
+ height += (wr.bottom - wr.top) - (cr.bottom - cr.top);
+ }
+
+ /* if the parent window is visible, we center the new credentials
+ dialog over the parent. Otherwise, we center it on the primary
+ display. */
+
+ if (IsWindowVisible(lpc->hwndParent)) {
+ GetWindowRect(lpc->hwndParent, &r);
+ } else {
+ if(!SystemParametersInfo(SPI_GETWORKAREA, 0, (PVOID) &r, 0)) {
+ /* failover to the window coordinates */
+ GetWindowRect(lpc->hwndParent, &r);
+ }
+ }
+ x = (r.right + r.left)/2 - width / 2;
+ y = (r.top + r.bottom)/2 - height / 2;
+
+ MoveWindow(hwnd, x, y, width, height, FALSE);
+
+ ncd->dlg_bb = CreateDialogParam(khm_hInstance,
+ MAKEINTRESOURCE(IDD_NC_BBAR),
+ hwnd,
+ nc_common_dlg_proc,
+ (LPARAM) ncd);
+
+#ifdef DEBUG
+ assert(ncd->dlg_bb);
+#endif
+
+ /* Call the identity provider callback to set the identity
+ selector controls. These controls need to be there before we
+ layout the main panel. */
+ c->ident_cb(c, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) ncd->dlg_main);
+
+ if (c->mode == KHUI_NC_MODE_EXPANDED) {
+ SendMessage(ncd->dlg_main, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
+ } else {
+ /* we don't call nc_layout_main_panel() if the dialog is
+ expanded because posting WMNC_DIALOG_EXPAND to the main
+ panel results in it getting called anyway. */
+ nc_layout_main_panel(ncd);
+ }
+
+ nc_layout_new_cred_window(ncd);
+
+ /* add this to the dialog chain */
+ khm_add_dialog(hwnd);
+
+ return TRUE;
+}
+
+/* add a control row supplied by an identity provider */
+static void
+nc_add_control_row(khui_nc_wnd_data * d,
+ HWND label,
+ HWND input,
+ khui_control_size size)
+{
+ RECT r_row;
+ RECT r_label;
+ RECT r_input;
+ HFONT hf;
+ HDWP hdefer;
+
+ hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
+ SendMessage(label, WM_SETFONT, (WPARAM) hf, FALSE);
+ SendMessage(input, WM_SETFONT, (WPARAM) hf, FALSE);
+
+ CopyRect(&r_row, &d->r_row);
+ OffsetRect(&r_row, d->r_idspec.left, d->r_idspec.bottom);
+
+ if (size == KHUI_CTRLSIZE_SMALL) {
+ CopyRect(&r_label, &d->r_n_label);
+ CopyRect(&r_input, &d->r_n_input);
+ OffsetRect(&r_label, r_row.left, r_row.top);
+ OffsetRect(&r_input, r_row.left, r_row.top);
+ } else if (size == KHUI_CTRLSIZE_HALF) {
+ CopyRect(&r_label, &d->r_e_label);
+ CopyRect(&r_input, &d->r_e_input);
+ OffsetRect(&r_label, r_row.left, r_row.top);
+ OffsetRect(&r_input, r_row.left, r_row.top);
+ } else if (size == KHUI_CTRLSIZE_FULL) {
+ CopyRect(&r_label, &d->r_n_label);
+ r_label.right = d->r_row.right;
+ CopyRect(&r_input, &d->r_n_input);
+ OffsetRect(&r_input, r_row.left, r_row.top);
+ OffsetRect(&r_input, 0, r_input.bottom);
+ r_row.bottom += r_input.bottom;
+ OffsetRect(&r_label, r_row.left, r_row.top);
+ } else {
+ SetRectEmpty(&r_label);
+ SetRectEmpty(&r_input);
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ return;
+ }
+
+ hdefer = BeginDeferWindowPos(2);
+
+ if (label)
+ DeferWindowPos(hdefer, label,
+ ((d->hwnd_last_idspec != NULL)?
+ d->hwnd_last_idspec:
+ HWND_TOP),
+ r_label.left, r_label.top,
+ r_label.right - r_label.left,
+ r_label.bottom - r_label.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+
+ if (input)
+ DeferWindowPos(hdefer, input,
+ (label ? label : ((d->hwnd_last_idspec != NULL)?
+ d->hwnd_last_idspec:
+ HWND_TOP)),
+ r_input.left, r_input.top,
+ r_input.right - r_input.left,
+ r_input.bottom - r_input.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+
+ EndDeferWindowPos(hdefer);
+
+ d->hwnd_last_idspec = (input ? input : label);
+
+ d->r_idspec.bottom = r_row.bottom;
+
+ /* we don't update the layout of the main panel yet, since these
+ control additions happen before the main panel is displayed. A
+ call to nc_layout_main_panel() will be made before the main
+ panel is shown anyway. */
+
+}
+
+
+static LRESULT
+nc_handle_wm_destroy(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ khui_nc_wnd_data * d;
+
+ /* remove self from dialog chain */
+ khm_del_dialog(hwnd);
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);
+
+ if (d->hwnd_notif_label)
+ DestroyWindow(d->hwnd_notif_label);
+ if (d->hwnd_notif_aux)
+ DestroyWindow(d->hwnd_notif_aux);
+
+ if(d->dlg_bb)
+ DestroyWindow(d->dlg_bb);
+ if(d->dlg_main)
+ DestroyWindow(d->dlg_main);
+
+ d->dlg_bb = NULL;
+ d->dlg_main = NULL;
+
+ PFREE(d);
+
+ return TRUE;
+}
+
+static LRESULT
+nc_handle_wm_command(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ switch(HIWORD(wParam)) {
+ case BN_CLICKED:
+ switch(LOWORD(wParam)) {
+
+ case IDOK:
+ d->nc->result = KHUI_NC_RESULT_PROCESS;
+
+ /* fallthrough */
+
+ case IDCANCEL:
+ /* the default value for d->nc->result is set to
+ KHUI_NC_RESULT_CANCEL */
+ d->nc->response = KHUI_NC_RESPONSE_PROCESSING;
+
+ nc_enable_controls(d, FALSE);
+
+ nc_notify_types(d->nc,
+ KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0,WMNC_DIALOG_PREPROCESS),
+ (LPARAM) d->nc,
+ TRUE);
+
+ khui_cw_sync_prompt_values(d->nc);
+
+ khm_cred_dispatch_process_message(d->nc);
+
+ /* we won't know whether to abort or not until we get
+ feedback from the plugins, even if the command was
+ to cancel */
+ {
+ HWND hw;
+
+ hw = GetDlgItem(d->dlg_main, IDOK);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(d->dlg_main, IDCANCEL);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(d->dlg_bb, IDOK);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(d->dlg_bb, IDCANCEL);
+ EnableWindow(hw, FALSE);
+ }
+ return FALSE;
+
+ case IDC_NC_HELP:
+ khm_html_help(hwnd, NULL, HH_HELP_CONTEXT, IDH_ACTION_NEW_ID);
+ return FALSE;
+
+ case IDC_NC_BASIC:
+ case IDC_NC_ADVANCED:
+ /* the Options button in the main window was clicked. we
+ respond by expanding the dialog. */
+ PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
+ return FALSE;
+
+ case IDC_NC_CREDTEXT: /* credtext link activated */
+ {
+ khui_htwnd_link * l;
+ wchar_t sid[KHUI_MAXCCH_HTLINK_FIELD];
+ wchar_t sparam[KHUI_MAXCCH_HTLINK_FIELD];
+ wchar_t * colon;
+
+ l = (khui_htwnd_link *) lParam;
+
+ /* do we have a valid link? */
+ if(l->id == NULL || l->id_len >= ARRAYLENGTH(sid))
+ return TRUE; /* nope */
+
+ StringCchCopyN(sid, ARRAYLENGTH(sid), l->id, l->id_len);
+ sid[l->id_len] = L'\0'; /* just make sure */
+
+ if(l->param != NULL &&
+ l->param_len < ARRAYLENGTH(sparam) &&
+ l->param_len > 0) {
+
+ StringCchCopyN(sparam, ARRAYLENGTH(sparam),
+ l->param, l->param_len);
+ sparam[l->param_len] = L'\0';
+
+ } else {
+ sparam[0] = L'\0';
+ }
+
+ /* If the ID is of the form '<credtype>:<link_tag>'
+ and <credtype> is a valid name of a credentials
+ type that is participating in the credentials
+ acquisition process, then we forward the message to
+ the panel that is providing the UI for that cred
+ type. We also switch to that panel first, unless
+ the link is of the form '<credtype>:!<link_tag>'. */
+
+ colon = wcschr(sid, L':');
+ if (colon != NULL) {
+ khm_int32 credtype;
+ khui_new_creds_by_type * t;
+
+ *colon = L'\0';
+ if (KHM_SUCCEEDED(kcdb_credtype_get_id(sid, &credtype)) &&
+ KHM_SUCCEEDED(khui_cw_find_type(d->nc, credtype, &t))){
+ *colon = L':';
+
+ if (t->ordinal != d->current_panel &&
+ *(colon + 1) != L'!')
+ PostMessage(hwnd,
+ KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(t->ordinal,
+ WMNC_DIALOG_SWITCH_PANEL),
+ 0);
+
+ return SendMessage(t->hwnd_panel,
+ KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_CREDTEXT_LINK),
+ lParam);
+ } else {
+ *colon = L':';
+ }
+ }
+
+ /* if it was for us, then we need to process the message */
+ if(!_wcsicmp(sid, CTLINKID_SWITCH_PANEL)) {
+ khm_int32 credtype;
+ khui_new_creds_by_type * t;
+
+ if (KHM_SUCCEEDED(kcdb_credtype_get_id(sparam,
+ &credtype)) &&
+ KHM_SUCCEEDED(khui_cw_find_type(d->nc,
+ credtype, &t))) {
+ if (t->ordinal != d->current_panel)
+ PostMessage(hwnd,
+ KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(t->ordinal,
+ WMNC_DIALOG_SWITCH_PANEL),
+ 0);
+ }
+ } else if (!_wcsicmp(sid, L"NotDef")) {
+ d->nc->set_default = FALSE;
+ nc_update_credtext(d);
+ } else if (!_wcsicmp(sid, L"MakeDef")) {
+ d->nc->set_default = TRUE;
+ nc_update_credtext(d);
+ }
+ }
+ return FALSE;
+
+#if 0
+ case NC_BN_SET_DEF_ID:
+ {
+ d->nc->set_default =
+ (IsDlgButtonChecked(d->dlg_main, NC_BN_SET_DEF_ID)
+ == BST_CHECKED);
+ }
+ return FALSE;
+#endif
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+static LRESULT nc_handle_wm_moving(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_DIALOG_MOVE), (LPARAM) d->nc, TRUE);
+
+ return FALSE;
+}
+
+static LRESULT nc_handle_wm_nc_notify(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ khui_nc_wnd_data * d;
+ int id;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ switch(HIWORD(wParam)) {
+
+ case WMNC_DIALOG_SWITCH_PANEL:
+ id = LOWORD(wParam);
+ if(id >= 0 && id <= (int) d->nc->n_types) {
+ /* one of the tab buttons were pressed */
+ if(d->current_panel == id) {
+ return TRUE; /* nothing to do */
+ }
+
+ d->current_panel = id;
+
+ TabCtrl_SetCurSel(d->tab_wnd, id);
+ }
+
+ if(d->nc->mode == KHUI_NC_MODE_EXPANDED) {
+ nc_layout_new_cred_window(d);
+ return TRUE;
+ }
+ /*else*/
+ /* fallthrough */
+
+ case WMNC_DIALOG_EXPAND:
+ /* we are switching from basic to advanced or vice versa */
+
+ if (d->nc->mode == KHUI_NC_MODE_EXPANDED) {
+ d->nc->mode = KHUI_NC_MODE_MINI;
+ } else {
+ d->nc->mode = KHUI_NC_MODE_EXPANDED;
+ }
+
+ /* if we are switching to the advanced mode, we clear any
+ notifications because we now have a credential text area
+ for that. */
+ if (d->nc->mode == KHUI_NC_MODE_EXPANDED)
+ nc_notify_clear(d);
+
+ nc_layout_main_panel(d);
+
+ nc_layout_new_cred_window(d);
+
+ break;
+
+ case WMNC_DIALOG_SETUP:
+
+ if(d->nc->n_types > 0) {
+ khm_size i;
+ for(i=0; i < d->nc->n_types;i++) {
+
+ if (d->nc->types[i]->dlg_proc == NULL) {
+ d->nc->types[i]->hwnd_panel = NULL;
+ } else {
+ /* Create the dialog panel */
+ d->nc->types[i]->hwnd_panel =
+ CreateDialogParam(d->nc->types[i]->h_module,
+ d->nc->types[i]->dlg_template,
+ d->nc->hwnd,
+ d->nc->types[i]->dlg_proc,
+ (LPARAM) d->nc);
+
+#ifdef DEBUG
+ assert(d->nc->types[i]->hwnd_panel);
+#endif
+ }
+ }
+ }
+
+ break;
+
+ case WMNC_DIALOG_ACTIVATE:
+ {
+ wchar_t wname[KCDB_MAXCCH_NAME];
+ TCITEM tabitem;
+ khm_int32 t;
+
+ /* About to activate the window. We should add all the
+ panels to the tab control. */
+
+#ifdef DEBUG
+ assert(d->tab_wnd != NULL);
+#endif
+
+ ZeroMemory(&tabitem, sizeof(tabitem));
+
+ tabitem.mask = TCIF_PARAM | TCIF_TEXT;
+
+ LoadString(khm_hInstance, IDS_NC_IDENTITY,
+ wname, ARRAYLENGTH(wname));
+
+ tabitem.pszText = wname;
+ tabitem.lParam = 0; /* ordinal */
+
+ TabCtrl_InsertItem(d->tab_wnd, 0, &tabitem);
+
+ khui_cw_lock_nc(d->nc);
+
+ if(d->nc->n_types > 0) {
+ khm_size i;
+
+ /* We should sort the tabs first. See
+ nc_tab_sort_func() for sort criteria. */
+ qsort(d->nc->types,
+ d->nc->n_types,
+ sizeof(*(d->nc->types)),
+ nc_tab_sort_func);
+
+ for(i=0; i < d->nc->n_types;i++) {
+
+ d->nc->types[i]->ordinal = i + 1;
+
+ if(d->nc->types[i]->name)
+ tabitem.pszText = d->nc->types[i]->name;
+ else {
+ khm_size cbsize;
+
+ cbsize = sizeof(wname);
+
+ if(KHM_FAILED
+ (kcdb_credtype_describe
+ (d->nc->types[i]->type,
+ wname,
+ &cbsize,
+ KCDB_TS_SHORT))) {
+
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ wname[0] = L'\0';
+
+ }
+
+ tabitem.pszText = wname;
+
+ }
+
+ tabitem.lParam = d->nc->types[i]->ordinal;
+
+ TabCtrl_InsertItem(d->tab_wnd, d->nc->types[i]->ordinal,
+ &tabitem);
+ }
+ }
+
+ khui_cw_unlock_nc(d->nc);
+
+ nc_update_credtext(d);
+
+ TabCtrl_SetCurSel(d->tab_wnd, 0); /* the first selected
+ tab is the main
+ panel. */
+
+ /* bring the window to the top, if necessary */
+ if (KHM_SUCCEEDED(khc_read_int32(NULL,
+ L"CredWindow\\Windows\\NewCred\\ForceToTop",
+ &t)) &&
+
+ t != 0) {
+ /* it used to be that the above condition also called
+ !khm_is_dialog_active() to find out whether there
+ was a dialog active. If there was, we wouldn't try
+ to bring the new cred window to the foreground. But
+ that was not the behavior we want. */
+
+ /* if the main window is not visible, then the SetWindowPos()
+ call is sufficient to bring the new creds window to the
+ top. However, if the main window is visible but not
+ active, the main window needs to be activated before a
+ child window can be activated. */
+ khm_activate_main_window();
+
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
+ (SWP_NOMOVE | SWP_NOSIZE));
+ }
+
+ ShowWindow(hwnd, SW_SHOWNOACTIVATE);
+
+ /* we don't enable animations until a specific timeout
+ elapses after showing the window. We don't need to
+ animate any size changes if the user has barely had a
+ chance to notice the original size. This prevents the
+ new cred window from appearing in an animated state. */
+ SetTimer(hwnd, NC_TIMER_ENABLEANIMATE, ENABLEANIMATE_TIMEOUT, NULL);
+
+ SetFocus(hwnd);
+
+ if (d->nc->n_identities == 0)
+ break;
+ /* else */
+ /* fallthrough */
+ }
+
+ case WMNC_IDENTITY_CHANGE:
+ {
+ BOOL okEnable = FALSE;
+
+ nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_IDENTITY_CHANGE), (LPARAM) d->nc,
+ TRUE);
+
+ if (d->nc->subtype == KMSG_CRED_NEW_CREDS &&
+ d->nc->n_identities > 0 &&
+ d->nc->identities[0]) {
+ khm_int32 f = 0;
+
+ kcdb_identity_get_flags(d->nc->identities[0], &f);
+
+ if (!(f & KCDB_IDENT_FLAG_DEFAULT)) {
+ d->nc->set_default = FALSE;
+ }
+ }
+
+ nc_update_credtext(d);
+
+ }
+ break;
+
+ case WMNC_TYPE_STATE:
+ /* fallthrough */
+ case WMNC_UPDATE_CREDTEXT:
+ nc_update_credtext(d);
+ break;
+
+ case WMNC_CLEAR_PROMPTS:
+ {
+ khm_size i;
+
+ khui_cw_lock_nc(d->nc);
+
+ if(d->hwnd_banner != NULL) {
+ DestroyWindow(d->hwnd_banner);
+ d->hwnd_banner = NULL;
+ }
+
+ if(d->hwnd_name != NULL) {
+ DestroyWindow(d->hwnd_name);
+ d->hwnd_name = NULL;
+ }
+
+ for(i=0;i<d->nc->n_prompts;i++) {
+ if(!(d->nc->prompts[i]->flags &
+ KHUI_NCPROMPT_FLAG_STOCK)) {
+ if(d->nc->prompts[i]->hwnd_static != NULL)
+ DestroyWindow(d->nc->prompts[i]->hwnd_static);
+
+ if(d->nc->prompts[i]->hwnd_edit != NULL)
+ DestroyWindow(d->nc->prompts[i]->hwnd_edit);
+ }
+
+ d->nc->prompts[i]->hwnd_static = NULL;
+ d->nc->prompts[i]->hwnd_edit = NULL;
+ }
+
+ khui_cw_unlock_nc(d->nc);
+
+ SetRectEmpty(&d->r_custprompt);
+
+ nc_layout_main_panel(d);
+
+ nc_layout_new_cred_window(d);
+ }
+ break;
+
+ case WMNC_SET_PROMPTS:
+ {
+ khm_size i;
+ int y;
+ HWND hw, hw_prev;
+ HFONT hf, hfold;
+ HDC hdc;
+ BOOL use_large_lables = FALSE;
+
+ /* we assume that WMNC_CLEAR_PROMPTS has already been
+ received */
+
+#ifdef DEBUG
+ assert(IsRectEmpty(&d->r_custprompt));
+#endif
+
+ khui_cw_lock_nc(d->nc);
+
+#if 0
+ /* special case, we have one prompt and it is a password
+ prompt. very common */
+ if(d->nc->n_prompts == 1 &&
+ d->nc->prompts[0]->type == KHUI_NCPROMPT_TYPE_PASSWORD) {
+
+ hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD);
+ EnableWindow(hw, TRUE);
+
+ d->nc->prompts[0]->flags |= KHUI_NCPROMPT_FLAG_STOCK;
+ d->nc->prompts[0]->hwnd_edit = hw;
+ d->nc->prompts[0]->hwnd_static = NULL; /* don't care */
+
+ khui_cw_unlock_nc(d->nc);
+ break;
+ }
+#endif
+ /* for everything else */
+
+ y = d->r_idspec.bottom;
+
+ d->r_custprompt.left = d->r_area.left;
+ d->r_custprompt.right = d->r_area.right;
+ d->r_custprompt.top = y;
+
+ hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
+
+ if (d->nc->pname != NULL) {
+ hw =
+ CreateWindowEx
+ (0,
+ L"STATIC",
+ d->nc->pname,
+ SS_SUNKEN | WS_CHILD,
+ d->r_area.left, y,
+ d->r_row.right,
+ d->r_n_label.bottom - d->r_n_label.top,
+ d->dlg_main,
+ NULL,
+ khm_hInstance,
+ NULL);
+
+#ifdef DEBUG
+ assert(hw);
+#endif
+ d->hwnd_name = hw;
+ SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM) TRUE);
+ ShowWindow(hw, SW_SHOW);
+
+ y += d->r_n_label.bottom - d->r_n_label.top;
+ }
+
+ if (d->nc->banner != NULL) {
+ hw =
+ CreateWindowEx
+ (0,
+ L"STATIC",
+ d->nc->banner,
+ WS_CHILD,
+ d->r_area.left, y,
+ d->r_row.right, d->r_row.bottom,
+ d->dlg_main,
+ NULL,
+ khm_hInstance,
+ NULL);
+#ifdef DEBUG
+ assert(hw);
+#endif
+ d->hwnd_banner = hw;
+ SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM)TRUE);
+ ShowWindow(hw, SW_SHOW);
+ y += d->r_row.bottom;
+ }
+
+ hw_prev = d->hwnd_last_idspec;
+
+ hdc = GetWindowDC(d->dlg_main);
+ hfold = SelectObject(hdc,hf);
+
+ /* first do a trial run and see if we should use the
+ larger text labels or not. This is so that all the
+ labels and input controls align properly. */
+ for (i=0; i < d->nc->n_prompts; i++) {
+ if (d->nc->prompts[i]->prompt != NULL) {
+ SIZE s;
+
+ GetTextExtentPoint32(hdc,
+ d->nc->prompts[i]->prompt,
+ (int) wcslen(d->nc->prompts[i]->prompt),
+ &s);
+
+ if(s.cx >= d->r_n_label.right - d->r_n_label.left) {
+ use_large_lables = TRUE;
+ break;
+ }
+ }
+ }
+
+ for(i=0; i<d->nc->n_prompts; i++) {
+ RECT pr, er;
+ SIZE s;
+ int dy;
+
+ if(d->nc->prompts[i]->prompt != NULL) {
+ GetTextExtentPoint32(hdc,
+ d->nc->prompts[i]->prompt,
+ (int) wcslen(d->nc->prompts[i]->prompt),
+ &s);
+ if(s.cx < d->r_n_label.right - d->r_n_label.left &&
+ !use_large_lables) {
+ CopyRect(&pr, &d->r_n_label);
+ CopyRect(&er, &d->r_n_input);
+ dy = d->r_row.bottom;
+ } else if(s.cx <
+ d->r_e_label.right - d->r_e_label.left) {
+ CopyRect(&pr, &d->r_e_label);
+ CopyRect(&er, &d->r_e_input);
+ dy = d->r_row.bottom;
+ } else {
+ /* oops. the prompt doesn't fit in our
+ controls. we need to use up two lines */
+ pr.left = 0;
+ pr.right = d->r_row.right;
+ pr.top = 0;
+ pr.bottom = d->r_n_label.bottom -
+ d->r_n_label.top;
+ CopyRect(&er, &d->r_n_input);
+ OffsetRect(&er, 0, pr.bottom);
+ dy = er.bottom + (d->r_row.bottom -
+ d->r_n_input.bottom);
+ }
+ } else {
+ SetRectEmpty(&pr);
+ CopyRect(&er, &d->r_n_input);
+ dy = d->r_row.bottom;
+ }
+
+ if(IsRectEmpty(&pr)) {
+ d->nc->prompts[i]->hwnd_static = NULL;
+ } else {
+ OffsetRect(&pr, d->r_area.left, y);
+
+ hw = CreateWindowEx
+ (0,
+ L"STATIC",
+ d->nc->prompts[i]->prompt,
+ WS_CHILD,
+ pr.left, pr.top,
+ pr.right - pr.left, pr.bottom - pr.top,
+ d->dlg_main,
+ NULL,
+ khm_hInstance,
+ NULL);
+#ifdef DEBUG
+ assert(hw);
+#endif
+
+ SendMessage(hw, WM_SETFONT,
+ (WPARAM) hf, (LPARAM) TRUE);
+
+ SetWindowPos(hw, hw_prev,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE |
+ SWP_NOOWNERZORDER | SWP_NOSIZE |
+ SWP_SHOWWINDOW);
+
+ d->nc->prompts[i]->hwnd_static = hw;
+ hw_prev = hw;
+ }
+
+ OffsetRect(&er, d->r_area.left, y);
+
+ hw = CreateWindowEx
+ (0,
+ L"EDIT",
+ (d->nc->prompts[i]->def ?
+ d->nc->prompts[i]->def : L""),
+ WS_CHILD | WS_TABSTOP |
+ WS_BORDER |
+ ((d->nc->prompts[i]->flags &
+ KHUI_NCPROMPT_FLAG_HIDDEN)? ES_PASSWORD:0),
+ er.left, er.top,
+ er.right - er.left, er.bottom - er.top,
+ d->dlg_main,
+ NULL,
+ khm_hInstance,
+ NULL);
+
+#ifdef DEBUG
+ assert(hw);
+#endif
+
+ SendMessage(hw, WM_SETFONT,
+ (WPARAM) hf, (LPARAM) TRUE);
+
+ SetWindowPos(hw, hw_prev,
+ 0, 0, 0, 0,
+ SWP_NOACTIVATE | SWP_NOMOVE |
+ SWP_NOOWNERZORDER | SWP_NOSIZE |
+ SWP_SHOWWINDOW);
+
+ SendMessage(hw, EM_SETLIMITTEXT,
+ KHUI_MAXCCH_PROMPT_VALUE -1,
+ 0);
+
+ d->nc->prompts[i]->hwnd_edit = hw;
+
+ hw_prev = hw;
+
+ y += dy;
+ }
+
+ if (d->nc->n_prompts > 0 &&
+ d->nc->prompts[0]->hwnd_edit) {
+
+ PostMessage(d->dlg_main, WM_NEXTDLGCTL,
+ (WPARAM) d->nc->prompts[0]->hwnd_edit,
+ MAKELPARAM(TRUE, 0));
+
+ }
+
+ SelectObject(hdc, hfold);
+ ReleaseDC(d->dlg_main, hdc);
+
+ khui_cw_unlock_nc(d->nc);
+
+ d->r_custprompt.bottom = y;
+
+ if (d->r_custprompt.bottom == d->r_custprompt.top)
+ SetRectEmpty(&d->r_custprompt);
+
+ nc_layout_main_panel(d);
+
+ nc_layout_new_cred_window(d);
+ }
+ break;
+
+ case WMNC_DIALOG_PROCESS_COMPLETE:
+ {
+ khui_new_creds * nc;
+
+ nc = d->nc;
+
+ nc->response &= ~KHUI_NC_RESPONSE_PROCESSING;
+
+ if(nc->response & KHUI_NC_RESPONSE_NOEXIT) {
+ HWND hw;
+
+ nc_enable_controls(d, TRUE);
+
+ /* reset state */
+ nc->result = KHUI_NC_RESULT_CANCEL;
+
+ hw = GetDlgItem(d->dlg_main, IDOK);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(d->dlg_main, IDCANCEL);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(d->dlg_main, IDC_NC_ADVANCED);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(d->dlg_bb, IDOK);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(d->dlg_bb, IDCANCEL);
+ EnableWindow(hw, TRUE);
+
+ nc_clear_password_fields(d);
+
+ return TRUE;
+ }
+
+ DestroyWindow(hwnd);
+
+ kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, (void *) nc);
+ }
+ break;
+
+ /* MUST be called with SendMessage */
+ case WMNC_ADD_CONTROL_ROW:
+ {
+ khui_control_row * row;
+
+ row = (khui_control_row *) lParam;
+
+#ifdef DEBUG
+ assert(row->label);
+ assert(row->input);
+#endif
+
+ nc_add_control_row(d, row->label, row->input, row->size);
+ }
+ break;
+
+ case WMNC_UPDATE_LAYOUT:
+ {
+
+ RECT r_client;
+ khm_int32 animate;
+ khm_int32 steps;
+ khm_int32 timeout;
+
+ /* We are already adjusting the size of the window. The
+ next time the timer fires, it will notice if the target
+ size has changed. */
+ if (d->size_changing)
+ return TRUE;
+
+ GetClientRect(hwnd, &r_client);
+
+ if ((r_client.right - r_client.left ==
+ d->r_required.right - d->r_required.left) &&
+ (r_client.bottom - r_client.top ==
+ d->r_required.bottom - d->r_required.top)) {
+
+ /* the window is already at the right size */
+ return TRUE;
+
+ }
+
+ if (!IsWindowVisible(hwnd)) {
+ /* The window is not visible yet. There's no need to
+ animate anything. */
+
+ animate = FALSE;
+
+ } else if (KHM_FAILED(khc_read_int32(NULL,
+ L"CredWindow\\Windows\\NewCred\\AnimateSizeChanges",
+ &animate))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ animate = TRUE;
+ }
+
+ /* if we aren't animating the window resize, then we just
+ do it in one call. */
+ if (!animate || !d->animation_enabled) {
+ RECT r_window;
+
+ CopyRect(&r_window, &d->r_required);
+ AdjustWindowRectEx(&r_window, NC_WINDOW_STYLES, FALSE,
+ NC_WINDOW_EX_STYLES);
+
+ SetWindowPos(hwnd, NULL, 0, 0,
+ r_window.right - r_window.left,
+ r_window.bottom - r_window.top,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER);
+
+ return TRUE;
+ }
+
+ if (KHM_FAILED(khc_read_int32(NULL,
+ L"CredWindow\\Windows\\NewCred\\AnimationSteps",
+ &steps))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ steps = NC_SZ_STEPS_DEF;
+ } else {
+
+ if (steps < NC_SZ_STEPS_MIN)
+ steps = NC_SZ_STEPS_MIN;
+ else if (steps > NC_SZ_STEPS_MAX)
+ steps = NC_SZ_STEPS_MAX;
+
+ }
+
+ if (KHM_FAILED(khc_read_int32(NULL,
+ L"CredWindow\\Windows\\NewCred\\AnimationStepTimeout",
+ &timeout))) {
+#ifdef DEBUG
+ assert(FALSE);
+#endif
+ timeout = NC_SZ_TIMEOUT_DEF;
+ } else {
+
+ if (timeout < NC_SZ_TIMEOUT_MIN)
+ timeout = NC_SZ_TIMEOUT_MIN;
+ else if (timeout > NC_SZ_TIMEOUT_MAX)
+ timeout = NC_SZ_TIMEOUT_MAX;
+
+ }
+
+ CopyRect(&d->sz_ch_source, &r_client);
+ OffsetRect(&d->sz_ch_source, -d->sz_ch_source.left, -d->sz_ch_source.top);
+ CopyRect(&d->sz_ch_target, &d->r_required);
+ OffsetRect(&d->sz_ch_target, -d->sz_ch_target.left, -d->sz_ch_target.top);
+ d->sz_ch_increment = 0;
+ d->sz_ch_max = steps;
+ d->sz_ch_timeout = timeout;
+ d->size_changing = TRUE;
+
+ SetTimer(hwnd, NC_TIMER_SIZER, timeout, NULL);
+ }
+ break;
+ } /* switch(HIWORD(wParam)) */
+
+ return TRUE;
+}
+
+static LRESULT nc_handle_wm_timer(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ if (wParam == NC_TIMER_SIZER) {
+
+ RECT r_now;
+
+ /* are we done with this sizing operation? */
+ if (!d->size_changing ||
+ d->sz_ch_increment >= d->sz_ch_max) {
+
+ d->size_changing = FALSE;
+ KillTimer(hwnd, NC_TIMER_SIZER);
+ return 0;
+ }
+
+ /* have the requirements changed while we were processing the
+ sizing operation? */
+ if ((d->r_required.right - d->r_required.left !=
+ d->sz_ch_target.right)
+
+ ||
+
+ (d->r_required.bottom - d->r_required.top !=
+ d->sz_ch_target.bottom)) {
+
+ /* the target size has changed. we need to restart the
+ sizing operation. */
+
+ RECT r_client;
+
+ GetClientRect(hwnd, &r_client);
+
+ CopyRect(&d->sz_ch_source, &r_client);
+ OffsetRect(&d->sz_ch_source, -d->sz_ch_source.left, -d->sz_ch_source.top);
+ CopyRect(&d->sz_ch_target, &d->r_required);
+ OffsetRect(&d->sz_ch_target, -d->sz_ch_target.left, -d->sz_ch_target.top);
+ d->sz_ch_increment = 0;
+
+ /* leave the other fields alone */
+
+#ifdef DEBUG
+ assert(d->sz_ch_max >= NC_SZ_STEPS_MIN);
+ assert(d->sz_ch_max <= NC_SZ_STEPS_MAX);
+ assert(d->sz_ch_timeout >= NC_SZ_TIMEOUT_MIN);
+ assert(d->sz_ch_timeout <= NC_SZ_TIMEOUT_MAX);
+ assert(d->size_changing);
+#endif
+ }
+
+ /* we are going to do the next increment */
+ d->sz_ch_increment ++;
+
+ /* now, figure out the size of the client area for this
+ step */
+
+ r_now.left = 0;
+ r_now.top = 0;
+
+#define PROPORTION(v1, v2, i, s) (((v1) * ((s) - (i)) + (v2) * (i)) / (s))
+
+ r_now.right = PROPORTION(d->sz_ch_source.right, d->sz_ch_target.right,
+ d->sz_ch_increment, d->sz_ch_max);
+
+ r_now.bottom = PROPORTION(d->sz_ch_source.bottom, d->sz_ch_target.bottom,
+ d->sz_ch_increment, d->sz_ch_max);
+
+#undef PROPORTION
+
+#ifdef DEBUG
+ {
+ long dx = (r_now.right - d->sz_ch_target.right) *
+ (d->sz_ch_source.right - d->sz_ch_target.right);
+
+ long dy = (r_now.bottom - d->sz_ch_target.bottom) *
+ (d->sz_ch_source.bottom - d->sz_ch_target.bottom);
+
+ if (dx < 0 || dy < 0) {
+ KillTimer(hwnd, NC_TIMER_SIZER);
+ assert(dx >= 0);
+ assert(dy >= 0);
+ SetTimer(hwnd, NC_TIMER_SIZER, d->sz_ch_timeout, NULL);
+ }
+ }
+#endif
+
+ AdjustWindowRectEx(&r_now, NC_WINDOW_STYLES, FALSE,
+ NC_WINDOW_EX_STYLES);
+
+ SetWindowPos(hwnd, NULL,
+ 0, 0,
+ r_now.right - r_now.left,
+ r_now.bottom - r_now.top,
+ SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER |
+ SWP_NOZORDER);
+
+ /* and now we wait for the next timer message */
+
+ return 0;
+ } else if (wParam == NC_TIMER_ENABLEANIMATE) {
+
+ d->animation_enabled = TRUE;
+ KillTimer(hwnd, NC_TIMER_ENABLEANIMATE);
+ }
+
+ return 0;
+}
+
+static LRESULT nc_handle_wm_notify(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+
+ LPNMHDR nmhdr;
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+ nmhdr = (LPNMHDR) lParam;
+
+ if (nmhdr->code == TCN_SELCHANGE) {
+ /* the current tab has changed. */
+ int idx;
+ TCITEM tcitem;
+
+ idx = TabCtrl_GetCurSel(d->tab_wnd);
+ ZeroMemory(&tcitem, sizeof(tcitem));
+
+ tcitem.mask = TCIF_PARAM;
+ TabCtrl_GetItem(d->tab_wnd, idx, &tcitem);
+
+ d->current_panel = (int) tcitem.lParam;
+
+ nc_layout_new_cred_window(d);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static LRESULT nc_handle_wm_help(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam) {
+ static DWORD ctxids[] = {
+ NC_TS_CTRL_ID_MIN, IDH_NC_TABMAIN,
+ NC_TS_CTRL_ID_MIN + 1, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 2, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 3, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 4, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 5, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 6, IDH_NC_TABBUTTON,
+ NC_TS_CTRL_ID_MIN + 7, IDH_NC_TABBUTTON,
+ IDOK, IDH_NC_OK,
+ IDCANCEL, IDH_NC_CANCEL,
+ IDC_NC_HELP, IDH_NC_HELP,
+ IDC_NC_ADVANCED, IDH_NC_ADVANCED,
+ IDC_NC_CREDTEXT, IDH_NC_CREDWND,
+ 0
+ };
+
+ HELPINFO * hlp;
+ HWND hw = NULL;
+ HWND hw_ctrl;
+ khui_nc_wnd_data * d;
+
+ d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
+
+ hlp = (HELPINFO *) lParam;
+
+ if (d->nc->subtype != KMSG_CRED_NEW_CREDS &&
+ d->nc->subtype != KMSG_CRED_PASSWORD)
+ return TRUE;
+
+ if (hlp->iContextType != HELPINFO_WINDOW)
+ return TRUE;
+
+ if (hlp->hItemHandle != NULL &&
+ hlp->hItemHandle != hwnd) {
+ DWORD id;
+ int i;
+
+ hw_ctrl =hlp->hItemHandle;
+
+ id = GetWindowLong(hw_ctrl, GWL_ID);
+ for (i=0; ctxids[i] != 0; i += 2)
+ if (ctxids[i] == id)
+ break;
+
+ if (ctxids[i] != 0)
+ hw = khm_html_help(hw_ctrl,
+ ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
+ L"::popups_newcreds.txt":
+ L"::popups_password.txt"),
+ HH_TP_HELP_WM_HELP,
+ (DWORD_PTR) ctxids);
+ }
+
+ if (hw == NULL) {
+ khm_html_help(hwnd, NULL, HH_HELP_CONTEXT,
+ ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
+ IDH_ACTION_NEW_ID: IDH_ACTION_PASSWD_ID));
+ }
+
+ return TRUE;
+}
+
+static LRESULT CALLBACK nc_window_proc(HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch(uMsg) {
+ case WM_CREATE:
+ return nc_handle_wm_create(hwnd, uMsg, wParam, lParam);
+
+ case WM_DESTROY:
+ return nc_handle_wm_destroy(hwnd, uMsg, wParam, lParam);
+
+ case WM_COMMAND:
+ return nc_handle_wm_command(hwnd, uMsg, wParam, lParam);
+
+ case WM_NOTIFY:
+ return nc_handle_wm_notify(hwnd, uMsg, wParam, lParam);
+
+ case WM_MOVE:
+ case WM_MOVING:
+ return nc_handle_wm_moving(hwnd, uMsg, wParam, lParam);
+
+ case WM_TIMER:
+ return nc_handle_wm_timer(hwnd, uMsg, wParam, lParam);
+
+ case WM_HELP:
+ return nc_handle_wm_help(hwnd, uMsg, wParam, lParam);
+
+ case KHUI_WM_NC_NOTIFY:
+ return nc_handle_wm_nc_notify(hwnd, uMsg, wParam, lParam);
+ }
+
+ /* Note that this is technically a dialog box */
+ return DefDlgProc(hwnd, uMsg, wParam, lParam);
+}
+
+void khm_register_newcredwnd_class(void)
+{
+ WNDCLASSEX wcx;
+
+ wcx.cbSize = sizeof(wcx);
+ wcx.style = CS_DBLCLKS | CS_OWNDC;
+ wcx.lpfnWndProc = nc_window_proc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR);
+ wcx.hInstance = khm_hInstance;
+ wcx.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
+ wcx.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
+ wcx.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = KHUI_NEWCREDWND_CLASS;
+ wcx.hIconSm = NULL;
+
+ khui_newcredwnd_cls = RegisterClassEx(&wcx);
+}
+
+void khm_unregister_newcredwnd_class(void)
+{
+ UnregisterClass((LPWSTR) khui_newcredwnd_cls, khm_hInstance);
+}
+
+HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c)
+{
+ wchar_t wtitle[256];
+ HWND hwnd;
+
+ if (c->window_title == NULL) {
+ if (c->subtype == KMSG_CRED_PASSWORD)
+ LoadString(khm_hInstance,
+ IDS_WT_PASSWORD,
+ wtitle,
+ ARRAYLENGTH(wtitle));
+ else
+ LoadString(khm_hInstance,
+ IDS_WT_NEW_CREDS,
+ wtitle,
+ ARRAYLENGTH(wtitle));
+ }
+
+ hwnd = CreateWindowEx(NC_WINDOW_EX_STYLES,
+ MAKEINTATOM(khui_newcredwnd_cls),
+ ((c->window_title)?c->window_title: wtitle),
+ NC_WINDOW_STYLES,
+ 0,0,400,400, /* bogus values. the window
+ is going to resize and
+ reposition itself
+ anyway */
+ parent,
+ NULL,
+ khm_hInstance,
+ (LPVOID) c);
+
+#ifdef DEBUG
+ assert(hwnd != NULL);
+#endif
+
+ /* note that the window is not visible yet. That's because, at
+ this point we don't know what the panels are */
+
+ return hwnd;
+}
+
+void khm_prep_newcredwnd(HWND hwnd)
+{
+ SendMessage(hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_DIALOG_SETUP), 0);
+}
+
+void khm_show_newcredwnd(HWND hwnd)
+{
+ /* add all the panels in and prep UI */
+ PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
+ MAKEWPARAM(0, WMNC_DIALOG_ACTIVATE), 0);
+}
diff --git a/src/windows/identity/ui/newcredwnd.h b/src/windows/identity/ui/newcredwnd.h
index 939cf01..22819a6 100644
--- a/src/windows/identity/ui/newcredwnd.h
+++ b/src/windows/identity/ui/newcredwnd.h
@@ -1,189 +1,189 @@
-/*
- * Copyright (c) 2005 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/* $Id$ */
-
-#ifndef __KHIMAIRA_NEWCREDWND_H
-#define __KHIMAIRA_NEWCREDWND_H
-
-#include<khuidefs.h>
-
-#define KHUI_NEWCREDWND_CLASS L"KhmNewCredWnd"
-
-typedef enum tag_nc_notification_types {
- NC_NOTIFY_NONE = 0, /* no notification */
- NC_NOTIFY_MARQUEE, /* marquee type notification */
- NC_NOTIFY_PROGRESS, /* progress notification */
- NC_NOTIFY_MESSAGE, /* a message */
-} nc_notification_type;
-
-typedef struct khui_nc_wnd_data_t {
- khui_new_creds * nc;
-
- /* The tab control */
-
- HWND tab_wnd; /* tab control */
- int current_panel; /* ordinal of the current panel being
- displayed. */
-
- /* The main panel */
- HWND dlg_main; /* main dialog */
- RECT r_main; /* the extent of the main panel that
- we have used so far. The rect
- includes the size of the area used
- by the identity selector controls,
- the custom controls added by
- credentials providers and the
- buttons that may be required when
- in the mini mode. */
- RECT r_required; /* required size of the main window */
-
- /* The button bar */
-
- HWND dlg_bb; /* button bar */
-
- /* Sizing the new credentials window */
-
- BOOL animation_enabled; /* Flag indicating whether animation
- is enabled for the dialg. If this
- flag is off, we don't animate size
- changes even if the configuration
- says so. */
- BOOL size_changing; /* flag indicating that the size of
- the main window is being
- adjusted. */
- RECT sz_ch_source; /* Source size, from which we are
- going towards target size in
- sz_ch_max steps. The RECT is self
- relative (i.e. left=0 and top=0)*/
- RECT sz_ch_target; /* If we are doing an incremental size
- change, this holds the target size
- that we were going for. Note that
- the target size might change while
- we are adjusting the size. So this
- helps keep track of whether we need
- to start the size change again. The
- RECT is self relative (i.e. left=0
- and top=0). */
- int sz_ch_increment; /* Current step of the incremental
- size change operation. */
- int sz_ch_max; /* Max number of steps in the size
- change operation. */
- int sz_ch_timeout; /* Milliseconds between each increment */
-
- /* Custom controls and identity specifiers */
-
- HWND hwnd_banner; /* static control for banner */
- HWND hwnd_name; /* static control for name */
-
- HWND hwnd_last_idspec; /* last identity specifier control */
-
- /* Notification windows */
-
- nc_notification_type notif_type; /* Type of notification */
- HWND hwnd_notif_label; /* Label for notifications */
- HWND hwnd_notif_aux; /* Other control for notifications */
-
- /* Areas of the main panel */
-
- RECT r_idspec; /* Area used by identity specifiers
- (relative to client) */
- RECT r_custprompt; /* Area used by custom controls (relative
- to client) */
- RECT r_notif; /* Area used for notifications. */
-
- /* Metrics for custom prompts and identity specifiers */
-
- RECT r_row; /* Metrics for a control row (left=0,
- top=0, right=width, bottom=height) */
- RECT r_area; /* Area available for controls (relative
- to client) */
- RECT r_n_label; /* coords of the static control (relative
- to row) */
- RECT r_n_input; /* coords of the edit control (relative to
- row) */
- RECT r_e_label; /* coords of the extended edit control
- (relative to row) */
- RECT r_e_input; /* coords of the extended edit control
- (relative to row) */
- RECT r_credtext; /* Area for credtext window (relative to
- row) */
-} khui_nc_wnd_data;
-
-void khm_register_newcredwnd_class(void);
-void khm_unregister_newcredwnd_class(void);
-HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c);
-void khm_prep_newcredwnd(HWND hwnd);
-void khm_show_newcredwnd(HWND hwnd);
-
-/* Width of the button bar in dialog units */
-#define NCDLG_BBAR_WIDTH 66
-/* Height of the button bar in dialog units */
-#define NCDLG_BBAR_HEIGHT 190
-
-/* Control identifier for the tab control in the new credentials
- dialog. We declare this here since we will be creating the control
- manually. */
-#define IDC_NC_TABS 8001
-
-/* This is the first control ID that is created in the custom tabstrip
- control buttons. Subsequent buttons get consecutive IDs starting
- from this one. */
-#define NC_TS_CTRL_ID_MIN 8002
-
-/* Maximum number of controls */
-#define NC_TS_MAX_CTRLS 8
-
-/* Maximum control ID */
-#define NC_TS_CTRL_ID_MAX (NC_TS_CTRL_ID_MIN + NC_TS_MAX_CTRLS - 1)
-
-#define NC_BN_SET_DEF_ID 8012
-
-/* the first control ID that may be used by an identity provider */
-#define NC_IS_CTRL_ID_MIN 8016
-
-/* the maximum number of controls that may be created by an identity
- provider*/
-#define NC_IS_CTRL_MAX_CTRLS 8
-
-/* the maximum control ID that may be used by an identity provider */
-#define NC_IS_CTRL_ID_MAX (NC_IS_CTRL_ID_MIN + NC_IS_MAX_CTRLS - 1)
-
-#define NC_WINDOW_EX_STYLES (WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP)
-#define NC_WINDOW_STYLES (WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN)
-
-#define NC_SZ_STEPS_MIN 3
-#define NC_SZ_STEPS_DEF 10
-#define NC_SZ_STEPS_MAX 100
-
-#define NC_SZ_TIMEOUT_MIN 5
-#define NC_SZ_TIMEOUT_DEF 10
-#define NC_SZ_TIMEOUT_MAX 500
-
-#define NC_TIMER_SIZER 1001
-#define NC_TIMER_ENABLEANIMATE 1002
-
-#define ENABLEANIMATE_TIMEOUT 400
-
-#endif
+/*
+ * Copyright (c) 2005 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef __KHIMAIRA_NEWCREDWND_H
+#define __KHIMAIRA_NEWCREDWND_H
+
+#include<khuidefs.h>
+
+#define KHUI_NEWCREDWND_CLASS L"KhmNewCredWnd"
+
+typedef enum tag_nc_notification_types {
+ NC_NOTIFY_NONE = 0, /* no notification */
+ NC_NOTIFY_MARQUEE, /* marquee type notification */
+ NC_NOTIFY_PROGRESS, /* progress notification */
+ NC_NOTIFY_MESSAGE, /* a message */
+} nc_notification_type;
+
+typedef struct khui_nc_wnd_data_t {
+ khui_new_creds * nc;
+
+ /* The tab control */
+
+ HWND tab_wnd; /* tab control */
+ int current_panel; /* ordinal of the current panel being
+ displayed. */
+
+ /* The main panel */
+ HWND dlg_main; /* main dialog */
+ RECT r_main; /* the extent of the main panel that
+ we have used so far. The rect
+ includes the size of the area used
+ by the identity selector controls,
+ the custom controls added by
+ credentials providers and the
+ buttons that may be required when
+ in the mini mode. */
+ RECT r_required; /* required size of the main window */
+
+ /* The button bar */
+
+ HWND dlg_bb; /* button bar */
+
+ /* Sizing the new credentials window */
+
+ BOOL animation_enabled; /* Flag indicating whether animation
+ is enabled for the dialg. If this
+ flag is off, we don't animate size
+ changes even if the configuration
+ says so. */
+ BOOL size_changing; /* flag indicating that the size of
+ the main window is being
+ adjusted. */
+ RECT sz_ch_source; /* Source size, from which we are
+ going towards target size in
+ sz_ch_max steps. The RECT is self
+ relative (i.e. left=0 and top=0)*/
+ RECT sz_ch_target; /* If we are doing an incremental size
+ change, this holds the target size
+ that we were going for. Note that
+ the target size might change while
+ we are adjusting the size. So this
+ helps keep track of whether we need
+ to start the size change again. The
+ RECT is self relative (i.e. left=0
+ and top=0). */
+ int sz_ch_increment; /* Current step of the incremental
+ size change operation. */
+ int sz_ch_max; /* Max number of steps in the size
+ change operation. */
+ int sz_ch_timeout; /* Milliseconds between each increment */
+
+ /* Custom controls and identity specifiers */
+
+ HWND hwnd_banner; /* static control for banner */
+ HWND hwnd_name; /* static control for name */
+
+ HWND hwnd_last_idspec; /* last identity specifier control */
+
+ /* Notification windows */
+
+ nc_notification_type notif_type; /* Type of notification */
+ HWND hwnd_notif_label; /* Label for notifications */
+ HWND hwnd_notif_aux; /* Other control for notifications */
+
+ /* Areas of the main panel */
+
+ RECT r_idspec; /* Area used by identity specifiers
+ (relative to client) */
+ RECT r_custprompt; /* Area used by custom controls (relative
+ to client) */
+ RECT r_notif; /* Area used for notifications. */
+
+ /* Metrics for custom prompts and identity specifiers */
+
+ RECT r_row; /* Metrics for a control row (left=0,
+ top=0, right=width, bottom=height) */
+ RECT r_area; /* Area available for controls (relative
+ to client) */
+ RECT r_n_label; /* coords of the static control (relative
+ to row) */
+ RECT r_n_input; /* coords of the edit control (relative to
+ row) */
+ RECT r_e_label; /* coords of the extended edit control
+ (relative to row) */
+ RECT r_e_input; /* coords of the extended edit control
+ (relative to row) */
+ RECT r_credtext; /* Area for credtext window (relative to
+ row) */
+} khui_nc_wnd_data;
+
+void khm_register_newcredwnd_class(void);
+void khm_unregister_newcredwnd_class(void);
+HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c);
+void khm_prep_newcredwnd(HWND hwnd);
+void khm_show_newcredwnd(HWND hwnd);
+
+/* Width of the button bar in dialog units */
+#define NCDLG_BBAR_WIDTH 66
+/* Height of the button bar in dialog units */
+#define NCDLG_BBAR_HEIGHT 190
+
+/* Control identifier for the tab control in the new credentials
+ dialog. We declare this here since we will be creating the control
+ manually. */
+#define IDC_NC_TABS 8001
+
+/* This is the first control ID that is created in the custom tabstrip
+ control buttons. Subsequent buttons get consecutive IDs starting
+ from this one. */
+#define NC_TS_CTRL_ID_MIN 8002
+
+/* Maximum number of controls */
+#define NC_TS_MAX_CTRLS 8
+
+/* Maximum control ID */
+#define NC_TS_CTRL_ID_MAX (NC_TS_CTRL_ID_MIN + NC_TS_MAX_CTRLS - 1)
+
+#define NC_BN_SET_DEF_ID 8012
+
+/* the first control ID that may be used by an identity provider */
+#define NC_IS_CTRL_ID_MIN 8016
+
+/* the maximum number of controls that may be created by an identity
+ provider*/
+#define NC_IS_CTRL_MAX_CTRLS 8
+
+/* the maximum control ID that may be used by an identity provider */
+#define NC_IS_CTRL_ID_MAX (NC_IS_CTRL_ID_MIN + NC_IS_MAX_CTRLS - 1)
+
+#define NC_WINDOW_EX_STYLES (WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP | WS_EX_APPWINDOW)
+#define NC_WINDOW_STYLES (WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN)
+
+#define NC_SZ_STEPS_MIN 3
+#define NC_SZ_STEPS_DEF 10
+#define NC_SZ_STEPS_MAX 100
+
+#define NC_SZ_TIMEOUT_MIN 5
+#define NC_SZ_TIMEOUT_DEF 10
+#define NC_SZ_TIMEOUT_MAX 500
+
+#define NC_TIMER_SIZER 1001
+#define NC_TIMER_ENABLEANIMATE 1002
+
+#define ENABLEANIMATE_TIMEOUT 400
+
+#endif