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