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