windows-vs2005b2-20050706
[openafs.git] / src / WINNT / client_creds / window.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 #include <afs/afskfw.h>
14 #include "ipaddrchg.h"
15 }
16
17 #include "afscreds.h"
18
19 /*
20  * DEFINITIONS ________________________________________________________________
21  *
22  */
23
24 #define ID_REMIND_TIMER      1000
25 #define ID_SERVICE_TIMER     1001
26
27 #define cREALLOC_TABS        4
28
29 #define dwTABPARAM_MOUNT     (LPTSTR)0
30 #define dwTABPARAM_ADVANCED  (LPTSTR)1
31 #define ISCELLTAB(_psz)      ((HIWORD((LONG)(_psz))) != 0)
32
33
34 /*
35  * PROTOTYPES _________________________________________________________________
36  *
37  */
38
39 void Main_OnInitDialog (HWND hDlg);
40 void Main_OnCheckMenuRemind (void);
41 void Main_OnRemindTimer (void);
42 void Main_OnMouseOver (void);
43 void Main_OnSelectTab (void);
44 void Main_OnCheckTerminate (void);
45 HWND Main_CreateTabDialog (HWND hTab, size_t iTab);
46
47 BOOL CALLBACK Terminate_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
48 void Terminate_OnInitDialog (HWND hDlg);
49 void Terminate_OnOK (HWND hDlg);
50
51
52 /*
53  * ROUTINES ___________________________________________________________________
54  *
55  */
56
57 BOOL CALLBACK Main_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
58 {
59    static UINT msgCheckTerminate = 0;
60    if (msgCheckTerminate == 0)
61       msgCheckTerminate = RegisterWindowMessage (TEXT("AfsCredsCheckTerminate"));
62
63    if (msg == msgCheckTerminate)
64       {
65       Main_OnCheckTerminate();
66       }
67    else switch (msg)
68       {
69       case WM_INITDIALOG:
70          g.hMain = hDlg;
71          Main_OnInitDialog (hDlg);
72          break;
73
74       case WM_DESTROY:
75          Creds_CloseLibraries();
76          ChangeTrayIcon (NIM_DELETE);
77          break;
78
79       case WM_ACTIVATEAPP:
80          if (wp)
81             {
82             Main_RepopulateTabs (FALSE);
83             }
84          break;
85
86       case WM_COMMAND:
87          switch (LOWORD(wp))
88             {
89             case IDOK:
90             case IDCANCEL:
91                Main_Show (FALSE);
92                break;
93
94             case M_ACTIVATE:
95                if (g.fIsWinNT || IsServiceRunning())
96                   {
97                   if (!lp) // Got here from "/show" parameter? switch tabs.
98                      {
99                      HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
100                      TabCtrl_SetCurSel (hTab, 0);
101                      Main_OnSelectTab();
102                      }
103                   Main_Show (TRUE);
104                   }
105                else
106                   {
107                   Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
108                   }
109                break;
110
111             case M_TERMINATE:
112                if (g.fIsWinNT && IsServiceRunning())
113                   ModalDialog (IDD_TERMINATE, NULL, (DLGPROC)Terminate_DlgProc);
114                else if (g.fIsWinNT)
115                   ModalDialog (IDD_TERMINATE_SMALL, NULL, (DLGPROC)Terminate_DlgProc);
116                else // (!g.fIsWinNT)
117                   ModalDialog (IDD_TERMINATE_SMALL_95, NULL, (DLGPROC)Terminate_DlgProc);
118                break;
119
120             case M_TERMINATE_NOW:
121                Quit();
122                break;
123
124             case M_REMIND:
125                Main_OnCheckMenuRemind();
126                break;
127             }
128          break;
129
130       case WM_TIMER:
131          Main_OnRemindTimer();
132          break;
133
134       case WM_NOTIFY:
135          switch (((NMHDR*)lp)->code)
136             {
137             case TCN_SELCHANGE:
138                Main_OnSelectTab();
139                break;
140             }
141          break;
142
143       case WM_TRAYICON:
144          switch (lp)
145             {
146             case WM_LBUTTONDOWN:
147                if (IsServiceRunning() || !IsServiceConfigured())
148                   Main_Show (TRUE);
149                else if (!g.fIsWinNT)
150                   Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
151                else
152                   ShowStartupWizard();
153                break;
154
155             case WM_RBUTTONDOWN:
156                HMENU hm;
157                if ((hm = TaLocale_LoadMenu (MENU_TRAYICON)) != 0)
158                   {
159                   POINT pt;
160                   GetCursorPos(&pt);
161
162                   HMENU hmDummy = CreateMenu();
163                   InsertMenu (hmDummy, 0, MF_POPUP, (UINT)hm, NULL);
164
165                   BOOL fRemind = FALSE;
166                   lock_ObtainMutex(&g.credsLock);
167                   for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
168                      {
169                      if (g.aCreds[ iCreds ].fRemind)
170                         fRemind = TRUE;
171                      }
172                   lock_ReleaseMutex(&g.credsLock);
173                   CheckMenuItem (hm, M_REMIND, MF_BYCOMMAND | ((fRemind) ? MF_CHECKED : MF_UNCHECKED));
174
175                   TrackPopupMenu (GetSubMenu (hmDummy, 0),
176                                   TPM_RIGHTALIGN | TPM_RIGHTBUTTON,
177                                   pt.x, pt.y, NULL, hDlg, NULL);
178
179                   DestroyMenu (hmDummy);
180                   }
181                break;
182
183             case WM_MOUSEMOVE:
184                Main_OnMouseOver();
185                break;
186             }
187          break;
188       case WM_OBTAIN_TOKENS:
189           if ( InterlockedIncrement (&g.fShowingMessage) != 1 )
190               InterlockedDecrement (&g.fShowingMessage);
191           else
192               ShowObtainCreds (wp, (char *)lp);
193           GlobalFree((void *)lp);
194           break;
195
196       case WM_START_SERVICE:
197           {
198               SC_HANDLE hManager;
199               if ((hManager = OpenSCManager ( NULL, NULL, 
200                                               SC_MANAGER_CONNECT |
201                                               SC_MANAGER_ENUMERATE_SERVICE |
202                                               SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
203               {
204                   SC_HANDLE hService;
205                   if ((hService = OpenService ( hManager, TEXT("TransarcAFSDaemon"), 
206                                                 SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
207                   {
208                       if (StartService (hService, 0, 0))
209                           TestAndDoMapShare(SERVICE_START_PENDING);
210                                   if ( KFW_is_available() && KFW_AFS_wait_for_service_start() ) {
211 #ifdef USE_MS2MIT
212                               KFW_import_windows_lsa();
213 #endif /* USE_MS2MIT */
214                                           KFW_AFS_renew_tokens_for_all_cells();
215                                                   }
216
217                       CloseServiceHandle (hService);
218                   }
219
220                   CloseServiceHandle (hManager);
221               }
222               KFW_AFS_wait_for_service_start();
223               ObtainTokensFromUserIfNeeded(g.hMain);
224           }
225           break;
226       }
227
228    return FALSE;
229 }
230
231
232 void Main_Show (BOOL fShow)
233 {
234    if (fShow)
235       {
236       ShowWindow (g.hMain, SW_SHOW);
237       SetWindowPos (g.hMain, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
238       SetForegroundWindow (g.hMain);
239       }
240    else
241       {
242       SetWindowPos (g.hMain, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW);
243       }
244 }
245
246
247 void Main_OnInitDialog (HWND hDlg)
248 {
249     if (!g.fIsWinNT)
250     {
251         TCHAR szTitle[256];
252         GetString (szTitle, IDS_TITLE_95);
253         SetWindowText (hDlg, szTitle);
254     }
255
256     TCHAR szVersion[256];
257     DWORD dwPatch = 0;
258     TCHAR szUser[256];
259     GetString (szVersion, IDS_UNKNOWN);
260     GetString (szUser, IDS_UNKNOWN);
261
262     HKEY hk;
263     if (RegOpenKey (HKEY_LOCAL_MACHINE, AFSREG_CLT_SW_VERSION_SUBKEY, &hk) == 0)
264     {
265         DWORD dwSize = sizeof(szVersion);
266         DWORD dwType = REG_SZ;
267         RegQueryValueEx (hk, REGVAL_AFS_VERSION, NULL, &dwType, (PBYTE)szVersion, &dwSize);
268
269         dwSize = sizeof(dwPatch);
270         dwType = REG_DWORD;
271         RegQueryValueEx (hk, REGVAL_AFS_PATCH, NULL, &dwType, (PBYTE)&dwPatch, &dwSize);
272         RegCloseKey (hk);
273     }
274
275     /* We should probably be using GetUserNameEx() for this */
276     BOOL fFoundUserName = FALSE;
277     if (RegOpenKey (HKEY_CURRENT_USER, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hk) == 0)
278     {
279         DWORD dwSize = sizeof(szUser);
280         DWORD dwType = REG_SZ;
281         if (RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize) == 0)
282             fFoundUserName = TRUE;
283         RegCloseKey (hk);
284     }
285     if (!fFoundUserName ) 
286     {
287         if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Explorer"), &hk) == 0)
288         {
289             DWORD dwSize = sizeof(szUser);
290             DWORD dwType = REG_SZ;
291             if (RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize) == 0)
292                 fFoundUserName = TRUE;
293             RegCloseKey (hk);
294         }
295     }
296     if (!fFoundUserName ) 
297     {
298         if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hk) == 0)
299         {
300             DWORD dwSize = sizeof(szUser);
301             DWORD dwType = REG_SZ;
302             if (RegQueryValueEx (hk, TEXT("DefaultUserName"), NULL, &dwType, (PBYTE)szUser, &dwSize) == 0)
303                 fFoundUserName = TRUE;
304             RegCloseKey (hk);
305         }
306     }   
307     if (!fFoundUserName)
308     {
309         if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("Network\\Logon"), &hk) == 0)
310         {
311             DWORD dwSize = sizeof(szUser);
312             DWORD dwType = REG_SZ;
313             if (RegQueryValueEx (hk, TEXT("UserName"), NULL, &dwType, (PBYTE)szUser, &dwSize) == 0)
314                 fFoundUserName = TRUE;
315             RegCloseKey (hk);
316         }
317     }
318
319     TCHAR szSource[ cchRESOURCE ];
320     TCHAR szTarget[ cchRESOURCE ];
321
322     GetString (szSource, (dwPatch) ? IDS_TITLE_VERSION : IDS_TITLE_VERSION_NOPATCH);
323     wsprintf (szTarget, szSource, szVersion, dwPatch);
324     SetDlgItemText (hDlg, IDC_TITLE_VERSION, szTarget);
325
326     GetDlgItemText (hDlg, IDC_TITLE_NT, szSource, cchRESOURCE);
327     wsprintf (szTarget, szSource, szUser);
328     SetDlgItemText (hDlg, IDC_TITLE_NT, szTarget);
329 }
330
331
332 void Main_OnCheckMenuRemind (void)
333 {
334    BOOL fRemind = FALSE;
335    lock_ObtainMutex(&g.credsLock);
336    size_t iCreds;
337    for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
338       {
339       if (g.aCreds[ iCreds ].fRemind)
340          fRemind = TRUE;
341       }
342
343    fRemind = !fRemind;
344    for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
345       {
346       if (g.aCreds[ iCreds ].fRemind != fRemind)
347          {
348          g.aCreds[ iCreds ].fRemind = fRemind;
349          SaveRemind (iCreds);
350          }
351       }
352    lock_ReleaseMutex(&g.credsLock);
353
354    // Check the active tab, and fix its checkbox if necessary
355    //
356    HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
357    LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, TabCtrl_GetCurSel(hTab));
358    if (ISCELLTAB(pszTab) && (*pszTab))
359       {
360       HWND hDlg = GetTabChild (hTab);
361       if (hDlg)
362          CheckDlgButton (hDlg, IDC_CREDS_REMIND, fRemind);
363       }
364
365    // Make sure the reminder timer is going
366    //
367    Main_EnableRemindTimer (fRemind);
368 }
369
370
371 void Main_OnRemindTimer (void)
372 {
373    Main_RepopulateTabs (TRUE);
374
375    // See if anything is close to expiring; if so, display a warning
376    // dialog. Make sure we never display a warning more than once.
377    //
378    size_t iExpired;
379    if ((iExpired = Main_FindExpiredCreds()) != -1)
380       {
381       if (InterlockedIncrement (&g.fShowingMessage) != 1)
382          InterlockedDecrement (&g.fShowingMessage);
383       else
384          ShowObtainCreds (TRUE, g.aCreds[ iExpired ].szCell);
385       }
386 }
387
388
389 void Main_OnMouseOver (void)
390 {
391    if ((GetTickCount() - g.tickLastRetest) > cmsecMOUSEOVER)
392       {
393       Main_RepopulateTabs (TRUE);
394       }
395 }
396
397
398 void Main_OnSelectTab (void)
399 {
400    HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
401    size_t iTab = TabCtrl_GetCurSel (hTab);
402
403    HWND hDlgOld = GetTabChild (hTab);
404
405    HWND hDlgNew;
406    if ((hDlgNew = Main_CreateTabDialog (hTab, iTab)) != NULL)
407       ShowWindow (hDlgNew, SW_SHOW);
408
409    if (hDlgOld)
410       DestroyWindow (hDlgOld);
411 }
412
413
414 void Main_OnCheckTerminate (void)
415 {
416     HKEY hk;
417
418     if (RegOpenKey (HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, &hk) == 0)
419     {
420         DWORD dwSize = sizeof(g.fStartup);
421         DWORD dwType = REG_DWORD;
422         RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize);
423         RegCloseKey (hk);
424     }
425     else if (RegOpenKey (HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY, &hk) == 0)
426     {
427       DWORD dwSize = sizeof(g.fStartup);
428       DWORD dwType = REG_DWORD;
429       RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize);
430       RegCloseKey (hk);
431     }
432
433     Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
434
435     if (!g.fStartup)
436         Quit();
437 }
438
439
440 HWND Main_CreateTabDialog (HWND hTab, size_t iTab)
441 {
442    HWND hDlg = NULL;
443    LPTSTR psz = NULL;
444
445    TC_ITEM Item;
446    memset (&Item, 0x00, sizeof(Item));
447    Item.mask = TCIF_PARAM;
448    if (TabCtrl_GetItem (hTab, iTab, &Item))
449       {
450       psz = (LPTSTR)(Item.lParam);
451       }
452
453    if (psz == dwTABPARAM_ADVANCED)    // Advanced tab
454       {
455       hDlg = ModelessDialog (IDD_TAB_ADVANCED, hTab, (DLGPROC)Advanced_DlgProc);
456       }
457    else if (psz == dwTABPARAM_MOUNT)  // Mount Points tab
458       {
459       hDlg = ModelessDialog (IDD_TAB_MOUNT, hTab, (DLGPROC)Mount_DlgProc);
460       }
461    else if (ISCELLTAB(psz) && !*psz)  // No Creds tab
462       {
463       hDlg = ModelessDialogParam (IDD_TAB_NOCREDS, hTab, (DLGPROC)Creds_DlgProc, (LPARAM)psz);
464       }
465    else if (ISCELLTAB(psz) && *psz)   // Creds tab for a particular cell
466       {
467       hDlg = ModelessDialogParam (IDD_TAB_CREDS, hTab, (DLGPROC)Creds_DlgProc, (LPARAM)psz);
468       }
469
470    return hDlg;
471 }
472
473
474 void Main_RepopulateTabs (BOOL fDestroyInvalid)
475 {
476    static BOOL fInHere = FALSE;
477    if (!fInHere)
478       {
479       fInHere = TRUE;
480
481       if (IsWindowVisible (g.hMain))
482          fDestroyInvalid = FALSE;
483
484       // First we'll have to look around and see what credentials we currently
485       // have. This call just updates g.aCreds[]; it doesn't do anything else.
486       //
487       (void)GetCurrentCredentials();
488
489       // We want one tab on the main dialog for each g.aCredentials entry,
490       // and one tab for Advanced.
491       //
492       HWND hTab = GetDlgItem (g.hMain, IDC_TABS);
493
494       // Generate a list of the lParams we'll be giving tabs...
495       //
496       LPTSTR *aTabs = NULL;
497       size_t cTabs = 0;
498       size_t iTabOut = 0;
499
500       size_t nCreds = 0;
501       lock_ObtainMutex(&g.credsLock);
502       size_t iCreds;
503       for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
504          {
505          if (g.aCreds[ iCreds ].szCell[0])
506             ++nCreds;
507          }
508       if (!nCreds)
509          {
510          fDestroyInvalid = TRUE;
511          }
512
513       if (!fDestroyInvalid)
514          {
515          int nTabs = TabCtrl_GetItemCount(hTab);
516          for (int iTab = 0; iTab < nTabs; ++iTab)
517             {
518             LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, iTab);
519             if (ISCELLTAB(pszTab) && (*pszTab))
520                {
521                if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
522                   aTabs[ iTabOut++ ] = CloneString(pszTab);
523                }
524             }
525          }
526
527       if (nCreds == 0)
528          {
529          if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
530             aTabs[ iTabOut++ ] = CloneString (TEXT(""));
531          }
532       else for (iCreds = 0; iCreds < g.cCreds; ++iCreds)
533          {
534          if (g.aCreds[ iCreds ].szCell[0])
535             {
536             size_t ii;
537             for (ii = 0; ii < iTabOut; ++ii)
538                {
539                if (!ISCELLTAB (aTabs[ii]))
540                   continue;
541                if (!lstrcmpi (g.aCreds[ iCreds ].szCell, aTabs[ ii ]))
542                   break;
543                }
544             if (ii == iTabOut)
545                {
546                if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
547                   aTabs[ iTabOut++ ] = CloneString (g.aCreds[ iCreds ].szCell);
548                }
549             }
550          }
551       lock_ReleaseMutex(&g.credsLock);
552
553       if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
554          aTabs[ iTabOut++ ] = dwTABPARAM_MOUNT;
555
556       if (g.fIsWinNT)
557          {
558          if (REALLOC (aTabs, cTabs, 1+iTabOut, cREALLOC_TABS))
559             aTabs[ iTabOut++ ] = dwTABPARAM_ADVANCED;
560          }
561
562       // Now erase the current tabs, and re-add new ones. Remember which tab is
563       // currently selected, so we can try to go back to it later.
564       //
565       int iTabSel = 0;
566       if (TabCtrl_GetItemCount(hTab))
567          {
568          LPTSTR pszTabSel = (LPTSTR)GetTabParam (hTab, TabCtrl_GetCurSel(hTab));
569          for (size_t iSel = 0; iSel < iTabOut; ++iSel)
570             {
571             if ((!ISCELLTAB(pszTabSel))  && (!ISCELLTAB(aTabs[iSel])) && (pszTabSel == aTabs[iSel]))
572                iTabSel = iSel;
573             else if (ISCELLTAB(pszTabSel) && ISCELLTAB(aTabs[iSel]) && !lstrcmpi (pszTabSel, aTabs[iSel]))
574                iTabSel = iSel;
575             }
576          }
577
578       int nTabs = TabCtrl_GetItemCount(hTab);
579       for (int iTab = 0; iTab < nTabs; ++iTab)
580          {
581          LPTSTR pszTab = (LPTSTR)GetTabParam (hTab, iTab);
582          if (ISCELLTAB(pszTab))
583             FreeString (pszTab);
584          }
585       TabCtrl_DeleteAllItems (hTab);
586
587       for (size_t ii = 0; ii < iTabOut; ++ii)
588          {
589          TCHAR szTitle[cchRESOURCE];
590          if (aTabs[ii] == dwTABPARAM_ADVANCED)
591             GetString (szTitle, IDS_ADVANCED);
592          else if (aTabs[ii] == dwTABPARAM_MOUNT)
593             GetString (szTitle, IDS_MOUNT);
594          else if ((nCreds <= 1) || (aTabs[ii][0] == TEXT('\0')))
595             GetString (szTitle, IDS_CREDENTIALS);
596          else
597             lstrcpy (szTitle, aTabs[ii]);
598
599          TC_ITEM Item;
600          memset (&Item, 0x00, sizeof(Item));
601          Item.mask = TCIF_PARAM | TCIF_TEXT;
602          Item.pszText = szTitle;
603          Item.cchTextMax = cchRESOURCE;
604          Item.lParam = (LPARAM)(aTabs[ii]);
605
606          TabCtrl_InsertItem (hTab, ii, &Item);
607          }
608
609       if (aTabs != NULL)
610          Free (aTabs);
611
612       TabCtrl_SetCurSel (hTab, iTabSel);
613       Main_OnSelectTab ();
614
615       fInHere = FALSE;
616       }
617 }
618
619
620 void Main_EnableRemindTimer (BOOL fEnable)
621 {
622    static BOOL bEnabled = FALSE;
623
624    if ( fEnable == FALSE && bEnabled == TRUE ) {
625        KillTimer (g.hMain, ID_REMIND_TIMER);
626        bEnabled = FALSE;
627    } else if ( fEnable == TRUE && bEnabled == FALSE ) {
628       SetTimer (g.hMain, ID_REMIND_TIMER, (ULONG)cmsec1MINUTE * cminREMIND_TEST, NULL);
629       bEnabled = TRUE;
630    }
631 }
632
633
634 size_t Main_FindExpiredCreds (void)
635 {
636    size_t retval = (size_t) -1;
637    lock_ObtainMutex(&g.expirationCheckLock);
638    if ( KFW_is_available() )
639        KFW_AFS_renew_expiring_tokens();
640    lock_ObtainMutex(&g.credsLock);
641    for (size_t iCreds = 0; iCreds < g.cCreds; ++iCreds)
642       {
643       if (!g.aCreds[ iCreds ].szCell[0])
644          continue;
645       if (!g.aCreds[ iCreds ].fRemind)
646          continue;
647
648       SYSTEMTIME stNow;
649       GetLocalTime (&stNow);
650
651       FILETIME ftNow;
652       SystemTimeToFileTime (&stNow, &ftNow);
653
654       FILETIME ftExpires;
655       SystemTimeToFileTime (&g.aCreds[ iCreds ].stExpires, &ftExpires);
656
657       LONGLONG llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
658       LONGLONG llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
659
660       llNow /= c100ns1SECOND;
661       llExpires /= c100ns1SECOND;
662
663       if (llExpires <= (llNow + (LONGLONG)cminREMIND_WARN * csec1MINUTE))
664          {
665          if ( KFW_is_available() &&
666               KFW_AFS_renew_token_for_cell(g.aCreds[ iCreds ].szCell) )
667              continue;
668          retval = (size_t) iCreds;
669          break;
670          }
671       }
672    
673    lock_ReleaseMutex(&g.credsLock);
674    lock_ReleaseMutex(&g.expirationCheckLock);
675
676    return retval;
677 }
678
679
680 BOOL CALLBACK Terminate_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
681 {
682    switch (msg)
683       {
684       case WM_INITDIALOG:
685          Terminate_OnInitDialog (hDlg);
686          break;
687
688       case WM_COMMAND:
689          switch (LOWORD(wp))
690             {
691             case IDOK:
692                Terminate_OnOK (hDlg);
693                break;
694
695             case IDCANCEL:
696                EndDialog (hDlg, IDCANCEL);
697                break;
698             }
699          break;
700       }
701
702    return FALSE;
703 }
704
705
706 void Terminate_OnInitDialog (HWND hDlg)
707 {
708    BOOL fPersistent = IsServicePersistent();
709
710    CheckDlgButton (hDlg, IDC_STARTUP, g.fStartup);
711    CheckDlgButton (hDlg, IDC_LEAVE, fPersistent);
712    CheckDlgButton (hDlg, IDC_STOP, !fPersistent);
713 }
714
715
716 void Terminate_OnOK (HWND hDlg)
717 {
718    if (IsServiceRunning())
719       {
720       if (IsDlgButtonChecked (hDlg, IDC_STOP))
721          {
722          SC_HANDLE hManager;
723              if ((hManager = OpenSCManager (NULL, NULL, 
724                                             SC_MANAGER_CONNECT |
725                                             SC_MANAGER_ENUMERATE_SERVICE |
726                                             SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
727             {
728             SC_HANDLE hService;
729             if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), 
730                                          SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
731                {
732                SERVICE_STATUS Status;
733                ControlService (hService, SERVICE_CONTROL_STOP, &Status);
734
735                CloseServiceHandle (hService);
736                }
737
738             CloseServiceHandle (hManager);
739             }
740          }
741       }
742
743    g.fStartup = IsDlgButtonChecked (hDlg, IDC_STARTUP);
744
745     HKEY hk;
746     if (RegCreateKey (HKEY_CURRENT_USER, AFSREG_USER_OPENAFS_SUBKEY, &hk) == 0)
747     {
748         DWORD dwSize = sizeof(g.fStartup);
749         DWORD dwType = REG_DWORD;
750         RegSetValueEx (hk, TEXT("ShowTrayIcon"), NULL, dwType, (PBYTE)&g.fStartup, dwSize);
751         RegCloseKey (hk);
752     }
753
754    Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
755
756    Quit();
757    EndDialog (hDlg, IDOK);
758 }
759