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