From e010c8e9379bd2fa9b08a142e57cee56c123791c Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Mon, 18 Jan 2010 16:47:31 -0500 Subject: [PATCH] Windows: Add a context menu for the AFS icon The OpenAFS plug-in for Network Identity Manager displays an icon in the notification area that displays status information about the AFS service and tokens. Add a context menu to the icon so that users can open the NIM application and get help for the plug-in from the notification icon. Change-Id: I704934b4f4eab72a18c54ef2a7a7dc3ca248ba78 Reviewed-on: http://gerrit.openafs.org/1121 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/netidmgr_plugin/afsicon.c | 160 ++++++++++++++++-- .../netidmgr_plugin/lang/en_us/langres.rc | 45 +++-- src/WINNT/netidmgr_plugin/langres.h | 27 ++- 3 files changed, 204 insertions(+), 28 deletions(-) diff --git a/src/WINNT/netidmgr_plugin/afsicon.c b/src/WINNT/netidmgr_plugin/afsicon.c index b6f93e831..54cb6dd85 100644 --- a/src/WINNT/netidmgr_plugin/afsicon.c +++ b/src/WINNT/netidmgr_plugin/afsicon.c @@ -4,6 +4,8 @@ #include "AFS_component_version_number.h" #include #include +#include +#include #include #include @@ -14,6 +16,119 @@ static volatile BOOL notification_icon_added = FALSE; #define TOKEN_ICON_ID 1 #define TOKEN_MESSAGE_ID WM_USER +static khm_int32 +get_default_notifier_action(void) +{ + khm_int32 cmd = KHUI_ACTION_OPEN_APP; + + khc_read_int32(NULL, L"CredWindow\\NotificationAction", &cmd); + + return cmd; +} + +static BOOL +get_release_notes(wchar_t rpath[MAX_PATH]) +{ + BOOL rv = FALSE; + HKEY hk_client = NULL; + wchar_t cpath[MAX_PATH]; + DWORD cb_data; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + L"Software\\TransarcCorporation\\AFS Client\\CurrentVersion", + 0, KEY_READ, &hk_client) != ERROR_SUCCESS) + return FALSE; + + cb_data = sizeof(cpath); + if (RegQueryValueEx(hk_client, L"PathName", NULL, NULL, (LPBYTE) cpath, &cb_data) != ERROR_SUCCESS) + goto done; + + cpath[min(cb_data, MAX_PATH - 1)] = L'\0'; + + if (!PathRemoveFileSpec(cpath)) + goto done; + + if (!PathAppend(cpath, L"Documentation")) + goto done; + + if (!PathAppend(cpath, L"ReleaseNotes.chm")) + goto done; + + if (!PathCanonicalize(rpath, cpath)) + goto done; + + if (!PathFileExists(rpath)) + goto done; + + rv = TRUE; + + done: + if (hk_client) + RegCloseKey(hk_client); + + return rv; +} + +static void +handle_select(void) +{ + NOTIFYICONDATA idata; + khm_int32 cmd; + + cmd = get_default_notifier_action(); + + khui_action_trigger(cmd, NULL); + + ZeroMemory(&idata, sizeof(idata)); + + Shell_NotifyIcon(NIM_SETFOCUS, &idata); +} + +static void +prepare_context_menu(HMENU hmenu) +{ + khm_int32 cmd; + wchar_t caption[128]; + wchar_t relnotes[MAX_PATH]; + + cmd = get_default_notifier_action(); + + if (cmd == KHUI_ACTION_NEW_CRED) + LoadString(hResModule, IDS_ACT_NEW, caption, ARRAYLENGTH(caption)); + else + LoadString(hResModule, IDS_ACT_OPEN, caption, ARRAYLENGTH(caption)); + + ModifyMenu(hmenu, ID_DEFAULT, MF_STRING|MF_BYCOMMAND, ID_DEFAULT, caption); + SetMenuDefaultItem(hmenu, ID_DEFAULT, FALSE); + + if (!get_release_notes(relnotes)) + RemoveMenu(hmenu, ID_RELEASENOTES, MF_BYCOMMAND); +} + +static void +handle_context_menu(void) +{ + POINT pt; + HMENU hMenu; + HMENU hMenuBar; + + GetCursorPos(&pt); + + hMenuBar = LoadMenu(hResModule, MAKEINTRESOURCE(IDR_CTXMENU)); + hMenu = GetSubMenu(hMenuBar, 0); + + if (hMenu) { + prepare_context_menu(hMenu); + TrackPopupMenu(hMenu, TPM_NONOTIFY, pt.x, pt.y, 0, notifier_window, NULL); + } + + { + NOTIFYICONDATA idata; + ZeroMemory(&idata, sizeof(idata)); + Shell_NotifyIcon(NIM_SETFOCUS, &idata); + } +} + static LRESULT CALLBACK notifier_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -22,22 +137,43 @@ notifier_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case NIN_SELECT: case NIN_KEYSELECT: + handle_select(); + return TRUE; + + case WM_CONTEXTMENU: + handle_context_menu(); + return TRUE; + + default: + return FALSE; + } + } + else if (uMsg == WM_COMMAND) { + switch (LOWORD(wParam)) { + case ID_DEFAULT: { - NOTIFYICONDATA idata; - khm_int32 cmd = KHUI_ACTION_OPEN_APP; + khm_int32 cmd; - khc_read_int32(NULL, L"CredWindow\\NotificationAction", &cmd); + cmd = get_default_notifier_action(); khui_action_trigger(cmd, NULL); + } + return TRUE; - ZeroMemory(&idata, sizeof(idata)); - - Shell_NotifyIcon(NIM_SETFOCUS, &idata); + case ID_SHOWHELP: + { + afs_html_help(notifier_window, L"::/html/welcome.htm", HH_DISPLAY_TOPIC, 0); } - return 0; + return TRUE; - default: - return 0; + case ID_RELEASENOTES: + { + wchar_t relnotes[MAX_PATH]; + + if (get_release_notes(relnotes)) + HtmlHelp(GetDesktopWindow(), relnotes, HH_DISPLAY_TOC, 0); + } + return TRUE; } } return DefWindowProc(hwnd, uMsg, wParam, lParam); @@ -53,7 +189,7 @@ initialize_if_necessary(void) notifier_wnd_proc, /* lpfnWndProc */ 0, /* cbClsExtra */ 0, /* cbWndExtra */ - hInstance, /* hinstance */ + NULL, /* hinstance */ NULL, /* hIcon */ NULL, /* hCursor */ NULL, /* hbrBackground */ @@ -62,6 +198,7 @@ initialize_if_necessary(void) NULL, /* hIconSm */ }; + c.hInstance = hInstance; message_window_class = RegisterClassEx(&c); } @@ -105,7 +242,6 @@ void afs_remove_icon(void) { NOTIFYICONDATA idata; - wchar_t buf[ARRAYLENGTH(idata.szTip)]; ZeroMemory(&idata, sizeof(idata)); @@ -214,6 +350,8 @@ set_state_from_ui_thread(HWND hwnd_main, void * stuff) assert(FALSE); } + (void) hwnd_main; /* unreferenced */ + return KHM_ERROR_SUCCESS; } diff --git a/src/WINNT/netidmgr_plugin/lang/en_us/langres.rc b/src/WINNT/netidmgr_plugin/lang/en_us/langres.rc index d09dcb34a..38b4302be 100644 --- a/src/WINNT/netidmgr_plugin/lang/en_us/langres.rc +++ b/src/WINNT/netidmgr_plugin/lang/en_us/langres.rc @@ -27,18 +27,18 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "..\\..\\langres.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" @@ -126,7 +126,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO +GUIDELINES DESIGNINFO BEGIN IDD_NC_AFS, DIALOG BEGIN @@ -183,15 +183,32 @@ IDI_CRED_NONE ICON "..\\..\\images\\creds_none.ico" IDI_CRED_OK ICON "..\\..\\images\\creds_ok.ico" IDI_CRED_SVCSTOP ICON "..\\..\\images\\creds_stopped.ico" +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_CTXMENU MENU +BEGIN + POPUP "Dummy popup" + BEGIN + MENUITEM "Open Network Identity Manager", ID_DEFAULT + MENUITEM SEPARATOR + MENUITEM "Help for OpenAFS Credentials Provider", ID_SHOWHELP + MENUITEM "OpenAFS Release Notes", ID_RELEASENOTES + END +END + + ///////////////////////////////////////////////////////////////////////////// // // String Table // -STRINGTABLE +STRINGTABLE BEGIN - IDS_AFS_SHORT_DESC "AFS credentials" - IDS_AFS_LONG_DESC "AFS credentials" + IDS_AFS_SHORT_DESC "AFS tokens" + IDS_AFS_LONG_DESC "AFS tokens" IDS_AFS_NAME "AFS" IDS_NCAFS_COL_CELL "Cell" IDS_NCAFS_COL_REALM "Realm" @@ -203,15 +220,15 @@ BEGIN IDS_NC_REALM_AUTO "(Automatic)" END -STRINGTABLE +STRINGTABLE BEGIN IDS_NC_TT_NO_CELL "You have not specified an AFS cell to authenticate to." IDS_NC_TT_CANT_ADD "Can't add a new token" - IDS_NC_TT_MALFORMED_CELL + IDS_NC_TT_MALFORMED_CELL "The cell name you specified contains invalid characters." IDS_NC_TT_NO_REALM "You have not specified a Kerberos realm to use to obtain tokesn for the cell." IDS_NC_AUTO "(Auto)" - IDS_NC_TT_MALFORMED_REALM + IDS_NC_TT_MALFORMED_REALM "The realm name you entered contains invalid characters." IDS_NC_TT_CANT_UPDATE "Can't update token" IDS_AFS_CREDTEXT_DIS "

AFS: AFS is disabled. (click here to enable)

" @@ -225,7 +242,7 @@ BEGIN IDS_ATTR_CLIENT_PRINC_SHORT_DESC "Client Principal" END -STRINGTABLE +STRINGTABLE BEGIN IDS_ATTR_SERVER_PRINC_SHORT_DESC "Server Principal" IDS_DEF_LOCATION "AFS Cache Manager" @@ -245,7 +262,7 @@ BEGIN IDS_NC_TT_CONFLICTM "Credentials for cell %s are already listed for identity %s.\nDo you want to keep the credentials for other identities as well as this one?" END -STRINGTABLE +STRINGTABLE BEGIN IDS_NC_TT_DETAILS "Details about credential" IDS_NC_TT_CONFLICTD "This credential already exists under a different identity." @@ -265,9 +282,11 @@ BEGIN IDS_CRED_TT_NOS "OpenAFS service has not been started." END -STRINGTABLE +STRINGTABLE BEGIN IDS_CRED_TT_SERR "OpenAFS service cannot be reached." + IDS_ACT_OPEN "&Open Network Identity Manager" + IDS_ACT_NEW "&Obtain new credentials ..." END #endif // English (U.S.) resources diff --git a/src/WINNT/netidmgr_plugin/langres.h b/src/WINNT/netidmgr_plugin/langres.h index b77b61ce7..7374eaaa7 100644 --- a/src/WINNT/netidmgr_plugin/langres.h +++ b/src/WINNT/netidmgr_plugin/langres.h @@ -4,7 +4,6 @@ // #define IDS_AFS_SHORT_DESC 101 #define IDS_AFS_LONG_DESC 102 -#define IDI_ICON1 102 #define IDD_NC_AFS 103 #define IDS_AFS_NAME 103 #define IDS_NCAFS_COL_CELL 104 @@ -33,6 +32,7 @@ #define IDI_CRED_SVCSTOP 115 #define IDS_NC_AUTO 116 #define IDS_NC_TT_MALFORMED_REALM 117 +#define IDR_CTXMENU 117 #define IDS_NC_TT_CANT_UPDATE 118 #define IDS_AFS_CREDTEXT_DIS 119 #define IDS_AFS_CREDTEXT_0 120 @@ -76,6 +76,8 @@ #define IDS_CRED_TT_TOK 158 #define IDS_CRED_TT_NOS 159 #define IDS_CRED_TT_SERR 160 +#define IDS_ACT_OPEN 161 +#define IDS_ACT_NEW 162 #define IDC_NCAFS_OBTAIN 1001 #define IDC_NCAFS_TOKENLIST 1002 #define IDC_NCAFS_CELL 1004 @@ -96,15 +98,32 @@ #define IDC_CFG_LBL_COMPANY 1020 #define IDC_CFG_COMPANY 1021 #define IDC_CFG_STARTGRP 1022 -#define IDC_CHECK1 1023 #define IDC_CFG_STARTAFSCREDS 1023 +#define ID_DEFAULT 40003 +#define ID_DUMMYPOPUP_OPENNETWORKIDENTITYMANAGER 40022 +#define ID_DUMMYPOPUP_GETNEWCREDENTIALS 40023 +#define ID_DUMMYPOPUP_ 40024 +#define ID_DUMMYPOPUP_PRINCIPAL 40025 +#define ID_DUMMYPOPUP_HELP 40026 +#define ID_DUMMYPOPUP_ABOUTTHEOPENAFSPLUG 40027 +#define ID_NEWCREDENTIALS 40028 +#define ID_NOTOKENS 40029 +#define ID_TOKEN 40030 +#define ID_ABOUT 40031 +#define ID_SHOWHELP 40032 +#define ID_DUMMYPOPUP_OPENAFSRELEASENOTES 40033 +#define ID_Menu 40034 +#define ID_Menu40035 40035 +#define ID_DUMMYPOPUP_40036 40036 +#define ID_DISCARDTOKENS_DUMMYTOKEN 40037 +#define ID_RELEASENOTES 40038 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 116 -#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_RESOURCE_VALUE 118 +#define _APS_NEXT_COMMAND_VALUE 40039 #define _APS_NEXT_CONTROL_VALUE 1024 #define _APS_NEXT_SYMED_VALUE 101 #endif -- 2.39.5