registry-20040316
[openafs.git] / src / WINNT / client_creds / main.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 <osilog.h>
14 #include <afs/fs_utils.h>
15 }
16
17 #include "afscreds.h"
18 #include "..\afsreg\afsreg.h" // So we can see if the server's installed
19 #include "drivemap.h"
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include "rxkad.h"
23 #include "afskfw.h"
24
25 /*
26  * DEFINITIONS ________________________________________________________________
27  *
28  */
29
30 const TCHAR cszCLASSNAME[] = TEXT("AfsCreds");
31
32
33 /*
34  * VARIABLES __________________________________________________________________
35  *
36  */
37
38 GLOBALS g;
39
40
41 /*
42  * PROTOTYPES _________________________________________________________________
43  *
44  */
45
46 BOOL InitApp (LPSTR pszCmdLineA);
47 void ExitApp (void);
48 void Quit (void);
49 void PumpMessage (MSG *pmsg);
50 BOOL IsServerInstalled (void);
51
52
53 /*
54  * ROUTINES ___________________________________________________________________
55  *
56  */
57
58 extern "C" int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR pCmdLine, int nCmdShow)
59 {
60    Shortcut_Init();
61    TaLocale_LoadCorrespondingModule (hInst);
62
63    osi_InitTraceOption();
64    osi_LogEvent0("AFSCreds Main command line",pCmdLine);
65    fs_utils_InitMountRoot();
66
67    if (InitApp (pCmdLine))
68       {
69       MSG msg;
70       while (GetMessage (&msg, NULL, 0, 0) > 0)
71          {
72          PumpMessage (&msg);
73          }
74
75       ExitApp();
76       }
77
78    Shortcut_Exit();
79    return 0;
80 }
81
82 #define ISHIGHSECURITY(v) ( ((v) & LOGON_OPTION_HIGHSECURITY)==LOGON_OPTION_HIGHSECURITY)
83 #define REG_CLIENT_PROVIDER_KEY "SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider"
84
85 BOOL InitApp (LPSTR pszCmdLineA)
86 {
87    BOOL fShow = FALSE;
88    BOOL fQuiet = FALSE;
89    BOOL fExit = FALSE;
90    BOOL fInstall = FALSE;
91    BOOL fUninstall = FALSE;
92    BOOL fAutoInit = FALSE;
93    BOOL fNetDetect = FALSE;
94    BOOL fRenewMaps = FALSE;
95
96    // Parse the command-line
97    //
98    while (pszCmdLineA && *pszCmdLineA)
99       {
100       if ((*pszCmdLineA != '-') && (*pszCmdLineA != '/'))
101          break;
102
103       switch (*(++pszCmdLineA))
104          {
105          case 'a':
106          case 'A':
107             fAutoInit = TRUE;
108             break;
109
110          case 'm':
111          case 'M':
112             fRenewMaps = TRUE;
113             break;
114
115          case 'n':
116          case 'N':
117             fNetDetect = TRUE;
118             break;
119
120          case 's':
121          case 'S':
122             fShow = TRUE;
123             break;
124
125          case 'q':
126          case 'Q':
127             fQuiet = TRUE;
128             break;
129
130          case 'e':
131          case 'E':
132             fExit = TRUE;
133             break;
134
135          case 'i':
136          case 'I':
137             fInstall = TRUE;
138             break;
139
140          case 'u':
141          case 'U':
142             fUninstall = TRUE;
143             break;
144
145                  case ':':
146                          MapShareName(pszCmdLineA);
147                          break;
148
149          case 'z':
150          case 'Z':
151              DoUnMapShare(TRUE);
152              return(0);
153
154          case 'x':
155          case 'X':
156              TestAndDoMapShare(SERVICE_START_PENDING);
157              TestAndDoMapShare(SERVICE_RUNNING);
158              return 0;
159          }
160
161       while (*pszCmdLineA && (*pszCmdLineA != ' '))
162          ++pszCmdLineA;
163           if (*pszCmdLineA==' ') ++pszCmdLineA;
164       }
165
166    if (fInstall)
167       Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup = TRUE);
168    else if (fUninstall)
169       Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup = FALSE);
170
171    if (fInstall)
172       {
173       HKEY hk;
174       if (RegCreateKey (HKEY_CURRENT_USER, REGSTR_PATH_OPENAFS_CLIENT, &hk) == 0)
175          {
176          DWORD dwSize = sizeof(g.fStartup);
177          DWORD dwType = REG_DWORD;
178          RegSetValueEx (hk, TEXT("ShowTrayIcon"), NULL, dwType, (PBYTE)&g.fStartup, dwSize);
179          RegCloseKey (hk);
180          }
181       }
182
183    // Only show up if there's not another version of this app around already.
184    //
185    for (HWND hSearch = GetWindow (GetDesktopWindow(), GW_CHILD);
186         hSearch && IsWindow(hSearch);
187         hSearch = GetWindow (hSearch, GW_HWNDNEXT))
188       {
189       TCHAR szClassName[ cchRESOURCE ];
190       if (GetClassName (hSearch, szClassName, cchRESOURCE))
191          {
192          if (!lstrcmpi (szClassName, cszCLASSNAME))
193             {
194             if (fShow)
195                PostMessage (hSearch, WM_COMMAND, M_ACTIVATE, 0);
196             else if (fExit)
197                PostMessage (hSearch, WM_COMMAND, M_TERMINATE_NOW, 0);
198             else if (fUninstall)
199                PostMessage (hSearch, WM_COMMAND, M_TERMINATE_NOW, 0);
200             return FALSE;
201             }
202          }
203       }
204
205    if (fExit || fUninstall || fInstall)
206       return FALSE;
207
208    // Initialize our global variables and window classes
209    //
210    memset (&g, 0x00, sizeof(g));
211    g.fStartup = TRUE;
212
213    HKEY hk;
214     if (RegOpenKey (HKEY_CURRENT_USER, REGSTR_PATH_OPENAFS_CLIENT, &hk) == 0)
215     {
216         DWORD dwSize = sizeof(g.fStartup);
217         DWORD dwType = REG_DWORD;
218         RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize);
219         RegCloseKey (hk);
220     }
221     else if (RegOpenKey (HKEY_LOCAL_MACHINE, REGSTR_PATH_OPENAFS_CLIENT, &hk) == 0)
222       {
223       DWORD dwSize = sizeof(g.fStartup);
224       DWORD dwType = REG_DWORD;
225       RegQueryValueEx (hk, TEXT("ShowTrayIcon"), NULL, &dwType, (PBYTE)&g.fStartup, &dwSize);
226       RegCloseKey (hk);
227       }
228
229    Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
230
231    // Is this Windows NT?
232    //
233    OSVERSIONINFO Version;
234    memset (&Version, 0x00, sizeof(Version));
235    Version.dwOSVersionInfoSize = sizeof(Version);
236    if (GetVersionEx (&Version))
237       g.fIsWinNT = (Version.dwPlatformId == VER_PLATFORM_WIN32_NT) ? TRUE : FALSE;
238
239    if (!g.fIsWinNT)
240       lstrcpy (g.szHelpFile, TEXT("afs-light.hlp"));
241    else
242       lstrcpy (g.szHelpFile, TEXT("afs-nt.hlp"));
243
244    // Initialize winsock etc
245    //
246    WSADATA Data;
247    WSAStartup (0x0101, &Data);
248
249    InitCommonControls();
250    RegisterCheckListClass();
251    osi_Init();
252    lock_InitializeMutex(&g.expirationCheckLock, "expiration check lock");
253    lock_InitializeMutex(&g.credsLock, "global creds lock");
254
255    KFW_AFS_wait_for_service_start();
256
257    if ( IsDebuggerPresent() ) {
258        if ( !g.fIsWinNT )
259            OutputDebugString("No Service Present on non-NT systems\n");
260        else {
261            if ( IsServiceRunning() )
262                OutputDebugString("AFSD Service started\n");
263            else {
264                OutputDebugString("AFSD Service stopped\n");
265                if ( !IsServiceConfigured() )
266                    OutputDebugString("AFSD Service not configured\n");
267                else if ( fAutoInit )
268                    OutputDebugString("AFSD Service will be started\n");
269            }   
270        }
271    }
272
273     // If the service isn't started yet, and autoInit start the service
274     if ( g.fIsWinNT && !IsServiceRunning() && IsServiceConfigured() && fAutoInit ) {
275         SC_HANDLE hManager;
276
277         if ((hManager = OpenSCManager( NULL, NULL, 
278                                        SC_MANAGER_CONNECT |
279                                        SC_MANAGER_ENUMERATE_SERVICE |
280                                        SC_MANAGER_QUERY_LOCK_STATUS)) != NULL )
281         {
282             SC_HANDLE hService;
283             if ((hService = OpenService( hManager, TEXT("TransarcAFSDaemon"), 
284                                          SERVICE_QUERY_STATUS | SERVICE_START) ) != NULL)
285             {
286                 if (StartService(hService, 0, 0)) {
287                     if ( IsDebuggerPresent() )
288                         OutputDebugString("AFSD Service start successful\n");
289                     fRenewMaps = TRUE;
290                 } else if ( IsDebuggerPresent() )
291                     OutputDebugString("AFSD Service start failed\n");
292
293                 CloseServiceHandle (hService);
294             }
295
296             CloseServiceHandle (hManager);
297         }
298         KFW_AFS_wait_for_service_start();
299     }
300
301     KFW_initialize();
302
303    // Create a main window. All further initialization will be done during
304    // processing of WM_INITDIALOG.
305    //
306    WNDCLASS wc;
307    if (!GetClassInfo (NULL, WC_DIALOG, &wc))   // Get dialog class info
308       return FALSE;
309    wc.hInstance = THIS_HINST;
310    wc.hIcon = TaLocale_LoadIcon (IDI_MAIN);
311    wc.lpszClassName = cszCLASSNAME;
312    wc.style |= CS_GLOBALCLASS;
313    RegisterClass(&wc);
314
315    g.hMain = ModelessDialog (IDD_MAIN, NULL, (DLGPROC)Main_DlgProc);
316    if (g.hMain == NULL)
317       return FALSE;
318
319    // If the service isn't started yet, show our startup wizard.
320    //
321    if (!IsServiceRunning() && !fQuiet)
322       {
323       if (!g.fIsWinNT)
324          Message (MB_ICONHAND, IDS_UNCONFIG_TITLE_95, IDS_UNCONFIG_DESC_95);
325       else if (IsServiceConfigured())
326          ShowStartupWizard();
327       else if (!IsServerInstalled())
328          Message (MB_ICONHAND, IDS_UNCONFIG_TITLE, IDS_UNCONFIG_DESC);
329       }
330    if (IsServiceRunning()) { 
331       if ( fRenewMaps )
332       {
333           if ( IsDebuggerPresent() )
334               OutputDebugString("Renewing Drive Maps\n");
335           TestAndDoMapShare(SERVICE_START_PENDING);
336           TestAndDoMapShare(SERVICE_RUNNING);
337       }
338       if (fShow)
339       {
340       if ( IsDebuggerPresent() )
341           OutputDebugString("Displaying Main window\n");
342       Main_Show (TRUE);
343       }
344       // If the root cell is reachable and we have no tokens
345       // display the Obtain Tokens dialog to the user
346       if ( fAutoInit ) {
347           if ( IsDebuggerPresent() )
348               OutputDebugString("Obtaining Tokens (if needed)\n");
349           ObtainTokensFromUserIfNeeded(g.hMain);
350       }
351    } else if ( IsDebuggerPresent() )
352        OutputDebugString("AFSD Service Stopped\n");
353
354     if ( fNetDetect ) {
355         // Start IP Address Change Monitor
356         if ( IsDebuggerPresent() )
357             OutputDebugString("Activating Network Change Monitor\n");
358         IpAddrChangeMonitorInit(g.hMain);
359     }
360     Main_EnableRemindTimer(TRUE);
361     return TRUE;
362 }
363
364
365 void ExitApp (void)
366 {
367    KFW_cleanup();
368    g.hMain = NULL;
369 }
370
371
372 void PumpMessage (MSG *pmsg)
373 {
374    if (!IsMemoryManagerMessage (pmsg))
375       {
376       if (!IsDialogMessage (g.hMain, pmsg))
377          {
378          TranslateMessage (pmsg);
379          DispatchMessage (pmsg);
380          }
381       }
382 }
383
384
385 void Quit (void)
386 {
387    if (IsWindow (g.hMain))
388       {
389       ChangeTrayIcon (NIM_DELETE);
390       DestroyWindow (g.hMain);
391       }
392    PostQuitMessage (0);
393 }
394
395
396 BOOL IsServerInstalled (void)
397 {
398    BOOL fInstalled = FALSE;
399
400    TCHAR szKey[] = AFSREG_SVR_SVC_KEY;
401    LPCTSTR pch = lstrchr (szKey, TEXT('\\'));
402
403    HKEY hk;
404    if (RegOpenKey (HKEY_LOCAL_MACHINE, &pch[1], &hk) == 0)
405       {
406       fInstalled = TRUE;
407       RegCloseKey (hk);
408       }
409
410    return fInstalled;
411 }
412