NIM commits for KFW 3.2 Beta 1
authorJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 29 Mar 2007 17:24:34 +0000 (17:24 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 29 Mar 2007 17:24:34 +0000 (17:24 +0000)
(NetIDMgr 1.2.0.0)

netidmgr.exe

- Simplify credential window UI element placement calculations.

- Add the Custom_1 view to the UI schema.  This is used to store
  customizations to the basic view.

- Extended styles for toolbars have to be set via TB_SETEXTENDEDSTYLE
  messages instead of the EX_STYLE parameter to CreateWindowEx().
  Also, set the extended style to support detached arrows.

- Support drop down menus in the standard toolbar.

- The per-identity commands that are added to expiration dialogs are
  now flagged for automatic dispatch.

- Remove unnecessary status bar parts and display the status bar icons
  at the correct size.

- The notification alerts now display the info balloon at the correct
  size.

- Increase the height of the height of the dialog button bar to 190
  from 181 dialog units.

- Lock the action tables when refreshing the per-identity actions.
  Perform the necessary notification after refreshing the per-identity
  actions.

- "Initialize <identity>" -> "Obtain new credentials for <identity>"

- Add a button to go back to the Basic view from the Advanced view in
  the new credentials dialog.

- Cache the extents of each row since we now support rows of variable
  heights.

- Selecting a credential row or a header should select all the
  credentials that are represented by the row.

- Update the selection state after loading a new view.

- Display the expiration times in the second line of an expanded
  identity header.

- Checks for expiration flags in the credentials window now take into
  account that the each flag may occupy more than one bit position.

- Calculate the expiration flags for the identity before assigning it
  to a header, so that the header can display accurate expiration
  data.

- Kill unnecessary timers in the credentials view and make sure taht
  the KHUI_CW_ROW_TIMERSET flag is consistent with whether there is an
  active timer for the row.

- In addition to rows that hold credentials, timers can also be
  assigned to headers for identities in the basic view.  This allows
  the headers to display expiration times.

- The credentials view keeps track of the count of credentials, the
  count of identity credentials (credentials which belong to the
  credentials type that the identity belongs to) and the number of
  initial credentials.

- Configuration spaces that hold credential view definitions now
  include an additional value "_AppVersion" which contains the version
  of NIM used to create the data.  If the current version is greater
  than the stated version, NIM will failover to using the schema
  instead of using the saved data.  This is because view definitions
  are version dependent.

- The app_version global variable is now a const.

- The renew and destroy icons in the standard toolbar are now drop
  down buttons.  If the drop down arrow is clicked, they display a
  menu with the list of identities that the operation can target.

- The renew and destroy actions on the credential menu have been
  replaced by submenus that allow the user to select the identity
  which would be the target of the operation.

- Consistently update the 'displayed' field of an alert so that
  plug-ins can keep track of which alerts are being displayed.

- If the currently displayed balloon alert has
  KHUI_ALERT_FLAG_DEFACTION flag, then dispatch the defualt command
  when the user clicks the notification icon, or display the expanded
  alert if necessary.

- Reduce flicker when drawing the credentials display by clipping the
  header control from the device context.

- The state of Advanced mode is now preserved between NIM sessions.

- The credential display layout is kept track of separately for the
  Basic and Advanced views.  Any customization done on either view
  (e.g.: changing sort order) will only affect that view.
  Customizations for the Advanced view will be saved in the Custom_0
  view, while customizations for the Basic view will be saved in
  Custom_1.

- New color scheme.

- Selecting a credential or identity will no longer mask the
  expiration state.  The selection rectangle is now alpha blended.

- In Basic view, the width of the Identity column changes with the
  width of the window so that the credentials display always fills the
  width of the window.

- The colors for the highlight, text color, highlighted text color,
  window background and other elements are now obtained via Windows so
  that NetIDMgr will be more consistent with any themes that have been
  applied.

- Correctly determine whether a column can be dragged or resized based
  on the KHUI_CW_COL_FIXED_WIDTH and KHUI_CW_COL_FIXED_POS flags.

- Correctly update the scroll bars when switching between views.

- The "marker" button for a displayed alert should not perform any
  action and it should not be the default control.  Selecting it
  should no longer cause an assertion to be thrown.

- Don't display the "... Click here for more." message when displaying
  a balloon alert if the operating system involved does not provide a
  reliable means of detecting that the user clicked on a balloon.

- When attempting to display queued alerts, if the alert at the top of
  the queue is of a type that cannot be consolidated, then show it by
  itself.

- If the size of the alert window changes, it should be redrawn
  properly.

krb5creds.dll

- Allow setting an identity as the default even if there are no
  credentials or credential caches associated with it.  We generate
  the name of the ccache we would use if we were getting new
  credentials for the identity and then set that as the default cache.

- Controls in the per-identity configuration panels resized to fit
  their contents.

- Set the credentials type and type name attributes for identities for
  which we have a TGT.

- Use khm_krb5_get_identity_params() when retrieving parameters for
  the identity global configuration panel.

- Add UI elements for setting the global values for forwardable,
  renewable and addressless flags.

- Make the schema default to issue forwardable tickets for identities
  that have no configuration and when krb5.ini does not define
  'forwardable'.

- When updating the identity properties, take all the active
  identities into account, so that we won't orphan any identities with
  Krb5 properties but no credentials associated with them.

- If there is no TGT associated with an identity, then strip it of any
  Krb5 provided properties.

- Associate identities that have a valid TGT with Krb5 by setting
  KCDB_ATTR_TYPE to the Krb5 credentials type.

- Don't attempt to renew an identity if the TGT is not renewable or is
  expired.

- When opening the configuration handle for an identity, if the
  identity does not have any configuration information, failover to
  using the per-realm configuration or the identity global
  configuration.

- When opening the configuration handle, don't return a handle that
  can't safely be closed.

- Add code from get_in_tkt.c that correctly handles per-realm settings
  when obtaining libdefaults settings from the profile.

ticket: new
component: windows

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19306 dc483132-0cff-0310-8789-dd5450dbe970

27 files changed:
src/windows/identity/config/Makefile.w2k
src/windows/identity/config/Makefile.w32
src/windows/identity/plugins/krb5/krb5configids.c
src/windows/identity/plugins/krb5/krb5funcs.c
src/windows/identity/plugins/krb5/krb5identpro.c
src/windows/identity/plugins/krb5/krbconfig.csv
src/windows/identity/plugins/krb5/lang/en_us/langres.rc
src/windows/identity/plugins/krb5/langres.h
src/windows/identity/ui/appglobal.h
src/windows/identity/ui/credwnd.c
src/windows/identity/ui/credwnd.h
src/windows/identity/ui/lang/en_us/khapp.rc
src/windows/identity/ui/main.c
src/windows/identity/ui/mainmenu.c
src/windows/identity/ui/mainwnd.c
src/windows/identity/ui/newcredwnd.c
src/windows/identity/ui/newcredwnd.h
src/windows/identity/ui/notifier.c
src/windows/identity/ui/resource.h
src/windows/identity/ui/statusbar.c
src/windows/identity/ui/statusbar.h
src/windows/identity/ui/timer.c
src/windows/identity/ui/toolbar.c
src/windows/identity/ui/toolbar.h
src/windows/identity/ui/uiconfig.csv
src/windows/identity/uilib/action.c
src/windows/identity/uilib/khnewcred.h

index a0632065c64d5ee374bdbfbad6677e73cee818c0..e8da2fc175850fe2d23ca604f84a1ccf94d00448 100644 (file)
@@ -46,8 +46,8 @@ KHIMAIRA_WIN32_CONFIG=1
 \r
 # Version info\r
 NETIDMGR_VERSION_MAJOR=1\r
-NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=11\r
+NETIDMGR_VERSION_MINOR=2\r
+NETIDMGR_VERSION_PATCH=0\r
 NETIDMGR_VERSION_AUX=0\r
 NETIDMGR_RELEASEDESC=\r
 \r
index 3a87ba6ff144cbaaa4eec9cc3fd6776ce76cba01..d65d45d73635f53dccd211d9eac7625b9aed1349 100644 (file)
@@ -46,8 +46,8 @@ KHIMAIRA_WIN32_CONFIG=1
 \r
 # Version info\r
 NETIDMGR_VERSION_MAJOR=1\r
-NETIDMGR_VERSION_MINOR=1\r
-NETIDMGR_VERSION_PATCH=11\r
+NETIDMGR_VERSION_MINOR=2\r
+NETIDMGR_VERSION_PATCH=0\r
 NETIDMGR_VERSION_AUX=0\r
 NETIDMGR_RELEASEDESC=\r
 \r
index afd86e541c4d9e9a7ed3dcbc897c00be0632c34c..5f4729253e975fdf68d93ba808f9d952e21c353a 100644 (file)
 #include<commctrl.h>\r
 #include<shlwapi.h>\r
 \r
+typedef struct tag_k5_ids_opts {\r
+    khm_int32 renewable;\r
+    khm_int32 forwardable;\r
+    khm_int32 addressless;\r
+} k5_ids_opts;\r
 \r
 typedef struct tag_k5_ids_dlg_data {\r
     khui_config_init_data cfg;\r
@@ -48,6 +53,10 @@ typedef struct tag_k5_ids_dlg_data {
     time_t life_max;\r
     time_t renew_min;\r
     time_t renew_max;\r
+\r
+    k5_ids_opts opt;\r
+    k5_ids_opts opt_saved;\r
+\r
 } k5_ids_dlg_data;\r
 \r
 static khm_boolean\r
@@ -57,7 +66,10 @@ k5_ids_is_mod(k5_ids_dlg_data * d) {
         d->life_max != d->tc_life_max.current ||\r
         d->life_min != d->tc_life_min.current ||\r
         d->renew_max != d->tc_renew_max.current ||\r
-        d->renew_min != d->tc_renew_min.current)\r
+        d->renew_min != d->tc_renew_min.current ||\r
+        !!d->opt.renewable != !!d->opt_saved.renewable ||\r
+        !!d->opt.forwardable != !!d->opt_saved.forwardable ||\r
+        !!d->opt.addressless != !!d->opt_saved.addressless)\r
         return TRUE;\r
     return FALSE;\r
 }\r
@@ -96,6 +108,9 @@ k5_ids_write_params(k5_ids_dlg_data * d) {
     WRITEPARAM(d->life_min,d->tc_life_min.current, L"MinLifetime");\r
     WRITEPARAM(d->renew_max,d->tc_renew_max.current, L"MaxRenewLifetime");\r
     WRITEPARAM(d->renew_min,d->tc_renew_min.current, L"MinRenewLifetime");\r
+    WRITEPARAM(d->opt_saved.renewable, d->opt.renewable, L"Renewable");\r
+    WRITEPARAM(d->opt_saved.forwardable, d->opt.forwardable, L"Forwardable");\r
+    WRITEPARAM(d->opt_saved.addressless, d->opt.addressless, L"Addressless");\r
 \r
 #undef WRITEPARAM\r
 \r
@@ -106,36 +121,23 @@ k5_ids_write_params(k5_ids_dlg_data * d) {
 \r
 static void\r
 k5_ids_read_params(k5_ids_dlg_data * d) {\r
-    khm_int32 t;\r
-    khm_int32 rv;\r
-\r
-#ifdef DEBUG\r
-    assert(csp_params);\r
-#endif\r
+    k5_params p;\r
 \r
-    rv = khc_read_int32(csp_params, L"DefaultLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->life = t;\r
+    khm_krb5_get_identity_params(NULL, &p);\r
 \r
-    rv = khc_read_int32(csp_params, L"DefaultRenewLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->renew_life = t;\r
+    d->life = p.lifetime;\r
+    d->life_max = p.lifetime_max;\r
+    d->life_min = p.lifetime_min;\r
 \r
-    rv = khc_read_int32(csp_params, L"MaxLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->life_max = t;\r
+    d->renew_life = p.renew_life;\r
+    d->renew_max = p.renew_life_max;\r
+    d->renew_min = p.renew_life_min;\r
 \r
-    rv = khc_read_int32(csp_params, L"MinLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->life_min = t;\r
+    d->opt_saved.forwardable = p.forwardable;\r
+    d->opt_saved.renewable = p.renewable;\r
+    d->opt_saved.addressless = p.addressless;\r
 \r
-    rv = khc_read_int32(csp_params, L"MaxRenewLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->renew_max = t;\r
-\r
-    rv = khc_read_int32(csp_params, L"MinRenewLifetime", &t);\r
-    assert(KHM_SUCCEEDED(rv));\r
-    d->renew_min = t;\r
+    d->opt = d->opt_saved;\r
 \r
     khui_tracker_initialize(&d->tc_life);\r
     d->tc_life.current = d->life;\r
@@ -209,6 +211,10 @@ k5_ids_tab_dlgproc(HWND hwnd,
         khui_tracker_refresh(&d->tc_renew);\r
         khui_tracker_refresh(&d->tc_renew_min);\r
         khui_tracker_refresh(&d->tc_renew_max);\r
+\r
+        CheckDlgButton(hwnd, IDC_CFG_RENEW, (d->opt.renewable ? BST_CHECKED: BST_UNCHECKED));\r
+        CheckDlgButton(hwnd, IDC_CFG_FORWARD, (d->opt.forwardable ? BST_CHECKED: BST_UNCHECKED));\r
+        CheckDlgButton(hwnd, IDC_CFG_ADDRESSLESS, (d->opt.addressless ? BST_CHECKED: BST_UNCHECKED));\r
         break;\r
 \r
     case WM_COMMAND:\r
@@ -216,6 +222,22 @@ k5_ids_tab_dlgproc(HWND hwnd,
             GetWindowLongPtr(hwnd, DWLP_USER);\r
 \r
         if (HIWORD(wParam) == EN_CHANGE) {\r
+            k5_ids_check_mod(d);\r
+        } else if (HIWORD(wParam) == BN_CLICKED) {\r
+            switch (LOWORD(wParam)) {\r
+            case IDC_CFG_RENEW:\r
+                d->opt.renewable = (IsDlgButtonChecked(hwnd, IDC_CFG_RENEW) == BST_CHECKED);\r
+                break;\r
+\r
+            case IDC_CFG_FORWARD:\r
+                d->opt.forwardable = (IsDlgButtonChecked(hwnd, IDC_CFG_FORWARD) == BST_CHECKED);\r
+                break;\r
+\r
+            case IDC_CFG_ADDRESSLESS:\r
+                d->opt.addressless = (IsDlgButtonChecked(hwnd, IDC_CFG_ADDRESSLESS) == BST_CHECKED);\r
+                break;\r
+            }\r
+\r
             k5_ids_check_mod(d);\r
         }\r
         break;\r
@@ -245,3 +267,4 @@ k5_ids_tab_dlgproc(HWND hwnd,
     return FALSE;\r
 }\r
 \r
+\r
index bab9ba4cd04cd9a49941d719c248a8de3d07e067..bc0170d8fab944ea95581231b5144fb848498c65 100644 (file)
@@ -228,9 +228,91 @@ typedef struct tag_identlist {
 \r
 static void\r
 tc_prep_idlist(identlist * idlist) {\r
+    khm_int32 rv;\r
+    khm_size cb_ids = 0;\r
+    khm_size n_ids = 0;\r
+    khm_size i;\r
+    wchar_t * ids = NULL;\r
+    wchar_t *thisid;\r
+\r
     idlist->list = NULL;\r
     idlist->n_list = 0;\r
     idlist->nc_list = 0;\r
+\r
+    do {\r
+\r
+        if (ids) {\r
+            PFREE(ids);\r
+            ids = NULL;\r
+        }\r
+\r
+        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,\r
+                                KCDB_IDENT_FLAG_ACTIVE,\r
+                                NULL,\r
+                                &cb_ids,\r
+                                &n_ids);\r
+\r
+        if (rv != KHM_ERROR_TOO_LONG)\r
+            break;              /* something else is wrong */\r
+\r
+        if (n_ids == 0 || cb_ids == 0)\r
+            break;              /* no identities to process */\r
+\r
+#ifdef DEBUG\r
+        assert(cb_ids > 0);\r
+#endif\r
+\r
+        ids = PMALLOC(cb_ids);\r
+#ifdef DEBUG\r
+        assert(ids != NULL);\r
+#endif\r
+        if (ids == NULL)\r
+            break;\r
+\r
+        rv = kcdb_identity_enum(KCDB_IDENT_FLAG_ACTIVE,\r
+                                KCDB_IDENT_FLAG_ACTIVE,\r
+                                ids,\r
+                                &cb_ids,\r
+                                &n_ids);\r
+\r
+        if (KHM_SUCCEEDED(rv))\r
+            break;\r
+\r
+    } while (TRUE);\r
+\r
+    if (ids == NULL)\r
+        return;\r
+\r
+    if (KHM_FAILED(rv) || n_ids == 0) {\r
+        if (ids)\r
+            PFREE(ids);\r
+        return;\r
+    }\r
+\r
+    idlist->nc_list = UBOUNDSS(n_ids, IDLIST_ALLOC_INCR, IDLIST_ALLOC_INCR);\r
+\r
+    idlist->list = PCALLOC(idlist->nc_list, sizeof(idlist->list[0]));\r
+\r
+    for (i = 0, thisid = ids;\r
+         thisid && thisid[0];\r
+         thisid = multi_string_next(thisid)) {\r
+\r
+        khm_handle ident;\r
+\r
+        rv = kcdb_identity_create(thisid, 0, &ident);\r
+\r
+        if (KHM_FAILED(rv))\r
+            continue;\r
+\r
+        idlist->list[i].ident = ident;\r
+        idlist->list[i].count = 0;\r
+\r
+        i++;\r
+    }\r
+\r
+    idlist->n_list = i;\r
+\r
+    PFREE(ids);\r
 }\r
 \r
 static ident_data *\r
@@ -286,42 +368,102 @@ tc_add_ident_to_list(identlist * idlist, khm_handle ident) {
 static void\r
 tc_set_ident_data(identlist * idlist) {\r
     khm_size i;\r
+    wchar_t k5idtype[KCDB_MAXCCH_NAME];\r
+\r
+    k5idtype[0] = L'\0';\r
+    LoadString(hResModule, IDS_KRB5_NC_NAME,\r
+               k5idtype, ARRAYLENGTH(k5idtype));\r
 \r
     for (i=0; i < idlist->n_list; i++) {\r
 #ifdef DEBUG\r
         assert(idlist->list[i].ident);\r
 #endif\r
 \r
-        kcdb_identity_set_attr(idlist->list[i].ident,\r
-                               attr_id_krb5_ccname,\r
-                               idlist->list[i].ccname,\r
-                               KCDB_CBSIZE_AUTO);\r
+        if (idlist->list[i].count > 0) {\r
+            khm_int32 t;\r
 \r
-        kcdb_identity_set_attr(idlist->list[i].ident,\r
-                               KCDB_ATTR_EXPIRE,\r
-                               &idlist->list[i].ft_expire,\r
-                               sizeof(idlist->list[i].ft_expire));\r
+            t = credtype_id_krb5;\r
+            kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                   KCDB_ATTR_TYPE,\r
+                                   &t,\r
+                                   sizeof(t));\r
+\r
+            /* We need to manually add the type name if we want the\r
+               name to show up in the property list for the identity.\r
+               The type name is only automatically calculated for\r
+               credentials. */\r
+            kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                   KCDB_ATTR_TYPE_NAME,\r
+                                   k5idtype,\r
+                                   KCDB_CBSIZE_AUTO);\r
 \r
-        kcdb_identity_set_attr(idlist->list[i].ident,\r
-                               KCDB_ATTR_ISSUE,\r
-                               &idlist->list[i].ft_issue,\r
-                               sizeof(idlist->list[i].ft_issue));\r
+            kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                   attr_id_krb5_ccname,\r
+                                   idlist->list[i].ccname,\r
+                                   KCDB_CBSIZE_AUTO);\r
 \r
-        kcdb_identity_set_attr(idlist->list[i].ident,\r
-                               attr_id_krb5_flags,\r
-                               &idlist->list[i].krb5_flags,\r
-                               sizeof(idlist->list[i].krb5_flags));\r
+            kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                   KCDB_ATTR_EXPIRE,\r
+                                   &idlist->list[i].ft_expire,\r
+                                   sizeof(idlist->list[i].ft_expire));\r
 \r
-        if (idlist->list[i].ft_renewexpire.dwLowDateTime == 0 &&\r
-            idlist->list[i].ft_renewexpire.dwHighDateTime == 0) {\r
             kcdb_identity_set_attr(idlist->list[i].ident,\r
-                                   KCDB_ATTR_RENEW_EXPIRE,\r
-                                   NULL, 0);\r
-        } else {\r
+                                   KCDB_ATTR_ISSUE,\r
+                                   &idlist->list[i].ft_issue,\r
+                                   sizeof(idlist->list[i].ft_issue));\r
+\r
             kcdb_identity_set_attr(idlist->list[i].ident,\r
-                                   KCDB_ATTR_RENEW_EXPIRE,\r
-                                   &idlist->list[i].ft_renewexpire,\r
-                                   sizeof(idlist->list[i].ft_renewexpire));\r
+                                   attr_id_krb5_flags,\r
+                                   &idlist->list[i].krb5_flags,\r
+                                   sizeof(idlist->list[i].krb5_flags));\r
+\r
+            if (idlist->list[i].ft_renewexpire.dwLowDateTime == 0 &&\r
+                idlist->list[i].ft_renewexpire.dwHighDateTime == 0) {\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_RENEW_EXPIRE,\r
+                                       NULL, 0);\r
+            } else {\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_RENEW_EXPIRE,\r
+                                       &idlist->list[i].ft_renewexpire,\r
+                                       sizeof(idlist->list[i].ft_renewexpire));\r
+            }\r
+\r
+        } else {\r
+            /* We didn't see any TGTs for this identity.  We have to\r
+               remove all the Krb5 supplied properties. */\r
+\r
+            khm_int32 t;\r
+            khm_size cb;\r
+\r
+            cb = sizeof(t);\r
+            if (KHM_SUCCEEDED(kcdb_identity_get_attr(idlist->list[i].ident,\r
+                                                     KCDB_ATTR_TYPE, NULL,\r
+                                                     &t,\r
+                                                     &cb)) &&\r
+                t == credtype_id_krb5) {\r
+\r
+                /* disown this and remove all our properties. the\r
+                   system will GC this identity if nobody claims it.*/\r
+\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_TYPE, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_TYPE_NAME, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       attr_id_krb5_ccname, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_EXPIRE, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_ISSUE, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       attr_id_krb5_flags, NULL, 0);\r
+                kcdb_identity_set_attr(idlist->list[i].ident,\r
+                                       KCDB_ATTR_RENEW_EXPIRE, NULL, 0);\r
+            } else {\r
+                /* otherwise, this identity doesn't belong to us.  We\r
+                   should leave it as is. */\r
+            }\r
         }\r
     }\r
 }\r
@@ -918,7 +1060,7 @@ khm_krb5_renew_cred(khm_handle cred)
 #endif\r
 \r
     if (strlen("krbtgt") != krb5_princ_name(ctx, server)->length ||\r
-        strncmp("krbtgt", krb5_princ_name(ctx, server)->data, krb5_princ_name(ctx, server)->length)) \r
+        strncmp("krbtgt", krb5_princ_name(ctx, server)->data, krb5_princ_name(ctx, server)->length)) \r
     {\r
        code = pkrb5_get_renewed_creds(ctx, &cc_creds, me, cc, name);\r
        if (code) {\r
@@ -1004,6 +1146,7 @@ khm_krb5_renew_ident(khm_handle identity)
     krb5_data           *realm = NULL;\r
     wchar_t             idname[KCDB_IDENT_MAXCCH_NAME];\r
     khm_size            cb;\r
+    khm_int32           k5_flags;\r
 \r
     memset(&my_creds, 0, sizeof(krb5_creds));\r
 \r
@@ -1036,6 +1179,37 @@ khm_krb5_renew_ident(khm_handle identity)
 #endif\r
     }\r
 \r
+    cb = sizeof(k5_flags);\r
+    if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,\r
+                                             attr_id_krb5_flags,\r
+                                             NULL,\r
+                                             &k5_flags,\r
+                                             &cb)) &&\r
+        !(k5_flags & TKT_FLG_RENEWABLE)) {\r
+\r
+        code = KRB5KDC_ERR_BADOPTION;\r
+        goto cleanup;\r
+    }\r
+\r
+    {\r
+        FILETIME ft_now;\r
+        FILETIME ft_exp;\r
+\r
+        cb = sizeof(ft_exp);\r
+        GetSystemTimeAsFileTime(&ft_now);\r
+        if (KHM_SUCCEEDED(kcdb_identity_get_attr(identity,\r
+                                                 KCDB_ATTR_EXPIRE,\r
+                                                 NULL,\r
+                                                 &ft_exp,\r
+                                                 &cb)) &&\r
+            CompareFileTime(&ft_exp, &ft_now) < 0) {\r
+\r
+            code = KRB5KRB_AP_ERR_TKT_EXPIRED;\r
+            goto cleanup;\r
+\r
+        }\r
+    }\r
+\r
     code = khm_krb5_initialize(identity, &ctx, &cc);\r
     if (code) \r
         goto cleanup;\r
@@ -2580,7 +2754,7 @@ khm_krb5_set_identity_flags(khm_handle identity,
     }\r
 \r
     t &= ~flag_mask;\r
-    t |= flag_value | flag_mask;\r
+    t |= (flag_value & flag_mask);\r
 \r
     kcdb_identity_set_attr(identity,\r
                            attr_id_krb5_idflags,\r
@@ -2679,11 +2853,13 @@ khm_krb5_get_identity_config(khm_handle ident,
     if (ident) {\r
         rv = kcdb_identity_get_config(ident, flags, &csp_i);\r
         if (KHM_FAILED(rv))\r
-            goto done;\r
+            goto try_realm;\r
 \r
         rv = khc_open_space(csp_i, CSNAME_KRB5CRED, flags, &csp_ik5);\r
         if (KHM_FAILED(rv))\r
-            goto done;\r
+            goto try_realm;\r
+\r
+    try_realm:\r
 \r
         if (realm[0] == L'\0')\r
             goto done_shadow_realm;\r
@@ -2700,16 +2876,31 @@ khm_krb5_get_identity_config(khm_handle ident,
 \r
     done_shadow_realm:\r
 \r
-        if (csp_realm)\r
-            rv = khc_shadow_space(csp_ik5, csp_realm);\r
-        else\r
-            rv = khc_shadow_space(csp_ik5, csp_params);\r
+        if (csp_ik5) {\r
+            if (csp_realm)\r
+                rv = khc_shadow_space(csp_ik5, csp_realm);\r
+            else\r
+                rv = khc_shadow_space(csp_ik5, csp_params);\r
 \r
-        csp_rv = csp_ik5;\r
+            csp_rv = csp_ik5;\r
+        } else {\r
+            if (csp_realm)\r
+                csp_rv = csp_realm;\r
+        }\r
+    }\r
 \r
-    } else {\r
+    if (csp_rv == NULL) {\r
+\r
+        /* No valid identity specified or the specified identity\r
+           doesn't have any configuration. We default to the\r
+           parameters key. */\r
+\r
+        /* we don't just return csp_params since that's a global\r
+           handle that we shouldn't close until the plugin is\r
+           unloaded.  The caller is going to close the returned handle\r
+           when it is done.  So we need to create a new csp_params\r
+           that can safely be closed. */\r
 \r
-        /* No valid identity specified. We default to the parameters key. */\r
         rv = kmm_get_plugins_config(0, &csp_plugins);\r
         if (KHM_FAILED(rv))\r
             goto done;\r
@@ -2731,8 +2922,11 @@ khm_krb5_get_identity_config(khm_handle ident,
         khc_close_space(csp_i);\r
     if (csp_realms)\r
         khc_close_space(csp_realms);\r
-    if (csp_realm)\r
+\r
+    /* csp_realm can also be a return value if csp_ik5 was NULL */\r
+    if (csp_realm && csp_realm != csp_rv)\r
         khc_close_space(csp_realm);\r
+\r
     if (csp_plugins)\r
         khc_close_space(csp_plugins);\r
     if (csp_krbcfg)\r
@@ -2741,6 +2935,82 @@ khm_krb5_get_identity_config(khm_handle ident,
     return rv;\r
 }\r
 \r
+/* from get_in_tkt.c */\r
+static krb5_error_code\r
+get_libdefault_string(profile_t profile, const char * realm,\r
+                      const char * option, char ** ret_val) {\r
+    char realmstr[K5_MAXCCH_REALM];\r
+    char **nameval = NULL;\r
+    const char * names[4];\r
+    krb5_error_code code = 0;\r
+\r
+    names[0] = "libdefaults";\r
+\r
+    if (!realm || !realm[0])\r
+        goto try_number_two;\r
+\r
+    StringCbCopyA(realmstr, sizeof(realmstr), realm);\r
+\r
+    /*\r
+     * Try number one:\r
+     *\r
+     * [libdefaults]\r
+     *         REALM = {\r
+     *                 option = <boolean>\r
+     *         }\r
+     */\r
+\r
+    names[1] = realmstr;\r
+    names[2] = option;\r
+    names[3] = 0;\r
+    code = pprofile_get_values(profile, names, &nameval);\r
+    if (code == 0 && nameval && nameval[0])\r
+       goto goodbye;\r
+\r
+ try_number_two:\r
+\r
+    /*\r
+     * Try number two:\r
+     *\r
+     * [libdefaults]\r
+     *         option = <boolean>\r
+     */\r
+    \r
+    names[1] = option;\r
+    names[2] = 0;\r
+    code = pprofile_get_values(profile, names, &nameval);\r
+    if (code == 0 && nameval && nameval[0])\r
+       goto goodbye;\r
+\r
+ goodbye:\r
+    if (!nameval) \r
+       return(ENOENT);\r
+\r
+    if (!nameval[0]) {\r
+        code = ENOENT;\r
+    } else {\r
+        size_t cb;\r
+\r
+        if (FAILED(StringCbLengthA(nameval[0], K5_MAXCCH_REALM * sizeof(char), &cb))) {\r
+            code = ENOMEM;\r
+        } else {\r
+            cb += sizeof(char);\r
+            *ret_val = PMALLOC(cb);\r
+\r
+            if (!*ret_val)\r
+                code = ENOMEM;\r
+            else {\r
+                StringCbCopyA(*ret_val, cb, nameval[0]);\r
+                code = 0;\r
+            }\r
+        }\r
+    }\r
+\r
+    pprofile_free_list(nameval);\r
+\r
+    return code;\r
+}\r
+\r
 khm_int32\r
 khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {\r
 \r
@@ -2751,6 +3021,7 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
     khm_int32 e;\r
     khm_int32 v;\r
     CHAR confname[MAX_PATH];\r
+    CHAR realmname[K5_MAXCCH_REALM];\r
 \r
     ZeroMemory(p, sizeof(*p));\r
 \r
@@ -2802,6 +3073,28 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
     if (rv)\r
         return rv;\r
 \r
+    /* we need to figure out the realm name, since there might be\r
+       per-realm configuration in the profile file. */\r
+\r
+    realmname[0] = '\0';\r
+\r
+    if (ident) {\r
+        wchar_t idname[KCDB_IDENT_MAXCCH_NAME];\r
+        khm_size cb;\r
+\r
+        idname[0] = L'\0';\r
+        cb = sizeof(idname);\r
+        rv = kcdb_identity_get_name(ident, idname, &cb);\r
+        if (KHM_SUCCEEDED(rv)) {\r
+            wchar_t * wrealm;\r
+\r
+            wrealm = khm_get_realm_from_princ(idname);\r
+            if (wrealm) {\r
+                UnicodeStrToAnsi(realmname, sizeof(realmname), wrealm);\r
+            }\r
+        }\r
+    }\r
+\r
     /* If we get here, then some of the settings we read from the\r
        configuration actually came from the schema.  In other words,\r
        the values weren't really defined for this identity.  So we now\r
@@ -2820,7 +3113,9 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
             /* default ticket lifetime */\r
             if (!(regf & K5PARAM_F_LIFE)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "ticket_lifetime", 0, 0, &value);\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "ticket_lifetime", &value);\r
+\r
                 if (retval == 0 && value) {\r
                     krb5_deltat d;\r
 \r
@@ -2871,13 +3166,15 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->lifetime = d;\r
                         proff |= K5PARAM_F_LIFE;\r
                     }\r
-                    pprofile_release_string(value);\r
+\r
+                    PFREE(value);\r
                 }\r
             }\r
 \r
             if (!(regf & K5PARAM_F_RLIFE)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "renew_lifetime", 0, 0, &value);\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "renew_lifetime", &value);\r
                 if (retval == 0 && value) {\r
                     krb5_deltat d;\r
 \r
@@ -2886,13 +3183,14 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->renew_life = d;\r
                         proff |= K5PARAM_F_RLIFE;\r
                     }\r
-                    pprofile_release_string(value);\r
+                    PFREE(value);\r
                 }\r
             }\r
 \r
             if (!(regf & K5PARAM_F_FORW)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "forwardable", 0, 0, &value);\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "forwardable", &value);\r
                 if (retval == 0 && value) {\r
                     khm_boolean b;\r
 \r
@@ -2900,15 +3198,15 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->forwardable = b;\r
                     else\r
                         p->forwardable = FALSE;\r
-                    pprofile_release_string(value);\r
+                    PFREE(value);\r
                     proff |= K5PARAM_F_FORW;\r
                 }\r
             }\r
 \r
             if (!(regf & K5PARAM_F_RENEW)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "renewable", 0, 0, &value);\r
-\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "renewable", &value);\r
                 if (retval == 0 && value) {\r
                     khm_boolean b;\r
 \r
@@ -2916,15 +3214,15 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->renewable = b;\r
                     else\r
                         p->renewable = TRUE;\r
-                    pprofile_release_string(value);\r
+                    PFREE(value);\r
                     proff |= K5PARAM_F_RENEW;\r
                 }\r
             }\r
 \r
             if (!(regf & K5PARAM_F_ADDL)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "noaddresses", 0, 0, &value);\r
-\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "noaddresses", &value);\r
                 if (retval == 0 && value) {\r
                     khm_boolean b;\r
 \r
@@ -2932,15 +3230,15 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->addressless = b;\r
                     else\r
                         p->addressless = TRUE;\r
-                    pprofile_release_string(value);\r
+                    PFREE(value);\r
                     proff |= K5PARAM_F_ADDL;\r
                 }\r
             }\r
 \r
             if (!(regf & K5PARAM_F_PROX)) {\r
                 char * value = NULL;\r
-                retval = pprofile_get_string(profile, "libdefaults", "proxiable", 0, 0, &value);\r
-\r
+                retval = get_libdefault_string(profile, realmname,\r
+                                               "proxiable", &value);\r
                 if (retval == 0 && value) {\r
                     khm_boolean b;\r
 \r
@@ -2948,7 +3246,7 @@ khm_krb5_get_identity_params(khm_handle ident, k5_params * p) {
                         p->proxiable = b;\r
                     else\r
                         p->proxiable = FALSE;\r
-                    pprofile_release_string(value);\r
+                    PFREE(value);\r
                     proff |= K5PARAM_F_PROX;\r
                 }\r
             }\r
index c036eb9762d62a095993e8a447435839af894798..bc77b26f05eaea6517be2e2357dd938d7fca9945 100644 (file)
@@ -846,9 +846,37 @@ k5_ident_set_default(khm_int32 msg_type,
                                               NULL,\r
                                               id_ccname,\r
                                               &cb))) {\r
+            khm_handle csp_ident = NULL;\r
+            khm_handle csp_k5 = NULL;\r
+\r
             _reportf(L"The specified identity does not have the Krb5CCName property");\r
-            _end_task();\r
-            return KHM_ERROR_NOT_FOUND;\r
+\r
+            cb = sizeof(id_ccname);\r
+            if (KHM_SUCCEEDED(kcdb_identity_get_config(def_ident, 0, &csp_ident)) &&\r
+                KHM_SUCCEEDED(khc_open_space(csp_ident, CSNAME_KRB5CRED, 0, &csp_k5)) &&\r
+                KHM_SUCCEEDED(khc_read_string(csp_k5, L"DefaultCCName",\r
+                                              id_ccname, &cb))) {\r
+\r
+                _reportf(L"Found CC name in configuration [%s]", id_ccname);\r
+            } else {\r
+                /* last resort, use the name of the identity as the cc\r
+                   name */\r
+                cb = sizeof(id_ccname);\r
+                if (KHM_FAILED(kcdb_identity_get_name(def_ident, id_ccname, &cb))) {\r
+                    _reportf(L"Can't use name of identity as CCName");\r
+                    _end_task();\r
+\r
+                    id_ccname[0] = L'\0';\r
+                }\r
+            }\r
+\r
+            if (csp_k5)\r
+                khc_close_space(csp_k5);\r
+            if (csp_ident)\r
+                khc_close_space(csp_ident);\r
+\r
+            if (id_ccname[0] == L'\0')\r
+                return KHM_ERROR_INVALID_PARAM;\r
         }\r
 \r
         khm_krb5_canon_cc_name(id_ccname, sizeof(id_ccname));\r
index 205cbcb42a732e705239808cebb5e1fbcbbe643d..4dc5b7d720a760daa562aaacc6944cde8b36f602 100644 (file)
@@ -13,7 +13,7 @@ Krb5Cred,KC_SPACE,0,Kerberos V Credentials Provider
     DefaultLifetime,KC_INT32,36000,Default ticket lifetime\r
     MaxLifetime,KC_INT32,86400,Maximum lifetime\r
     MinLifetime,KC_INT32,60,Minimum lifetime\r
-    Forwardable,KC_INT32,0,Obtain forwardable tickets (boolean)\r
+    Forwardable,KC_INT32,1,Obtain forwardable tickets (boolean)\r
     Proxiable,KC_INT32,0,Obtain proxiable tickets (boolean)\r
     Addressless,KC_INT32,1,Obtain addressless tickets (boolean)\r
     PublicIP,KC_INT32,0,Additional public IP address to use (int32)\r
index 4d98fd3141a6a9c6a1f31a8ede62b0160a8cfda5..1bdae10e28391eeb7b8ddb6f2ba947bd2aefef3d 100644 (file)
@@ -156,20 +156,23 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
 EXSTYLE WS_EX_CONTROLPARENT\r
 FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
 BEGIN\r
-    LTEXT           "Credential lifetime",IDC_CFG_LBL_DEFLIFE,7,10,44,8\r
-    EDITTEXT        IDC_CFG_DEFLIFE,91,7,137,14,ES_AUTOHSCROLL\r
-    LTEXT           "Credential renewable lifetime",IDC_CFG_LBL_DEFRLIFE,7,29,80,8\r
-    EDITTEXT        IDC_CFG_DEFRLIFE,91,26,137,14,ES_AUTOHSCROLL\r
-    GROUPBOX        "Credential lifetime range",IDC_CFG_LIFEGRP,7,43,221,49\r
-    LTEXT           "Minimum",IDC_STATIC,13,56,28,8\r
-    EDITTEXT        IDC_CFG_LRNG_MIN,91,53,131,14,ES_AUTOHSCROLL\r
-    LTEXT           "Maximum",IDC_STATIC,13,75,30,8\r
-    EDITTEXT        IDC_CFG_LRNG_MAX,91,72,131,14,ES_AUTOHSCROLL\r
-    GROUPBOX        "Credential renewable lifetime range",IDC_STATIC,7,95,221,49\r
-    LTEXT           "Minimum",IDC_STATIC,13,108,28,8\r
-    EDITTEXT        IDC_CFG_RLRNG_MIN,91,105,131,14,ES_AUTOHSCROLL\r
-    LTEXT           "Maximum",IDC_STATIC,13,128,30,8\r
-    EDITTEXT        IDC_CFG_RLRNG_MAX,91,125,131,14,ES_AUTOHSCROLL\r
+    LTEXT           "Ticket &lifetime",IDC_CFG_LBL_DEFLIFE,7,10,44,8\r
+    EDITTEXT        IDC_CFG_DEFLIFE,94,7,134,14,ES_AUTOHSCROLL\r
+    LTEXT           "Ticket re&newable lifetime",IDC_CFG_LBL_DEFRLIFE,7,29,80,8\r
+    EDITTEXT        IDC_CFG_DEFRLIFE,94,26,134,14,ES_AUTOHSCROLL\r
+    CONTROL         "&Renewable",IDC_CFG_RENEW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,47,51,10\r
+    CONTROL         "&Forwardable",IDC_CFG_FORWARD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,94,47,56,10\r
+    CONTROL         "&Addressless",IDC_CFG_ADDRESSLESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,63,54,10\r
+    GROUPBOX        "Credential lifetime range",IDC_CFG_LIFEGRP,7,79,221,31\r
+    LTEXT           "From",IDC_STATIC,13,93,17,8\r
+    EDITTEXT        IDC_CFG_LRNG_MIN,38,90,79,14,ES_AUTOHSCROLL\r
+    LTEXT           "To",IDC_STATIC,125,93,9,8\r
+    EDITTEXT        IDC_CFG_LRNG_MAX,143,90,79,14,ES_AUTOHSCROLL\r
+    GROUPBOX        "Credential renewable lifetime range",IDC_STATIC,7,113,221,31\r
+    LTEXT           "From",IDC_STATIC,13,128,17,8\r
+    EDITTEXT        IDC_CFG_RLRNG_MIN,38,125,79,14,ES_AUTOHSCROLL\r
+    LTEXT           "To",IDC_STATIC,125,128,9,8\r
+    EDITTEXT        IDC_CFG_RLRNG_MAX,143,125,79,14,ES_AUTOHSCROLL\r
 END\r
 \r
 IDD_CFG_ID_TAB DIALOGEX 0, 0, 235, 151\r
@@ -177,7 +180,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
 EXSTYLE WS_EX_CONTROLPARENT\r
 FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
 BEGIN\r
-    LTEXT           "Credential lifetime",IDC_CFG_LBL_DEFLIFE,7,10,44,8\r
+    LTEXT           "Credential lifetime",IDC_CFG_LBL_DEFLIFE,7,10,58,8\r
     EDITTEXT        IDC_CFG_DEFLIFE,91,7,137,14,ES_AUTOHSCROLL\r
     CONTROL         "Renewable for",IDC_CFG_RENEW,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,41,63,10\r
     EDITTEXT        IDC_CFG_DEFRLIFE,91,39,137,14,ES_AUTOHSCROLL\r
@@ -280,7 +283,7 @@ BEGIN
         LEFTMARGIN, 7\r
         RIGHTMARGIN, 228\r
         VERTGUIDE, 13\r
-        VERTGUIDE, 91\r
+        VERTGUIDE, 94\r
         VERTGUIDE, 222\r
         TOPMARGIN, 7\r
         BOTTOMMARGIN, 144\r
index 9381b99eecea7130f48a0ec17245375c4ba8bcb3..0e62ecda1d0c3d65e7d3f51d3aa29baa41f91d6e 100644 (file)
 #define IDC_CHECK3                      1077\r
 #define IDC_CFG_ADDRESSLESS             1077\r
 #define IDC_CFG_FORWARD                 1078\r
+#define IDC_CHECK1                      1079\r
 #define ID_FOO_BAR                      40001\r
 \r
 // Next default values for new objects\r
 #ifndef APSTUDIO_READONLY_SYMBOLS\r
 #define _APS_NEXT_RESOURCE_VALUE        219\r
 #define _APS_NEXT_COMMAND_VALUE         40002\r
-#define _APS_NEXT_CONTROL_VALUE         1079\r
+#define _APS_NEXT_CONTROL_VALUE         1080\r
 #define _APS_NEXT_SYMED_VALUE           101\r
 #endif\r
 #endif\r
index b25d38247146f743f07c3081d9237729cfd575a7..3e44282d168a266a57040ddb7a65d8c58440590d 100644 (file)
@@ -36,7 +36,7 @@ extern int khm_nCmdShow;
 extern const wchar_t * khm_facility;\r
 extern kconf_schema schema_uiconfig[];\r
 extern khm_ui_4 khm_commctl_version;\r
-extern khm_version app_version;\r
+extern const khm_version app_version;\r
 \r
 #define IS_COMMCTL6() (khm_commctl_version >= 0x60000)\r
 \r
@@ -134,6 +134,8 @@ HWND khm_html_help(HWND hwnd, wchar_t * suffix, UINT command, DWORD_PTR data);
 \r
 WPARAM khm_message_loop_int(khm_boolean * p_exit);\r
 \r
+int khm_compare_version(const khm_version * v1, const khm_version * v2);\r
+\r
 #define MAX_RES_STRING 1024\r
 \r
 #define ELLIPSIS L"..."\r
index 474bfa9aa00b91783efed429503e44c19ac4fd55..b4982218ecd7c6a0226688d70f0ed52a0f1147f8 100644 (file)
@@ -289,8 +289,15 @@ cw_save_view(khui_credwnd_tbl * tbl, wchar_t * view_name) {
 \r
     multi_string_init(col_list, cb_col_list);\r
 \r
+    /* if we aren't saving to a specific view, and the view has been\r
+       customized, then we save it to "Custom_0", unless we are in the\r
+       mini mode, in which case we save it to "Custom_1" */\r
     if (!view_name && (tbl->flags & KHUI_CW_TBL_CUSTVIEW)) {\r
-        view_name = L"Custom_0";\r
+        if (!(tbl->flags & KHUI_CW_TBL_EXPIDENT)) {\r
+            view_name = L"Custom_0";\r
+        } else {\r
+            view_name = L"Custom_1";\r
+        }\r
     }\r
 \r
     if (view_name) {\r
@@ -309,7 +316,9 @@ cw_save_view(khui_credwnd_tbl * tbl, wchar_t * view_name) {
         /* if we are switching to a custom view, then we should mark\r
            that as the default. */\r
         if (tbl->flags & KHUI_CW_TBL_CUSTVIEW) {\r
-            khc_write_string(csp_cw, L"DefaultView", L"Custom_0");\r
+            khc_write_string(csp_cw, ((!(tbl->flags & KHUI_CW_TBL_EXPIDENT))?\r
+                                      L"DefaultView":\r
+                                      L"DefaultViewMini"), view_name);\r
         }\r
 \r
     } else {\r
@@ -319,6 +328,22 @@ cw_save_view(khui_credwnd_tbl * tbl, wchar_t * view_name) {
     if (!csp_view)\r
         goto _cleanup;\r
 \r
+    if (tbl->flags & KHUI_CW_TBL_EXPIDENT) {\r
+        khc_write_int32(csp_view, L"ExpandedIdentity", 1);\r
+    } else {\r
+        khm_int32 t;\r
+        if (KHM_SUCCEEDED(khc_read_int32(csp_view, L"ExpandedIdentity", &t)) && t)\r
+            khc_write_int32(csp_view, L"ExpandedIdentity", 0);\r
+    }\r
+\r
+    if (tbl->flags & KHUI_CW_TBL_NOHEADER) {\r
+        khc_write_int32(csp_view, L"NoHeader", 1);\r
+    } else {\r
+        khm_int32 t;\r
+        if (KHM_SUCCEEDED(khc_read_int32(csp_view, L"NoHeader", &t)) && t)\r
+            khc_write_int32(csp_view, L"NoHeader", 0);\r
+    }\r
+\r
     if (KHM_FAILED(khc_open_space(csp_view, L"Columns",\r
                                   KHM_PERM_WRITE | KHM_FLAG_CREATE,\r
                                   &csp_cols)))\r
@@ -369,6 +394,12 @@ cw_save_view(khui_credwnd_tbl * tbl, wchar_t * view_name) {
 \r
     khc_write_multi_string(csp_view, L"ColumnList", col_list);\r
 \r
+    {\r
+        khm_version v = app_version;\r
+\r
+        khc_write_binary(csp_view, L"_AppVersion", &v, sizeof(v));\r
+    }\r
+\r
  _cleanup:\r
 \r
     if (view_name) {\r
@@ -389,6 +420,19 @@ cw_save_view(khui_credwnd_tbl * tbl, wchar_t * view_name) {
         PFREE(col_list);\r
 }\r
 \r
+static COLORREF\r
+cw_mix_colors(COLORREF c1, COLORREF c2, int alpha) {\r
+    int r = (GetRValue(c1) * alpha + GetRValue(c2) * (255 - alpha)) / 255;\r
+    int g = (GetGValue(c1) * alpha + GetGValue(c2) * (255 - alpha)) / 255;\r
+    int b = (GetBValue(c1) * alpha + GetBValue(c2) * (255 - alpha)) / 255;\r
+\r
+#ifdef DEBUG\r
+    assert(alpha >= 0 && alpha < 256);\r
+#endif\r
+\r
+    return RGB(r,g,b);\r
+}\r
+\r
 void \r
 cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) {\r
     khm_handle hc_cw = NULL;\r
@@ -405,6 +449,7 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) {
     LOGFONT log_font;\r
     khm_int32 t;\r
     const wchar_t * viewval;\r
+    khm_boolean reopen_csp = FALSE;\r
 \r
     tbl->hwnd = hwnd;\r
 \r
@@ -450,12 +495,39 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) {
         khc_write_string(hc_cw, viewval, view);\r
     }\r
 \r
-    if(KHM_FAILED(khc_open_space(hc_vs, view, KHM_PERM_READ, &hc_v)))\r
+    if(KHM_FAILED(khc_open_space(hc_vs, view, 0, &hc_v)))\r
         goto _exit;\r
 \r
+    /* view data is very sensitive to version changes.  We need to\r
+       check if this configuration data was created with this version\r
+       of NetIDMgr.  If not, we switch to using a schema handle. */\r
+    {\r
+        khm_version this_v = app_version;\r
+        khm_version cfg_v;\r
+\r
+        cbsize = sizeof(cfg_v);\r
+        if (KHM_FAILED(khc_read_binary(hc_v, L"_AppVersion", &cfg_v, &cbsize)) ||\r
+            khm_compare_version(&cfg_v, &this_v) != 0) {\r
+\r
+            khc_close_space(hc_v);\r
+\r
+            if (KHM_FAILED(khc_open_space(hc_vs, view, KCONF_FLAG_SCHEMA,\r
+                                          &hc_v)) &&\r
+                (wcscmp(view, L"Custom_1") ||\r
+                 KHM_FAILED(khc_open_space(hc_vs, L"CompactIdentity",\r
+                                           KCONF_FLAG_SCHEMA, &hc_v)))) {\r
+                goto _exit;\r
+            }\r
+\r
+            reopen_csp = TRUE;\r
+        }\r
+    }\r
+\r
     tbl->csp_view = hc_v;\r
 \r
-    if(KHM_FAILED(khc_open_space(hc_v, L"Columns", KHM_PERM_READ, &hc_cs)))\r
+    if(KHM_FAILED(khc_open_space(hc_v, L"Columns",\r
+                                 KHM_PERM_READ | (reopen_csp ? KCONF_FLAG_SCHEMA : 0),\r
+                                 &hc_cs)))\r
         goto _exit;\r
 \r
     cbsize = 0;\r
@@ -525,7 +597,9 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) {
 \r
         tbl->cols[i].attr_id = attr_id;\r
 \r
-        if(KHM_SUCCEEDED(khc_open_space(hc_cs, iter, KHM_PERM_READ, &hc_c))) {\r
+        if(KHM_SUCCEEDED(khc_open_space(hc_cs, iter,\r
+                                        KHM_PERM_READ | (reopen_csp ? KCONF_FLAG_SCHEMA : 0),\r
+                                        &hc_c))) {\r
             if(KHM_FAILED(khc_read_int32(hc_c, L"Flags", &(tbl->cols[i].flags))))\r
                 tbl->cols[i].flags = 0;\r
             if(KHM_FAILED(khc_read_int32(hc_c, L"Width", &(tbl->cols[i].width))))\r
@@ -601,23 +675,47 @@ _skip_col:
                                     0,\r
                                     LR_DEFAULTCOLOR));\r
 \r
-    tbl->hb_normal =        CreateSolidBrush(RGB(255,255,255));\r
-    tbl->hb_grey =          CreateSolidBrush(RGB(240,240,240));\r
-    tbl->hb_sel =           CreateSolidBrush(RGB(230,230,255));\r
-    tbl->hb_hdr_bg =        CreateSolidBrush(RGB(230,230,230));\r
-    tbl->hb_hdr_bg_sel =    CreateSolidBrush(RGB(0,0,255));\r
-    tbl->hb_hdr_bg_crit =   CreateSolidBrush(RGB(240,133,117));\r
-    tbl->hb_hdr_bg_warn =   CreateSolidBrush(RGB(251,199,77));\r
-    tbl->hb_hdr_bg_exp =    CreateSolidBrush(RGB(255,144,144));\r
-    tbl->hb_hdr_bg_def =    CreateSolidBrush(RGB(186,254,184));\r
-\r
-    tbl->cr_normal = RGB(0,0,0);\r
-    tbl->cr_sel = RGB(0,0,0);\r
-    tbl->cr_hdr_outline = RGB(0,0,0);\r
-    tbl->cr_hdr_normal = RGB(0,0,0);\r
-    tbl->cr_hdr_sel = RGB(255,255,255);\r
-    tbl->cr_hdr_gray = RGB(128,128,128);\r
-    tbl->cr_hdr_gray_sel = RGB(240,240,240);\r
+    {\r
+#define SEL_ALPHA 50\r
+\r
+        COLORREF bg_s = GetSysColor(COLOR_HIGHLIGHT);\r
+        COLORREF bg_normal = GetSysColor(COLOR_WINDOW);\r
+        COLORREF bg_gray = RGB(240,240,240);\r
+        COLORREF bg_hdr = RGB(240,240,240);\r
+        COLORREF bg_hdr_warn = RGB(235,235,134);\r
+        COLORREF bg_hdr_crit = RGB(235,184,134);\r
+        COLORREF bg_hdr_exp = RGB(235,134,134);\r
+        COLORREF bg_hdr_def = RGB(184,235,134);\r
+\r
+        tbl->cr_normal =       GetSysColor(COLOR_WINDOWTEXT);\r
+        tbl->cr_s =            GetSysColor(COLOR_WINDOWTEXT);\r
+        tbl->cr_hdr_outline =  RGB(0,0,0);\r
+        tbl->cr_hdr_normal =   GetSysColor(COLOR_WINDOWTEXT);\r
+        tbl->cr_hdr_s =        GetSysColor(COLOR_WINDOWTEXT);\r
+        tbl->cr_hdr_gray =     GetSysColor(COLOR_GRAYTEXT);\r
+        tbl->cr_hdr_gray_s =   GetSysColor(COLOR_HIGHLIGHTTEXT);\r
+\r
+        if (khm_main_wnd_mode == KHM_MAIN_WND_MINI) {\r
+            bg_hdr = bg_normal;\r
+            tbl->cr_hdr_outline = bg_gray;\r
+        }\r
+\r
+        tbl->hb_normal =      CreateSolidBrush(bg_normal);\r
+        tbl->hb_grey =        CreateSolidBrush(bg_gray);\r
+        tbl->hb_s =           CreateSolidBrush(cw_mix_colors(bg_s, bg_normal, SEL_ALPHA));\r
+\r
+        tbl->hb_hdr_bg =      CreateSolidBrush(bg_hdr);\r
+        tbl->hb_hdr_bg_warn = CreateSolidBrush(bg_hdr_warn);\r
+        tbl->hb_hdr_bg_crit = CreateSolidBrush(bg_hdr_crit);\r
+        tbl->hb_hdr_bg_exp =  CreateSolidBrush(bg_hdr_exp);\r
+        tbl->hb_hdr_bg_def =  CreateSolidBrush(bg_hdr_def);\r
+\r
+        tbl->hb_hdr_bg_s =      CreateSolidBrush(cw_mix_colors(bg_s, bg_hdr, SEL_ALPHA));\r
+        tbl->hb_hdr_bg_warn_s = CreateSolidBrush(cw_mix_colors(bg_s, bg_hdr_warn, SEL_ALPHA));\r
+        tbl->hb_hdr_bg_crit_s = CreateSolidBrush(cw_mix_colors(bg_s, bg_hdr_crit, SEL_ALPHA));\r
+        tbl->hb_hdr_bg_exp_s =  CreateSolidBrush(cw_mix_colors(bg_s, bg_hdr_exp, SEL_ALPHA));\r
+        tbl->hb_hdr_bg_def_s =  CreateSolidBrush(cw_mix_colors(bg_s, bg_hdr_def, SEL_ALPHA));\r
+    }\r
 \r
     tbl->ilist = khui_create_ilist(KHUI_SMICON_CX, KHUI_SMICON_CY-1, 20, 8, 0);\r
     {\r
@@ -657,12 +755,30 @@ _skip_col:
 #undef ADD_BITMAP\r
     }\r
 \r
+    if (tbl->flags & KHUI_CW_TBL_EXPIDENT) {\r
+        tbl->hi_lg_ident = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP),\r
+                                     IMAGE_ICON,\r
+                                     GetSystemMetrics(SM_CXICON),\r
+                                     GetSystemMetrics(SM_CYICON),\r
+                                     LR_DEFAULTCOLOR);\r
+    }\r
+\r
     tbl->cursor_row = -1;\r
     tbl->scr_left = 0;\r
     tbl->scr_top = 0;\r
     tbl->ext_height = 0;\r
     tbl->ext_width = 0;\r
 \r
+    if (reopen_csp) {\r
+        khc_close_space(hc_v);\r
+\r
+        hc_v = NULL;\r
+\r
+        khc_open_space(hc_vs, view, 0, &hc_v);\r
+\r
+        tbl->csp_view = hc_v;\r
+    }\r
+\r
 _exit:\r
     if(hc_cw)\r
         khc_close_space(hc_cw);\r
@@ -676,12 +792,29 @@ _exit:
        We keep that open until the view is unloaded. */\r
 }\r
 \r
+khui_credwnd_ident *\r
+cw_find_ident(khui_credwnd_tbl * tbl, khm_handle ident) {\r
+    khm_size i;\r
+\r
+    for (i=0; i < tbl->n_idents; i++) {\r
+        if (kcdb_identity_is_equal(ident, tbl->idents[i].ident))\r
+            break;\r
+    }\r
+\r
+    if (i < tbl->n_idents)\r
+        return &tbl->idents[i];\r
+    else\r
+        return NULL;\r
+}\r
+\r
 khm_int32 KHMAPI\r
 cw_credset_iter_func(khm_handle cred, void * rock) {\r
     khui_credwnd_tbl * tbl = (khui_credwnd_tbl *) rock;\r
     khm_handle ident = NULL;\r
     khm_size i;\r
     khui_credwnd_ident * cwi = NULL;\r
+    khm_int32 cred_credtype = KCDB_CREDTYPE_INVALID;\r
+    khm_int32 cred_flags = 0;\r
 \r
     kcdb_cred_get_identity(cred, &ident);\r
 \r
@@ -715,25 +848,59 @@ cw_credset_iter_func(khm_handle cred, void * rock) {
         i = tbl->n_idents;\r
         cwi = &tbl->idents[tbl->n_idents++];\r
 \r
+        ZeroMemory(cwi, sizeof(*cwi));\r
+\r
         cwi->ident = ident;\r
         kcdb_identity_hold(ident);\r
+\r
         cb = sizeof(cwi->name);\r
         kcdb_identity_get_name(ident, cwi->name, &cb);\r
-        kcdb_identity_get_type(&cwi->credtype);\r
-        cb = sizeof(cwi->credtype_name);\r
-        kcdb_credtype_describe(cwi->credtype, cwi->credtype_name, &cb, KCDB_TS_SHORT);\r
-        cwi->credcount = 0;\r
     }\r
 \r
     cwi = &tbl->idents[i];\r
 \r
-    /* this is the first time we are seeing this */\r
+    /* this is the first time we are seeing this identity. */\r
     if (cwi->credcount == 0) {\r
+        khm_size cb;\r
+\r
+        cb = sizeof(cwi->credtype);\r
+        if (KHM_SUCCEEDED(kcdb_identity_get_attr(ident, KCDB_ATTR_TYPE, NULL,\r
+                                                 &cwi->credtype, &cb))) {\r
+            cwi->credtype_name[0] = L'\0';\r
+\r
+            cb = sizeof(cwi->credtype_name);\r
+            if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_TYPE_NAME, NULL,\r
+                                                  &cwi->credtype, &cb))) {\r
+                cb = sizeof(cwi->credtype_name);\r
+                kcdb_credtype_describe(cwi->credtype, cwi->credtype_name,\r
+                                       &cb, KCDB_TS_SHORT);\r
+            }\r
+        } else {\r
+            cwi->credtype = KCDB_CREDTYPE_INVALID;\r
+            cwi->credtype_name[0] = L'\0';\r
+        }\r
+\r
+        cb = sizeof(cwi->ft_expire);\r
+        if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE, NULL,\r
+                                              &cwi->ft_expire, &cb))) {\r
+            cwi->ft_expire = IntToFt(0);\r
+        }\r
+\r
         kcdb_identity_get_flags(cwi->ident, &cwi->ident_flags);\r
     }\r
 \r
     cwi->credcount++;\r
 \r
+    kcdb_cred_get_type(cred, &cred_credtype);\r
+    if (cred_credtype >= 0 && cred_credtype == cwi->credtype) {\r
+        cwi->id_credcount++;\r
+\r
+        kcdb_cred_get_flags(cred, &cred_flags);\r
+        if (cred_flags & KCDB_CRED_FLAG_INITIAL) {\r
+            cwi->init_credcount++;\r
+        }\r
+    }\r
+\r
  _cleanup:\r
     if (ident)\r
         kcdb_identity_release(ident);\r
@@ -843,6 +1010,8 @@ cw_update_creds(khui_credwnd_tbl * tbl)
     /* refresh the per-identity information */\r
     for (i=0; i < (int) tbl->n_idents; i++) {\r
         tbl->idents[i].credcount = 0;\r
+        tbl->idents[i].id_credcount = 0;\r
+        tbl->idents[i].init_credcount = 0;\r
     }\r
 \r
     kcdb_credset_apply(tbl->credset, cw_credset_iter_func, (void *) tbl);\r
@@ -935,6 +1104,9 @@ cw_get_buf_exp_flags(khui_credwnd_tbl * tbl, khm_handle buf)
 \r
 void cw_update_outline(khui_credwnd_tbl * tbl);\r
 \r
+static void \r
+cw_update_selection_state(khui_credwnd_tbl * tbl);\r
+\r
 VOID CALLBACK \r
 cw_timer_proc(HWND hwnd,\r
               UINT uMsg,\r
@@ -948,46 +1120,96 @@ cw_timer_proc(HWND hwnd,
     long ms;\r
     FILETIME ft;\r
     khm_size cbsize;\r
+    int timer_set = 0;\r
+\r
+    KillTimer(hwnd, idEvent);\r
 \r
     tbl = (khui_credwnd_tbl *)(LONG_PTR) GetWindowLongPtr(hwnd, 0);\r
     r = (khui_credwnd_row *) idEvent;\r
+    r->flags &= ~KHUI_CW_ROW_TIMERSET;\r
 \r
     nr = (int)(r - tbl->rows);\r
 \r
     if(nr < 0 || nr >= tbl->n_rows)\r
         return;\r
 \r
-    if(!(r->flags & KHUI_CW_ROW_CRED))\r
-        return; /* we only know what to do with cred rows */\r
+    if(r->flags & KHUI_CW_ROW_CRED) {\r
+\r
+        nflags = cw_get_buf_exp_flags(tbl, (khm_handle) r->data);\r
+        if((r->flags & CW_EXPSTATE_MASK) != nflags) {\r
+            /* flags have changed */\r
+            /* the outline needs to be updated */\r
+            cw_update_outline(tbl);\r
+            InvalidateRect(tbl->hwnd, NULL, FALSE);\r
+        } else {\r
+            /* just invalidate the row */\r
+            RECT rc,rr,ri;\r
+\r
+            GetClientRect(tbl->hwnd, &rc);\r
+            rc.top += tbl->header_height;\r
+\r
+            rr = r->r_ext;\r
+            OffsetRect(&rr, 0, tbl->header_height - tbl->scr_top);\r
+\r
+            if(IntersectRect(&ri, &rc, &rr))\r
+                InvalidateRect(tbl->hwnd, &ri, FALSE);\r
+\r
+            cbsize = sizeof(ft);\r
+            if(KHM_SUCCEEDED(kcdb_cred_get_attr((khm_handle) r->data,\r
+                                                KCDB_ATTR_TIMELEFT, NULL,\r
+                                                &ft, &cbsize))) {\r
+                ms = FtIntervalMsToRepChange(&ft);\r
+                if(ms > 0) {\r
+                    SetTimer(tbl->hwnd, (UINT_PTR) r, ms + 100, cw_timer_proc);\r
+                    timer_set = 1;\r
+                }\r
+            }\r
 \r
-    nflags = cw_get_buf_exp_flags(tbl, (khm_handle) r->data);\r
-    if((r->flags & CW_EXPSTATE_MASK) != nflags) {\r
-        /* flags have changed */\r
-        /* the outline needs to be updated */\r
-        cw_update_outline(tbl);\r
-        InvalidateRect(tbl->hwnd, NULL, FALSE);\r
+            if (timer_set)\r
+                r->flags |= KHUI_CW_ROW_TIMERSET;\r
+        }\r
     } else {\r
-        /* just invalidate the row */\r
-        RECT r,rr,ri;\r
+        khui_credwnd_outline * o;\r
+        khui_credwnd_ident * cwi;\r
+        FILETIME ft_now;\r
 \r
-        GetClientRect(tbl->hwnd, &r);\r
-        r.top += tbl->header_height;\r
-        rr.top = r.top + (long)nr * tbl->cell_height - tbl->scr_top;\r
-        rr.bottom = rr.top + tbl->cell_height;\r
-        rr.left = r.left;\r
-        rr.right = r.right;\r
-\r
-        if(IntersectRect(&ri, &r, &rr))\r
-            InvalidateRect(tbl->hwnd, &ri, FALSE);\r
-    }\r
+        o = (khui_credwnd_outline *) r->data;\r
+#ifdef DEBUG\r
+        assert(r->flags & KHUI_CW_ROW_EXPVIEW);\r
+        assert(o->attr_id == KCDB_ATTR_ID);\r
+        assert(tbl->flags & KHUI_CW_TBL_EXPIDENT);\r
+#endif\r
 \r
-    cbsize = sizeof(ft);\r
-    if(KHM_SUCCEEDED(kcdb_cred_get_attr((khm_handle) r->data,\r
-                                        KCDB_ATTR_TIMELEFT, NULL,\r
-                                        &ft, &cbsize))) {\r
-        ms = FtIntervalMsToRepChange(&ft);\r
-        if(ms > 0) {\r
-            SetTimer(tbl->hwnd, (UINT_PTR) r, ms + 100, cw_timer_proc);\r
+        nflags = cw_get_buf_exp_flags(tbl, (khm_handle) o->data);\r
+        if ((o->flags & CW_EXPSTATE_MASK) != nflags) {\r
+            cw_update_outline(tbl);\r
+            InvalidateRect(tbl->hwnd, NULL, FALSE);\r
+        } else {\r
+            RECT rc, rr, ri;\r
+\r
+            GetClientRect(tbl->hwnd, &rc);\r
+            rc.top += tbl->header_height;\r
+\r
+            rr = r->r_ext;\r
+            OffsetRect(&rr, 0, tbl->header_height - tbl->scr_top);\r
+\r
+            if (IntersectRect(&ri, &rc, &rr))\r
+                InvalidateRect(tbl->hwnd, &ri, FALSE);\r
+\r
+            cwi = cw_find_ident(tbl, o->data);\r
+\r
+            GetSystemTimeAsFileTime(&ft_now);\r
+            if (CompareFileTime(&cwi->ft_expire, &ft_now) > 0) {\r
+                ft = FtSub(&cwi->ft_expire, &ft_now);\r
+                ms = FtIntervalMsToRepChange(&ft);\r
+                if (ms > 0) {\r
+                    SetTimer(tbl->hwnd, (UINT_PTR) r, ms + 100, cw_timer_proc);\r
+                    timer_set = 1;\r
+                }\r
+            }\r
+\r
+            if (timer_set)\r
+                r->flags |= KHUI_CW_ROW_TIMERSET;\r
         }\r
     }\r
 }\r
@@ -1053,9 +1275,38 @@ cw_set_tbl_row_header(khui_credwnd_tbl * tbl,
     tbl->rows[row].flags = KHUI_CW_ROW_HEADER;\r
     if(o->flags & KHUI_CW_O_SELECTED)\r
         tbl->rows[row].flags |= KHUI_CW_ROW_SELECTED;\r
+\r
+    /* if we are showing expanded identity information, we need to set\r
+       a timer so that we can update the identity row when the\r
+       identity changes. */\r
     if ((tbl->flags & KHUI_CW_TBL_EXPIDENT) &&\r
-        tbl->cols[col].attr_id == KCDB_ATTR_ID_NAME)\r
+        tbl->cols[col].attr_id == KCDB_ATTR_ID_NAME) {\r
+\r
+        khui_credwnd_ident * cwi;\r
+\r
         tbl->rows[row].flags |= KHUI_CW_ROW_EXPVIEW;\r
+\r
+        cwi = cw_find_ident(tbl, o->data);\r
+        if (cwi && FtToInt(&cwi->ft_expire) != 0) {\r
+            FILETIME ft;\r
+            FILETIME ft_now;\r
+\r
+            ft = cwi->ft_expire;\r
+            GetSystemTimeAsFileTime(&ft_now);\r
+\r
+            if (CompareFileTime(&ft, &ft_now) > 0) {\r
+                long ms;\r
+\r
+                ft = FtSub(&ft, &ft_now);\r
+                ms = FtIntervalMsToRepChange(&ft);\r
+                if (ms > 0) {\r
+                    SetTimer(tbl->hwnd, (UINT_PTR) &(tbl->rows[row]), ms + 100,\r
+                             cw_timer_proc);\r
+                    tbl->rows[row].flags |= KHUI_CW_ROW_TIMERSET;\r
+                }\r
+            }\r
+        }\r
+    }\r
 }\r
 \r
 static int \r
@@ -1329,25 +1580,6 @@ cw_update_outline(khui_credwnd_tbl * tbl)
             ol->flags &= ~KHUI_CW_O_SHOWFLAG;\r
             ol->flags &= ~KHUI_CW_O_STICKY;\r
 \r
-            if (grouping[j] == tbl->n_cols - 1) {\r
-                ol->flags |= KHUI_CW_O_NOOUTLINE;\r
-            } else {\r
-                ol->flags &= ~KHUI_CW_O_NOOUTLINE;\r
-            }\r
-\r
-            if(selected) {\r
-                ol->flags |= KHUI_CW_O_SELECTED;\r
-            }\r
-            if(visible) {\r
-                cw_set_tbl_row_header(tbl, n_rows, grouping[j], ol);\r
-                n_rows ++;\r
-                ol->flags |= KHUI_CW_O_VISIBLE;\r
-            } else {\r
-                ol->flags &= ~KHUI_CW_O_VISIBLE;\r
-            }\r
-            visible = visible && (ol->flags & KHUI_CW_O_EXPAND);\r
-            selected = (selected || (ol->flags & KHUI_CW_O_SELECTED));\r
-\r
             /* if the outline node is for an identity, then we have to\r
                check the expiration state for the identity. */\r
 \r
@@ -1368,6 +1600,26 @@ cw_update_outline(khui_credwnd_tbl * tbl)
                     ol->flags |= KHUI_CW_O_SHOWFLAG;\r
                 }\r
             }\r
+\r
+            if (grouping[j] == tbl->n_cols - 1) {\r
+                ol->flags |= KHUI_CW_O_NOOUTLINE;\r
+            } else {\r
+                ol->flags &= ~KHUI_CW_O_NOOUTLINE;\r
+            }\r
+\r
+            if(selected) {\r
+                ol->flags |= KHUI_CW_O_SELECTED;\r
+            }\r
+            if(visible) {\r
+                cw_set_tbl_row_header(tbl, n_rows, grouping[j], ol);\r
+                n_rows ++;\r
+                ol->flags |= KHUI_CW_O_VISIBLE;\r
+            } else {\r
+                ol->flags &= ~KHUI_CW_O_VISIBLE;\r
+            }\r
+            visible = visible && (ol->flags & KHUI_CW_O_EXPAND);\r
+            selected = (selected || (ol->flags & KHUI_CW_O_SELECTED));\r
+\r
         }\r
 \r
         /* we need to do this here too just in case we were already at\r
@@ -1375,20 +1627,23 @@ cw_update_outline(khui_credwnd_tbl * tbl)
         if (ol)\r
             visible = visible && (ol->flags & KHUI_CW_O_EXPAND);\r
 \r
-        flags = cw_get_buf_exp_flags(tbl, thiscred);\r
-\r
         if(visible && grouping[n_grouping - 1] < tbl->n_cols - 1) {\r
             khm_int32 c_flags;\r
 \r
             cw_set_tbl_row_cred(tbl, n_rows, thiscred, \r
                                 grouping[n_grouping-1]);\r
-            kcdb_cred_get_flags(thiscred, &c_flags);\r
+\r
+            flags = cw_get_buf_exp_flags(tbl, thiscred);\r
             if(flags) {\r
                 tbl->rows[n_rows].flags |= flags;\r
             }\r
+\r
+            kcdb_cred_get_flags(thiscred, &c_flags);\r
             if(selected ||\r
-               (c_flags & KCDB_CRED_FLAG_SELECTED))\r
+               (c_flags & KCDB_CRED_FLAG_SELECTED)) {\r
                 tbl->rows[n_rows].flags |= KHUI_CW_ROW_SELECTED;\r
+            }\r
+\r
             tbl->rows[n_rows].idx_start = i;\r
             tbl->rows[n_rows].idx_end = i;\r
 \r
@@ -1519,10 +1774,10 @@ _exit:
      * we have expiration states set for any active identities */\r
     if (n_creds == 0)\r
         khm_notify_icon_expstate(KHM_NOTIF_EMPTY);\r
-    else if (expstate & CW_EXPSTATE_EXPIRED)\r
+    else if ((expstate & CW_EXPSTATE_EXPIRED) == CW_EXPSTATE_EXPIRED)\r
         khm_notify_icon_expstate(KHM_NOTIF_EXP);\r
-    else if ((expstate & CW_EXPSTATE_WARN) ||\r
-             (expstate & CW_EXPSTATE_CRITICAL))\r
+    else if ((expstate & CW_EXPSTATE_WARN) == CW_EXPSTATE_WARN ||\r
+             (expstate & CW_EXPSTATE_CRITICAL) == CW_EXPSTATE_CRITICAL)\r
         khm_notify_icon_expstate(KHM_NOTIF_WARN);\r
     else\r
         khm_notify_icon_expstate(KHM_NOTIF_OK);\r
@@ -1543,18 +1798,30 @@ cw_unload_view(khui_credwnd_tbl * tbl)
     SafeDeleteObject(tbl->hf_normal);\r
     SafeDeleteObject(tbl->hf_bold);\r
     SafeDeleteObject(tbl->hf_bold_header);\r
+\r
     SafeDeleteObject(tbl->hb_grey);\r
     SafeDeleteObject(tbl->hb_normal);\r
-    SafeDeleteObject(tbl->hb_sel);\r
+    SafeDeleteObject(tbl->hb_s);\r
+\r
     SafeDeleteObject(tbl->hb_hdr_bg);\r
-    SafeDeleteObject(tbl->hb_hdr_bg_sel);\r
     SafeDeleteObject(tbl->hb_hdr_bg_crit);\r
     SafeDeleteObject(tbl->hb_hdr_bg_exp);\r
     SafeDeleteObject(tbl->hb_hdr_bg_warn);\r
     SafeDeleteObject(tbl->hb_hdr_bg_def);\r
 \r
+    SafeDeleteObject(tbl->hb_hdr_bg_s);\r
+    SafeDeleteObject(tbl->hb_hdr_bg_crit_s);\r
+    SafeDeleteObject(tbl->hb_hdr_bg_exp_s);\r
+    SafeDeleteObject(tbl->hb_hdr_bg_warn_s);\r
+    SafeDeleteObject(tbl->hb_hdr_bg_def_s);\r
+\r
 #undef SafeDeleteObject\r
 \r
+    if (tbl->hi_lg_ident) {\r
+        DestroyIcon(tbl->hi_lg_ident);\r
+        tbl->hi_lg_ident = NULL;\r
+    }\r
+\r
     if(tbl->credset) {\r
         kcdb_credset_delete(tbl->credset);\r
         tbl->credset = NULL;\r
@@ -1679,19 +1946,71 @@ cw_get_cell_height(HDC hdc, HFONT hf) {
     return size.cy;\r
 }\r
 \r
+int\r
+cw_update_header_column_width(khui_credwnd_tbl * tbl, int c) {\r
+    int idx;\r
+    HDITEM hi;\r
+\r
+#ifdef DEBUG\r
+    assert(c >= 0 && c < tbl->n_cols);\r
+#endif\r
+\r
+    if (tbl->hwnd_header == NULL)\r
+        return 0;\r
+\r
+    idx = Header_OrderToIndex(tbl->hwnd_header, c);\r
+    ZeroMemory(&hi, sizeof(hi));\r
+    hi.mask = HDI_WIDTH;\r
+    hi.cxy = tbl->cols[c].width;\r
+    return Header_SetItem(tbl->hwnd_header, idx, &hi);\r
+}\r
+\r
 /* returns a bitmask indicating which measures were changed */\r
 int \r
 cw_update_extents(khui_credwnd_tbl * tbl, \r
                   khm_boolean update_scroll) {\r
-    int ext_x, ext_y;\r
+    int ext_x = 0;\r
+    int ext_y = 0;\r
     int i;\r
+    int filler_col = -1;\r
+    int fill_adjusted = 0;\r
+\r
+ recompute_columns:\r
 \r
     ext_x = 0;\r
     for(i=0; i < (int) tbl->n_cols; i++) {\r
         tbl->cols[i].x = ext_x;\r
+        if (tbl->cols[i].flags & KHUI_CW_COL_FILLER) {\r
+            if (filler_col == -1)\r
+                filler_col = i;\r
+        }\r
         ext_x += tbl->cols[i].width;\r
     }\r
 \r
+    if (filler_col != -1 && !fill_adjusted) {\r
+        RECT r;\r
+        int delta;\r
+\r
+        GetClientRect(tbl->hwnd, &r);\r
+\r
+        /* we decrement the width so that the width data area is\r
+           strictly less than the width of the client area.  Windows\r
+           doesn't disable a scrollbar unless the range is strictly\r
+           less than the page size. */\r
+        delta = ((r.right - r.left) - 1) - ext_x;\r
+\r
+        if (tbl->cols[filler_col].width + delta <= GetSystemMetrics(SM_CXSMICON)) {\r
+            tbl->cols[filler_col].width = GetSystemMetrics(SM_CXICON);\r
+        } else {\r
+            tbl->cols[filler_col].width += delta;\r
+        }\r
+\r
+        cw_update_header_column_width(tbl, filler_col);\r
+\r
+        fill_adjusted = 1;\r
+        goto recompute_columns;\r
+    }\r
+\r
     if(!tbl->cell_height) {\r
         HDC dc;\r
         int maxheight = 0;\r
@@ -1716,16 +2035,35 @@ cw_update_extents(khui_credwnd_tbl * tbl,
     }\r
 \r
     if (tbl->flags & KHUI_CW_TBL_EXPIDENT) {\r
+        RECT r;\r
+\r
         ext_y = 0;\r
+        r.left = 0;\r
+        r.right = ext_x;\r
 \r
         for (i=0; i < (int) tbl->n_rows; i++) {\r
+            r.top = ext_y;\r
             if (tbl->rows[i].flags & KHUI_CW_ROW_EXPVIEW) {\r
                 ext_y += tbl->cell_height * CW_EXP_ROW_MULT;\r
             } else {\r
                 ext_y += tbl->cell_height;\r
             }\r
+            r.bottom = ext_y;\r
+            tbl->rows[i].r_ext = r;\r
         }\r
     } else {\r
+        RECT r;\r
+\r
+        r.left = 0;\r
+        r.right = ext_x;\r
+\r
+        for (i=0; i < (int) tbl->n_rows; i++) {\r
+            r.top = i * tbl->cell_height;\r
+            r.bottom = r.top + tbl->cell_height;\r
+\r
+            tbl->rows[i].r_ext = r;\r
+        }\r
+\r
         ext_y = (int) tbl->n_rows * tbl->cell_height;\r
     }\r
 \r
@@ -1848,7 +2186,7 @@ cw_erase_rect(HDC hdc,
         break;\r
 \r
     case CW_ER_SEL:\r
-        hbr = tbl->hb_sel;\r
+        hbr = tbl->hb_s;\r
         break;\r
 \r
     default:\r
@@ -1936,18 +2274,30 @@ cw_draw_header(HDC hdc,
 \r
     {\r
         HBRUSH hbr;\r
-        if(selected)\r
-            hbr = tbl->hb_hdr_bg_sel;\r
-        else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_EXPIRED)\r
-            hbr = tbl->hb_hdr_bg_exp;\r
-        else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_CRITICAL)\r
-            hbr = tbl->hb_hdr_bg_crit;\r
-        else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_WARN)\r
-            hbr = tbl->hb_hdr_bg_warn;\r
-        else if (idf & KCDB_IDENT_FLAG_DEFAULT)\r
-            hbr = tbl->hb_hdr_bg_def;\r
-        else\r
-            hbr = tbl->hb_hdr_bg;\r
+\r
+        if(selected) {\r
+            if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_EXPIRED)\r
+                hbr = tbl->hb_hdr_bg_exp_s;\r
+            else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_CRITICAL)\r
+                hbr = tbl->hb_hdr_bg_crit_s;\r
+            else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_WARN)\r
+                hbr = tbl->hb_hdr_bg_warn_s;\r
+            else if (idf & KCDB_IDENT_FLAG_DEFAULT)\r
+                hbr = tbl->hb_hdr_bg_def_s;\r
+            else\r
+                hbr = tbl->hb_hdr_bg_s;\r
+        } else {\r
+            if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_EXPIRED)\r
+                hbr = tbl->hb_hdr_bg_exp;\r
+            else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_CRITICAL)\r
+                hbr = tbl->hb_hdr_bg_crit;\r
+            else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_WARN)\r
+                hbr = tbl->hb_hdr_bg_warn;\r
+            else if (idf & KCDB_IDENT_FLAG_DEFAULT)\r
+                hbr = tbl->hb_hdr_bg_def;\r
+            else\r
+                hbr = tbl->hb_hdr_bg;\r
+        }\r
 \r
         FillRect(hdc, r, hbr);\r
     }\r
@@ -1968,25 +2318,21 @@ cw_draw_header(HDC hdc,
             if(o->flags & KHUI_CW_O_EXPAND) {\r
                 khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND_HI,\r
                                    hdc, r->left,\r
-                                   r->bottom - (KHUI_SMICON_CY +\r
-                                                (r->bottom - (r->top + KHUI_SMICON_CY)) / 2), 0);\r
+                                   (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
             } else {\r
                 khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE_HI,\r
                                    hdc, r->left,\r
-                                   r->bottom - (KHUI_SMICON_CY +\r
-                                                (r->bottom - (r->top + KHUI_SMICON_CY)) / 2), 0);\r
+                                   (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
             }\r
         } else {\r
             if(o->flags & KHUI_CW_O_EXPAND) {\r
                 khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND,\r
                                    hdc, r->left,\r
-                                   r->bottom - (KHUI_SMICON_CY +\r
-                                                (r->bottom - (r->top + KHUI_SMICON_CY)) / 2), 0);\r
+                                   (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
             } else {\r
                 khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE,\r
                                    hdc, r->left,\r
-                                   r->bottom - (KHUI_SMICON_CY +\r
-                                                (r->bottom - (r->top + KHUI_SMICON_CY)) / 2), 0);\r
+                                   (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
             }\r
         }\r
 \r
@@ -2007,22 +2353,30 @@ cw_draw_header(HDC hdc,
                              IDB_WDG_STICK)),\r
                            hdc,\r
                            r->left,\r
-                           r->bottom - (KHUI_SMICON_CY +\r
-                                        (r->bottom - (r->top + KHUI_SMICON_CY)) / 2),\r
-                           0);\r
+                           (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
 \r
         r->left += KHUI_SMICON_CX * 3 / 2;\r
 \r
-        khui_ilist_draw_id(tbl->ilist, \r
-                           ((o->flags & KHUI_CW_O_STICKY)?\r
-                            IDB_ID_DIS_SM:\r
-                            IDB_ID_SM), \r
-                           hdc, \r
-                           r->left,\r
-                           r->bottom - (KHUI_SMICON_CY +\r
-                                        (r->bottom - (r->top + KHUI_SMICON_CY)) / 2), \r
-                           0);\r
-        r->left += KHUI_SMICON_CX * 3 / 2 ;\r
+        /* the TRUE part of the 'if' is for drawing large icons.  It's\r
+           disabled for now until we have new icons. */\r
+        if ((cr->flags & KHUI_CW_ROW_EXPVIEW) && FALSE) {\r
+            int cx = GetSystemMetrics(SM_CXICON);\r
+            int cy = GetSystemMetrics(SM_CYICON);\r
+\r
+            DrawIcon(hdc, r->left, (r->top + r->bottom - cy) / 2, tbl->hi_lg_ident);\r
+\r
+            r->left += cx + KHUI_SMICON_CX / 2;\r
+\r
+        } else {\r
+            khui_ilist_draw_id(tbl->ilist, \r
+                               ((o->flags & KHUI_CW_O_STICKY)?\r
+                                IDB_ID_DIS_SM:\r
+                                IDB_ID_SM), \r
+                               hdc, \r
+                               r->left,\r
+                               (r->top + r->bottom - KHUI_SMICON_CY) / 2, 0);\r
+            r->left += KHUI_SMICON_CX * 3 / 2 ;\r
+        }\r
     }\r
 \r
 \r
@@ -2031,7 +2385,7 @@ cw_draw_header(HDC hdc,
         SetTextAlign(hdc, TA_BOTTOM | TA_LEFT);\r
 \r
         if(selected)\r
-            SetTextColor(hdc, tbl->cr_hdr_sel);\r
+            SetTextColor(hdc, tbl->cr_hdr_s);\r
         else\r
             SetTextColor(hdc, tbl->cr_hdr_normal);\r
 \r
@@ -2057,64 +2411,81 @@ cw_draw_header(HDC hdc,
 \r
         RECT tr;\r
         int len;\r
+        wchar_t typestr[128];\r
+        int cx_id;\r
+        SIZE size;\r
+        khui_credwnd_ident * cwi;\r
 \r
         /* expanded view */\r
 #ifdef DEBUG\r
         assert(colattr == KCDB_ATTR_ID_NAME);\r
 #endif\r
 \r
+        cwi = cw_find_ident(tbl, o->data);\r
+\r
         CopyRect(&tr, r);\r
         tr.bottom -= (tr.bottom - tr.top) / 2; /* drawing two lines of text */\r
 \r
         if (selected)\r
-            SetTextColor(hdc, tbl->cr_hdr_sel);\r
+            SetTextColor(hdc, tbl->cr_hdr_s);\r
         else\r
             SetTextColor(hdc, tbl->cr_hdr_normal);\r
 \r
         len = (int) wcslen(o->header);\r
         DrawText(hdc, o->header, len, &tr, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);\r
+        GetTextExtentPoint32(hdc, o->header, (int) len, &size);\r
+        cx_id = size.cx;\r
+\r
+        typestr[0] = L'\0';\r
 \r
         if ((idf & KCDB_IDENT_FLAG_DEFAULT)) {\r
-            SIZE size;\r
-            int cx_id;\r
-            int cx_def;\r
-            wchar_t defstr[64];\r
+            if (cwi && cwi->credtype_name[0]) {\r
+                wchar_t fmt[64];\r
 \r
-            LoadString(khm_hInstance, IDS_CW_DEFAULT,\r
-                       defstr, ARRAYLENGTH(defstr));\r
+                LoadString(khm_hInstance, IDS_CW_DEFAULTTF,\r
+                           fmt, ARRAYLENGTH(fmt));\r
+                StringCbPrintf(typestr, sizeof(typestr), fmt,\r
+                               cwi->credtype_name);\r
+            } else {\r
+                LoadString(khm_hInstance, IDS_CW_DEFAULT,\r
+                           typestr, ARRAYLENGTH(typestr));\r
+            }\r
+        } else if (cwi && cwi->credtype_name[0]) {\r
+            wchar_t fmt[64];\r
 \r
-            GetTextExtentPoint32(hdc, o->header, (int) len, &size);\r
-            cx_id = size.cx;\r
+            LoadString(khm_hInstance, IDS_CW_TYPEF,\r
+                       fmt, ARRAYLENGTH(fmt));\r
+            StringCbPrintf(typestr, sizeof(typestr), fmt,\r
+                           cwi->credtype_name);\r
+        }\r
+\r
+        if (typestr[0]) {\r
+            int cx_str;\r
 \r
-            len = (int) wcslen(defstr);\r
-            GetTextExtentPoint32(hdc, defstr, (int) len, &size);\r
-            cx_def = size.cx + KHUI_SMICON_CX / 2;\r
+            len = (int) wcslen(typestr);\r
+            GetTextExtentPoint32(hdc, typestr, (int) len, &size);\r
+            cx_str = size.cx + KHUI_SMICON_CX / 2;\r
 \r
-            tr.left = max(tr.right - cx_def, tr.left + cx_id + KHUI_SMICON_CX * 2);\r
+            tr.left = max(tr.right - cx_str, tr.left + cx_id + KHUI_SMICON_CX * 2);\r
             if (selected)\r
-                SetTextColor(hdc, tbl->cr_hdr_gray_sel);\r
+                SetTextColor(hdc, tbl->cr_hdr_gray_s);\r
             else\r
                 SetTextColor(hdc, tbl->cr_hdr_gray);\r
-            DrawText(hdc, defstr, len, &tr, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);\r
+            DrawText(hdc, typestr, len, &tr, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);\r
         }\r
 \r
         CopyRect(&tr, r);\r
         tr.top += (tr.bottom - tr.top) / 2;\r
 \r
-        if (0) {\r
-            khm_size i;\r
+        if (1) {\r
             wchar_t buf[128];\r
+            khui_credwnd_ident * cwi;\r
 \r
-            for (i = 0; i < tbl->n_idents; i++) {\r
-                if (kcdb_identity_is_equal(o->data, tbl->idents[i].ident))\r
-                    break;\r
-            }\r
-\r
-            if (i < tbl->n_idents) {\r
-                khui_credwnd_ident * cwi;\r
-\r
-                cwi = &tbl->idents[i];\r
+            buf[0] = L'\0';\r
+            cwi = cw_find_ident(tbl, o->data);\r
 \r
+            if (cwi) {\r
+#ifdef SHOW_CREDENTIAL_COUNTS\r
                 if (cwi->credcount == 0)\r
                     LoadString(khm_hInstance, IDS_IDEXPDISP_NOCRED,\r
                                buf, ARRAYLENGTH(buf));\r
@@ -2127,15 +2498,40 @@ cw_draw_header(HDC hdc,
                                fmt, ARRAYLENGTH(fmt));\r
                     StringCbPrintf(buf, sizeof(buf), fmt, (int) cwi->credcount);\r
                 }\r
-            }\r
+#else\r
+                if (FtToInt(&cwi->ft_expire) != 0) {\r
+                    FILETIME ft_now;\r
+\r
+                    GetSystemTimeAsFileTime(&ft_now);\r
+                    if (CompareFileTime(&cwi->ft_expire, &ft_now) > 0) {\r
+                        wchar_t fmt[64];\r
+                        wchar_t intstr[128];\r
+                        FILETIME ft;\r
+                        khm_size cb;\r
+\r
+                        ft = FtSub(&cwi->ft_expire, &ft_now);\r
+                        intstr[0] = L'\0';\r
+                        cb = sizeof(intstr);\r
+                        FtIntervalToString(&ft, intstr, &cb);\r
+\r
+                        LoadString(khm_hInstance, IDS_CW_EXPIREF,\r
+                                   fmt, ARRAYLENGTH(fmt));\r
+                        StringCbPrintf(buf, sizeof(buf), fmt, intstr);\r
+                    } else {\r
+                        LoadString(khm_hInstance, IDS_CW_EXPIRED,\r
+                                   buf, ARRAYLENGTH(buf));\r
+                    }\r
+                }\r
+#endif\r
 \r
-            len = (int) wcslen(buf);\r
+                len = (int) wcslen(buf);\r
 \r
-            if (selected)\r
-                SetTextColor(hdc, tbl->cr_hdr_gray_sel);\r
-            else\r
-                SetTextColor(hdc, tbl->cr_hdr_gray);\r
-            DrawText(hdc, buf, len, &tr, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);\r
+                if (selected)\r
+                    SetTextColor(hdc, tbl->cr_hdr_gray_s);\r
+                else\r
+                    SetTextColor(hdc, tbl->cr_hdr_gray);\r
+                DrawText(hdc, buf, len, &tr, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);\r
+            }\r
         }\r
     }\r
 }\r
@@ -2160,6 +2556,8 @@ cw_handle_header_msg(khui_credwnd_tbl * tbl, LPNMHEADER ph) {
         }\r
 \r
     case HDN_TRACK:\r
+        return FALSE;\r
+\r
     case HDN_ENDTRACK:\r
         {\r
             int width;\r
@@ -2182,7 +2580,7 @@ cw_handle_header_msg(khui_credwnd_tbl * tbl, LPNMHEADER ph) {
             hi.mask = HDI_ORDER;\r
             Header_GetItem(tbl->hwnd_header, ph->iItem, &hi);\r
 \r
-            if (tbl->cols[hi.iOrder].flags & KHUI_CW_COL_FIXED_WIDTH) {\r
+            if (tbl->cols[hi.iOrder].flags & KHUI_CW_COL_FIXED_POS) {\r
                 return TRUE;\r
             } else {\r
                 return FALSE;\r
@@ -2215,7 +2613,7 @@ cw_handle_header_msg(khui_credwnd_tbl * tbl, LPNMHEADER ph) {
 \r
             /* we don't allow dragging in to the "fixed" area. */\r
             for (i=0; i < tbl->n_cols; i++) {\r
-                if (tbl->cols[i].attr_id >= 0)\r
+                if (!(tbl->cols[i].flags & KHUI_CW_COL_FIXED_POS))\r
                     break;\r
             }\r
 \r
@@ -2305,7 +2703,10 @@ cw_handle_header_msg(khui_credwnd_tbl * tbl, LPNMHEADER ph) {
             Header_GetItem(tbl->hwnd_header, ph->iItem, &hi);\r
             idx = hi.iOrder;\r
 \r
-            if (idx == 0 || idx >= tbl->n_cols)\r
+            if (idx < 0 || idx >= tbl->n_cols)\r
+                return FALSE;\r
+\r
+            if (tbl->cols[idx].flags & KHUI_CW_COL_META)\r
                 return FALSE;\r
 \r
             if (tbl->cols[idx].flags &\r
@@ -2511,6 +2912,7 @@ cw_wm_create(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
     cw_update_creds(tbl);\r
     cw_update_outline(tbl);\r
+    cw_update_selection_state(tbl);\r
     cw_update_extents(tbl, FALSE);\r
 \r
     {\r
@@ -2685,9 +3087,9 @@ cw_wm_paint(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
                 cw_draw_header(hdc, tbl, i, &rh);\r
             }\r
-            \r
+\r
             if(selected)\r
-                SetTextColor(hdc, tbl->cr_sel);\r
+                SetTextColor(hdc, tbl->cr_s);\r
             else\r
                 SetTextColor(hdc, tbl->cr_normal);\r
 \r
@@ -2955,6 +3357,7 @@ cw_kmq_wm_dispatch(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
+            cw_update_selection_state(tbl);\r
             cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
@@ -3121,6 +3524,51 @@ cw_select_outline(khui_credwnd_outline * o,
         o->flags &= ~KHUI_CW_O_SELECTED;\r
 }\r
 \r
+static void\r
+cw_select_cred_row(khui_credwnd_tbl * tbl, int row, int selected) {\r
+\r
+    khm_size j;\r
+    khm_size idx_start, idx_end;\r
+\r
+#ifdef DEBUG\r
+    assert(row >= 0 && row < tbl->n_rows);\r
+#endif\r
+\r
+    if (row >= tbl->n_rows)\r
+        return;\r
+\r
+    if (tbl->rows[row].flags & KHUI_CW_ROW_HEADER) {\r
+        khui_credwnd_outline * o;\r
+\r
+        o = (khui_credwnd_outline *) tbl->rows[row].data;\r
+        if (o->col == tbl->n_cols - 1) {\r
+            /* this is a special case where the outline column is the\r
+               last displayed column.  In this case, the credentials\r
+               do not occupy any rows, and this header row acts as a\r
+               group credential row. */\r
+            idx_start = o->idx_start;\r
+            idx_end = o->idx_end;\r
+        } else {\r
+            return;\r
+        }\r
+    } else {\r
+        idx_start = tbl->rows[row].idx_start;\r
+        idx_end = tbl->rows[row].idx_end;\r
+    }\r
+\r
+    for (j = idx_start; j <= idx_end; j++) {\r
+        khm_handle cred = NULL;\r
+\r
+        kcdb_credset_get_cred(tbl->credset, (khm_int32) j, &cred);\r
+\r
+        if (cred) {\r
+            kcdb_cred_set_flags(cred, ((selected)?KCDB_CRED_FLAG_SELECTED:0),\r
+                                KCDB_CRED_FLAG_SELECTED);\r
+            kcdb_cred_release(cred);\r
+        }\r
+    }\r
+}\r
+\r
 static void \r
 cw_unselect_all(khui_credwnd_tbl * tbl)\r
 {\r
@@ -3128,10 +3576,10 @@ cw_unselect_all(khui_credwnd_tbl * tbl)
 \r
     for(i=0; i<tbl->n_rows; i++) {\r
         tbl->rows[i].flags &= ~KHUI_CW_ROW_SELECTED;\r
-        if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER))\r
-            kcdb_cred_set_flags((khm_handle) tbl->rows[i].data,\r
-                                0,\r
-                                KCDB_CRED_FLAG_SELECTED);\r
+\r
+        if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) {\r
+            cw_select_cred_row(tbl, i, FALSE);\r
+        }\r
     }\r
 \r
     cw_select_outline_level(tbl->outline, FALSE);\r
@@ -3352,9 +3800,7 @@ cw_select_all(khui_credwnd_tbl * tbl)
     for(i=0; i<tbl->n_rows; i++) {\r
         tbl->rows[i].flags |= KHUI_CW_ROW_SELECTED;\r
         if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER))\r
-            kcdb_cred_set_flags((khm_handle) tbl->rows[i].data,\r
-                                KCDB_CRED_FLAG_SELECTED,\r
-                                KCDB_CRED_FLAG_SELECTED);\r
+            cw_select_cred_row(tbl, i, TRUE);\r
     }\r
 \r
     cw_select_outline_level(tbl->outline, TRUE);\r
@@ -3410,11 +3856,7 @@ cw_select_row(khui_credwnd_tbl * tbl, int row, WPARAM wParam)
 \r
         for (i = group_begin; i <= group_end; i++) {\r
             tbl->rows[i].flags |= KHUI_CW_ROW_SELECTED;\r
-            if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) {\r
-                kcdb_cred_set_flags((khm_handle) tbl->rows[i].data,\r
-                                    KCDB_CRED_FLAG_SELECTED,\r
-                                    KCDB_CRED_FLAG_SELECTED);\r
-            }\r
+            cw_select_cred_row(tbl, i, TRUE);\r
         }\r
     } else if (toggle) {\r
         BOOL select;\r
@@ -3430,11 +3872,7 @@ cw_select_row(khui_credwnd_tbl * tbl, int row, WPARAM wParam)
             else\r
                 tbl->rows[i].flags &= ~KHUI_CW_ROW_SELECTED;\r
 \r
-            if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) {\r
-                kcdb_cred_set_flags((khm_handle) tbl->rows[i].data,\r
-                                    (select)?KCDB_CRED_FLAG_SELECTED:0,\r
-                                    KCDB_CRED_FLAG_SELECTED);\r
-            }\r
+            cw_select_cred_row(tbl, i, select);\r
         }\r
     } else if (extend) {\r
         int range_begin;\r
@@ -3448,11 +3886,7 @@ cw_select_row(khui_credwnd_tbl * tbl, int row, WPARAM wParam)
         for (i = range_begin; i <= range_end; i++) {\r
             tbl->rows[i].flags |= KHUI_CW_ROW_SELECTED;\r
 \r
-            if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) {\r
-                kcdb_cred_set_flags((khm_handle) tbl->rows[i].data,\r
-                                    KCDB_CRED_FLAG_SELECTED,\r
-                                    KCDB_CRED_FLAG_SELECTED);\r
-            }\r
+            cw_select_cred_row(tbl, i, TRUE);\r
         }\r
 \r
         tbl->cursor_row = row;\r
@@ -4549,6 +4983,7 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
+            cw_update_selection_state(tbl);\r
             cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
@@ -4565,7 +5000,8 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
-            cw_update_extents(tbl, FALSE);\r
+            cw_update_selection_state(tbl);\r
+            cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
 \r
@@ -4584,7 +5020,8 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
-            cw_update_extents(tbl, FALSE);\r
+            cw_update_selection_state(tbl);\r
+            cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
 \r
@@ -4604,7 +5041,8 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
-            cw_update_extents(tbl, FALSE);\r
+            cw_update_selection_state(tbl);\r
+            cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
 \r
@@ -4624,7 +5062,8 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
-            cw_update_extents(tbl, FALSE);\r
+            cw_update_selection_state(tbl);\r
+            cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
 \r
@@ -4644,7 +5083,8 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 \r
             cw_update_creds(tbl);\r
             cw_update_outline(tbl);\r
-            cw_update_extents(tbl, FALSE);\r
+            cw_update_selection_state(tbl);\r
+            cw_update_extents(tbl, TRUE);\r
 \r
             InvalidateRect(tbl->hwnd, NULL, TRUE);\r
         }\r
@@ -5040,7 +5480,7 @@ khm_create_credwnd(HWND parent) {
         (0,\r
          MAKEINTATOM(khui_credwnd_cls),\r
          L"",\r
-         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,\r
+         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | WS_CLIPCHILDREN,\r
          r.left,\r
          r.top,\r
          r.right - r.left,\r
index 3d39ebc4f1d796f0e60e1ff7e96300520f4a7bf1..42edf2842b5f8678a43c26b2ad74e465c348fbac 100644 (file)
@@ -75,6 +75,7 @@ typedef struct khui_credwnd_row_t {
     khm_handle  data;\r
     khm_size idx_start;\r
     khm_size idx_end;\r
+    RECT        r_ext;          /* extents of this row */\r
 } khui_credwnd_row;\r
 \r
 #define KHUI_CW_ROW_CRED        0x00000002\r
@@ -111,6 +112,7 @@ typedef struct khui_credwnd_col_t {
 #define KHUI_CW_COL_FIXED_WIDTH 0x00000010\r
 #define KHUI_CW_COL_FIXED_POS   0x00000020\r
 #define KHUI_CW_COL_META        0x00000040\r
+#define KHUI_CW_COL_FILLER      0x00000080\r
 \r
 /* Custom column attributes (are not kcdb attributes) */\r
 #define CW_CA_FLAGS -1\r
@@ -129,7 +131,12 @@ typedef struct tag_khui_credwnd_ident {
     wchar_t    name[KCDB_IDENT_MAXCCH_NAME];\r
     wchar_t    credtype_name[KCDB_MAXCCH_NAME];\r
 \r
-    khm_size   credcount;\r
+    khm_size   credcount;       /* count of all credentials */\r
+    khm_size   id_credcount;    /* count of identity credentials\r
+                                   (credentials that are of the\r
+                                   identity type */\r
+    khm_size   init_credcount;  /* count of initial credentials */\r
+    FILETIME   ft_expire;\r
 \r
 } khui_credwnd_ident;\r
 \r
@@ -181,25 +188,37 @@ typedef struct khui_credwnd_tbl_t {
     HFONT hf_header;        /* header text */\r
     HFONT hf_bold;          /* bold text */\r
     HFONT hf_bold_header;   /* bold header text */\r
+\r
     HBRUSH hb_normal;       /* normal background brush */\r
-    HBRUSH hb_grey;         /* normal grey background brush */\r
-    HBRUSH hb_sel;          /* selected background brush */\r
+    HBRUSH hb_grey;         /* normal background brush (greyed) */\r
+    HBRUSH hb_s;            /* normal background brush (selected) */\r
+\r
+    HBRUSH hb_hdr_bg;       /* header background brush (normal) */\r
+    HBRUSH hb_hdr_bg_exp;   /* header background brush (expired) */\r
+    HBRUSH hb_hdr_bg_warn;  /* header background brush (warn) */\r
+    HBRUSH hb_hdr_bg_crit;  /* header background brush (critical) */\r
+    HBRUSH hb_hdr_bg_def;   /* header background brush (default) */\r
+\r
+    HBRUSH hb_hdr_bg_s;     /* header background brush (selected) */\r
+    HBRUSH hb_hdr_bg_exp_s; /* header background brush (expired,selected) */\r
+    HBRUSH hb_hdr_bg_warn_s;/* header background brush (warn,selected) */\r
+    HBRUSH hb_hdr_bg_crit_s;/* header background brush (critical,selected) */\r
+    HBRUSH hb_hdr_bg_def_s; /* header background brush (default,selected) */\r
+\r
+    COLORREF cr_normal;     /* text color (normal) */\r
+    COLORREF cr_s;          /* text color (selected) */\r
+    COLORREF cr_hdr_normal; /* header text color (normal) */\r
+    COLORREF cr_hdr_s;      /* header text color (selected) */\r
+    COLORREF cr_hdr_gray;   /* header text color (greyed) */\r
+    COLORREF cr_hdr_gray_s; /* header text color (greyed,selected) */\r
+\r
     COLORREF cr_hdr_outline;/* header outline color */\r
-    COLORREF cr_normal;     /* normal text color */\r
-    COLORREF cr_sel;        /* selected text color */\r
-    COLORREF cr_hdr_normal; /* normal header text color */\r
-    COLORREF cr_hdr_sel;    /* selected header text color */\r
-    COLORREF cr_hdr_gray;   /* gray header text color */\r
-    COLORREF cr_hdr_gray_sel;   /* selected gray header text color */\r
-    HBRUSH hb_hdr_bg;       /* header background color (normal) */\r
-    HBRUSH hb_hdr_bg_exp;   /* header background color (expired) */\r
-    HBRUSH hb_hdr_bg_warn;  /* header background color (warn) */\r
-    HBRUSH hb_hdr_bg_crit;  /* header background color (critical) */\r
-    HBRUSH hb_hdr_bg_sel;   /* header background color (selected) */\r
-    HBRUSH hb_hdr_bg_def;   /* header background color (default) */\r
+\r
     HCURSOR hc_hand;        /* the HAND cursor */\r
     khui_ilist * ilist;     /* image list */\r
 \r
+    HICON   hi_lg_ident;    /* large identity icon */\r
+\r
 #if 0\r
     /* icon indices */\r
     int idx_expand;         /* index of 'expanded' icon in image list */\r
index b8e2e3d2a64f139c193a181cf5da16708f7fb2d4..74255fb021ee0a11be7d85fcca0a0a514d676793 100644 (file)
@@ -181,14 +181,15 @@ BEGIN
     PUSHBUTTON      "&>>",IDC_NC_ADVANCED,260,142,34,18\r
 END\r
 \r
-IDD_NC_BBAR DIALOGEX 0, 0, 66, 181\r
+IDD_NC_BBAR DIALOGEX 0, 0, 66, 190\r
 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\r
 EXSTYLE WS_EX_CONTROLPARENT\r
 FONT 8, "MS Shell Dlg", 400, 0, 0x1\r
 BEGIN\r
     DEFPUSHBUTTON   "&Ok",IDOK,7,7,52,41,WS_DISABLED\r
     PUSHBUTTON      "&Cancel",IDCANCEL,7,58,52,19\r
-    PUSHBUTTON      "&Help",IDC_NC_HELP,7,155,52,19\r
+    PUSHBUTTON      "<<",IDC_NC_BASIC,7,144,52,14\r
+    PUSHBUTTON      "&Help",IDC_NC_HELP,7,164,52,19\r
 END\r
 \r
 IDD_PP_IDENT DIALOGEX 0, 0, 235, 156\r
@@ -412,7 +413,7 @@ BEGIN
         LEFTMARGIN, 7\r
         RIGHTMARGIN, 59\r
         TOPMARGIN, 7\r
-        BOTTOMMARGIN, 174\r
+        BOTTOMMARGIN, 183\r
     END\r
 \r
     IDD_PP_IDENT, DIALOG\r
@@ -790,7 +791,7 @@ BEGIN
     IDS_NCN_IDENT_UNKNOWN   "Validity of identity %s coudn't be determined."\r
     IDS_REMOTE_FAIL         "The instance of Network Identity Manager that is already running is not responding to the remote request properly.  Please check if you are running the latest version of Network Identity Manger software included with MIT Kerberos for Windows."\r
     IDS_REMOTE_FAIL_TITLE   "Failed to communicate with Network Identity Manager"\r
-    IDS_IDACTION_NEW        "Initialize %s"\r
+    IDS_IDACTION_NEW        "Obtain new credentials for %s"\r
     IDS_IDACTIONT_NEW       "New credentials for %s"\r
 END\r
 \r
@@ -807,6 +808,10 @@ BEGIN
     IDS_IDEXPDISP_NOCRED    "(This identity has no credentials)"\r
     IDS_IDEXPDISP_1CRED     "(This identity has 1 credential)"\r
     IDS_IDEXPDISP_NCRED     "(This identity has %d credentials)"\r
+    IDS_CW_DEFAULTTF        "(Default, %s)"\r
+    IDS_CW_TYPEF            "(%s)"\r
+    IDS_CW_EXPIREF          "Expires in %s"\r
+    IDS_CW_EXPIRED          "(Expired)"\r
 END\r
 \r
 #endif    // English (U.S.) resources\r
index 82d0fb75d01a682aa35228a6722686367faff08e..e7d59eddb9471540e3bc07186904db44405cbe1a 100644 (file)
@@ -45,7 +45,7 @@ khm_ui_4 khm_commctl_version = 0;
 \r
 khm_startup_options khm_startup;\r
 \r
-khm_version app_version = {KH_VERSION_LIST};\r
+const khm_version app_version = {KH_VERSION_LIST};\r
 \r
 void khm_init_gui(void) {\r
     khui_init_actions();\r
@@ -522,7 +522,7 @@ void khm_load_default_modules(void) {
     kmm_load_default_modules();\r
 }\r
 \r
-int version_compare(const khm_version * v1, const khm_version * v2) {\r
+int khm_compare_version(const khm_version * v1, const khm_version * v2) {\r
 \r
     if (v1->major != v2->major)\r
         return ((int)v1->major) - ((int)v2->major);\r
@@ -744,8 +744,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
         v.patch = 0;\r
         v.aux = 0;\r
 \r
-        if (version_compare(&query_app_version.ver_remote, &app_version) == 0 ||\r
-            version_compare(&query_app_version.ver_remote, &v) > 0)\r
+        if (khm_compare_version(&query_app_version.ver_remote, &app_version) == 0 ||\r
+            khm_compare_version(&query_app_version.ver_remote, &v) > 0)\r
             use_cmd_v2 = TRUE;\r
         else\r
             use_cmd_v2 = FALSE;\r
index 70913f472202cf4875b40d7f054a56df64167780..5d9e4d9973058b856e61e74f0ed68ba4ea41492e 100644 (file)
@@ -190,62 +190,99 @@ void add_action_to_menu(HMENU hm, khui_action * act,
 \r
 static void refresh_menu(HMENU hm, khui_menu_def * def);\r
 \r
-static void refresh_menu_item(HMENU hm, khui_action * act, \r
-                              int idx, int flags) {\r
+static int refresh_menu_item(HMENU hm, khui_action * act, \r
+                             int idx, int flags) {\r
     MENUITEMINFO mii;\r
+    khui_menu_def * def;\r
 \r
     mii.cbSize = sizeof(mii);\r
     mii.fMask = 0;\r
 \r
-    if (act == NULL)\r
-        return;\r
-    else {\r
-        khui_menu_def * def;\r
-\r
-        /* first check if the menu item is there.  Otherwise we need\r
-           to add it. */\r
-        mii.fMask = MIIM_STATE;\r
-        if (!GetMenuItemInfo(hm, act->cmd, FALSE, &mii)) {\r
-            add_action_to_menu(hm, act, idx, flags);\r
-            return;\r
+    if (flags & KHUI_ACTIONREF_END) {\r
+        /* we have been asked to assert that the menu doesn't have\r
+           more than idx items */\r
+        mii.fMask = MIIM_FTYPE;\r
+        while (GetMenuItemInfo(hm, idx, TRUE, &mii)) {\r
+            RemoveMenu(hm, idx, MF_BYPOSITION);\r
+            mii.fMask = MIIM_FTYPE;\r
         }\r
 \r
-        mii.fMask = 0;\r
+        return 0;\r
+    }\r
 \r
-        if(act->state & KHUI_ACTIONSTATE_DISABLED) {\r
-            mii.fMask |= MIIM_STATE;\r
-            mii.fState = MFS_DISABLED;\r
-        } else {\r
+    /* Check if the menu item is there.  Otherwise we need to add\r
+       it. */\r
+    mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;\r
+    if (!GetMenuItemInfo(hm, idx, TRUE, &mii) ||\r
+        ((flags & KHUI_ACTIONREF_SEP) && !(mii.fType & MFT_SEPARATOR)) ||\r
+        (!(flags & KHUI_ACTIONREF_SEP) && mii.wID != act->cmd)) {\r
+        add_action_to_menu(hm, ((flags & KHUI_ACTIONREF_SEP)? NULL : act),\r
+                           idx, flags);\r
+        return 0;\r
+    }\r
+\r
+    if (flags & KHUI_ACTIONREF_SEP)\r
+        return 0;\r
+\r
+#ifdef DEBUG\r
+    assert(act);\r
+#endif\r
+    if (!act)\r
+        return 0;\r
+\r
+    if (flags & KHUI_ACTIONREF_DEFAULT) {\r
+        if (!(mii.fState & MFS_DEFAULT)) {\r
             mii.fMask |= MIIM_STATE;\r
-            mii.fState = MFS_ENABLED;\r
+            mii.fState |= MFS_DEFAULT;\r
+        }\r
+    } else {\r
+        if (mii.fState & MFS_DEFAULT) {\r
+            RemoveMenu(hm, idx, MF_BYPOSITION);\r
+            add_action_to_menu(hm, act, idx, flags);\r
+            return 0;\r
         }\r
+    }\r
 \r
-        if(act->type & KHUI_ACTIONTYPE_TOGGLE) {\r
-            mii.fMask |= MIIM_STATE;\r
-            if (act->state & KHUI_ACTIONSTATE_CHECKED) {\r
-                mii.fState |= MFS_CHECKED;\r
-            } else {\r
-                mii.fState |= MFS_UNCHECKED;\r
-            }\r
+    mii.fMask = 0;\r
+\r
+    if(act->state & KHUI_ACTIONSTATE_DISABLED) {\r
+        mii.fMask |= MIIM_STATE;\r
+        mii.fState &= ~MFS_ENABLED;\r
+        mii.fState |= MFS_DISABLED;\r
+    } else {\r
+        mii.fMask |= MIIM_STATE;\r
+        mii.fState &= ~MFS_DISABLED;\r
+        mii.fState |= MFS_ENABLED;\r
+    }\r
+\r
+    if(act->type & KHUI_ACTIONTYPE_TOGGLE) {\r
+        mii.fMask |= MIIM_STATE;\r
+        if (act->state & KHUI_ACTIONSTATE_CHECKED) {\r
+            mii.fState |= MFS_CHECKED;\r
+        } else {\r
+            mii.fState |= MFS_UNCHECKED;\r
         }\r
+    }\r
 \r
-        SetMenuItemInfo(hm, act->cmd, FALSE, &mii);\r
+    SetMenuItemInfo(hm, act->cmd, FALSE, &mii);\r
 \r
-        def = khui_find_menu(act->cmd);\r
+    def = khui_find_menu(act->cmd);\r
 \r
-        if(def) {\r
-            MENUITEMINFO mii2;\r
+    if(def) {\r
+        MENUITEMINFO mii2;\r
 \r
-            mii2.cbSize = sizeof(mii2);\r
-            mii2.fMask = MIIM_SUBMENU;\r
+        mii2.cbSize = sizeof(mii2);\r
+        mii2.fMask = MIIM_SUBMENU;\r
 \r
-            if (GetMenuItemInfo(hm, act->cmd, FALSE, &mii2)) {\r
-                refresh_menu(mii2.hSubMenu, def);\r
-            }\r
+        if (GetMenuItemInfo(hm, act->cmd, FALSE, &mii2)) {\r
+            refresh_menu(mii2.hSubMenu, def);\r
         }\r
     }\r
+\r
+    return 0;\r
 }\r
 \r
+\r
 static void refresh_menu(HMENU hm, khui_menu_def * def) {\r
     khui_action_ref * act;\r
     khm_size i, n;\r
@@ -254,6 +291,8 @@ static void refresh_menu(HMENU hm, khui_menu_def * def) {
         act = khui_menu_get_action(def, i);\r
         refresh_menu_item(hm, khui_find_action(act->action), (int) i, act->flags);\r
     }\r
+\r
+    refresh_menu_item(hm, NULL, (int) i, KHUI_ACTIONREF_END);\r
 }\r
 \r
 static HMENU mm_create_menu_from_def(khui_menu_def * def, BOOL main) {\r
@@ -778,6 +817,8 @@ khm_refresh_identity_menus(void) {
     khm_size t;\r
     khm_int32 rv = KHM_ERROR_SUCCESS;\r
 \r
+    khui_action_lock();\r
+\r
     idcmd_refreshcycle++;\r
 \r
     do {\r
@@ -867,6 +908,10 @@ khm_refresh_identity_menus(void) {
         PFREE(idlist);\r
 \r
     purge_identity_cmd_map();\r
+\r
+    khui_action_unlock();\r
+\r
+    khui_refresh_actions();\r
 }\r
 \r
 khm_boolean\r
@@ -929,10 +974,14 @@ void khm_menu_refresh_items(void) {
     if (!khui_hmenu_main)\r
         return;\r
 \r
+    khui_action_lock();\r
+\r
     def = khui_find_menu(KHUI_MENU_MAIN);\r
 \r
     refresh_menu(khui_hmenu_main, def);\r
 \r
+    khui_action_unlock();\r
+\r
     DrawMenuBar(khm_hwnd_main);\r
 }\r
 \r
index 494ef4bb64d84aba8c46647d7364ddcb08c92a8c..128be085c33715230d43a3a7cb2ef11e4c3000d6 100644 (file)
@@ -1093,6 +1093,7 @@ void
 khm_set_main_window_mode(int mode) {\r
 \r
     RECT r;\r
+    khm_handle csp_cw;\r
 \r
     if (mode == khm_main_wnd_mode)\r
         return;\r
@@ -1115,6 +1116,14 @@ khm_set_main_window_mode(int mode) {
                      SWP_NOACTIVATE | SWP_NOOWNERZORDER |\r
                      SWP_NOZORDER);\r
     }\r
+\r
+    if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", KHM_PERM_WRITE,\r
+                                     &csp_cw))) {\r
+\r
+        khc_write_int32(csp_cw, L"DefaultWindowMode", mode);\r
+        khc_close_space(csp_cw);\r
+\r
+    }\r
 }\r
 \r
 void \r
index 72c58a0a1cde56d0c97f00ace84637121e4ba897..4e4e5e116e957c56e68b9f824f426f8809cc79b6 100644 (file)
@@ -1570,9 +1570,9 @@ nc_handle_wm_create(HWND hwnd,
         SendMessage(ncd->dlg_main, KHUI_WM_NC_NOTIFY,\r
                     MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);\r
     } else {\r
-        /* we don't call this if the dialog is expanded because\r
-           posting WMNC_DIALOG_EXPAND to the main panel results in\r
-           this getting called anyway. */\r
+        /* we don't call nc_layout_main_panel() if the dialog is\r
+           expanded because posting WMNC_DIALOG_EXPAND to the main\r
+           panel results in it getting called anyway. */\r
         nc_layout_main_panel(ncd);\r
     }\r
 \r
@@ -1759,6 +1759,7 @@ nc_handle_wm_command(HWND hwnd,
             khm_html_help(hwnd, NULL, HH_HELP_CONTEXT, IDH_ACTION_NEW_ID);\r
             return FALSE;\r
 \r
+        case IDC_NC_BASIC:\r
         case IDC_NC_ADVANCED: \r
             /* the Options button in the main window was clicked.  we\r
                respond by expanding the dialog. */\r
@@ -1919,15 +1920,19 @@ static LRESULT nc_handle_wm_nc_notify(HWND hwnd,
         /* fallthrough */\r
 \r
     case WMNC_DIALOG_EXPAND:\r
-        /* we are expanding the dialog box */\r
+        /* we are switching from basic to advanced or vice versa */\r
 \r
-        /* nothing to do? */\r
-        if (d->nc->mode == KHUI_NC_MODE_EXPANDED)\r
-            break;\r
-\r
-        d->nc->mode = KHUI_NC_MODE_EXPANDED;\r
+        if (d->nc->mode == KHUI_NC_MODE_EXPANDED) {\r
+            d->nc->mode = KHUI_NC_MODE_MINI;\r
+        } else {\r
+            d->nc->mode = KHUI_NC_MODE_EXPANDED;\r
+        }\r
 \r
-        nc_notify_clear(d);\r
+        /* if we are switching to the advanced mode, we clear any\r
+           notifications because we now have a credential text area\r
+           for that. */\r
+        if (d->nc->mode == KHUI_NC_MODE_EXPANDED)\r
+            nc_notify_clear(d);\r
 \r
         nc_layout_main_panel(d);\r
 \r
index 46ac831697bedfe3d364c337bf23c154754e6ae4..939cf0141f6abfd14e87936e22cb26a5ada79c7d 100644 (file)
@@ -140,7 +140,7 @@ void khm_show_newcredwnd(HWND hwnd);
 /* Width of the button bar in dialog units */\r
 #define NCDLG_BBAR_WIDTH 66\r
 /* Height of the button bar in dialog units */\r
-#define NCDLG_BBAR_HEIGHT 181\r
+#define NCDLG_BBAR_HEIGHT 190\r
 \r
 /* Control identifier for the tab control in the new credentials\r
    dialog. We declare this here since we will be creating the control\r
index 530c22b5654fce3c57a63e9238f7b9e07581acd8..e0582eb94abb741775f8aa72588bbbbf58052a51 100644 (file)
@@ -118,7 +118,7 @@ alerter_wnd_data * khui_alert_windows = NULL;
 int  iid_normal = IDI_NOTIFY_NONE;\r
 \r
 /* The alert currently being displayed in a balloon */\r
-khui_alert * balloon_alert;\r
+khui_alert * balloon_alert = NULL;\r
 \r
 /**********************************************************************\r
   Alert Queue\r
@@ -488,6 +488,7 @@ notifier_wnd_proc(HWND hwnd,
                 balloon_alert = NULL;\r
 \r
                 khui_alert_lock(a);\r
+                a->displayed = FALSE;\r
 \r
                 if ((a->flags & KHUI_ALERT_FLAG_DEFACTION) &&\r
                     !(a->flags & KHUI_ALERT_FLAG_REQUEST_WINDOW) &&\r
@@ -515,8 +516,15 @@ notifier_wnd_proc(HWND hwnd,
         case NIN_BALLOONTIMEOUT:\r
             khm_notify_icon_change(KHERR_NONE);\r
             if (balloon_alert) {\r
-                khui_alert_release(balloon_alert);\r
+                khui_alert * a;\r
+                a = balloon_alert;\r
                 balloon_alert = NULL;\r
+\r
+                khui_alert_lock(a);\r
+                a->displayed = FALSE;\r
+                khui_alert_unlock(a);\r
+\r
+                khui_alert_release(a);\r
             }\r
             break;\r
         }\r
@@ -681,9 +689,9 @@ typedef struct tag_alerter_wnd_data {
 #define IDC_NTF_CLOSE    999\r
 \r
 #define IDC_NTF_CMDBUTTONS 1001\r
-#define IDC_FROM_IDX(alert, bn) ((alert) * KHUI_MAX_ALERT_COMMANDS + (bn) + IDC_NTF_CMDBUTTONS)\r
-#define ALERT_FROM_IDC(idc)  (((idc) - IDC_NTF_CMDBUTTONS) / KHUI_MAX_ALERT_COMMANDS)\r
-#define BUTTON_FROM_IDC(idc) (((idc) - IDC_NTF_CMDBUTTONS) % KHUI_MAX_ALERT_COMMANDS)\r
+#define IDC_FROM_IDX(alert, bn) ((alert) * (KHUI_MAX_ALERT_COMMANDS + 1) + (bn) + 1 + IDC_NTF_CMDBUTTONS)\r
+#define ALERT_FROM_IDC(idc)  (((idc) - IDC_NTF_CMDBUTTONS) / (KHUI_MAX_ALERT_COMMANDS + 1))\r
+#define BUTTON_FROM_IDC(idc) (((idc) - IDC_NTF_CMDBUTTONS) % (KHUI_MAX_ALERT_COMMANDS + 1) - 1)\r
 \r
 /* if the only command in an alert is "Close", we assume that the\r
    alert has no commands. */\r
@@ -717,8 +725,9 @@ add_alert_to_wnd_data(alerter_wnd_data * d,
 \r
     a->flags |= KHUI_ALERT_FLAG_DISPLAY_WINDOW;\r
 \r
-    if (!exists)\r
+    if (!exists) {\r
         a->displayed = TRUE;\r
+    }\r
 \r
     khui_alert_unlock(a);\r
 \r
@@ -1376,7 +1385,7 @@ setup_alerter_window_controls(alerter_wnd_data * d) {
                                        -10, 0,\r
                                        5, 5,\r
                                        d->hw_bin,\r
-                                       (HMENU) (INT_PTR) IDC_FROM_IDX(idx, 0),\r
+                                       (HMENU) (INT_PTR) IDC_FROM_IDX(idx, -1),\r
                                        khm_hInstance,\r
                                        NULL);\r
 #ifdef DEBUG\r
@@ -1391,8 +1400,13 @@ setup_alerter_window_controls(alerter_wnd_data * d) {
 \r
                 last_window = adata->hwnd_marker;\r
 \r
-                if (hw_focus == NULL)\r
-                    hw_focus = adata->hwnd_marker;\r
+                if (scrollbar) {\r
+                    EnableWindow(adata->hwnd_marker, TRUE);\r
+                    if (hw_focus == NULL)\r
+                        hw_focus = adata->hwnd_marker;\r
+                } else {\r
+                    EnableWindow(adata->hwnd_marker, FALSE);\r
+                }\r
             }\r
 \r
             y += adata->r_alert.bottom;\r
@@ -1441,7 +1455,7 @@ setup_alerter_window_controls(alerter_wnd_data * d) {
                          SWP_SHOWWINDOW);\r
         }\r
 \r
-        if (hw_focus == NULL)\r
+        if (hw_focus == NULL || d->n_cmd_buttons == 0)\r
             hw_focus = d->hw_close;\r
 \r
     } else {\r
@@ -1473,7 +1487,6 @@ setup_alerter_window_controls(alerter_wnd_data * d) {
                      r_window.right - r_window.left,\r
                      r_window.bottom - r_window.top,\r
                      SWP_SHOWWINDOW | SWP_NOOWNERZORDER);\r
-\r
     }\r
 \r
     if (hw_focus != NULL)\r
@@ -1645,6 +1658,11 @@ process_command_button(alerter_wnd_data * d, int id) {
     if (alert_idx >= d->n_alerts || alert_idx < 0)\r
         return;\r
 \r
+    if (cmd_idx < 0) {\r
+        /* the user selected a marker button.  Nothing to do. */\r
+        return;\r
+    }\r
+\r
     adata = QTOP(d);\r
     while(adata && alert_idx > 0) {\r
         alert_idx--;\r
@@ -2011,15 +2029,22 @@ alert_show_minimized(khui_alert * a) {
 \r
     a->flags |= KHUI_ALERT_FLAG_DISPLAY_BALLOON;\r
 \r
-#if (_WIN32_IE >= 0x0501)\r
+#ifdef DEBUG\r
+    assert(balloon_alert == NULL);\r
+#endif\r
+\r
     if (balloon_alert) {\r
+        khui_alert_lock(balloon_alert);\r
+        balloon_alert->displayed = FALSE;\r
+        khui_alert_unlock(balloon_alert);\r
         khui_alert_release(balloon_alert);\r
         balloon_alert = NULL;\r
     }\r
 \r
     balloon_alert = a;\r
     khui_alert_hold(a);\r
-#endif\r
+\r
+    a->displayed = TRUE;\r
 \r
     khm_notify_icon_balloon(a->severity,\r
                             tbuf,\r
@@ -2205,6 +2230,21 @@ show_queued_alerts(void) {
 \r
         alert_list_destroy(&alist);\r
 \r
+        if (n == 0) {\r
+            khui_alert * a;\r
+\r
+            /* no alerts were shown above.  This maybe because none of\r
+               the alerts were consolidatable or they were requested\r
+               to be shown in a balloon.  In this case, we just take\r
+               the first alert from the queue and show it manually. */\r
+\r
+            a = alert_queue_get_alert();\r
+            if (a) {\r
+                alert_show(a);\r
+                khui_alert_release(a);\r
+            }\r
+        }\r
+\r
         check_for_queued_alerts();\r
     }\r
 }\r
@@ -2550,6 +2590,7 @@ alert_bin_wnd_proc(HWND hwnd,
 \r
                 if (a->suggestion) {\r
                     HICON hicon;\r
+                    SIZE sz;\r
 \r
                     CopyRect(&r, &adata->r_suggestion);\r
                     OffsetRect(&r, 0, y);\r
@@ -2558,14 +2599,18 @@ alert_bin_wnd_proc(HWND hwnd,
 \r
                     InflateRect(&r, -d->s_pad.cx, -d->s_pad.cy);\r
 \r
+                    sz.cx = GetSystemMetrics(SM_CXSMICON);\r
+                    sz.cy = GetSystemMetrics(SM_CYSMICON);\r
+\r
                     hicon = (HICON) LoadImage(NULL,\r
                                               MAKEINTRESOURCE(OIC_NOTE),\r
                                               IMAGE_ICON,\r
-                                              GetSystemMetrics(SM_CXSMICON),\r
-                                              GetSystemMetrics(SM_CYSMICON),\r
+                                              sz.cx,\r
+                                              sz.cy,\r
                                               LR_SHARED);\r
 \r
-                    DrawIcon(hdc, r.left, r.top, hicon);\r
+                    DrawIconEx(hdc, r.left, r.top, hicon, sz.cx, sz.cy, 0, NULL,\r
+                               DI_NORMAL);\r
 \r
                     r.left += d->s_pad.cx + GetSystemMetrics(SM_CXSMICON);\r
 \r
@@ -2691,6 +2736,12 @@ alert_bin_wnd_proc(HWND hwnd,
         }\r
         break;\r
 \r
+    case WM_SIZE:\r
+        {\r
+            InvalidateRect(hwnd, NULL, TRUE);\r
+        }\r
+        break;\r
+\r
     case WM_DESTROY:\r
         {\r
             /* nothing needs to be done here */\r
@@ -2944,26 +2995,52 @@ void khm_notify_icon_activate(void) {
 \r
     khm_notify_icon_change(KHERR_NONE);\r
 \r
-    if (!is_alert_queue_empty() && !ALERT_DISPLAYED()) {\r
-\r
-        khm_show_main_window();\r
-        show_queued_alerts();\r
-\r
-    } else if (balloon_alert != NULL && khui_alert_windows == NULL) {\r
+    if (balloon_alert != NULL && khui_alert_windows == NULL) {\r
 \r
         khui_alert * a;\r
+        khm_boolean alert_done = FALSE;\r
 \r
         a = balloon_alert;\r
         balloon_alert = NULL;\r
 \r
         khui_alert_lock(a);\r
-        if (balloon_alert->flags & KHUI_ALERT_FLAG_REQUEST_WINDOW) {\r
+\r
+        a->displayed = FALSE;\r
+\r
+        if ((a->flags & KHUI_ALERT_FLAG_DEFACTION) &&\r
+            (a->n_alert_commands > 0)) {\r
+\r
+            PostMessage(khm_hwnd_main, WM_COMMAND,\r
+                        MAKEWPARAM(a->alert_commands[0], \r
+                                   0),\r
+                        0);\r
+            alert_done = TRUE;\r
+\r
+        } else if (a->flags & KHUI_ALERT_FLAG_REQUEST_WINDOW) {\r
+\r
             alert_show_normal(a);\r
+            alert_done = TRUE;\r
+\r
         }\r
         khui_alert_unlock(a);\r
         khui_alert_release(a);\r
 \r
-    } else {\r
+        if (alert_done)\r
+            return;\r
+    }\r
+\r
+    if (!is_alert_queue_empty() && !ALERT_DISPLAYED()) {\r
+\r
+        khm_show_main_window();\r
+        show_queued_alerts();\r
+\r
+        return;\r
+    }\r
+\r
+\r
+    /* if none of the above applied, then we perform the default\r
+       action for the notification icon. */\r
+    {\r
         khm_int32 cmd = 0;\r
 \r
         cmd = get_default_notifier_action();\r
@@ -3069,6 +3146,7 @@ create_test_alerts(void) {
         StringCbPrintf(buf, sizeof(buf), L"Foo bar baz.  This is alert number %d", i);\r
         khui_alert_create_simple(L"Title", buf, KHERR_INFO, &a);\r
         khui_alert_set_type(a, KHUI_ALERTTYPE_PLUGIN);\r
+        khui_alert_set_suggestion(a, L"This is a suggestion.  It is kinda long to see if the word wrapping actually works as we expect it to.  Just in case, here's a line feed.\n\nDoes this show up on a different line? Cool!");\r
 \r
         khui_alert_add_command(a, KHUI_ACTION_NEW_CRED);\r
         khui_alert_add_command(a, KHUI_ACTION_CLOSE_APP);\r
index d7c9f27a60e99891bd8d6c66d874bef0b6240d9f..31df1fe7e48614f5e5cd140b047fd6b03bd2179b 100644 (file)
 #define IDS_IDEXPDISP_NOCRED            312\r
 #define IDS_IDEXPDISP_1CRED             313\r
 #define IDS_IDEXPDISP_NCRED             314\r
+#define IDS_CW_DEFAULTTF                315\r
+#define IDS_CW_TYPEF                    316\r
+#define IDS_CW_EXPIREF                  317\r
+#define IDS_CW_EXPIRED                  318\r
 #define IDC_NC_USERNAME                 1007\r
 #define IDC_NC_PASSWORD                 1008\r
 #define IDC_NC_CREDTEXT_LABEL           1009\r
 #define IDC_LG_LBL                      1139\r
 #define IDC_CFG_NOTACTION               1141\r
 #define IDC_CFG_NOTACT_STATIC           1142\r
+#define IDC_BUTTON1                     1143\r
+#define IDC_NC_BASIC                    1143\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         1143\r
+#define _APS_NEXT_CONTROL_VALUE         1144\r
 #define _APS_NEXT_SYMED_VALUE           101\r
 #endif\r
 #endif\r
index 5bcf2c2a5133e40b7fa78ca30a40c1cf15a53660..e5f7e200902e14689d8ffde318fd8b51bb875f59 100644 (file)
 #endif\r
 \r
 khm_statusbar_part khm_statusbar_parts[] = {\r
-    {KHUI_SBPART_INFO, 0, KHUI_SB_WTYPE_FILLER},\r
-    {KHUI_SBPART_NOTICE, 40, KHUI_SB_WTYPE_RELATIVE},\r
-    {KHUI_SBPART_LOC, 40, KHUI_SB_WTYPE_ABSOLUTE}\r
+    {KHUI_SBPART_INFO, 0, KHUI_SB_WTYPE_FILLER, NULL},\r
+    {KHUI_SBPART_NOTICE, 40, KHUI_SB_WTYPE_RELATIVE, NULL},\r
+#if 0\r
+    /* Not implemented. This was originally intended to provide\r
+       location information. */\r
+    {KHUI_SBPART_LOC, 40, KHUI_SB_WTYPE_ABSOLUTE, NULL}\r
+#endif\r
 };\r
 \r
 int khm_n_statusbar_parts = sizeof(khm_statusbar_parts) / sizeof(khm_statusbar_part);\r
@@ -178,10 +182,22 @@ void khm_statusbar_set_part(int id, HICON icon, wchar_t * text) {
     if(idx < 0)\r
         return;\r
 \r
+    if (khm_statusbar_parts[idx].hIcon != NULL) {\r
+        DestroyIcon(khm_statusbar_parts[idx].hIcon);\r
+        khm_statusbar_parts[idx].hIcon = NULL;\r
+    }\r
+\r
+    if (icon) {\r
+        khm_statusbar_parts[idx].hIcon = CopyImage(icon, IMAGE_ICON,\r
+                                                   GetSystemMetrics(SM_CXSMICON),\r
+                                                   GetSystemMetrics(SM_CYSMICON),\r
+                                                   LR_COPYFROMRESOURCE);\r
+    }\r
+\r
     SendMessage(khm_hwnd_statusbar,\r
                 SB_SETICON,\r
                 idx,\r
-                (LPARAM) icon);\r
+                (LPARAM) (khm_statusbar_parts[idx].hIcon ? khm_statusbar_parts[idx].hIcon:icon));\r
 \r
     SendMessage(khm_hwnd_statusbar,\r
                 SB_SETTEXT,\r
@@ -189,3 +205,4 @@ void khm_statusbar_set_part(int id, HICON icon, wchar_t * text) {
                 (LPARAM) text);\r
 }\r
 \r
+\r
index 2fd267e9e1f586d2d3ba1b0b0fbf14c60c6740dc..6a2b3ddfb60113391aa2c3cfc1735fc01e9e0590 100644 (file)
@@ -31,6 +31,7 @@ typedef struct khm_statusbar_part_t {
     int id;\r
     int width;\r
     int wtype; /* one of KHUI_SB_WTYPE_* */\r
+    HICON hIcon;\r
 } khm_statusbar_part;\r
 \r
 #define KHUI_SB_WTYPE_RELATIVE    1\r
index 77fa6c16117e3da465218178125e0c1d2789d9c8..7024481c4a710155b1859aad9d97ed13c864959a 100644 (file)
@@ -256,8 +256,9 @@ tmr_fire_timer(void) {
                    wtitle, ARRAYLENGTH(wtitle));\r
 \r
         khui_alert_create_simple(wtitle, wmsg, KHERR_WARNING, &alert);\r
-        khui_alert_set_flags(alert, KHUI_ALERT_FLAG_REQUEST_BALLOON,\r
-                             KHUI_ALERT_FLAG_REQUEST_BALLOON);\r
+        khui_alert_set_flags(alert,\r
+                             KHUI_ALERT_FLAG_REQUEST_BALLOON | KHUI_ALERT_FLAG_DISPATCH_CMD,\r
+                             KHUI_ALERT_FLAG_REQUEST_BALLOON | KHUI_ALERT_FLAG_DISPATCH_CMD);\r
 \r
         if (eff_ident != NULL) {\r
             khm_int32 cmd;\r
index f3781b93016026edfae9ba07195d1194b20950ec..a464009fc63eb14857920a3d629c119db72e04ad 100644 (file)
@@ -106,6 +106,28 @@ LRESULT khm_toolbar_notify(LPNMHDR notice) {
         }\r
         break;\r
 \r
+    case TBN_DROPDOWN:\r
+        {\r
+            LPNMTOOLBAR nmtb = (LPNMTOOLBAR) notice;\r
+            RECT r;\r
+\r
+            GetWindowRect(khui_hwnd_standard_toolbar, &r);\r
+            if (nmtb->iItem == KHUI_ACTION_DESTROY_CRED) {\r
+                khm_menu_show_panel(KHUI_MENU_DESTROY_CRED,\r
+                                    r.left + nmtb->rcButton.left,\r
+                                    r.top + nmtb->rcButton.bottom);\r
+            } else if (nmtb->iItem == KHUI_ACTION_RENEW_CRED) {\r
+                khm_menu_show_panel(KHUI_MENU_RENEW_CRED,\r
+                                    r.left + nmtb->rcButton.left,\r
+                                    r.top + nmtb->rcButton.bottom);\r
+            } else {\r
+                return TBDDRET_NODEFAULT;\r
+            }\r
+\r
+            return TBDDRET_DEFAULT;\r
+        }\r
+        break;\r
+\r
     case NM_CUSTOMDRAW:\r
         {\r
             LPNMTBCUSTOMDRAW nmcd = (LPNMTBCUSTOMDRAW) notice;\r
@@ -156,11 +178,14 @@ LRESULT khm_toolbar_notify(LPNMHDR notice) {
                     return CDRF_DODEFAULT;\r
 \r
                 CopyRect(&r, &(nmcd->nmcd.rc));\r
-                r.left += ((r.right - r.left) - \r
-                           KHUI_TOOLBAR_IMAGE_WIDTH) / 2;\r
+                r.left += ((r.bottom - r.top) -\r
+                          KHUI_TOOLBAR_IMAGE_HEIGHT) / 2;\r
                 r.top += ((r.bottom - r.top) -\r
                           KHUI_TOOLBAR_IMAGE_HEIGHT) / 2;\r
-                \r
+#if 0\r
+                r.left += ((r.right - r.left) - \r
+                           KHUI_TOOLBAR_IMAGE_WIDTH) / 2;\r
+#endif\r
                 khui_ilist_draw(ilist_toolbar, \r
                                 iidx, \r
                                 nmcd->nmcd.hdc, \r
@@ -317,17 +342,12 @@ void khm_create_standard_toolbar(HWND rebar) {
         return;\r
     }\r
 \r
-    hwtb = CreateWindowEx(0\r
-#if (_WIN32_IE >= 0x0501)\r
-                          | TBSTYLE_EX_MIXEDBUTTONS\r
-#endif\r
-                          ,\r
+    hwtb = CreateWindowEx(0 ,\r
                           TOOLBARCLASSNAME,\r
                           (LPWSTR) NULL,\r
                           WS_CHILD |\r
                           TBSTYLE_FLAT |\r
                           TBSTYLE_AUTOSIZE | \r
-                          TBSTYLE_LIST |\r
                           TBSTYLE_TOOLTIPS |\r
                           CCS_NORESIZE | \r
                           CCS_NOPARENTALIGN |\r
@@ -344,6 +364,11 @@ void khm_create_standard_toolbar(HWND rebar) {
         return;\r
     }\r
 \r
+#if (_WIN32_IE >= 0x0501)\r
+    SendMessage(hwtb, TB_SETEXTENDEDSTYLE, 0,\r
+                TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS);\r
+#endif\r
+\r
     hiList = ImageList_Create(\r
         KHUI_TOOLBAR_IMAGE_WIDTH,\r
         KHUI_TOOLBAR_IMAGE_HEIGHT,\r
@@ -395,7 +420,9 @@ void khm_create_standard_toolbar(HWND rebar) {
             act = khui_find_action(aref->action);\r
             khui_add_action_to_toolbar(hwtb, \r
                                        act, \r
-                                       KHUI_TOOLBAR_ADD_BITMAP, \r
+                                       KHUI_TOOLBAR_ADD_BITMAP |\r
+                                       ((aref->flags & KHUI_ACTIONREF_SUBMENU)?\r
+                                        KHUI_TOOLBAR_ADD_DROPDOWN: 0),\r
                                        hiList);\r
         }\r
         aref ++;\r
index 89700f2e4e2fcba43c545fdb2d8370260421c6a7..8068a6be240871e71ab86724728bf5f9fd0259a6 100644 (file)
@@ -37,12 +37,12 @@ void khui_add_action_to_toolbar(HWND toolbar, khui_action * act, int opt, HIMAGE
 void khm_update_standard_toolbar(void);\r
 \r
 /* options for khui_add_action_to_toolbar */\r
-#define KHUI_TOOLBAR_ADD_TEXT   1\r
-#define KHUI_TOOLBAR_ADD_BITMAP 2\r
-#define KHUI_TOOLBAR_ADD_LONGTEXT 5\r
-#define KHUI_TOOLBAR_ADD_DROPDOWN 8\r
-#define KHUI_TOOLBAR_ADD_SEP    16\r
-#define KHUI_TOOLBAR_VARSIZE    32\r
+#define KHUI_TOOLBAR_ADD_TEXT      0x00000001\r
+#define KHUI_TOOLBAR_ADD_BITMAP    0x00000002\r
+#define KHUI_TOOLBAR_ADD_LONGTEXT  0x00000005\r
+#define KHUI_TOOLBAR_ADD_DROPDOWN  0x00000008\r
+#define KHUI_TOOLBAR_ADD_SEP       0x00000010\r
+#define KHUI_TOOLBAR_VARSIZE       0x00000020\r
 \r
 #define KHUI_TOOLBAR_IMAGE_WIDTH 29\r
 #define KHUI_TOOLBAR_IMAGE_HEIGHT 27\r
index 7056fce6e67721298055f4e85479b718f1c07b6a..20130489f937975570251ee1c6aa0dba07ff7ba3 100644 (file)
@@ -187,10 +187,23 @@ CredWindow,KC_SPACE,0,Options for the credentials window
        IdentityName,KC_SPACE,0,\r
          Width,KC_INT32,415,\r
          SortIndex,KC_INT32,0,\r
-         Flags,KC_INT32,11\r
+         Flags,KC_INT32,171\r
        IdentityName,KC_ENDSPACE,0,\r
      Columns,KC_ENDSPACE,0,\r
    CompactIdentity,KC_ENDSPACE,0\r
+   Custom_1,KC_SPACE,0,Default Compact View by Identity\r
+     Description,KC_STRING,Compact view of identities\r
+     ColumnList,KC_STRING,"IdentityName",\r
+     ExpandedIdentity,KC_INT32,1,Use expanded display of identity headers\r
+     NoHeader,KC_INT32,1,Suppress the column header\r
+     Columns,KC_SPACE,0,\r
+       IdentityName,KC_SPACE,0,\r
+         Width,KC_INT32,415,\r
+         SortIndex,KC_INT32,0,\r
+         Flags,KC_INT32,171\r
+       IdentityName,KC_ENDSPACE,0,\r
+     Columns,KC_ENDSPACE,0,\r
+   Custom_1,KC_ENDSPACE,0\r
   Views,KC_ENDSPACE,0\r
   Notices,KC_SPACE,0,Notices and alerts\r
     MinimizeWarning,KC_INT32,1,Show the minimize warning?\r
index 8ec98f8cde077d52cf683fcdc2aef75096896d56..00902eec9eaa40c34a263f96c9438ca309876f38 100644 (file)
@@ -52,9 +52,9 @@ khui_action_ref khui_menu_file[] = {
 khui_action_ref khui_menu_cred[] = {\r
     MENU_ACTION(KHUI_ACTION_NEW_CRED),\r
     MENU_SEP(),\r
-    MENU_ACTION(KHUI_ACTION_RENEW_CRED),\r
+    MENU_SUBMENU(KHUI_MENU_RENEW_CRED),\r
+    MENU_SUBMENU(KHUI_MENU_DESTROY_CRED),\r
     MENU_ACTION(KHUI_ACTION_IMPORT),\r
-    MENU_ACTION(KHUI_ACTION_DESTROY_CRED),\r
     MENU_SEP(),\r
     MENU_ACTION(KHUI_ACTION_SET_DEF_ID),\r
 #if 0\r
@@ -119,9 +119,9 @@ khui_action_ref khui_menu_help[] = {
 \r
 khui_action_ref khui_toolbar_standard[] = {\r
     MENU_ACTION(KHUI_ACTION_NEW_CRED),\r
-    MENU_ACTION(KHUI_ACTION_RENEW_CRED),\r
+    MENU_SUBMENU(KHUI_ACTION_RENEW_CRED),\r
     MENU_ACTION(KHUI_ACTION_IMPORT),\r
-    MENU_ACTION(KHUI_ACTION_DESTROY_CRED),\r
+    MENU_SUBMENU(KHUI_ACTION_DESTROY_CRED),\r
     MENU_SEP(),\r
     MENU_ACTION(KHUI_ACTION_PASSWD_ID),\r
     MENU_SEP(),\r
index 45a565cde15bf7dce580edc4d648d91e4f334113..e22e1f77f25e188d4df73a7183f57781cc084a57 100644 (file)
@@ -69,7 +69,8 @@
 */\r
 enum khui_wm_nc_notifications {\r
     WMNC_DIALOG_EXPAND = 1, \r
-    /*!< The dialog is getting expanded.\r
+    /*!< The dialog is switching from basic to advanced mode or vice\r
+      versa.\r
 \r
       This message is sent to the new creds dialog to set the dialog\r
       to expanded mode.  In expanded mode, all credentials type panels\r