2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afsconfig.h>
15 #include <afs/param.h>
17 #include <afs/afskfw.h>
18 #include "ipaddrchg.h"
23 #define SECURITY_WIN32 1
27 * DEFINITIONS ________________________________________________________________
31 #define ID_REMIND_TIMER 1000
32 #define ID_SERVICE_TIMER 1001
34 #define cREALLOC_TABS 4
36 #define dwTABPARAM_MOUNT (LPTSTR)0
37 #define dwTABPARAM_ADVANCED (LPTSTR)1
38 #define ISCELLTAB(_psz) ((HIWORD((LONG)(_psz))) != 0)
42 * PROTOTYPES _________________________________________________________________
46 void Main_OnInitDialog (HWND hDlg);
47 void Main_OnCheckMenuRemind (void);
48 void Main_OnRemindTimer (void);
49 void Main_OnMouseOver (void);
50 void Main_OnSelectTab (void);
51 void Main_OnCheckTerminate (void);
52 HWND Main_CreateTabDialog (HWND hTab, size_t iTab);
54 BOOL CALLBACK Terminate_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
55 void Terminate_OnInitDialog (HWND hDlg);
56 void Terminate_OnOK (HWND hDlg);
60 * ROUTINES ___________________________________________________________________
64 BOOL CALLBACK Main_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
66 static UINT msgCheckTerminate = 0;
67 if (msgCheckTerminate == 0)
68 msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate"));
70 if (msg == msgCheckTerminate)
72 Main_OnCheckTerminate();
78 Main_OnInitDialog (hDlg);
82 Creds_CloseLibraries();
83 ChangeTrayIcon (NIM_DELETE);
89 Main_RepopulateTabs (FALSE);
102 if (g.fIsWinNT || IsServiceRunning())
104 if (!lp) // Got here from "/show" parameter? switch tabs.
106 HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
107 TabCtrl_SetCurSel (hTab, 0);
114 Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
119 #ifndef UAC_COMPATIBLE
120 if (g.fIsWinNT && IsServiceRunning())
121 ModalDialog (IDD_TERMINATE, NULL, (DLGPROC)Terminate_DlgProc);
125 ModalDialog (IDD_TERMINATE_SMALL, NULL, (DLGPROC)Terminate_DlgProc);
126 else // (!g.fIsWinNT)
127 ModalDialog (IDD_TERMINATE_SMALL_95, NULL, (DLGPROC)Terminate_DlgProc);
130 case M_TERMINATE_NOW:
135 Main_OnCheckMenuRemind();
141 Main_OnRemindTimer();
145 switch (((NMHDR*)lp)->code)
157 if (IsServiceRunning() || !IsServiceConfigured())
159 else if (!g.fIsWinNT)
160 Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
167 if ((hm = TaLocale_LoadMenu (MENU_TRAYICON)) != 0)
172 HMENU hmDummy = CreateMenu();
173 InsertMenu (hmDummy, 0, MF_POPUP, (UINT)hm, NULL);
175 BOOL fRemind = FALSE;
176 lock_ObtainMutex(&g.credsLock);
177 for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
179 if (g.aCreds[ iCreds ].fRemind)
182 lock_ReleaseMutex(&g.credsLock);
183 CheckMenuItem (hm, M_REMIND, MF_BYCOMMAND | ((fRemind) ? MF_CHECKED : MF_UNCHECKED));
184 SetForegroundWindow(hDlg);
185 TrackPopupMenu (GetSubMenu (hmDummy, 0),
186 TPM_RIGHTALIGN | TPM_RIGHTBUTTON,
187 pt.x, pt.y, NULL, hDlg, NULL);
188 PostMessage(hDlg, WM_NULL, 0, 0);
189 DestroyMenu (hmDummy);
198 case WM_OBTAIN_TOKENS:
199 if ( InterlockedIncrement (&g.fShowingMessage) != 1 )
200 InterlockedDecrement (&g.fShowingMessage);
202 ShowObtainCreds (wp, (char *)lp);
203 GlobalFree((void *)lp);
206 case WM_START_SERVICE:
209 if ((hManager = OpenSCManager ( NULL, NULL,
211 SC_MANAGER_ENUMERATE_SERVICE |
212 SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
215 if ((hService = OpenService ( hManager, TEXT("TransarcAFSDaemon"),
216 SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
218 if (StartService (hService, 0, 0))
219 TestAndDoMapShare(SERVICE_START_PENDING);
220 if ( KFW_is_available() && KFW_AFS_wait_for_service_start() ) {
222 KFW_import_windows_lsa();
223 #endif /* USE_MS2MIT */
224 KFW_AFS_renew_tokens_for_all_cells();
227 CloseServiceHandle (hService);
230 CloseServiceHandle (hManager);
232 if (KFW_AFS_wait_for_service_start())
233 ObtainTokensFromUserIfNeeded(g.hMain);
242 void Main_Show (BOOL fShow)
246 ShowWindow (g.hMain, SW_SHOW);
247 SetWindowPos (g.hMain, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
248 SetForegroundWindow (g.hMain);
252 SetWindowPos (g.hMain, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
257 void Main_OnInitDialog (HWND hDlg)
262 GetString (szTitle, IDS_TITLE_95);
263 SetWindowText (hDlg, szTitle);
266 TCHAR szVersion[256];
269 GetString (szVersion, IDS_UNKNOWN);
270 GetString (szUser, IDS_UNKNOWN);
273 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSREG_CLT_SW_VERSION_SUBKEY, 0,
274 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
276 DWORD dwSize = sizeof(szVersion);
277 DWORD dwType = REG_SZ;
278 RegQueryValueEx (hk, REGVAL_AFS_VERSION, NULL, &dwType, (PBYTE)szVersion, &dwSize);
280 dwSize = sizeof(dwPatch);
282 RegQueryValueEx (hk, REGVAL_AFS_PATCH, NULL, &dwType, (PBYTE)&dwPatch, &dwSize);
286 DWORD dwUserLen = sizeof(szUser)/sizeof(TCHAR);
287 if (!GetUserNameEx(NameUserPrincipal, szUser, &dwUserLen))
288 GetUserNameEx(NameSamCompatible, szUser, &dwUserLen);
290 TCHAR szSource[ cchRESOURCE ];
291 TCHAR szTarget[ cchRESOURCE ];
293 GetString (szSource, (dwPatch) ? IDS_TITLE_VERSION : IDS_TITLE_VERSION_NOPATCH);
294 wsprintf (szTarget, szSource, szVersion, dwPatch);
295 SetDlgItemText (hDlg, IDC_TITLE_VERSION, szTarget);
297 GetDlgItemText (hDlg, IDC_TITLE_NT, szSource, cchRESOURCE);
298 wsprintf (szTarget, szSource, szUser);
299 SetDlgItemText (hDlg, IDC_TITLE_NT, szTarget);
303 void Main_OnCheckMenuRemind (void)
305 BOOL fRemind = FALSE;
306 lock_ObtainMutex(&g.credsLock);
308 for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
310 if (g.aCreds[ iCreds ].fRemind)
315 for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
317 if (g.aCreds[ iCreds ].fRemind != fRemind)
319 g.aCreds[ iCreds ].fRemind = fRemind;
323 lock_ReleaseMutex(&g.credsLock);
325 // Check the active tab, and fix its checkbox if necessary
327 HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
328 LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, TabCtrl_GetCurSel(hTab));
329 if (ISCELLTAB(pszTab) && (*pszTab))
331 HWND hDlg = GetTabChild (hTab);
333 CheckDlgButton (hDlg, IDC_CREDS_REMIND, fRemind);
336 // Make sure the reminder timer is going
338 Main_EnableRemindTimer (fRemind);
342 void Main_OnRemindTimer (void)
344 Main_RepopulateTabs (TRUE);
346 // See if anything is close to expiring; if so, display a warning
347 // dialog. Make sure we never display a warning more than once.
350 if ((iExpired = Main_FindExpiredCreds()) != -1) {
351 if (InterlockedIncrement (&g.fShowingMessage) != 1) {
352 InterlockedDecrement (&g.fShowingMessage);
354 char * rootcell = NULL;
355 char password[PROBE_PASSWORD_LEN+1];
356 struct afsconf_cell cellconfig;
357 BOOL serverReachable = FALSE;
360 rootcell = (char *)GlobalAlloc(GPTR,MAXCELLCHARS+1);
364 code = KFW_AFS_get_cellconfig(g.aCreds[ iExpired ].szCell,
365 (afsconf_cell*)&cellconfig, rootcell);
369 if (KFW_is_available()) {
370 // If we can't use the FSProbe interface we can attempt to forge
371 // a kinit and if we can back an invalid user error we know the
372 // kdc is at least reachable
373 serverReachable = KFW_probe_kdc(&cellconfig);
377 for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
380 code = ObtainNewCredentials(rootcell, PROBE_USERNAME, password, TRUE);
383 case KERB_ERR_PRINCIPAL_UNKNOWN:
384 case KERB_ERR_SERVICE_EXP:
386 serverReachable = TRUE;
389 serverReachable = FALSE;
394 GlobalFree(rootcell);
397 ShowObtainCreds (TRUE, g.aCreds[ iExpired ].szCell);
399 InterlockedDecrement (&g.fShowingMessage);
405 void Main_OnMouseOver (void)
407 if ((GetTickCount() - g.tickLastRetest) > cmsecMOUSEOVER)
409 Main_RepopulateTabs (TRUE);
414 void Main_OnSelectTab (void)
416 HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
417 size_t iTab = TabCtrl_GetCurSel (hTab);
419 HWND hDlgOld = GetTabChild (hTab);
422 if ((hDlgNew = Main_CreateTabDialog (hTab, iTab)) != NULL)
423 ShowWindow (hDlgNew, SW_SHOW);
426 DestroyWindow (hDlgOld);
430 void Main_OnCheckTerminate (void)
433 BOOL bSuccess = FALSE;
435 if (RegOpenKeyEx (HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, 0,
436 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
438 DWORD dwSize = sizeof(g.fStartup);
439 DWORD dwType = REG_DWORD;
440 bSuccess = (RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize) == 0);
445 RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, 0,
446 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
448 DWORD dwSize = sizeof(g.fStartup);
449 DWORD dwType = REG_DWORD;
450 RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize);
454 Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
461 HWND Main_CreateTabDialog (HWND hTab, size_t iTab)
467 memset (&Item, 0x00, sizeof(Item));
468 Item.mask = TCIF_PARAM;
469 if (TabCtrl_GetItem (hTab, iTab, &Item))
471 psz = (LPTSTR)(Item.lParam);
474 if (psz == dwTABPARAM_ADVANCED) // Advanced tab
476 hDlg = ModelessDialog (IDD_TAB_ADVANCED, hTab, (DLGPROC)Advanced_DlgProc);
478 else if (psz == dwTABPARAM_MOUNT) // Mount Points tab
480 hDlg = ModelessDialog (IDD_TAB_MOUNT, hTab, (DLGPROC)Mount_DlgProc);
482 else if (ISCELLTAB(psz) && !*psz) // No Creds tab
484 hDlg = ModelessDialogParam (IDD_TAB_NOCREDS, hTab, (DLGPROC)Creds_DlgProc, (LPARAM)psz);
486 else if (ISCELLTAB(psz) && *psz) // Creds tab for a particular cell
488 hDlg = ModelessDialogParam (IDD_TAB_CREDS, hTab, (DLGPROC)Creds_DlgProc, (LPARAM)psz);
494 static BOOL Main_ShowMountTab(void)
498 BOOL bSuccess = FALSE;
500 if (RegOpenKeyEx (HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, 0,
501 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
503 DWORD dwSize = sizeof(bShow);
504 DWORD dwType = REG_DWORD;
505 bSuccess = (RegQueryValueEx (hk, TEXT("ShowMountTab"), NULL, &dwType, (PBYTE)&bShow, &dwSize) == 0);
510 RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, 0,
511 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_QUERY_VALUE, &hk) == 0)
513 DWORD dwSize = sizeof(bShow);
514 DWORD dwType = REG_DWORD;
515 bSuccess = (RegQueryValueEx (hk, TEXT("ShowMountTab"), NULL, &dwType, (PBYTE)&bShow, &dwSize) == 0);
522 void Main_RepopulateTabs (BOOL fDestroyInvalid)
524 static BOOL fInHere = FALSE;
529 if (IsWindowVisible (g.hMain))
530 fDestroyInvalid = FALSE;
532 // First we'll have to look around and see what credentials we currently
533 // have. This call just updates g.aCreds[]; it doesn't do anything else.
535 (void)GetCurrentCredentials();
537 // We want one tab on the main dialog for each g.aCredentials entry,
538 // and one tab for Advanced.
540 HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
542 // Generate a list of the lParams we'll be giving tabs...
544 LPTSTR *aTabs = NULL;
549 lock_ObtainMutex(&g.credsLock);
551 for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
553 if (g.aCreds[ iCreds ].szCell[0])
558 fDestroyInvalid = TRUE;
561 if (!fDestroyInvalid)
563 int nTabs = TabCtrl_GetItemCount(hTab);
564 for (int iTab = 0; iTab < nTabs; ++iTab)
566 LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, iTab);
567 if (ISCELLTAB(pszTab) && (*pszTab))
569 if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
570 aTabs[ iTabOut++ ] = CloneString(pszTab);
577 if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
578 aTabs[ iTabOut++ ] = CloneString (TEXT(""));
580 else for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
582 if (g.aCreds[ iCreds ].szCell[0])
585 for (ii = 0; ii < iTabOut; ++ii)
587 if (!ISCELLTAB (aTabs[ii]))
589 if (!lstrcmpi (g.aCreds[ iCreds ].szCell, aTabs[ ii ]))
594 if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
595 aTabs[ iTabOut++ ] = CloneString (g.aCreds[ iCreds ].szCell);
599 lock_ReleaseMutex(&g.credsLock);
601 if (Main_ShowMountTab())
603 if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
604 aTabs[ iTabOut++ ] = dwTABPARAM_MOUNT;
607 #ifndef UAC_COMPATIBLE
610 if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
611 aTabs[ iTabOut++ ] = dwTABPARAM_ADVANCED;
614 // Now erase the current tabs, and re-add new ones. Remember which tab is
615 // currently selected, so we can try to go back to it later.
618 if (TabCtrl_GetItemCount(hTab))
620 LPTSTR pszTabSel = (LPTSTR)GetTabParam (hTab, TabCtrl_GetCurSel(hTab));
621 for (size_t iSel = 0; iSel < iTabOut; ++iSel)
623 if ((!ISCELLTAB(pszTabSel)) && (!ISCELLTAB(aTabs[iSel])) && (pszTabSel == aTabs[iSel]))
625 else if (ISCELLTAB(pszTabSel) && ISCELLTAB(aTabs[iSel]) && !lstrcmpi (pszTabSel, aTabs[iSel]))
630 int nTabs = TabCtrl_GetItemCount(hTab);
631 for (int iTab = 0; iTab < nTabs; ++iTab)
633 LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, iTab);
634 if (ISCELLTAB(pszTab))
637 TabCtrl_DeleteAllItems (hTab);
639 for (size_t ii = 0; ii < iTabOut; ++ii)
641 TCHAR szTitle[cchRESOURCE];
642 if (aTabs[ii] == dwTABPARAM_ADVANCED)
643 GetString (szTitle, IDS_ADVANCED);
644 else if (aTabs[ii] == dwTABPARAM_MOUNT)
645 GetString (szTitle, IDS_MOUNT);
646 else if ((nCreds <= 1) || (aTabs[ii][0] == TEXT('\0')))
647 GetString (szTitle, IDS_CREDENTIALS);
649 lstrcpy (szTitle, aTabs[ii]);
652 memset (&Item, 0x00, sizeof(Item));
653 Item.mask = TCIF_PARAM | TCIF_TEXT;
654 Item.pszText = szTitle;
655 Item.cchTextMax = cchRESOURCE;
656 Item.lParam = (LPARAM)(aTabs[ii]);
658 TabCtrl_InsertItem (hTab, ii, &Item);
664 TabCtrl_SetCurSel (hTab, iTabSel);
672 void Main_EnableRemindTimer (BOOL fEnable)
674 static BOOL bEnabled = FALSE;
676 if ( fEnable == FALSE && bEnabled == TRUE ) {
677 KillTimer (g.hMain, ID_REMIND_TIMER);
679 } else if ( fEnable == TRUE && bEnabled == FALSE ) {
680 SetTimer (g.hMain, ID_REMIND_TIMER, (ULONG)cmsec1MINUTE * cminREMIND_TEST, NULL);
686 size_t Main_FindExpiredCreds (void)
688 size_t retval = (size_t) -1;
689 static bool expirationCheck = false;
690 lock_ObtainMutex(&g.expirationCheckLock);
691 if (expirationCheck) {
692 lock_ReleaseMutex(&g.expirationCheckLock);
695 expirationCheck = true;
696 lock_ReleaseMutex(&g.expirationCheckLock);
698 if ( KFW_is_available() ) {
700 KFW_import_windows_lsa();
701 #endif /* USE_MS2MIT */
702 KFW_AFS_renew_expiring_tokens();
705 lock_ObtainMutex(&g.credsLock);
706 for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
708 if (!g.aCreds[ iCreds ].szCell[0])
710 if (!g.aCreds[ iCreds ].fRemind)
714 GetLocalTime (&stNow);
717 SystemTimeToFileTime (&stNow, &ftNow);
720 SystemTimeToFileTime (&g.aCreds[ iCreds ].stExpires, &ftExpires);
722 LONGLONG llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
723 LONGLONG llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
725 llNow /= c100ns1SECOND;
726 llExpires /= c100ns1SECOND;
728 if (llExpires <= (llNow + (LONGLONG)cminREMIND_WARN * csec1MINUTE))
730 if ( KFW_is_available() &&
731 KFW_AFS_renew_token_for_cell(g.aCreds[ iCreds ].szCell) )
733 retval = (size_t) iCreds;
738 lock_ReleaseMutex(&g.credsLock);
740 lock_ObtainMutex(&g.expirationCheckLock);
741 expirationCheck = false;
742 lock_ReleaseMutex(&g.expirationCheckLock);
748 BOOL CALLBACK Terminate_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
753 Terminate_OnInitDialog (hDlg);
760 Terminate_OnOK (hDlg);
764 EndDialog (hDlg, IDCANCEL);
774 void Terminate_OnInitDialog (HWND hDlg)
776 BOOL fPersistent = IsServicePersistent();
778 CheckDlgButton (hDlg, IDC_STARTUP, g.fStartup);
779 CheckDlgButton (hDlg, IDC_LEAVE, fPersistent);
780 CheckDlgButton (hDlg, IDC_STOP, !fPersistent);
784 void Terminate_OnOK (HWND hDlg)
786 if (IsServiceRunning())
788 if (IsDlgButtonChecked (hDlg, IDC_STOP))
791 if ((hManager = OpenSCManager (NULL, NULL,
793 SC_MANAGER_ENUMERATE_SERVICE |
794 SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
797 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"),
798 SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
800 SERVICE_STATUS Status;
801 ControlService (hService, SERVICE_CONTROL_STOP, &Status);
803 CloseServiceHandle (hService);
806 CloseServiceHandle (hManager);
811 g.fStartup = IsDlgButtonChecked (hDlg, IDC_STARTUP);
814 if (RegCreateKeyEx (HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, 0, NULL, 0,
815 (IsWow64()?KEY_WOW64_64KEY:0)|KEY_WRITE, NULL, &hk, NULL) == 0)
817 DWORD dwSize = sizeof(g.fStartup);
818 DWORD dwType = REG_DWORD;
819 RegSetValueEx (hk, TEXT("ShowTrayIcon"), NULL, dwType, (PBYTE)&g.fStartup, dwSize);
823 Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
826 EndDialog (hDlg, IDOK);