pull up r18670 from trunk
authorTom Yu <tlyu@mit.edu>
Wed, 11 Oct 2006 19:26:08 +0000 (19:26 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 11 Oct 2006 19:26:08 +0000 (19:26 +0000)
 r18670@cathode-dark-space:  jaltman | 2006-10-09 14:08:10 -0400
 ticket: new
 subject: final commits for KFW 3.1 Beta 2
 tags: pullup

   krb5cred.dll (1.1.2.0)

   - Fix the control logic so that if the password is expired for an
     identity, the krb5 credentials provider will initiate a change
     password request.  Once the password is successfully changed, the
     new password will be used to obtain new credentials.

   - Fix an incorrect condition which caused the new credentials dialog
     to refresh custom prompts unnecessarily.

   - Removing an identity from the list of NetIDMgr identities now causes
     the corresponding principal to be removed from the LRU principals
     list.

   - Properly handle KMSG_CRED_PROCESS message when the user is
     cancelling out.

   - Add more debug output

   - Do not renew Kerberos tickets which are not initial tickets.

   - Fix whitespace in source code.

   - When providing identity selection controls, disable the realm
     selector when the user specifies the realm in the username control.

   - k5_ident_valiate_name() will refuse principal names with empty or
     unspecified realms.

   - When updating identity properties, the identity provider will
     correctly set the properties for identities that were destroyed.
     This fixes a problem where the values may be incorrect if an
     identity has two or more credential caches and one of them is
     destroyed.

   nidmgr32.dll (1.1.2.0)

   - Send out a separate notification if the configuration information
     associated with an identity is removed.

   - If an identity is being removed from the NetIDMgr identity list in
     the configuration panel, do not send out APPLY notifications to the
     subpanels after the configuration information has been removed.
     Otherwise this causes the configuration information to be reinstated
     and prevent the identity from being removed.

   - Properly initialize the new credentials blob including the UI
     context structure.

   netidmgr.exe (1.1.2.0)

   - When suppressing error messages, make sure that the final
     KMSG_CRED_END notification is sent.  Otherwise the new credentials
     acquisition operation will not be cleaned up.

   - Autoinit option now checks to see if there are identity credentials
     for the default identity and triggers the new credentials dialog if
     there aren't any.

   - Properly synchronize the configuration node list when applying
     changes (e.g.: when removing or adding an identity).

   - Fix a handle leak when removing an identity from the NetIDMgr
     identity list.

   - Refresh the properties for the active identities before calculating
     the renewal and expiration timers.  Otherwise the timestamps being
     used might be incorrect.

   - Add Identity dialog (in the configuration panel) now uses the
     identity selection controls provided by the identity provider.

   - Improve type safety when handling timer refreshes.

   - When getting the expiration times and issue times for an identity,
     the timer refresh code may fail over to the expiration and issue
     times for the credential it is currently looking at.  Now the code
     makes sure that both the issue and expiration times come from the
     identity or the credential but not mixed.

   - Not being able to get the time of issue of a credential now does not
     result in the credential being skipped from the timer refresh pass.
     However, not having a time of issue will result in the half-life
     algorithm not being applied for the renew timer.

   - Fix a bug which caused a credential to be abandoned from the timer
     refresh pass if the reamining lifetime of the credential is less
     than the renewal threshold.

   - Fix a bug where the vertical scroll bars for the hypertext window
     would not appear when the contents of the window changed.

   - Trigger a refresh of the configuration nodes when adding or removing
     an identity.

   source for (1.1.2.0)

   - Explicitly include <prsht.h> so that the SDK can be used in build
     environments that define WIN32_LEAN_AND_MEAN.

ticket: 4407
version_fixed: 1.5.2

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-5@18681 dc483132-0cff-0310-8789-dd5450dbe970

25 files changed:
src/windows/identity/apiversion.txt
src/windows/identity/config/Makefile
src/windows/identity/config/Makefile.w2k
src/windows/identity/config/Makefile.w32
src/windows/identity/kcreddb/identity.c
src/windows/identity/kcreddb/kcreddb.h
src/windows/identity/plugins/krb5/krb5funcs.c
src/windows/identity/plugins/krb5/krb5identpro.c
src/windows/identity/plugins/krb5/krb5newcreds.c
src/windows/identity/plugins/krb5/krb5plugin.c
src/windows/identity/plugins/krb5/krbcred.h
src/windows/identity/plugins/krb5/lang/en_us/langres.rc
src/windows/identity/ui/cfg_identities_wnd.c
src/windows/identity/ui/configwnd.c
src/windows/identity/ui/credfuncs.c
src/windows/identity/ui/htwnd.c
src/windows/identity/ui/lang/en_us/khapp.rc
src/windows/identity/ui/newcredwnd.c
src/windows/identity/ui/notifier.c
src/windows/identity/ui/resource.h
src/windows/identity/ui/timer.c
src/windows/identity/ui/timer.h
src/windows/identity/uilib/configui.c
src/windows/identity/uilib/creddlg.c
src/windows/identity/uilib/khprops.h

index 2a49540cdd51bb9fc1e6b6657484765208e65519..4399861e8e89a62bb51063b0d2195165e5859cea 100644 (file)
@@ -1,5 +1,4 @@
-# Copyright (c) 2004-2006 Massachusetts Institute of Technology\r
-# Copyright (c) 2006 Secure Endpoints Inc.\r
+# Copyright (c) 2004 Massachusetts Institute of Technology\r
 #\r
 # Permission is hereby granted, free of charge, to any person\r
 # obtaining a copy of this software and associated documentation files\r
@@ -213,3 +212,5 @@ Date=(TBD)
 !kcdb_buf_get_attrib(), kcdb_buf_get_attrib_string(), kcbd_buf_set_attrib()\r
 # attr_name is now a const pointer\r
 \r
++KCDB_OP_DELCONFIG\r
+# notification that the configuration information for an identity is to be removed.\r
index f1ac2ac67e2a29cb0b7e72a9c9fcfb169ef8c5a2..41e29bf8203cdf50ccd36069bf3a446bcf7da9a8 100644 (file)
@@ -1,5 +1,6 @@
 #\r
-# Copyright (c) 2004 Massachusetts Institute of Technology\r
+# Copyright (c) 2004,2005,2006 Massachusetts Institute of Technology\r
+# Copyright (c) 2006 Secure Endpoints Inc.\r
 #\r
 # Permission is hereby granted, free of charge, to any person\r
 # obtaining a copy of this software and associated documentation files\r
index 0677d13c90cf4d97ec6d9314bfe09ba79a2bddf6..dbc2690cd2c752356d365beacfe31eb93f39f386 100644 (file)
@@ -3,7 +3,7 @@
 #             This file will be included by all the makefiles\r
 #             in the build tree.\r
 #\r
-# Copyright (c) 2004,2005 Massachusetts Institute of Technology\r
+# Copyright (c) 2004,2005,2006 Massachusetts Institute of Technology\r
 # Copyright (c) 2006 Secure Endpoints Inc.\r
 #\r
 # Permission is hereby granted, free of charge, to any person\r
@@ -47,8 +47,8 @@ KHIMAIRA_WIN32_CONFIG=1
 # Version info\r
 NETIDMGR_VERSION_MAJOR=1\r
 NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=1\r
-NETIDMGR_VERSION_AUX=2\r
+NETIDMGR_VERSION_PATCH=2\r
+NETIDMGR_VERSION_AUX=0\r
 NETIDMGR_RELEASEDESC=\r
 \r
 # The API version.  This number must be incremented each time the API\r
index 0f47bcb13b9602a309807c3eabf01495325d0a02..7d259d19cb59f88e7178703ee671a777d64effa1 100644 (file)
@@ -47,8 +47,8 @@ KHIMAIRA_WIN32_CONFIG=1
 # Version info\r
 NETIDMGR_VERSION_MAJOR=1\r
 NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=0\r
-NETIDMGR_VERSION_AUX=2\r
+NETIDMGR_VERSION_PATCH=2\r
+NETIDMGR_VERSION_AUX=0\r
 NETIDMGR_RELEASEDESC=\r
 \r
 # The API version.  This number must be incremented each time the API\r
index 15c36130ffad1bb0bda6fb832571c6ee8a367215..4236c2795a93ab8e142d8eeda79731186a0ad02c 100644 (file)
@@ -617,9 +617,13 @@ kcdb_identity_get_config(khm_handle vid,
                             &hident);\r
 \r
         if(KHM_FAILED(rv)) {\r
+            khm_int32 oldflags;\r
             EnterCriticalSection(&cs_ident);\r
+            oldflags = id->flags;\r
             id->flags &= ~KCDB_IDENT_FLAG_CONFIG;\r
             LeaveCriticalSection(&cs_ident);\r
+            if (oldflags & KCDB_IDENT_FLAG_CONFIG)\r
+                kcdbint_ident_post_message(KCDB_OP_DELCONFIG, id);\r
             goto _exit;\r
         }\r
 \r
index 1b5d9b67cb60ccca3c35acfc419e864ae2d738da..060f556acec8d68ab0b7270bddaa9075d2ff495e 100644 (file)
@@ -3310,6 +3310,7 @@ kcdb_buf_release(khm_handle record);
 #define KCDB_OP_SETSEARCH   8\r
 #define KCDB_OP_UNSETSEARCH 9\r
 #define KCDB_OP_NEW_DEFAULT 10\r
+#define KCDB_OP_DELCONFIG   11\r
 \r
 /*@}*/\r
 \r
index 95f9a38c6f7f7461606b2391ed1a99822ffc5267..331e789dcda531572c94bf5bc7cd713129bcc2af 100644 (file)
@@ -702,6 +702,19 @@ khm_krb5_renew_cred(khm_handle cred)
     khm_boolean                brenewIdentity = FALSE;\r
     khm_boolean                istgt = FALSE;\r
 \r
+    khm_int32           flags;\r
+\r
+    cbname = sizeof(wname);\r
+    kcdb_cred_get_name(cred, wname, &cbname);\r
+    _reportf(L"Krb5 renew cred for %s", wname);\r
+\r
+    kcdb_cred_get_flags(cred, &flags);\r
+\r
+    if (!(flags & KCDB_CRED_FLAG_INITIAL)) {\r
+        _reportf(L"Krb5 skipping renewal because this is not an initial credential");\r
+        return 0;\r
+    }\r
+\r
     memset(&in_creds, 0, sizeof(in_creds));\r
     memset(&cc_creds, 0, sizeof(cc_creds));\r
 \r
@@ -2161,80 +2174,79 @@ khm_krb5_changepwd(char * principal,
     if ( !pkrb5_init_context )\r
         goto cleanup;\r
 \r
-   if (rc = pkrb5_init_context(&context)) {\r
-       goto cleanup;\r
-   }\r
-\r
-   if (rc = pkrb5_parse_name(context, principal, &princ)) {\r
-       goto cleanup;\r
-   }\r
-\r
-   pkrb5_get_init_creds_opt_init(&opts);\r
-   pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);\r
-   pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);\r
-   pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);\r
-   pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);\r
-   pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);\r
-\r
-   if (rc = pkrb5_get_init_creds_password(context, &creds, princ, \r
-                                          password, 0, 0, 0, \r
-                                          "kadmin/changepw", &opts)) {\r
-       if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {\r
+    if (rc = pkrb5_init_context(&context)) {\r
+        goto cleanup;\r
+    }\r
+\r
+    if (rc = pkrb5_parse_name(context, principal, &princ)) {\r
+        goto cleanup;\r
+    }\r
+\r
+    pkrb5_get_init_creds_opt_init(&opts);\r
+    pkrb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);\r
+    pkrb5_get_init_creds_opt_set_renew_life(&opts, 0);\r
+    pkrb5_get_init_creds_opt_set_forwardable(&opts, 0);\r
+    pkrb5_get_init_creds_opt_set_proxiable(&opts, 0);\r
+    pkrb5_get_init_creds_opt_set_address_list(&opts,NULL);\r
+\r
+    if (rc = pkrb5_get_init_creds_password(context, &creds, princ, \r
+                                           password, 0, 0, 0, \r
+                                           "kadmin/changepw", &opts)) {\r
+        if (rc == KRB5KRB_AP_ERR_BAD_INTEGRITY) {\r
 #if 0\r
-           com_err(argv[0], 0,\r
-                   "Password incorrect while getting initial ticket");\r
+            com_err(argv[0], 0,\r
+                    "Password incorrect while getting initial ticket");\r
 #endif\r
-       }\r
-       else {\r
+        } else {\r
 #if 0\r
-           com_err(argv[0], ret, "getting initial ticket");\r
+            com_err(argv[0], ret, "getting initial ticket");\r
 #endif\r
-       }\r
-       goto cleanup;\r
-   }\r
+        }\r
+        goto cleanup;\r
+    }\r
 \r
-   if (rc = pkrb5_change_password(context, &creds, newpassword,\r
-                                  &result_code, &result_code_string,\r
-                                  &result_string)) {\r
+    if (rc = pkrb5_change_password(context, &creds, newpassword,\r
+                                   &result_code, &result_code_string,\r
+                                   &result_string)) {\r
 #if 0\r
-       com_err(argv[0], ret, "changing password");\r
+        com_err(argv[0], ret, "changing password");\r
 #endif\r
-       goto cleanup;\r
-   }\r
-\r
-   if (result_code) {\r
-       int len = result_code_string.length + \r
-           (result_string.length ? (sizeof(": ") - 1) : 0) +\r
-           result_string.length;\r
-       if (len && error_str) {\r
-           *error_str = PMALLOC(len + 1);\r
-           if (*error_str)\r
-               StringCchPrintfA(*error_str, len+1,\r
-                                "%.*s%s%.*s",\r
-                                result_code_string.length, \r
-                                result_code_string.data,\r
-                                result_string.length?": ":"",\r
-                                result_string.length, \r
-                                result_string.data);\r
-       }\r
-       rc = result_code;\r
-       goto cleanup;\r
-   }\r
+        goto cleanup;\r
+    }\r
+\r
+    if (result_code) {\r
+        int len = result_code_string.length + \r
+            (result_string.length ? (sizeof(": ") - 1) : 0) +\r
+            result_string.length;\r
+        if (len && error_str) {\r
+            *error_str = PMALLOC(len + 1);\r
+            if (*error_str)\r
+                StringCchPrintfA(*error_str, len+1,\r
+                                 "%.*s%s%.*s",\r
+                                 result_code_string.length, \r
+                                 result_code_string.data,\r
+                                 result_string.length?": ":"",\r
+                                 result_string.length, \r
+                                 result_string.data);\r
+        }\r
+        rc = result_code;\r
+        goto cleanup;\r
+    }\r
 \r
  cleanup:\r
-   if (result_string.data)\r
-       pkrb5_free_data_contents(context, &result_string);\r
+    if (result_string.data)\r
+        pkrb5_free_data_contents(context, &result_string);\r
 \r
-   if (result_code_string.data)\r
-       pkrb5_free_data_contents(context, &result_code_string);\r
+    if (result_code_string.data)\r
+        pkrb5_free_data_contents(context, &result_code_string);\r
 \r
-   if (princ)\r
-       pkrb5_free_principal(context, princ);\r
+    if (princ)\r
+        pkrb5_free_principal(context, princ);\r
 \r
-   if (context)\r
-       pkrb5_free_context(context);\r
+    if (context)\r
+        pkrb5_free_context(context);\r
 \r
-   return rc;\r
+    return rc;\r
 }\r
 \r
 khm_int32 KHMAPI\r
index 11a7410b122e2987b06388796c1c7b562494c3b9..05f93fcd3603f623afcae6227197f205cfe4f305 100644 (file)
@@ -226,8 +226,10 @@ update_crossfeed(khui_new_creds * nc,
 \r
     un_realm = khm_get_realm_from_princ(un);\r
 \r
-    if (un_realm == NULL)\r
+    if (un_realm == NULL) {\r
+        EnableWindow(d->hw_realm, TRUE);\r
         return FALSE;\r
+    }\r
 \r
     if (ctrl_id_src == K5_NCID_UN) {\r
 \r
@@ -270,6 +272,15 @@ update_crossfeed(khui_new_creds * nc,
         SetWindowText(d->hw_realm,\r
                       un_realm);\r
 \r
+        if (GetFocus() == d->hw_realm) {\r
+            HWND hw_next = GetNextDlgTabItem(nc->hwnd, d->hw_realm,\r
+                                             FALSE);\r
+            if (hw_next)\r
+                SetFocus(hw_next);\r
+        }\r
+\r
+        EnableWindow(d->hw_realm, FALSE);\r
+\r
         return TRUE;\r
     }\r
     /* else... */\r
@@ -739,6 +750,7 @@ k5_ident_valiate_name(khm_int32 msg_type,
     char princ_name[KCDB_IDENT_MAXCCH_NAME];\r
     kcdb_ident_name_xfer * nx;\r
     krb5_error_code code;\r
+    wchar_t * atsign;\r
 \r
     nx = (kcdb_ident_name_xfer *) vparam;\r
 \r
@@ -759,11 +771,18 @@ k5_ident_valiate_name(khm_int32 msg_type,
         return KHM_ERROR_SUCCESS;\r
     }\r
 \r
-    if (princ != NULL) \r
+    if (princ != NULL)\r
         pkrb5_free_principal(k5_identpro_ctx,\r
                              princ);\r
 \r
-    nx->result = KHM_ERROR_SUCCESS;\r
+    /* krb5_parse_name() accepts principal names with no realm or an\r
+       empty realm.  We don't. */\r
+    atsign = wcschr(nx->name_src, L'@');\r
+    if (atsign == NULL || atsign[1] == L'\0') {\r
+        nx->result = KHM_ERROR_INVALID_NAME;\r
+    } else {\r
+        nx->result = KHM_ERROR_SUCCESS;\r
+    }\r
 \r
     return KHM_ERROR_SUCCESS;\r
 }\r
@@ -1032,15 +1051,23 @@ k5_ident_notify_create(khm_int32 msg_type,
     return KHM_ERROR_SUCCESS;\r
 }\r
 \r
+struct k5_ident_update_data {\r
+    khm_handle identity;\r
+\r
+    FILETIME   ft_expire;      /* expiration */\r
+    FILETIME   ft_issue;       /* issue */\r
+    FILETIME   ft_rexpire;     /* renew expiration */\r
+    wchar_t    ccname[KRB5_MAXCCH_CCNAME];\r
+    khm_int32  k5_flags;\r
+};\r
+\r
 static khm_int32 KHMAPI\r
 k5_ident_update_apply_proc(khm_handle cred,\r
                            void * rock) {\r
-    wchar_t ccname[KRB5_MAXCCH_CCNAME];\r
-    khm_handle tident = (khm_handle) rock;\r
+    struct k5_ident_update_data * d = (struct k5_ident_update_data *) rock;\r
     khm_handle ident = NULL;\r
     khm_int32 t;\r
     khm_int32 flags;\r
-    FILETIME t_expire;\r
     FILETIME t_cexpire;\r
     FILETIME t_rexpire;\r
     khm_size cb;\r
@@ -1049,12 +1076,15 @@ k5_ident_update_apply_proc(khm_handle cred,
     if (KHM_FAILED(kcdb_cred_get_type(cred, &t)) ||\r
         t != credtype_id_krb5 ||\r
         KHM_FAILED(kcdb_cred_get_identity(cred, &ident)))\r
+\r
         return KHM_ERROR_SUCCESS;\r
 \r
-    if (!kcdb_identity_is_equal(ident,tident))\r
+    if (!kcdb_identity_is_equal(ident,d->identity))\r
+\r
         goto _cleanup;\r
 \r
     if (KHM_FAILED(kcdb_cred_get_flags(cred, &flags)))\r
+\r
         flags = 0;\r
 \r
     if (flags & KCDB_CRED_FLAG_INITIAL) {\r
@@ -1064,13 +1094,9 @@ k5_ident_update_apply_proc(khm_handle cred,
                                              NULL,\r
                                              &t_cexpire,\r
                                              &cb))) {\r
-            cb = sizeof(t_expire);\r
-            if (KHM_FAILED(kcdb_identity_get_attr(tident,\r
-                                                  KCDB_ATTR_EXPIRE,\r
-                                                  NULL,\r
-                                                  &t_expire,\r
-                                                  &cb)) ||\r
-                CompareFileTime(&t_cexpire, &t_expire) > 0) {\r
+            if ((d->ft_expire.dwLowDateTime == 0 &&\r
+                 d->ft_expire.dwHighDateTime == 0) ||\r
+                CompareFileTime(&t_cexpire, &d->ft_expire) > 0) {\r
                 goto update_identity;\r
             }\r
         }\r
@@ -1080,52 +1106,35 @@ k5_ident_update_apply_proc(khm_handle cred,
 \r
  update_identity:\r
 \r
-    kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE,\r
-                           &t_cexpire, sizeof(t_cexpire));\r
+    d->ft_expire = t_cexpire;\r
 \r
-    cb = sizeof(ccname);\r
-    if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION,\r
-                                         NULL,\r
-                                         ccname,\r
-                                         &cb))) {\r
-        kcdb_identity_set_attr(tident, attr_id_krb5_ccname,\r
-                               ccname, cb);\r
-    } else {\r
-        kcdb_identity_set_attr(tident, attr_id_krb5_ccname,\r
-                               NULL, 0);\r
+    cb = sizeof(d->ccname);\r
+    if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_LOCATION, NULL, d->ccname, &cb))) {\r
+        d->ccname[0] = L'\0';\r
     }\r
-                \r
-    cb = sizeof(t);\r
-    if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred,\r
-                                         attr_id_krb5_flags,\r
-                                         NULL,\r
-                                         &t,\r
-                                         &cb))) {\r
 \r
-        kcdb_identity_set_attr(tident, attr_id_krb5_flags, \r
-                               &t, sizeof(t));\r
+    cb = sizeof(d->k5_flags);\r
+    if (KHM_FAILED(kcdb_cred_get_attr(cred, attr_id_krb5_flags, NULL,\r
+                                         &d->k5_flags, &cb))) {\r
+        d->k5_flags = 0;\r
+    }\r
 \r
-        cb = sizeof(t_rexpire);\r
-        if (!(t & TKT_FLG_RENEWABLE) ||\r
-            KHM_FAILED(kcdb_cred_get_attr(cred,\r
-                                          KCDB_ATTR_RENEW_EXPIRE,\r
-                                          NULL,\r
-                                          &t_rexpire,\r
-                                          &cb))) {\r
-            kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,\r
-                                   NULL, 0);\r
-        } else {\r
-            kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,\r
-                                   &t_rexpire, sizeof(t_rexpire));\r
-        }\r
-    } else {\r
-        kcdb_identity_set_attr(tident, attr_id_krb5_flags,\r
-                               NULL, 0);\r
-        kcdb_identity_set_attr(tident, KCDB_ATTR_RENEW_EXPIRE,\r
-                               NULL, 0);\r
+    cb = sizeof(d->ft_issue);\r
+    if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, NULL, &d->ft_issue, &cb))) {\r
+        ZeroMemory(&d->ft_issue, sizeof(d->ft_issue));\r
     }\r
 \r
-    rv = KHM_ERROR_EXIT;\r
+    cb = sizeof(t_rexpire);\r
+    if ((d->k5_flags & TKT_FLG_RENEWABLE) &&\r
+        KHM_SUCCEEDED(kcdb_cred_get_attr(cred,\r
+                                         KCDB_ATTR_RENEW_EXPIRE,\r
+                                         NULL,\r
+                                         &t_rexpire,\r
+                                         &cb))) {\r
+        d->ft_rexpire = t_rexpire;\r
+    } else {\r
+        ZeroMemory(&d->ft_rexpire, sizeof(d->ft_rexpire));\r
+    }\r
 \r
  _cleanup:\r
     if (ident)\r
@@ -1140,6 +1149,7 @@ k5_ident_update(khm_int32 msg_type,
                 khm_ui_4 uparam,\r
                 void * vparam) {\r
 \r
+    struct k5_ident_update_data d;\r
     khm_handle ident;\r
     khm_handle tident;\r
     krb5_ccache cc = NULL;\r
@@ -1153,9 +1163,52 @@ k5_ident_update(khm_int32 msg_type,
     if (ident == NULL)\r
         return KHM_ERROR_SUCCESS;\r
 \r
+    ZeroMemory(&d, sizeof(d));\r
+    d.identity = ident;\r
+\r
     kcdb_credset_apply(NULL,\r
                        k5_ident_update_apply_proc,\r
-                       (void *) ident);\r
+                       (void *) &d);\r
+\r
+    if (d.ft_expire.dwLowDateTime != 0 ||\r
+        d.ft_expire.dwHighDateTime != 0) {\r
+\r
+        /* we found a TGT */\r
+\r
+        kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE,\r
+                               &d.ft_expire, sizeof(d.ft_expire));\r
+        if (d.ft_issue.dwLowDateTime != 0 ||\r
+            d.ft_issue.dwHighDateTime != 0)\r
+            kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE,\r
+                                   &d.ft_issue, sizeof(d.ft_issue));\r
+        else\r
+            kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);\r
+\r
+        if (d.ft_rexpire.dwLowDateTime != 0 ||\r
+            d.ft_rexpire.dwHighDateTime != 0)\r
+            kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE,\r
+                                   &d.ft_rexpire, sizeof(d.ft_rexpire));\r
+        else\r
+            kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);\r
+\r
+        kcdb_identity_set_attr(ident, attr_id_krb5_flags,\r
+                               &d.k5_flags, sizeof(d.k5_flags));\r
+\r
+        if (d.ccname[0])\r
+            kcdb_identity_set_attr(ident, attr_id_krb5_ccname,\r
+                                   d.ccname, KCDB_CBSIZE_AUTO);\r
+        else\r
+            kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);\r
+\r
+    } else {\r
+        /* Clear out the attributes.  We don't have any information\r
+           about this identity */\r
+        kcdb_identity_set_attr(ident, KCDB_ATTR_EXPIRE, NULL, 0);\r
+        kcdb_identity_set_attr(ident, KCDB_ATTR_ISSUE, NULL, 0);\r
+        kcdb_identity_set_attr(ident, KCDB_ATTR_RENEW_EXPIRE, NULL, 0);\r
+        kcdb_identity_set_attr(ident, attr_id_krb5_flags, NULL, 0);\r
+        kcdb_identity_set_attr(ident, attr_id_krb5_ccname, NULL, 0);\r
+    }\r
 \r
     if (KHM_SUCCEEDED(kcdb_identity_get_default(&tident))) {\r
         kcdb_identity_release(tident);\r
index db9462eb6ebbf4bfaf7cb62ea91034686e8f3d69..e7641df8a358ffeccf839fa785dbcd32c6f64dee 100644 (file)
@@ -232,6 +232,20 @@ k5_handle_wmnc_notify(HWND hwnd,
 \r
                 d->pwd_change = TRUE;\r
 \r
+                if (is_k5_identpro &&\r
+                    d->nc->n_identities > 0 &&\r
+                    d->nc->identities[0]) {\r
+\r
+                    kcdb_identity_set_flags(d->nc->identities[0],\r
+                                            KCDB_IDENT_FLAG_VALID,\r
+                                            KCDB_IDENT_FLAG_VALID);\r
+\r
+                }\r
+\r
+                PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,\r
+                            MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT),\r
+                            (LPARAM) d->nc);\r
+\r
                 return TRUE;\r
             }\r
         }\r
@@ -347,7 +361,7 @@ k5_handle_wmnc_notify(HWND hwnd,
                 /* the above notification effectively takes all our\r
                    changes into account.  The data we have is no\r
                    longer out of sync */\r
-                d->sync = FALSE;\r
+                d->sync = TRUE;\r
             }\r
         }\r
         break;\r
@@ -1573,6 +1587,47 @@ k5_find_tgt_filter(khm_handle cred,
     return rv;\r
 }\r
 \r
+khm_int32\r
+k5_remove_from_LRU(khm_handle identity)\r
+{\r
+    wchar_t * wbuf = NULL;\r
+    wchar_t idname[KCDB_IDENT_MAXCCH_NAME];\r
+    khm_size cb;\r
+    khm_size cb_ms;\r
+    khm_int32 rv = KHM_ERROR_SUCCESS;\r
+\r
+    cb = sizeof(idname);\r
+    rv = kcdb_identity_get_name(identity, idname, &cb);\r
+    assert(rv == KHM_ERROR_SUCCESS);\r
+\r
+    rv = khc_read_multi_string(csp_params, L"LRUPrincipals", NULL, &cb_ms);\r
+    if (rv != KHM_ERROR_TOO_LONG)\r
+        cb_ms = sizeof(wchar_t) * 2;\r
+\r
+    wbuf = PMALLOC(cb_ms);\r
+    assert(wbuf);\r
+\r
+    cb = cb_ms;\r
+\r
+    if (rv == KHM_ERROR_TOO_LONG) {\r
+        rv = khc_read_multi_string(csp_params, L"LRUPrincipals", wbuf, &cb);\r
+        assert(KHM_SUCCEEDED(rv));\r
+\r
+        if (multi_string_find(wbuf, idname, KHM_CASE_SENSITIVE) != NULL) {\r
+            multi_string_delete(wbuf, idname, KHM_CASE_SENSITIVE);\r
+        }\r
+    } else {\r
+        multi_string_init(wbuf, cb_ms);\r
+    }\r
+\r
+    rv = khc_write_multi_string(csp_params, L"LRUPrincipals", wbuf);\r
+\r
+    if (wbuf)\r
+        PFREE(wbuf);\r
+\r
+    return rv;\r
+}\r
+\r
 khm_int32\r
 k5_update_LRU(khm_handle identity)\r
 {\r
@@ -1915,6 +1970,13 @@ k5_msg_cred_dialog(khm_int32 msg_type,
 \r
             assert(nc->subtype == KMSG_CRED_NEW_CREDS);\r
 \r
+            /* If we are forcing a password change, then we don't do\r
+               anything here.  Note that if the identity changed, then\r
+               this field would have been reset, so we would proceed\r
+               as usual. */\r
+            if (d->pwd_change)\r
+                return KHM_ERROR_SUCCESS;\r
+\r
             /* if the fiber is already in a kinit, cancel it */\r
             if(g_fjob.state == FIBER_STATE_KINIT) {\r
                 g_fjob.command = FIBER_CMD_CANCEL;\r
@@ -1965,7 +2027,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                         break;\r
 \r
                     case KRB5KDC_ERR_KEY_EXP:\r
-                        /* password needs changing */\r
+                        /* password needs changing. */\r
                         LoadString(hResModule, IDS_K5ERR_KEY_EXPIRED,\r
                                    msg, ARRAYLENGTH(msg));\r
                         break;\r
@@ -2320,7 +2382,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                         kherr_suggestion sug_id;\r
 \r
                         /* if we failed to get new tickets, but the\r
-                           identity isstill valid, then we assume that\r
+                           identity is still valid, then we assume that\r
                            the current tickets are still good enough\r
                            for other credential types to obtain their\r
                            credentials. */\r
@@ -2374,7 +2436,13 @@ k5_msg_cred_dialog(khm_int32 msg_type,
 \r
                 khui_cw_lock_nc(nc);\r
 \r
-                if (nc->n_identities == 0 ||\r
+                if (nc->result == KHUI_NC_RESULT_CANCEL) {\r
+\r
+                    khui_cw_set_response(nc, credtype_id_krb5,\r
+                                         KHUI_NC_RESPONSE_SUCCESS |\r
+                                         KHUI_NC_RESPONSE_EXIT);\r
+\r
+                } else if (nc->n_identities == 0 ||\r
                     nc->identities[0] == NULL) {\r
                     _report_mr0(KHERR_ERROR, MSG_PWD_NO_IDENTITY);\r
                     _suggest_mr(MSG_PWD_S_NO_IDENTITY, KHERR_SUGGEST_RETRY);\r
@@ -2382,6 +2450,7 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                     khui_cw_set_response(nc, credtype_id_krb5,\r
                                          KHUI_NC_RESPONSE_FAILED |\r
                                          KHUI_NC_RESPONSE_NOEXIT);\r
+\r
                 } else {\r
                     wchar_t   widname[KCDB_IDENT_MAXCCH_NAME];\r
                     char      idname[KCDB_IDENT_MAXCCH_NAME];\r
@@ -2483,9 +2552,12 @@ k5_msg_cred_dialog(khm_int32 msg_type,
                             goto _pwd_exit;\r
                         }\r
 \r
+                        /* the password change phase is now done */\r
+                        d->pwd_change = FALSE;\r
+\r
                         code = khm_krb5_kinit(NULL, /* context (create one) */\r
                                               idname, /* principal_name */\r
-                                              npwd, /* password */\r
+                                              npwd, /* new password */\r
                                               NULL, /* ccache name (figure out the identity cc)*/\r
                                               (krb5_deltat) d->tc_lifetime.current,\r
                                               d->forwardable,\r
index 7c5287769ca08a61c3089f1b1aabf35fc89fdda9..e80e01c47064158b4b2bbae080739b117b9cc368 100644 (file)
@@ -169,6 +169,23 @@ k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype,
     return rv;\r
 }\r
 \r
+khm_int32 KHMAPI\r
+k5_msg_kcdb(khm_int32 msg_type, khm_int32 msg_subtype,\r
+            khm_ui_4 uparam, void * vparam)\r
+{\r
+    khm_int32 rv = KHM_ERROR_SUCCESS;\r
+\r
+    switch(msg_subtype) {\r
+    case KMSG_KCDB_IDENT:\r
+        if (uparam == KCDB_OP_DELCONFIG) {\r
+            k5_remove_from_LRU((khm_handle) vparam);\r
+        }\r
+        break;\r
+    }\r
+\r
+    return rv;\r
+}\r
+\r
 \r
 /* Handler for CRED type messages\r
 \r
@@ -241,6 +258,8 @@ k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype,
         return k5_msg_system(msg_type, msg_subtype, uparam, vparam);\r
     case KMSG_CRED:\r
         return k5_msg_cred(msg_type, msg_subtype, uparam, vparam);\r
+    case KMSG_KCDB:\r
+        return k5_msg_kcdb(msg_type, msg_subtype, uparam, vparam);\r
     }\r
     return KHM_ERROR_SUCCESS;\r
 }\r
index f31bde4e62272a7514fd5018cbfb0c6841057061..694323ce3f3ca9e145c19cd04a8fb8e26dab066b 100644 (file)
@@ -200,6 +200,9 @@ k5_msg_ident(khm_int32 msg_type,
                khm_ui_4 uparam, \r
                void * vparam);\r
 \r
+khm_int32\r
+k5_remove_from_LRU(khm_handle identity);\r
+\r
 int \r
 k5_get_realm_from_nc(khui_new_creds * nc, \r
                      wchar_t * buf, \r
index 54f3ed78743883872c1c67126b1aefc0c8c5a053..dde30e387bf0e2f5d45c72604d18f568bd3c2989 100644 (file)
@@ -59,7 +59,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
 BEGIN\r
     CONTROL         "Kerberos 5 Ticket Options",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN | WS_GROUP,7,7,286,11\r
     LTEXT           "Realm",IDC_STATIC,7,25,52,13\r
-    COMBOBOX        IDC_NCK5_REALM,60,25,233,17,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_NCK5_REALM,60,25,233,51,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
     PUSHBUTTON      "Specify &additional realms ...",IDC_NCK5_ADD_REALMS,181,43,112,16,BS_NOTIFY | NOT WS_VISIBLE | WS_DISABLED\r
     LTEXT           "&Lifetime",IDC_STATIC,7,67,61,12\r
     EDITTEXT        IDC_NCK5_LIFETIME_EDIT,85,67,107,12,ES_AUTOHSCROLL\r
@@ -119,7 +119,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
 FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
 BEGIN\r
     LTEXT           "Default Realm",IDC_CFG_LBL_REALM,13,9,46,8\r
-    COMBOBOX        IDC_CFG_DEFREALM,76,7,166,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_CFG_DEFREALM,76,7,166,51,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
     PUSHBUTTON      "Configure Realms ...",IDC_CFG_CFGREALMS,76,25,84,14,NOT WS_VISIBLE | WS_DISABLED\r
     GROUPBOX        "Keberos Configuration File",IDC_CFG_CFGFILEGRP,7,45,241,61\r
     LTEXT           "Location",IDC_CFG_LBL_CFGFILE,13,61,28,8\r
@@ -134,7 +134,7 @@ BEGIN
     LTEXT           "Domain",IDC_CFG_LBL_DOMAIN,13,141,24,8\r
     EDITTEXT        IDC_CFG_DOMAIN,76,138,166,14,ES_AUTOHSCROLL | ES_READONLY\r
     LTEXT           "Import tickets",IDC_LBL_IMPORT,13,158,45,8\r
-    COMBOBOX        IDC_CFG_IMPORT,76,156,166,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_CFG_IMPORT,76,156,166,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
 END\r
 \r
 IDD_CFG_REALMS DIALOGEX 0, 0, 255, 182\r
@@ -195,7 +195,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
 BEGIN\r
     CONTROL         "Kerberos 5 Change Password Options",IDC_STATIC,"Static",SS_LEFTNOWORDWRAP | SS_SUNKEN | WS_GROUP,7,7,286,11\r
     LTEXT           "Realm",IDC_STATIC,7,25,52,13\r
-    COMBOBOX        IDC_NCK5_REALM,60,25,233,17,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_NCK5_REALM,60,25,233,51,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
     PUSHBUTTON      "Specify &additional realms ...",IDC_NCK5_ADD_REALMS,181,43,112,16,BS_NOTIFY | WS_DISABLED\r
 END\r
 \r
index 3297b05be7e93a9c775cd3cbdb65497b1ed03d74..3f92ad83987f9f81ad01a6db842270dfb0313f4f 100644 (file)
@@ -130,10 +130,11 @@ apply_all(HWND hwnd,
     khui_config_node_reg reg;\r
     int idx;\r
     int count;\r
+    BOOL cont = TRUE;\r
 \r
     count = TabCtrl_GetItemCount(hw_tab);\r
 \r
-    for (idx = 0; idx < count; idx++) {\r
+    for (idx = 0; idx < count && cont; idx++) {\r
 \r
         ZeroMemory(&tci, sizeof(tci));\r
 \r
@@ -156,7 +157,7 @@ apply_all(HWND hwnd,
 #endif\r
 \r
         SendMessage(hw, KHUI_WM_CFG_NOTIFY,\r
-                    MAKEWPARAM(0, WMCFG_APPLY), 0);\r
+                    MAKEWPARAM(0, WMCFG_APPLY), (LPARAM) &cont);\r
     }\r
 }\r
 \r
@@ -317,6 +318,7 @@ typedef struct tag_idents_data {
     ident_data * idents;\r
     khm_size     n_idents;\r
     khm_size     nc_idents;\r
+#define IDENTS_DATA_ALLOC_INCR 8\r
 \r
     /* global options */\r
     global_props saved;\r
@@ -430,6 +432,7 @@ write_params_ident(ident_data * d) {
 \r
     if (d->removed) {\r
         khm_handle h = NULL;\r
+        khm_int32 flags = 0;\r
 \r
         khc_remove_space(csp_ident);\r
 \r
@@ -444,6 +447,10 @@ write_params_ident(ident_data * d) {
 #endif\r
             khc_close_space(h);\r
         }\r
+#ifdef DEBUG\r
+        kcdb_identity_get_flags(d->ident, &flags);\r
+        assert(!(flags & KCDB_IDENT_FLAG_CONFIG));\r
+#endif\r
 \r
     } else {\r
 \r
@@ -470,11 +477,15 @@ write_params_ident(ident_data * d) {
     if (d->hwnd)\r
         PostMessage(d->hwnd, KHUI_WM_CFG_NOTIFY,\r
                     MAKEWPARAM(0, WMCFG_UPDATE_STATE), 0);\r
+\r
+    khm_refresh_config();\r
 }\r
 \r
 static void\r
 write_params_idents(void) {\r
+#if 0\r
     int i;\r
+#endif\r
     khm_handle csp_cw;\r
 \r
     if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow",\r
@@ -500,9 +511,11 @@ write_params_idents(void) {
         khc_close_space(csp_cw);\r
     }\r
 \r
+#if 0\r
     for (i=0; i < (int)cfg_idents.n_idents; i++) {\r
         write_params_ident(&cfg_idents.idents[i]);\r
     }\r
+#endif\r
 \r
     if (cfg_idents.hwnd)\r
         PostMessage(cfg_idents.hwnd, KHUI_WM_CFG_NOTIFY,\r
@@ -622,6 +635,9 @@ init_idents_data(void) {
         cfg_idents.idents[i].removed = FALSE;\r
 \r
         kcdb_identity_get_flags(ident, &cfg_idents.idents[i].flags);\r
+#ifdef DEBUG\r
+        assert(cfg_idents.idents[i].flags & KCDB_IDENT_FLAG_CONFIG);\r
+#endif\r
 \r
         read_params_ident(&cfg_idents.idents[i]);\r
 \r
@@ -712,82 +728,258 @@ refresh_view_idents_state(HWND hwnd) {
                             KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED);\r
 }\r
 \r
+struct ctrl_row_dimensions {\r
+    RECT enclosure;\r
+    RECT label;\r
+    RECT control;\r
+};\r
+\r
+typedef struct tag_add_ident_data {\r
+    khui_new_creds * nc;\r
+\r
+    struct ctrl_row_dimensions dim_small;\r
+    struct ctrl_row_dimensions dim_medium;\r
+    struct ctrl_row_dimensions dim_large;\r
+    int row_gap;\r
+\r
+    int current_y;\r
+    int current_x;\r
+\r
+    HWND hwnd_last_ctrl;\r
+} add_ident_data;\r
+\r
+void\r
+get_ctrl_row_metrics(struct ctrl_row_dimensions * dim, HWND hw_lbl, HWND hw_ctl) {\r
+\r
+    assert(hw_lbl);\r
+    assert(hw_ctl);\r
+\r
+    GetWindowRect(hw_lbl, &dim->label);\r
+    GetWindowRect(hw_ctl, &dim->control);\r
+\r
+    UnionRect(&dim->enclosure, &dim->label, &dim->control);\r
+    OffsetRect(&dim->label,\r
+               -dim->enclosure.left,\r
+               -dim->enclosure.top);\r
+    OffsetRect(&dim->control,\r
+               -dim->enclosure.left,\r
+               -dim->enclosure.top);\r
+    OffsetRect(&dim->enclosure,\r
+               -dim->enclosure.left,\r
+               -dim->enclosure.top);\r
+}\r
+\r
 /* dialog box procedure for the "Add new identity" dialog */\r
 INT_PTR CALLBACK\r
 khm_cfg_add_ident_proc(HWND hwnd,\r
                        UINT umsg,\r
                        WPARAM wParam,\r
-                       LPARAM lparam) {\r
+                       LPARAM lParam) {\r
+    add_ident_data * d;\r
+\r
     switch(umsg) {\r
     case WM_INITDIALOG:\r
-        /* set the max length of the edit control first */\r
-        SendDlgItemMessage(hwnd, IDC_CFG_IDNAME,\r
-                           EM_SETLIMITTEXT,\r
-                           KCDB_IDENT_MAXCCH_NAME - 1,\r
-                           0);\r
+        /* we create a new credentials blob and pull in the identity\r
+           selectors from the identity provider. */\r
+        d = PMALLOC(sizeof(*d));\r
+        ZeroMemory(d, sizeof(*d));\r
+\r
+        khui_cw_create_cred_blob(&d->nc);\r
+#ifdef DEBUG\r
+        assert(d->nc != NULL);\r
+#endif\r
+        if (d->nc == NULL) {\r
+            PFREE(d);\r
+            break;\r
+        }\r
+\r
+        if (KHM_FAILED(kcdb_identpro_get_ui_cb(&d->nc->ident_cb))) {\r
+            /* this should have worked.  The only reason it would fail\r
+               is if there is no identity provider or if the identity\r
+               provider does not support providing idnetity\r
+               selectors. */\r
+            khui_cw_destroy_cred_blob(d->nc);\r
+            PFREE(d);\r
+            break;\r
+        }\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable: 4244)\r
+        SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d);\r
+#pragma warning(pop)\r
+\r
+        /* get metrics for dynamic controls */\r
+        get_ctrl_row_metrics(&d->dim_small,\r
+                             GetDlgItem(hwnd, IDC_SM_LBL),\r
+                             GetDlgItem(hwnd, IDC_SM_CTL));\r
+        get_ctrl_row_metrics(&d->dim_medium,\r
+                             GetDlgItem(hwnd, IDC_MED_LBL),\r
+                             GetDlgItem(hwnd, IDC_MED_CTL));\r
+        get_ctrl_row_metrics(&d->dim_large,\r
+                             GetDlgItem(hwnd, IDC_LG_LBL),\r
+                             GetDlgItem(hwnd, IDC_LG_CTL));\r
+\r
+        {\r
+            RECT rlbl;\r
+            RECT rctl;\r
+            RECT rwnd;\r
+\r
+            GetWindowRect(GetDlgItem(hwnd, IDC_SM_LBL),\r
+                          &rlbl);\r
+            GetWindowRect(GetDlgItem(hwnd, IDC_SM_CTL),\r
+                          &rctl);\r
+            GetWindowRect(hwnd, &rwnd);\r
+\r
+            OffsetRect(&rlbl, -rwnd.left, -rwnd.top);\r
+            OffsetRect(&rctl, -rwnd.left, -rwnd.top);\r
+\r
+            d->current_x = rlbl.left;\r
+            d->current_y = rctl.top - GetSystemMetrics(SM_CYCAPTION);\r
+\r
+            GetWindowRect(GetDlgItem(hwnd, IDC_MED_CTL),\r
+                          &rlbl);\r
+            OffsetRect(&rlbl, -rwnd.left, -rwnd.top);\r
+\r
+            d->row_gap = rlbl.top - rctl.bottom;\r
+        }\r
+\r
+        d->nc->hwnd = hwnd;\r
+\r
+        /* now call the UI callback and make it create the\r
+           controls. */\r
+        d->nc->ident_cb(d->nc, WMNC_IDENT_INIT, NULL, 0, 0,\r
+                        (LPARAM) hwnd);\r
+\r
         break;\r
 \r
     case WM_DESTROY:\r
-        /* nor do we have to do anything here */\r
+        d = (add_ident_data *)(LONG_PTR)\r
+            GetWindowLongPtr(hwnd, DWLP_USER);\r
+        if (d == NULL)\r
+            break;\r
+\r
+        d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);\r
+\r
+        khui_cw_destroy_cred_blob(d->nc);\r
+        PFREE(d);\r
         break;\r
 \r
+    case KHUI_WM_NC_NOTIFY:\r
+        d = (add_ident_data *)(LONG_PTR)\r
+            GetWindowLongPtr(hwnd, DWLP_USER);\r
+\r
+        switch(HIWORD(wParam)) {\r
+        case WMNC_ADD_CONTROL_ROW:\r
+            {\r
+                khui_control_row * row;\r
+                RECT r_lbl, r_inp, r_enc;\r
+                struct ctrl_row_dimensions * dim;\r
+                HFONT hf;\r
+\r
+                row = (khui_control_row *) lParam;\r
+\r
+#ifdef DEBUG\r
+                assert(row->label);\r
+                assert(row->input);\r
+                assert(d);\r
+#endif\r
+\r
+                if (row->size == KHUI_CTRLSIZE_SMALL) {\r
+                    dim = &d->dim_small;\r
+                } else if (row->size == KHUI_CTRLSIZE_HALF) {\r
+                    dim = &d->dim_medium;\r
+                } else {\r
+                    dim = &d->dim_large;\r
+#ifdef DEBUG\r
+                    assert(row->size == KHUI_CTRLSIZE_FULL);\r
+#endif\r
+                }\r
+\r
+                CopyRect(&r_enc, &dim->enclosure);\r
+                CopyRect(&r_lbl, &dim->label);\r
+                CopyRect(&r_inp, &dim->control);\r
+\r
+                OffsetRect(&r_enc, d->current_x, d->current_y);\r
+                OffsetRect(&r_lbl, r_enc.left, r_enc.top);\r
+                OffsetRect(&r_inp, r_enc.left, r_enc.top);\r
+\r
+                d->current_y += r_enc.bottom - r_enc.top;\r
+\r
+                hf = (HFONT) SendDlgItemMessage(hwnd, IDOK, WM_GETFONT, 0, 0);\r
+\r
+                if (row->label) {\r
+                    SetWindowPos(row->label,\r
+                                 ((d->hwnd_last_ctrl != NULL)?\r
+                                  d->hwnd_last_ctrl :\r
+                                  HWND_TOP),\r
+                                 r_lbl.left, r_lbl.top,\r
+                                 r_lbl.right - r_lbl.left,\r
+                                 r_lbl.bottom - r_lbl.top,\r
+                                 SWP_DEFERERASE | SWP_NOACTIVATE |\r
+                                 SWP_NOOWNERZORDER);\r
+                    if (hf)\r
+                        SendMessage(row->label, WM_SETFONT,\r
+                                    (WPARAM) hf,\r
+                                    TRUE);\r
+                    d->hwnd_last_ctrl = row->label;\r
+                }\r
+\r
+                if (row->input) {\r
+                    SetWindowPos(row->input,\r
+                                 ((d->hwnd_last_ctrl != NULL)?\r
+                                  d->hwnd_last_ctrl :\r
+                                  HWND_TOP),\r
+                                 r_inp.left, r_inp.top,\r
+                                 r_inp.right - r_inp.left,\r
+                                 r_inp.bottom - r_inp.top,\r
+                                 SWP_DEFERERASE | SWP_NOACTIVATE |\r
+                                 SWP_NOOWNERZORDER);\r
+                    if (hf)\r
+                        SendMessage(row->input, WM_SETFONT,\r
+                                    (WPARAM) hf,\r
+                                    TRUE);\r
+                    d->hwnd_last_ctrl = row->input;\r
+                }\r
+            }\r
+            break;\r
+\r
+        case WMNC_IDENTITY_CHANGE:\r
+            break;\r
+        }\r
+        return TRUE;\r
+\r
     case WM_COMMAND:\r
         if (LOWORD(wParam) == IDOK) {\r
             wchar_t idname[KCDB_IDENT_MAXCCH_NAME];\r
-            khm_int32 rv = KHM_ERROR_SUCCESS;\r
+            wchar_t err_msg[1024];\r
             khm_handle ident = NULL;\r
             khm_handle csp_ident = NULL;\r
-            khm_size i;\r
-            wchar_t err_msg[512] = L"";\r
-\r
-            GetDlgItemText(hwnd, IDC_CFG_IDNAME, idname,\r
-                           ARRAYLENGTH(idname));\r
-\r
-            idname[ARRAYLENGTH(idname) - 1] = L'\0';\r
-            if (KHM_FAILED(rv = kcdb_identpro_validate_name(idname)) &&\r
-                rv != KHM_ERROR_NO_PROVIDER &&\r
-                rv != KHM_ERROR_NOT_IMPLEMENTED) {\r
-                /* the supplied name was invalid or something */\r
-\r
-                wchar_t fmt[256];\r
+            khm_size cb;\r
+            khm_int32 rv = KHM_ERROR_SUCCESS;\r
 \r
-                LoadString(khm_hInstance, IDS_CFG_IDNAME_INV,\r
-                           fmt, ARRAYLENGTH(fmt));\r
-                StringCbPrintf(err_msg, sizeof(err_msg), fmt, idname);\r
+            d = (add_ident_data *)(LONG_PTR)\r
+                GetWindowLongPtr(hwnd, DWLP_USER);\r
 \r
-                goto show_failure;\r
-            }\r
+            if (!d || !d->nc)\r
+                break;\r
 \r
-            /* now check if this is actually a new identity */\r
-            for (i=0; i < cfg_idents.n_idents; i++) {\r
-                if (!kcdb_identpro_compare_name(cfg_idents.idents[i].idname,\r
-                                                idname))\r
-                    break;\r
-            }\r
+            /* check if there was an identity selected */\r
+            if (d->nc->n_identities == 0 ||\r
+                d->nc->identities[0] == NULL) {\r
 \r
-            if (i < cfg_idents.n_idents) {\r
-                wchar_t fmt[256];\r
+                StringCbCopy(idname, sizeof(idname), L"");\r
 \r
-                LoadString(khm_hInstance, IDS_CFG_IDNAME_EXT,\r
-                           fmt, ARRAYLENGTH(fmt));\r
-                StringCbPrintf(err_msg, sizeof(err_msg), fmt, idname);\r
+                LoadString(khm_hInstance, IDS_CFG_IDNAME_NON,\r
+                           err_msg, ARRAYLENGTH(err_msg));\r
 \r
                 goto show_failure;\r
             }\r
 \r
-            /* ok.  now we are all set to add the new identity */\r
-            if (KHM_FAILED(rv = kcdb_identity_create(idname,\r
-                                                     KCDB_IDENT_FLAG_CREATE,\r
-                                                     &ident))) {\r
-                /* oops */\r
-                wchar_t fmt[256];\r
-\r
-                LoadString(khm_hInstance, IDS_CFG_IDNAME_CCR,\r
-                           fmt, ARRAYLENGTH(fmt));\r
-                StringCbPrintf(err_msg, sizeof(err_msg), fmt, rv);\r
+            ident = d->nc->identities[0];\r
+            kcdb_identity_hold(ident);\r
 \r
-                goto show_failure;\r
-            }\r
+            cb = sizeof(idname);\r
+            kcdb_identity_get_name(ident, idname, &cb);\r
 \r
             /* now we have to create the identity configuration. */\r
             if (KHM_FAILED(rv = kcdb_identity_get_config(ident,\r
@@ -804,6 +996,11 @@ khm_cfg_add_ident_proc(HWND hwnd,
                 goto show_failure;\r
             }\r
 \r
+            /* create a value so that the configuration space will\r
+               actually be created in the registry.  We don't want\r
+               this new identity to be sticky. */\r
+            khc_write_int32(csp_ident, L"Sticky", 0);\r
+\r
             khm_refresh_config();\r
 \r
             kcdb_identity_release(ident);\r
@@ -833,6 +1030,14 @@ khm_cfg_add_ident_proc(HWND hwnd,
             \r
         } else if (LOWORD(wParam) == IDCANCEL) {\r
             EndDialog(hwnd, 1);\r
+        } else {\r
+            d = (add_ident_data *)(LONG_PTR)\r
+                GetWindowLongPtr(hwnd, DWLP_USER);\r
+\r
+            if (d && d->nc && d->nc->ident_cb) {\r
+                return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG,\r
+                                       hwnd, umsg, wParam, lParam);\r
+            }\r
         }\r
         break;\r
     }\r
@@ -1023,6 +1228,7 @@ find_ident_by_node(khui_config_node node) {
     khm_size cb;\r
     wchar_t idname[KCDB_IDENT_MAXCCH_NAME];\r
     int i;\r
+    khm_handle ident = NULL;\r
 \r
     cb = sizeof(idname);\r
     khui_cfg_get_name(node, idname, &cb);\r
@@ -1034,8 +1240,56 @@ find_ident_by_node(khui_config_node node) {
 \r
     if (i < (int)cfg_idents.n_idents)\r
         return &cfg_idents.idents[i];\r
-    else\r
+\r
+    /* there is no identity data for this configuration node.  We try\r
+       to create it. */\r
+    if (KHM_FAILED(kcdb_identity_create(idname, 0, &ident)))\r
         return NULL;\r
+\r
+    if (cfg_idents.n_idents >= cfg_idents.nc_idents) {\r
+        cfg_idents.nc_idents = UBOUNDSS(cfg_idents.n_idents + 1,\r
+                                        IDENTS_DATA_ALLOC_INCR,\r
+                                        IDENTS_DATA_ALLOC_INCR);\r
+#ifdef DEBUG\r
+        assert(cfg_idents.nc_idents > cfg_idents.n_idents);\r
+#endif\r
+        cfg_idents.idents = PREALLOC(cfg_idents.idents,\r
+                                     sizeof(*cfg_idents.idents) *\r
+                                     cfg_idents.nc_idents);\r
+#ifdef DEBUG\r
+        assert(cfg_idents.idents);\r
+#endif\r
+        ZeroMemory(&(cfg_idents.idents[cfg_idents.n_idents]),\r
+                   sizeof(*cfg_idents.idents) *\r
+                   (cfg_idents.nc_idents - cfg_idents.n_idents));\r
+    }\r
+\r
+    i = (int) cfg_idents.n_idents;\r
+\r
+    StringCbLength(idname, KCDB_IDENT_MAXCB_NAME, &cb);\r
+    cb += sizeof(wchar_t);\r
+\r
+    cfg_idents.idents[i].idname = PMALLOC(cb);\r
+#ifdef DEBUG\r
+    assert(cfg_idents.idents[i].idname);\r
+#endif\r
+    StringCbCopy(cfg_idents.idents[i].idname, cb, idname);\r
+\r
+    cfg_idents.idents[i].ident = ident;\r
+    cfg_idents.idents[i].removed = FALSE;\r
+\r
+    kcdb_identity_get_flags(ident, &cfg_idents.idents[i].flags);\r
+#ifdef DEBUG\r
+    assert(cfg_idents.idents[i].flags & KCDB_IDENT_FLAG_CONFIG);\r
+#endif\r
+\r
+    read_params_ident(&cfg_idents.idents[i]);\r
+\r
+    cfg_idents.n_idents++;\r
+\r
+    /* leave ident held. */\r
+\r
+    return &cfg_idents.idents[i];\r
 }\r
 \r
 static void\r
@@ -1191,13 +1445,17 @@ khm_cfg_id_tab_proc(HWND hwnd,
     case KHUI_WM_CFG_NOTIFY:\r
         {\r
             ident_data * d;\r
+            BOOL * cont;\r
 \r
             khui_cfg_get_dialog_data(hwnd, &idata, NULL);\r
 \r
             switch (HIWORD(wParam)) {\r
             case WMCFG_APPLY:\r
+                cont = (BOOL *) lParam;\r
                 d = find_ident_by_node(idata->ctx_node);\r
                 write_params_ident(d);\r
+                if (d->removed && cont)\r
+                    *cont = FALSE;\r
                 khui_cfg_set_flags_inst(idata, KHUI_CNFLAG_APPLIED,\r
                                         KHUI_CNFLAG_APPLIED | \r
                                         KHUI_CNFLAG_MODIFIED);\r
index 24f9a619c4eeffabd0aafc20d5bbac42dea09235..660c1fae8e202a7e5a7a29ed1c528ed491dac2f4 100644 (file)
@@ -422,6 +422,209 @@ cfgui_apply_settings(khui_config_node node) {
     }\r
 }\r
 \r
+static void\r
+cfgui_remove_item(HWND hwtv,\r
+                  HTREEITEM hItem) {\r
+    khui_config_node node;\r
+    HTREEITEM hChild;\r
+    TVITEMEX itemex;\r
+\r
+    for (hChild = TreeView_GetChild(hwtv, hItem);\r
+         hChild;\r
+         hChild = TreeView_GetChild(hwtv, hItem)) {\r
+\r
+        cfgui_remove_item(hwtv, hChild);\r
+\r
+    }\r
+\r
+    ZeroMemory(&itemex, sizeof(itemex));\r
+\r
+    itemex.mask = TVIF_PARAM;\r
+    itemex.hItem = hItem;\r
+\r
+    TreeView_GetChild(hwtv, &itemex);\r
+\r
+    node = (khui_config_node) itemex.lParam;\r
+\r
+    if (node) {\r
+        HWND hw;\r
+        hw = khui_cfg_get_hwnd(node);\r
+\r
+        if (hw)\r
+            DestroyWindow(hw);\r
+\r
+        khui_cfg_release(node);\r
+    }\r
+\r
+    TreeView_DeleteItem(hwtv, hItem);\r
+}\r
+\r
+struct cfgui_child_info {\r
+    HTREEITEM hItem;\r
+    khui_config_node node;\r
+    BOOL checked;\r
+};\r
+\r
+#define CI_ALLOC_INCR 8\r
+\r
+static void\r
+cfgui_sync_node(cfgui_wnd_data * d,\r
+                HWND hwtv,\r
+                khui_config_node c,\r
+                HTREEITEM hItem) {\r
+    khui_config_node child;\r
+    HTREEITEM hChild;\r
+    struct cfgui_child_info * childinfo = NULL;\r
+    khm_size n_childinfo = 0;\r
+    khm_size nc_childinfo = 0;\r
+    khm_size i;\r
+\r
+    /* first, get the list of children from the treeview control */\r
+    for (hChild = TreeView_GetChild(hwtv, hItem);\r
+         hChild;\r
+         hChild = TreeView_GetNextSibling(hwtv, hChild)) {\r
+\r
+        if (n_childinfo >= nc_childinfo) {\r
+            nc_childinfo = UBOUNDSS(n_childinfo + 1,\r
+                                    CI_ALLOC_INCR, CI_ALLOC_INCR);\r
+#ifdef DEBUG\r
+            assert(nc_childinfo > n_childinfo);\r
+#endif\r
+            childinfo = PREALLOC(childinfo,\r
+                                 sizeof(*childinfo) * nc_childinfo);\r
+#ifdef DEBUG\r
+            assert(childinfo);\r
+#endif\r
+        }\r
+\r
+        ZeroMemory(&childinfo[n_childinfo],\r
+                   sizeof(childinfo[n_childinfo]));\r
+\r
+        childinfo[n_childinfo].hItem = hChild;\r
+        childinfo[n_childinfo].checked = FALSE;\r
+        n_childinfo++;\r
+    }\r
+\r
+    /* now, go through the list of actual nodes and make sure they\r
+       match up */\r
+    child = NULL;\r
+    for (khui_cfg_get_first_child(c, &child);\r
+         child;\r
+         khui_cfg_get_next_release(&child)) {\r
+\r
+        hChild = (HTREEITEM) khui_cfg_get_param(child);\r
+\r
+        for (i=0; i < n_childinfo; i++) {\r
+            if (childinfo[i].hItem == hChild)\r
+                break;\r
+        }\r
+\r
+        if (i < n_childinfo) {\r
+            childinfo[i].checked = TRUE;\r
+        } else {\r
+            /* add it to the list, so we can create the node in the\r
+               tree view control later. */\r
+            if (n_childinfo >= nc_childinfo) {\r
+                nc_childinfo = UBOUNDSS(n_childinfo + 1,\r
+                                        CI_ALLOC_INCR, CI_ALLOC_INCR);\r
+#ifdef DEBUG\r
+                assert(nc_childinfo > n_childinfo);\r
+#endif\r
+                childinfo = PREALLOC(childinfo,\r
+                                     sizeof(*childinfo) * nc_childinfo);\r
+#ifdef DEBUG\r
+                assert(childinfo);\r
+#endif\r
+            }\r
+\r
+            ZeroMemory(&childinfo[n_childinfo],\r
+                       sizeof(childinfo[n_childinfo]));\r
+\r
+            childinfo[n_childinfo].node = child;\r
+            khui_cfg_hold(child);\r
+            n_childinfo++;\r
+        }\r
+    }\r
+\r
+    /* by this point, the childinfo list contains items of the\r
+       following forms:\r
+\r
+       1. childinfo[i].hItem != NULL && childinfo[i].checked == TRUE\r
+\r
+          Corresponds to a tree view item that has a matching\r
+          configuration node.  Nothing to do here.\r
+\r
+       2. childinfo[i].hItem != NULL && childinfo[i].checked == FALSE\r
+\r
+          Corresponds to a tree view item that has no matching\r
+          configuration node.  These should be removed.\r
+\r
+       3. childinfo[i].hItem == NULL && childinfo[i].node != NULL\r
+\r
+          Corresponds to a configuration node that has no matching\r
+          tree view item.  These nodes should be added.\r
+    */\r
+\r
+    /* first do the removals */\r
+    for (i=0; i < n_childinfo; i++) {\r
+        if (childinfo[i].hItem == NULL)\r
+            break;              /* nothing more to see from this point\r
+                                   on */\r
+        if (!childinfo[i].checked) {\r
+            /* remove! */\r
+            cfgui_remove_item(hwtv, childinfo[i].hItem);\r
+        }\r
+    }\r
+\r
+    /* continue from where the previous loop left off */\r
+    for (; i < n_childinfo; i++) {\r
+#ifdef DEBUG\r
+        assert(childinfo[i].hItem == NULL);\r
+        assert(childinfo[i].node != NULL);\r
+#endif\r
+\r
+        cfgui_add_node(d, hwtv, childinfo[i].node, c, FALSE);\r
+\r
+        khui_cfg_release(childinfo[i].node);\r
+        childinfo[i].node = NULL;\r
+    }\r
+\r
+    if (childinfo)\r
+        PFREE(childinfo);\r
+\r
+    /* finally recurse through to the next level */\r
+    for (hChild = TreeView_GetChild(hwtv, hItem);\r
+         hChild;\r
+         hChild = TreeView_GetNextSibling(hwtv, hChild)) {\r
+\r
+        TVITEMEX itemex;\r
+\r
+        ZeroMemory(&itemex, sizeof(itemex));\r
+\r
+        itemex.mask = TVIF_PARAM;\r
+        itemex.hItem = hChild;\r
+\r
+        TreeView_GetItem(hwtv, &itemex);\r
+\r
+        if (itemex.lParam) {\r
+            child = (khui_config_node) itemex.lParam;\r
+\r
+            cfgui_sync_node(d, hwtv, child, hChild);\r
+        }\r
+    }\r
+}\r
+\r
+static void\r
+cfgui_sync_node_list(cfgui_wnd_data * d, HWND hwnd) {\r
+    HWND hwtv;\r
+    HTREEITEM hItem;\r
+\r
+    hwtv = GetDlgItem(hwnd, IDC_CFG_NODELIST);\r
+    hItem = TreeView_GetRoot(hwtv);\r
+\r
+    cfgui_sync_node(d, hwtv, NULL, hItem);\r
+}\r
+\r
 static void\r
 cfgui_update_state(HWND hwnd, \r
                    khm_int32 flags,\r
@@ -670,7 +873,8 @@ cfgui_dlgproc(HWND hwnd,
             break;\r
 \r
         case WMCFG_SYNC_NODE_LIST:\r
-            /*TODO: synchronize the node lists here */\r
+            d = cfgui_get_wnd_data(hwnd);\r
+            cfgui_sync_node_list(d, hwnd);\r
             break;\r
         }\r
 \r
@@ -825,6 +1029,9 @@ void khm_refresh_config(void) {
 \r
             khui_cfg_remove(cfg_iter);\r
         }\r
+\r
+        if (tident)\r
+            kcdb_identity_release(tident);\r
     }\r
 \r
     /* Now iterate through the root level configuration nodes and make\r
index d695afead30fd9a1881b95e7b13c9aefe1516489..530ef08521f54feaffc40f565aba0cf8d9d81f1c 100644 (file)
@@ -267,8 +267,9 @@ kmsg_cred_completion(kmq_message *m)
                     kcdb_credset_get_size(tcs, &count);\r
                     kcdb_credset_delete(tcs);\r
 \r
-                    if (count == 0)\r
-                        break;\r
+                    if (count == 0) {\r
+                        goto done_with_op;\r
+                    }\r
                 }\r
 \r
                 ctx = kherr_peek_context();\r
@@ -348,6 +349,8 @@ kmsg_cred_completion(kmq_message *m)
                 kherr_clear_error();\r
             }\r
 \r
+        done_with_op:\r
+\r
             if (nc->subtype == KMSG_CRED_RENEW_CREDS) {\r
                 kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, \r
                                  m->vparam);\r
@@ -994,11 +997,23 @@ khm_cred_process_startup_actions(void) {
         }\r
 \r
         if (khm_startup.autoinit) {\r
-            khm_size count;\r
+            khm_size count = 0;\r
+            khm_handle credset = NULL;\r
+            khm_int32 ctype_ident = KCDB_CREDTYPE_INVALID;\r
+            khm_int32 delta = 0;\r
 \r
             khm_startup.autoinit = FALSE;\r
 \r
-            kcdb_credset_get_size(NULL, &count);\r
+            kcdb_credset_create(&credset);\r
+            kcdb_identity_get_type(&ctype_ident);\r
+\r
+            kcdb_credset_collect(credset, NULL,\r
+                                 defident, ctype_ident,\r
+                                 &delta);\r
+\r
+            kcdb_credset_get_size(credset, &count);\r
+\r
+            kcdb_credset_delete(credset);\r
 \r
             if (count == 0) {\r
                 if (defident)\r
index f65525690987e3289210abbb17b995d21b33edc0..afb68aa0296689fcb0468254e89732b5d9256f61 100644 (file)
@@ -806,7 +806,8 @@ static LRESULT htw_paint(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
     EndPaint(hwnd, &ps);\r
 \r
-    if (d->ext_width < ext_width) {\r
+    if (d->ext_width < ext_width ||\r
+        d->ext_height < ext_height) {\r
         SCROLLINFO si;\r
         LONG l;\r
 \r
index eb84b8f1e41cd0afca447d174c37d35d50ce72de..48f577684a7451fa9c3db2046f33ec330e63c54a 100644 (file)
@@ -370,9 +370,9 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1
 BEGIN\r
     GROUPBOX        "Font for credentials display",IDC_STATIC,7,7,241,137\r
     LTEXT           "&Font name",IDC_STATIC,17,22,35,8\r
-    COMBOBOX        IDC_CFG_FONTS,62,20,178,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_CFG_FONTS,62,20,178,51,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP\r
     LTEXT           "&Size",IDC_STATIC,62,43,14,8\r
-    COMBOBOX        IDC_CFG_SIZE,87,41,48,14,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_CFG_SIZE,87,41,48,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "&Bold",IDC_CFG_BOLD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,162,42,29,10\r
     CONTROL         "&Italics",IDC_CFG_ITALICS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,42,35,10\r
     EDITTEXT        IDC_CFG_SAMPLE_NORMAL,62,66,178,21,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP,WS_EX_STATICEDGE\r
@@ -380,15 +380,19 @@ BEGIN
     PUSHBUTTON      "&Revert to default",IDC_CFG_REVERT,168,122,72,14\r
 END\r
 \r
-IDD_CFG_ADDIDENT DIALOGEX 0, 0, 325, 70\r
+IDD_CFG_ADDIDENT DIALOGEX 0, 0, 279, 95\r
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r
 CAPTION "Add new identity"\r
 FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
 BEGIN\r
-    LTEXT           "&Identity name",IDC_STATIC,7,10,46,8\r
-    EDITTEXT        IDC_CFG_IDNAME,67,7,195,14,ES_AUTOHSCROLL\r
-    DEFPUSHBUTTON   "OK",IDOK,268,7,50,14\r
-    PUSHBUTTON      "Cancel",IDCANCEL,268,24,50,14\r
+    LTEXT           "&Identity name",IDC_SM_LBL,7,10,46,8,NOT WS_VISIBLE\r
+    EDITTEXT        IDC_SM_CTL,67,7,205,14,ES_AUTOHSCROLL | NOT WS_VISIBLE\r
+    DEFPUSHBUTTON   "OK",IDOK,145,74,71,14\r
+    PUSHBUTTON      "Cancel",IDCANCEL,222,74,50,14\r
+    LTEXT           "&Identity name",IDC_MED_LBL,7,27,130,8,NOT WS_VISIBLE\r
+    EDITTEXT        IDC_MED_CTL,141,24,131,14,ES_AUTOHSCROLL | NOT WS_VISIBLE\r
+    LTEXT           "&Identity name",IDC_LG_LBL,7,41,265,8,NOT WS_VISIBLE\r
+    EDITTEXT        IDC_LG_CTL,141,50,131,14,ES_AUTOHSCROLL | NOT WS_VISIBLE\r
 END\r
 \r
 \r
@@ -531,9 +535,9 @@ BEGIN
     IDD_CFG_ADDIDENT, DIALOG\r
     BEGIN\r
         LEFTMARGIN, 7\r
-        RIGHTMARGIN, 318\r
+        RIGHTMARGIN, 272\r
         TOPMARGIN, 7\r
-        BOTTOMMARGIN, 63\r
+        BOTTOMMARGIN, 88\r
     END\r
 END\r
 #endif    // APSTUDIO_INVOKED\r
@@ -777,6 +781,7 @@ END
 STRINGTABLE \r
 BEGIN\r
     IDS_NC_REN_FAILED_TITLE_I "Failed to renew creds for %s"\r
+    IDS_CFG_IDNAME_NON      "No identity selected.  Please select an identity and try again."\r
 END\r
 \r
 #endif    // English (U.S.) resources\r
index f5b302ec06d0ed4a0adfee4fede96dfe89f6c764..a52d09b41e71829cf4ae5530b977a772fe5bf7f6 100644 (file)
@@ -522,7 +522,8 @@ nc_update_credtext(khui_nc_wnd_data * d)
     }\r
 \r
     if (!(d->nc->response & KHUI_NC_RESPONSE_PROCESSING)) {\r
-        if(validId || d->nc->subtype == KMSG_CRED_PASSWORD) {\r
+        if(validId ||\r
+           d->nc->subtype == KMSG_CRED_PASSWORD) {\r
             /* TODO: check if all the required fields have valid values\r
                before enabling the Ok button */\r
             okEnable = TRUE;\r
@@ -876,9 +877,8 @@ nc_add_control_row(khui_nc_wnd_data * d,
         SetRectEmpty(&r_input);\r
 #ifdef DEBUG\r
         assert(FALSE);\r
-#else\r
-        return;\r
 #endif\r
+        return;\r
     }\r
 \r
     if (label)\r
index 12b746b1f7c4ce883853c8e80bddc2734490711f..9804abfae57561cdb01fdbd42a9ce34562a947dc 100644 (file)
@@ -305,6 +305,7 @@ notifier_wnd_proc(HWND hwnd,
             khm_timer_fire(hwnd);\r
         } else if (wParam == KHUI_REFRESH_TIMER_ID) {\r
             KillTimer(hwnd, KHUI_REFRESH_TIMER_ID);\r
+            kcdb_identity_refresh_all();\r
             khm_timer_refresh(hwnd);\r
         }\r
     }\r
index 35b493e919e4368178b89f9320b249266cc7c309..b8dc0ec048a20321f42e1b920a776a81c60db101 100644 (file)
 #define IDS_NC_FAILED_TITLE_I           286\r
 #define IDS_NC_PWD_FAILED_TITLE_I       287\r
 #define IDS_NC_REN_FAILED_TITLE_I       288\r
+#define IDS_CFG_IDNAME_NON              289\r
 #define IDC_NC_USERNAME                 1007\r
 #define IDC_NC_PASSWORD                 1008\r
 #define IDC_NC_CREDTEXT_LABEL           1009\r
 #define IDC_CFG_ITALICS                 1132\r
 #define IDC_CFG_ADDIDENT                1133\r
 #define IDC_CFG_IDNAME                  1134\r
+#define IDC_SM_CTL                      1134\r
 #define IDC_CFG_SHOWLOG                 1135\r
+#define IDC_MED_CTL                     1135\r
+#define IDC_LG_CTL                      1136\r
+#define IDC_SM_LBL                      1137\r
+#define IDC_MED_LBL                     1138\r
+#define IDC_LG_LBL                      1139\r
 #define IDA_ACTIVATE_MENU               40003\r
 #define IDA_UP                          40004\r
 #define IDA_DOWN                        40005\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
 #define _APS_NEXT_RESOURCE_VALUE        212\r
 #define _APS_NEXT_COMMAND_VALUE         40010\r
-#define _APS_NEXT_CONTROL_VALUE         1136\r
+#define _APS_NEXT_CONTROL_VALUE         1140\r
 #define _APS_NEXT_SYMED_VALUE           101\r
 #endif\r
 #endif\r
index 40464d5ad0d22154bc2cf69a1b55ead98207bc54..3adf9e9a4e1dc400f8ed7c7d66e98ef6df343083 100644 (file)
@@ -92,17 +92,21 @@ khm_timer_exit(void) {
 static void\r
 tmr_fire_timer(void) {\r
     int i;\r
-    unsigned __int64 curtime;\r
-    unsigned __int64 err;\r
-    unsigned __int64 next_event;\r
+    khm_int64 curtime;\r
+    khm_int64 err;\r
+    khm_int64 next_event;\r
     int     tmr_count[KHUI_N_TTYPES];\r
-    unsigned __int64 tmr_offset[KHUI_N_TTYPES];\r
+    khm_int64 tmr_offset[KHUI_N_TTYPES];\r
     int t;\r
     khm_handle eff_ident = NULL;\r
     khui_timer_type eff_type = 0; /* meaningless */\r
     int fire_count = 0;\r
     FILETIME ft;\r
 \r
+    _begin_task(0);\r
+    _report_cs0(KHERR_DEBUG_1, L"Checking for expired timers");\r
+    _describe();\r
+\r
     TimetToFileTimeInterval(KHUI_TIMEEQ_ERROR_SMALL, &ft);\r
     err = FtToInt(&ft);\r
     GetSystemTimeAsFileTime(&ft);\r
@@ -119,10 +123,16 @@ tmr_fire_timer(void) {
             khui_timers[i].type != KHUI_TTYPE_ID_MARK &&\r
             khui_timers[i].expire < curtime + err) {\r
 \r
+            _report_cs3(KHERR_DEBUG_1, L"Expiring timer index=%1!d!, type=%2!d!, key=%3!p!",\r
+                        _int32(i), _int32(khui_timers[i].type),\r
+                        _cptr(khui_timers[i].key));\r
+\r
             t = khui_timers[i].type;\r
 \r
             switch(t) {\r
             case KHUI_TTYPE_ID_RENEW:\r
+                _report_cs1(KHERR_DEBUG_1, L"Renewing identity %1!p!",\r
+                            _cptr(khui_timers[i].key));\r
                 khm_cred_renew_identity(khui_timers[i].key);\r
                 khui_timers[i].flags |= KHUI_TE_FLAG_EXPIRED;\r
                 break;\r
@@ -134,6 +144,8 @@ tmr_fire_timer(void) {
                    we assume that it is safe to trigger a renew_cred\r
                    call here without checking if there's an imminent\r
                    renew_identity call. */\r
+                _report_cs1(KHERR_DEBUG_1, L"Renewing credential %1!p!",\r
+                            _cptr(khui_timers[i].key));\r
                 khm_cred_renew_cred(khui_timers[i].key);\r
                 khui_timers[i].flags |= KHUI_TE_FLAG_EXPIRED;\r
                 break;\r
@@ -184,7 +196,7 @@ tmr_fire_timer(void) {
         wchar_t wtime[128];\r
         wchar_t wmsg[256];\r
         wchar_t wtitle[64];\r
-        unsigned __int64 second;\r
+        khm_int64 second;\r
         khui_alert * alert = NULL;\r
 \r
         khm_size cb;\r
@@ -249,6 +261,9 @@ tmr_fire_timer(void) {
         khui_alert_show(alert);\r
         khui_alert_release(alert);\r
     }\r
+\r
+    _end_task();\r
+\r
 }\r
 \r
 void \r
@@ -264,6 +279,85 @@ static int
 tmr_update(khm_handle key, khui_timer_type type, __int64 expire,\r
            __int64 offset, void * data, khm_boolean reinstate) {\r
     int i;\r
+    wchar_t name[KCDB_MAXCCH_NAME];\r
+    wchar_t tstamp[128];\r
+    wchar_t *type_str = NULL;\r
+    SYSTEMTIME st;\r
+    FILETIME ft;\r
+    FILETIME ftl;\r
+    khm_size cb;\r
+\r
+    switch(type) {\r
+    case KHUI_TTYPE_ID_MARK:\r
+        type_str = L"marker";\r
+        break;\r
+\r
+    case KHUI_TTYPE_CRED_WARN:\r
+    case KHUI_TTYPE_ID_WARN:\r
+        type_str = L"warning";\r
+        break;\r
+\r
+    case KHUI_TTYPE_CRED_CRIT:\r
+    case KHUI_TTYPE_ID_CRIT:\r
+        type_str = L"critical";\r
+        break;\r
+\r
+    case KHUI_TTYPE_CRED_EXP:\r
+    case KHUI_TTYPE_ID_EXP:\r
+        type_str = L"expiry";\r
+        break;\r
+\r
+    case KHUI_TTYPE_CRED_RENEW:\r
+    case KHUI_TTYPE_ID_RENEW:\r
+        type_str = L"renew";\r
+        break;\r
+    }\r
+\r
+    ft = IntToFt(expire);\r
+    FileTimeToLocalFileTime(&ft, &ftl);\r
+    FileTimeToSystemTime(&ftl, &st);\r
+    StringCbPrintf(tstamp, sizeof(tstamp),\r
+                   L"%d-%d-%d %d:%d:%d",\r
+                   st.wYear, st.wMonth, st.wDay,\r
+                   st.wHour, st.wMinute, st.wSecond);\r
+\r
+    cb = sizeof(name); name[0] = L'\0';\r
+    if (type_str == NULL) {\r
+\r
+        _report_cs2(KHERR_DEBUG_1,\r
+                    L"Updating uknown timer of type %1!d! exp(%2!s!)",\r
+                    _int32(type),\r
+                    _cstr(tstamp));\r
+        _resolve();\r
+\r
+    } else if (type == KHUI_TTYPE_ID_MARK ||\r
+               type == KHUI_TTYPE_ID_WARN ||\r
+               type == KHUI_TTYPE_ID_CRIT ||\r
+               type == KHUI_TTYPE_ID_EXP ||\r
+               type == KHUI_TTYPE_ID_RENEW) {\r
+\r
+        kcdb_identity_get_name(key, name, &cb);\r
+        _report_cs3(KHERR_DEBUG_1,\r
+                    L"Updating identity %1!s! timer for %2!s! exp(%3!s!)",\r
+                    _cstr(type_str),\r
+                    _cstr(name),\r
+                    _cstr(tstamp));\r
+        _resolve();\r
+\r
+    } else if (type == KHUI_TTYPE_CRED_RENEW ||\r
+               type == KHUI_TTYPE_CRED_WARN ||\r
+               type == KHUI_TTYPE_CRED_CRIT ||\r
+               type == KHUI_TTYPE_CRED_EXP) {\r
+\r
+        kcdb_cred_get_name(key, name, &cb);\r
+        _report_cs3(KHERR_DEBUG_1,\r
+                    L"Updating credential %1!s! timer for %2!s! exp(%3!s!)",\r
+                    _cstr(type_str),\r
+                    _cstr(name),\r
+                    _cstr(tstamp));\r
+        _resolve();\r
+\r
+    }\r
 \r
     for (i=0; i < (int) khui_n_timers; i++) {\r
         if (khui_timers[i].key == key &&\r
@@ -385,7 +479,7 @@ tmr_next_halflife_timeout(int idx, FILETIME * issue, FILETIME * expire) {
        not expired.  However, we leave it to the caller to update the\r
        actual timer and mark it as not stale. */\r
     if (idx >= 0 &&\r
-        khui_timers[idx].expire < (khm_ui_8) iret) {\r
+        khui_timers[idx].expire < iret) {\r
 \r
         khui_timers[idx].flags &= ~KHUI_TE_FLAG_EXPIRED;\r
         khui_timers[idx].expire = iret;\r
@@ -394,7 +488,8 @@ tmr_next_halflife_timeout(int idx, FILETIME * issue, FILETIME * expire) {
     return ret;\r
 }\r
 \r
-/* called with cs_timers held */\r
+/* called with cs_timers held.  Called once for each credential in the\r
+   root credentials set. */\r
 static khm_int32 KHMAPI\r
 tmr_cred_apply_proc(khm_handle cred, void * rock) {\r
     khm_handle ident = NULL;\r
@@ -410,40 +505,56 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
     FILETIME fte;\r
     FILETIME ft_reinst;\r
     khm_size cb;\r
+    wchar_t wname[KCDB_MAXCCH_NAME];\r
+\r
+    cb = sizeof(wname);\r
+    wname[0] = L'\0';\r
+    kcdb_cred_get_name(cred, wname, &cb);\r
+\r
+    _report_cs1(KHERR_DEBUG_1, L"Looking at cred [%1!s!]",\r
+                _cstr(wname));\r
+    _resolve();\r
 \r
     kcdb_cred_get_identity(cred, &ident);\r
 #ifdef DEBUG\r
     assert(ident);\r
 #endif\r
 \r
-    /* now get the expiry */\r
+    /* now get the expiry for the identity*/\r
     cb = sizeof(ft_expiry);\r
     if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE,\r
                                           NULL,\r
                                           &ft_expiry, &cb))) {\r
+\r
+        /* failing which, we get the expiry for this credential */\r
         cb = sizeof(ft_expiry);\r
         if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE,\r
                                           NULL,\r
                                           &ft_expiry, &cb))) {\r
             /* we don't have an expiry time to work with */\r
+            _report_cs1(KHERR_DEBUG_1, L"Skipping cred [%1!s!].  No expiry time",\r
+                        _cstr(wname));\r
+            _resolve();\r
+\r
             kcdb_identity_release(ident);\r
             return KHM_ERROR_SUCCESS;\r
+        } else {\r
+            /* and the time of issue */\r
+            cb = sizeof(ft_issue);\r
+            if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,\r
+                                              NULL, &ft_issue, &cb)))\r
+                ZeroMemory(&ft_issue, sizeof(ft_issue));\r
         }\r
-    }\r
 \r
-    cb = sizeof(ft_issue);\r
-    if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE,\r
-                                          NULL,\r
-                                          &ft_issue, &cb))) {\r
+    } else {\r
+        /* also try to get the time of issue. */\r
         cb = sizeof(ft_issue);\r
-        if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,\r
-                                          NULL,\r
-                                          &ft_issue, &cb))) {\r
-            /* we don't really abandon the timer.  In this case, we\r
-               fall back to using the threshold value to set the\r
-               expiry timer. */\r
+        if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE,\r
+                                              NULL, &ft_issue, &cb)))\r
+            /* if we fail, we just zero out the time of issue and\r
+               failover to using the threshold value to set the expiry\r
+               timer instead of the half life algorithm. */\r
             ZeroMemory(&ft_issue, sizeof(ft_issue));\r
-        }\r
     }\r
 \r
     /* and the current time */\r
@@ -540,7 +651,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
             prev =\r
                 tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0);\r
 \r
-            if (do_halflife)\r
+            if (do_halflife && (ft_issue.dwLowDateTime != 0 ||\r
+                                ft_issue.dwHighDateTime != 0))\r
                 fte = tmr_next_halflife_timeout(prev, &ft_issue, &ft_expiry);\r
             else\r
                 fte = FtSub(&ft_expiry, &ft);\r
@@ -613,15 +725,22 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
     if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE,\r
                                       NULL,\r
                                       &ft_cred_expiry,\r
-                                      &cb)))\r
+                                      &cb))) {\r
+        _report_cs1(KHERR_DEBUG_1, L"Skipping cred [%1!s!]. Can't lookup cred expiry",\r
+                    _cstr(wname));\r
+        _resolve();\r
         goto _cleanup;\r
+    }\r
 \r
     cb = sizeof(ft_cred_issue);\r
     if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE,\r
                                       NULL,\r
                                       &ft_cred_issue,\r
-                                      &cb)))\r
-        goto _cleanup;\r
+                                      &cb))) {\r
+\r
+        ZeroMemory(&ft_cred_issue, sizeof(ft_cred_issue));\r
+\r
+    }\r
 \r
     TimetToFileTimeInterval(KHUI_TIMEEQ_ERROR, &ft);\r
 \r
@@ -636,8 +755,14 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
         ft_delta = FtSub(&ft_expiry, &ft_cred_expiry);\r
 \r
         if (CompareFileTime(&ft_cred_expiry, &ft_expiry) >= 0 ||\r
-            CompareFileTime(&ft_delta, &ft) < 0)\r
+            CompareFileTime(&ft_delta, &ft) < 0) {\r
+\r
+            _report_cs1(KHERR_DEBUG_1,\r
+                        L"Skipping credential [%1!s!].  The expiry time is too close to the identity expiry.",\r
+                        _cstr(wname));\r
+            _resolve();\r
             goto _cleanup;\r
+        }\r
     }\r
 \r
     if ((idx = tmr_find(ident, KHUI_TTYPE_ID_WARN, 0, 0)) >= 0 &&\r
@@ -669,8 +794,34 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) {
     if ((idx = tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0)) >= 0 &&\r
         !(khui_timers[idx].flags & KHUI_TE_FLAG_STALE)) {\r
 \r
-        //fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset);\r
-        fte = tmr_next_halflife_timeout(idx, &ft_cred_issue, &ft_cred_expiry);\r
+        int cidx = tmr_find(cred, KHUI_TTYPE_CRED_RENEW, 0, 0);\r
+\r
+        if (ft_cred_issue.dwLowDateTime == 0 &&\r
+            ft_cred_issue.dwHighDateTime == 0) {\r
+            fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset);\r
+            /* a special case, for a credential whose remaining\r
+               lifetime is less than the offset, we try half life on\r
+               the current time and the expiry. */\r
+            if (CompareFileTime(&fte, &ft_current) <= 0 &&\r
+                CompareFileTime(&ft_current, &ft_expiry) < 0) {\r
+                fte = tmr_next_halflife_timeout(cidx, &ft_current, &ft_cred_expiry);\r
+#if 0\r
+                /* now, if we already have a renew timer for this\r
+                   credential that hasn't expired yet and that is set\r
+                   for earlier than fte, we let it be. */\r
+                if (cidx >= 0 &&\r
+                    khui_timers[cidx].expire < FtToInt(&fte) &&\r
+                    khui_timers[cidx].expire > FtToInt(&ft_current) &&\r
+                    !(khui_timers[cidx].flags & KHUI_TE_FLAG_EXPIRED)) {\r
+\r
+                    fte = IntToFt(khui_timers[cidx].expire);\r
+\r
+                }\r
+#endif\r
+            }\r
+        } else {\r
+            fte = tmr_next_halflife_timeout(cidx, &ft_cred_issue, &ft_cred_expiry);\r
+        }\r
 \r
         if (CompareFileTime(&fte, &ft_current) > 0) {\r
             tmr_update(cred, KHUI_TTYPE_CRED_RENEW,\r
@@ -754,13 +905,18 @@ tmr_purge(void) {
     khui_n_timers = j;\r
 }\r
 \r
-/* go through all the credentials and set timers as appropriate. */\r
+/* go through all the credentials and set timers as appropriate.  hwnd\r
+   is the window that will receive the timer events.*/\r
 void \r
 khm_timer_refresh(HWND hwnd) {\r
     int i;\r
-    unsigned __int64 next_event = 0;\r
-    unsigned __int64 curtime;\r
-    unsigned __int64 diff;\r
+    khm_int64 next_event = 0;\r
+    khm_int64 curtime;\r
+    khm_int64 diff;\r
+\r
+    _begin_task(0);\r
+    _report_cs0(KHERR_DEBUG_1, L"Refreshing timers");\r
+    _describe();\r
 \r
     EnterCriticalSection(&cs_timers);\r
 \r
@@ -788,12 +944,18 @@ khm_timer_refresh(HWND hwnd) {
 #endif\r
     }\r
 \r
+    _report_cs1(KHERR_DEBUG_1, L"Starting with %1!d! timers",\r
+                _int32(khui_n_timers));\r
+\r
     kcdb_credset_apply(NULL,\r
                        tmr_cred_apply_proc,\r
                        NULL);\r
 \r
     tmr_purge();\r
 \r
+    _report_cs1(KHERR_DEBUG_1, L"Leaving with %1!d! timers",\r
+                _int32(khui_n_timers));\r
+\r
  _check_next_event:\r
 \r
     /* Before we return, we should check if any timers are set to\r
@@ -805,9 +967,11 @@ khm_timer_refresh(HWND hwnd) {
         if (!(khui_timers[i].flags & KHUI_TE_FLAG_EXPIRED) &&\r
             khui_timers[i].type != KHUI_TTYPE_ID_MARK &&\r
             (next_event == 0 ||\r
-             next_event > khui_timers[i].expire))\r
+             next_event > khui_timers[i].expire)) {\r
 \r
             next_event = khui_timers[i].expire;\r
+\r
+        }\r
     }\r
 \r
     if (next_event != 0) {\r
@@ -833,4 +997,6 @@ khm_timer_refresh(HWND hwnd) {
     }\r
 \r
     LeaveCriticalSection(&cs_timers);\r
+\r
+    _end_task();\r
 }\r
index 081d27852da9565033f266557f6e65338176911c..130ae999ac00722d2f5a9d56fdf1749ff37fa11c 100644 (file)
@@ -58,9 +58,9 @@ typedef struct tag_khui_timer_event {
     khm_handle       key;\r
     khui_timer_type  type;\r
 \r
-    unsigned __int64 expire;    /* time at which the timer expires */\r
-    unsigned __int64 offset;    /* time offset at which the event that\r
-                                   the timer warns of happens */\r
+    khm_int64 expire;    /* time at which the timer expires */\r
+    khm_int64 offset;    /* time offset at which the event that the\r
+                            timer warns of happens */\r
     void *           data;\r
     khm_int32        flags;\r
 } khui_timer_event;\r
index 79e570820ab8b53df4c75a2508d9cc18adcc2200..c8c61f5cb38aa7d44b6276e224fe7ffb8a2f2a62 100644 (file)
@@ -349,7 +349,9 @@ khui_cfg_get_first_child(khui_config_node vparent,
 \r
     if (parent) {\r
         for(c = TFIRSTCHILD(parent);\r
-            c && (c->reg.flags & KHUI_CNFLAG_SUBPANEL);\r
+            c &&\r
+                ((c->reg.flags & KHUI_CNFLAG_SUBPANEL) ||\r
+                 (c->flags & KHUI_CN_FLAG_DELETED));\r
             c = LNEXT(c));\r
     } else {\r
         c = NULL;\r
@@ -390,7 +392,9 @@ khui_cfg_get_first_subpanel(khui_config_node vparent,
 \r
     if (parent) {\r
         for(c = TFIRSTCHILD(parent);\r
-            c && !(c->reg.flags & KHUI_CNFLAG_SUBPANEL);\r
+            c &&\r
+                (!(c->reg.flags & KHUI_CNFLAG_SUBPANEL) ||\r
+                 (c->flags & KHUI_CN_FLAG_DELETED));\r
             c = LNEXT(c));\r
     } else {\r
         c = NULL;\r
@@ -458,8 +462,9 @@ khui_cfg_get_next_release(khui_config_node * pvnode) {
         node = cfgui_node_i_from_handle(*pvnode);\r
         for(nxt_node = LNEXT(node);\r
             nxt_node &&\r
-                ((node->reg.flags ^ nxt_node->reg.flags) & \r
-                 KHUI_CNFLAG_SUBPANEL);\r
+                (((node->reg.flags ^ nxt_node->reg.flags) & \r
+                  KHUI_CNFLAG_SUBPANEL) ||\r
+                 (nxt_node->flags & KHUI_CN_FLAG_DELETED));\r
             nxt_node = LNEXT(nxt_node));\r
         if (nxt_node)\r
             cfgui_hold_node(nxt_node);\r
index 84d6e17ed66b10bc0ebaf47551207e1eae0be7bd..1d36d3c5bdce29c4ae919953211bc313ab851b0c 100644 (file)
@@ -57,6 +57,8 @@ khui_cw_create_cred_blob(khui_new_creds ** ppnc)
     c->result = KHUI_NC_RESULT_CANCEL;\r
     c->mode = KHUI_NC_MODE_MINI;\r
 \r
+    khui_context_create(&c->ctx, KHUI_SCOPE_NONE, NULL, KCDB_CREDTYPE_INVALID, NULL);\r
+\r
     *ppnc = c;\r
 \r
     return KHM_ERROR_SUCCESS;\r
index fc5629dc946803ce7ae1a04af0d9961ff16b01ef..c0977b80cb685a635488c3e3cb2e1650d0665f21 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef __KHIMAIRA_KHPROPS_H\r
 #define __KHIMAIRA_KHPROPS_H\r
 \r
+#include<prsht.h>\r
+\r
 /*********************************************************************\r
   Property sheets\r
 **********************************************************************/\r