4 #include "AFS_component_version_number.h"
12 static ATOM message_window_class = 0;
13 static HWND notifier_window = NULL;
14 static volatile BOOL notification_icon_added = FALSE;
16 #define TOKEN_ICON_ID 1
17 #define TOKEN_MESSAGE_ID WM_USER
20 get_default_notifier_action(void)
22 khm_int32 cmd = KHUI_ACTION_OPEN_APP;
24 khc_read_int32(NULL, L"CredWindow\\NotificationAction", &cmd);
30 get_release_notes(wchar_t rpath[MAX_PATH])
33 HKEY hk_client = NULL;
34 wchar_t cpath[MAX_PATH];
37 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
38 L"Software\\TransarcCorporation\\AFS Client\\CurrentVersion",
39 0, KEY_READ, &hk_client) != ERROR_SUCCESS)
42 cb_data = sizeof(cpath);
43 if (RegQueryValueEx(hk_client, L"PathName", NULL, NULL, (LPBYTE) cpath, &cb_data) != ERROR_SUCCESS)
46 cpath[min(cb_data, MAX_PATH - 1)] = L'\0';
48 if (!PathRemoveFileSpec(cpath))
51 if (!PathAppend(cpath, L"Documentation"))
54 if (!PathAppend(cpath, L"ReleaseNotes.chm"))
57 if (!PathCanonicalize(rpath, cpath))
60 if (!PathFileExists(rpath))
67 RegCloseKey(hk_client);
78 cmd = get_default_notifier_action();
80 khui_action_trigger(cmd, NULL);
82 ZeroMemory(&idata, sizeof(idata));
84 Shell_NotifyIcon(NIM_SETFOCUS, &idata);
88 prepare_context_menu(HMENU hmenu)
92 wchar_t relnotes[MAX_PATH];
94 cmd = get_default_notifier_action();
96 if (cmd == KHUI_ACTION_NEW_CRED)
97 LoadString(hResModule, IDS_ACT_NEW, caption, ARRAYLENGTH(caption));
99 LoadString(hResModule, IDS_ACT_OPEN, caption, ARRAYLENGTH(caption));
101 ModifyMenu(hmenu, ID_DEFAULT, MF_STRING|MF_BYCOMMAND, ID_DEFAULT, caption);
102 SetMenuDefaultItem(hmenu, ID_DEFAULT, FALSE);
104 if (!get_release_notes(relnotes))
105 RemoveMenu(hmenu, ID_RELEASENOTES, MF_BYCOMMAND);
109 handle_context_menu(void)
117 hMenuBar = LoadMenu(hResModule, MAKEINTRESOURCE(IDR_CTXMENU));
118 hMenu = GetSubMenu(hMenuBar, 0);
121 prepare_context_menu(hMenu);
122 TrackPopupMenu(hMenu, TPM_NONOTIFY, pt.x, pt.y, 0, notifier_window, NULL);
126 NOTIFYICONDATA idata;
127 ZeroMemory(&idata, sizeof(idata));
128 Shell_NotifyIcon(NIM_SETFOCUS, &idata);
132 static LRESULT CALLBACK
133 notifier_wnd_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
135 if (uMsg == TOKEN_MESSAGE_ID) {
144 handle_context_menu();
151 else if (uMsg == WM_COMMAND) {
152 switch (LOWORD(wParam)) {
157 cmd = get_default_notifier_action();
159 khui_action_trigger(cmd, NULL);
165 afs_html_help(notifier_window, L"::/html/welcome.htm", HH_DISPLAY_TOPIC, 0);
169 case ID_RELEASENOTES:
171 wchar_t relnotes[MAX_PATH];
173 if (get_release_notes(relnotes))
174 HtmlHelp(GetDesktopWindow(), relnotes, HH_DISPLAY_TOC, 0);
179 return DefWindowProc(hwnd, uMsg, wParam, lParam);
183 initialize_if_necessary(void)
185 if (message_window_class == 0) {
187 sizeof(WNDCLASSEX), /* cbSize */
189 notifier_wnd_proc, /* lpfnWndProc */
192 NULL, /* hinstance */
195 NULL, /* hbrBackground */
196 NULL, /* lpszMenuName */
197 L"OpenAFSTokenStateIconNotifier", /* lpszClassName */
201 c.hInstance = hInstance;
202 message_window_class = RegisterClassEx(&c);
205 if (notifier_window == NULL && message_window_class != 0) {
206 notifier_window = CreateWindow(MAKEINTATOM(message_window_class),
207 L"OpenAFSTokenStateIconNotifierWindow",
215 assert(notifier_window != NULL);
217 if (!notification_icon_added && notifier_window != NULL) {
218 NOTIFYICONDATA idata;
220 ZeroMemory(&idata, sizeof(idata));
222 idata.cbSize = sizeof(idata);
223 idata.hWnd = notifier_window;
224 idata.uID = TOKEN_ICON_ID;
225 idata.uFlags = NIF_ICON | NIF_MESSAGE;
226 idata.uCallbackMessage = TOKEN_MESSAGE_ID;
227 idata.hIcon = (HICON) LoadImage(hResModule, MAKEINTRESOURCE(IDI_CRED_NONE),
229 LR_DEFAULTSIZE | LR_DEFAULTCOLOR | LR_SHARED);
230 notification_icon_added = Shell_NotifyIcon(NIM_ADD, &idata);
232 idata.cbSize = sizeof(idata);
233 idata.uVersion = NOTIFYICON_VERSION;
235 Shell_NotifyIcon(NIM_SETVERSION, &idata);
237 assert(notification_icon_added);
242 afs_remove_icon(void)
244 NOTIFYICONDATA idata;
246 ZeroMemory(&idata, sizeof(idata));
248 idata.cbSize = sizeof(idata);
249 idata.hWnd = notifier_window;
250 idata.uID = TOKEN_ICON_ID;
251 Shell_NotifyIcon(NIM_DELETE, &idata);
252 notification_icon_added = FALSE;
256 set_tooltip_and_icon(UINT tooltip_text, const wchar_t * postfix, UINT icon_id)
258 NOTIFYICONDATA idata;
259 wchar_t buf[ARRAYLENGTH(idata.szTip)];
261 ZeroMemory(&idata, sizeof(idata));
263 idata.cbSize = sizeof(idata);
264 idata.hWnd = notifier_window;
265 idata.uID = TOKEN_ICON_ID;
266 idata.uFlags = NIF_ICON | NIF_TIP;
267 idata.hIcon = (HICON) LoadImage(hResModule, MAKEINTRESOURCE(icon_id),
269 LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
270 if (tooltip_text != 0) {
271 LoadString(hResModule, tooltip_text, buf, ARRAYLENGTH(buf));
273 StringCbPrintf(idata.szTip, sizeof(idata.szTip),
275 (tooltip_text != 0)? buf : L"",
276 (postfix != NULL)? postfix : L"",
277 (tooltip_text != 0 || postfix != NULL)? L"\n": L"",
278 _T(AFS_VERINFO_BUILD));
280 Shell_NotifyIcon(NIM_MODIFY, &idata);
284 enum notification_icon_state state;
288 #define COLLECT_STR_LEN 256
290 static khm_int32 KHMAPI
291 collect_cell_names(khm_handle cred, void * rock)
293 wchar_t *str = (wchar_t *) rock;
294 wchar_t cell[KCDB_MAXCCH_NAME] = L"";
299 cb = sizeof(ft_expire);
300 if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE, NULL, &ft_expire, &cb)))
301 return KHM_ERROR_SUCCESS;
303 GetSystemTimeAsFileTime(&ft_now);
304 if (CompareFileTime(&ft_now, &ft_expire) >= 0)
305 return KHM_ERROR_SUCCESS;
309 if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, afs_attr_cell, NULL, cell, &cb)) &&
311 StringCchCat(str, COLLECT_STR_LEN, cell);
312 StringCchCat(str, COLLECT_STR_LEN, L"\n");
315 return KHM_ERROR_SUCCESS;
318 static khm_int32 KHMAPI
319 set_state_from_ui_thread(HWND hwnd_main, void * stuff)
321 struct state_data * d = (struct state_data *) stuff;
323 initialize_if_necessary();
326 case AFSICON_REPORT_TOKENS:
328 wchar_t cells[COLLECT_STR_LEN] = L"";
330 kcdb_credset_apply(d->credset, collect_cell_names, cells);
332 if (cells[0] == L'\0') {
333 set_tooltip_and_icon(IDS_CRED_TT_NONE, NULL, IDI_CRED_NONE);
337 set_tooltip_and_icon(0, cells, IDI_CRED_OK);
341 case AFSICON_SERVICE_STOPPED:
342 set_tooltip_and_icon(IDS_CRED_TT_NOS, NULL, IDI_CRED_SVCSTOP);
345 case AFSICON_SERVICE_ERROR:
346 set_tooltip_and_icon(IDS_CRED_TT_SERR, NULL, IDI_CRED_BROKEN);
353 (void) hwnd_main; /* unreferenced */
355 return KHM_ERROR_SUCCESS;
359 afs_icon_set_state(enum notification_icon_state state,
360 khm_handle credset_with_tokens)
364 #if KH_VERSION_API < 7
365 if (pkhui_request_UI_callback == NULL)
370 d.credset = credset_with_tokens;
372 if (notification_icon_added) {
373 set_state_from_ui_thread(NULL, &d);
375 khui_request_UI_callback(set_state_from_ui_thread, &d);