Windows: no longer use WinExec in afscreds
[openafs.git] / src / WINNT / client_creds / advtab.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 #include <windows.h>
13 #include <shellapi.h>
14
15 extern "C" {
16 #include <afs/param.h>
17 #include <afs/stds.h>
18 #include <afs/afskfw.h>
19 }
20 #include <WINNT\afsreg.h>
21
22 #include "afscreds.h"
23 #ifdef USE_KFW
24 #include "afskrb5.h"
25 #endif
26
27 /*
28  * PROTOTYPES _________________________________________________________________
29  *
30  */
31
32 void Advanced_OnInitDialog (HWND hDlg);
33 void Advanced_StartTimer (HWND hDlg);
34 void Advanced_OnServiceTimer (HWND hDlg);
35 void Advanced_OnOpenCPL (HWND hDlg);
36 void Advanced_OnChangeService (HWND hDlg, WORD wCmd);
37 void Advanced_OnStartup (HWND hDlg);
38
39
40 /*
41  * ROUTINES ___________________________________________________________________
42  *
43  */
44
45 BOOL CALLBACK Advanced_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
46 {
47    switch (msg)
48       {
49       case WM_INITDIALOG:
50          RECT rTab;
51          GetClientRect (GetParent(hDlg), &rTab);
52          TabCtrl_AdjustRect (GetParent (hDlg), FALSE, &rTab); 
53          SetWindowPos (hDlg, NULL, rTab.left, rTab.top, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
54
55          Advanced_OnInitDialog (hDlg);
56          break;
57
58       case WM_TIMER:
59          Advanced_OnServiceTimer (hDlg);
60          break;
61
62       case WM_COMMAND:
63          switch (LOWORD(wp))
64             {
65             case IDC_SERVICE_STOP:
66             case IDC_SERVICE_START:
67             case IDC_SERVICE_AUTO:
68                Advanced_OnChangeService (hDlg, LOWORD(wp));
69                break;
70
71             case IDC_OPEN_CPL:
72                Advanced_OnOpenCPL (hDlg);
73                break;
74
75             case IDC_STARTUP:
76                Advanced_OnStartup (hDlg);
77                break;
78
79             case IDHELP:
80                Advanced_DlgProc (hDlg, WM_HELP, 0, 0);
81                break;
82             }
83          break;
84
85       case WM_HELP:
86          WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCREDS_TAB_ADVANCED);
87          break;
88       }
89    return FALSE;
90 }
91
92
93 void Advanced_OnInitDialog (HWND hDlg)
94 {
95    CheckDlgButton (hDlg, IDC_STARTUP, g.fStartup);
96    Advanced_OnServiceTimer (hDlg);
97    Advanced_StartTimer (hDlg);
98 }
99
100
101 void Advanced_StartTimer (HWND hDlg)
102 {
103    KillTimer (hDlg, ID_SERVICE_TIMER);
104    SetTimer (hDlg, ID_SERVICE_TIMER, (ULONG)cmsecSERVICE, NULL);
105 }
106
107
108 void Advanced_OnServiceTimer (HWND hDlg)
109 {
110    BOOL fFinal = TRUE;
111    BOOL fFound = FALSE;
112
113    struct {
114       QUERY_SERVICE_CONFIG Config;
115       BYTE buf[1024];
116    } Config;
117    memset (&Config, 0x00, sizeof(Config));
118    Config.Config.dwStartType = SERVICE_DEMAND_START;
119
120    SERVICE_STATUS Status;
121    memset (&Status, 0x00, sizeof(Status));
122    Status.dwCurrentState = SERVICE_STOPPED;
123
124    SC_HANDLE hManager;
125    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
126       {
127       SC_HANDLE hService;
128       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
129          {
130          fFound = TRUE;
131          DWORD dwSize = sizeof(Config);
132          QueryServiceConfig (hService, (QUERY_SERVICE_CONFIG*)&Config, sizeof(Config), &dwSize);
133          QueryServiceStatus (hService, &Status);
134                  TestAndDoMapShare(Status.dwCurrentState);
135
136          CloseServiceHandle (hService);
137          }
138
139       CloseServiceHandle (hManager);
140       }
141
142    if (fFound)
143       {
144       if ((Status.dwCurrentState == SERVICE_STOP_PENDING) ||
145           (Status.dwCurrentState == SERVICE_START_PENDING))
146          {
147          fFinal = FALSE;
148          }
149       }
150
151    EnableWindow (GetDlgItem (hDlg, IDC_SERVICE_START), fFound && (Status.dwCurrentState == SERVICE_STOPPED));
152    EnableWindow (GetDlgItem (hDlg, IDC_SERVICE_STOP), fFound && (Status.dwCurrentState == SERVICE_RUNNING));
153    EnableWindow (GetDlgItem (hDlg, IDC_SERVICE_AUTO), fFound);
154    CheckDlgButton (hDlg, IDC_SERVICE_AUTO, fFound && (Config.Config.dwStartType == SERVICE_AUTO_START));
155
156    TCHAR szStatus[cchRESOURCE];
157    if (!fFound)
158       GetString (szStatus, IDS_SERVICE_BROKEN);
159    else if (Status.dwCurrentState == SERVICE_RUNNING)
160       GetString (szStatus, IDS_SERVICE_RUNNING);
161    else if (Status.dwCurrentState == SERVICE_STOPPED)
162       GetString (szStatus, IDS_SERVICE_STOPPED);
163    else if (Status.dwCurrentState == SERVICE_STOP_PENDING)
164       GetString (szStatus, IDS_SERVICE_STOPPING);
165    else if (Status.dwCurrentState == SERVICE_START_PENDING)
166       GetString (szStatus, IDS_SERVICE_STARTING);
167    else
168       GetString (szStatus, IDS_SERVICE_UNKNOWN);
169    TestAndDoMapShare(Status.dwCurrentState);
170    SetDlgItemText (hDlg, IDC_SERVICE_STATUS, szStatus);
171
172    if (fFinal && GetWindowLongPtr (hDlg, DWLP_USER))
173       {
174       SetWindowLongPtr (hDlg, DWLP_USER, 0);
175       Main_RepopulateTabs (FALSE);
176       }
177
178    if (fFinal)
179       {
180       KillTimer (hDlg, ID_SERVICE_TIMER);
181       }
182 }
183
184
185 void Advanced_OnChangeService (HWND hDlg, WORD wCmd)
186 {
187    BOOL fSuccess = FALSE;
188    ULONG error = 0;
189    SC_HANDLE hManager, hService;
190    
191     switch (wCmd)
192     {
193     case IDC_SERVICE_AUTO:
194         DWORD StartType;
195         if ((hManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT |
196                                         SC_MANAGER_ENUMERATE_SERVICE |
197                                         SC_MANAGER_QUERY_LOCK_STATUS)) != NULL)
198         {
199             if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), 
200                                          SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | 
201                                          SERVICE_QUERY_STATUS)) != NULL)
202             {
203                 StartType = (IsDlgButtonChecked (hDlg, wCmd)) ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
204                 if (ChangeServiceConfig (hService, SERVICE_NO_CHANGE, StartType, 
205                                          SERVICE_NO_CHANGE, 0, 0, 0, 0, 0, 0, 0))
206                     fSuccess = TRUE;
207                 CloseServiceHandle (hService);
208             }
209             CloseServiceHandle (hManager);
210         }
211         break;
212
213     case IDC_SERVICE_START:
214         if ((hManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT |
215                                         SC_MANAGER_ENUMERATE_SERVICE |
216                                         SC_MANAGER_QUERY_LOCK_STATUS )) != NULL)
217         {
218             if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), 
219                                          SERVICE_QUERY_STATUS | SERVICE_START)) != NULL)
220             {
221                 if (StartService (hService, 0, 0))
222                 {
223                     TestAndDoMapShare(SERVICE_START_PENDING);
224                     if ( KFW_is_available() && KFW_AFS_wait_for_service_start() ) {
225 #ifdef USE_MS2MIT
226                         KFW_import_windows_lsa();
227 #endif /* USE_MS2MIT */
228                         KFW_AFS_renew_tokens_for_all_cells();
229                     }
230                     fSuccess = TRUE;
231                 }
232                 CloseServiceHandle (hService);
233             }
234             CloseServiceHandle (hManager);
235         }
236         break;
237
238     case IDC_SERVICE_STOP:
239         if ((hManager = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT |
240                                         SC_MANAGER_ENUMERATE_SERVICE |
241                                         SC_MANAGER_QUERY_LOCK_STATUS )) != NULL)
242         {            
243             if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), 
244                                          SERVICE_QUERY_STATUS | SERVICE_STOP)) != NULL)
245             {
246                 SERVICE_STATUS Status;
247                 TestAndDoUnMapShare();
248                 ControlService (hService, SERVICE_CONTROL_STOP, &Status);
249                 fSuccess = TRUE;
250             }
251             CloseServiceHandle (hService);
252         }
253         CloseServiceHandle (hManager);
254         break;
255     }
256
257    if (fSuccess)
258       {
259       if (wCmd == IDC_SERVICE_STOP)
260          SetWindowLongPtr (hDlg, DWLP_USER, TRUE);
261       Advanced_OnServiceTimer (hDlg);
262       Advanced_StartTimer (hDlg);
263 #ifdef USE_KFW
264       if ( wCmd == IDC_SERVICE_START && KRB5_is_available() && KRB5_wait_for_service_start() )
265           KRB5_AFS_renew_tokens_for_all_cells();
266 #endif /* USE_KFW */
267       }
268    else
269       {
270       if (!error)
271          error = GetLastError();
272
273       int ids;
274       switch (wCmd)
275          {
276          case IDC_SERVICE_START:
277             ids = IDS_SERVICE_FAIL_START;
278             break;
279          case IDC_SERVICE_STOP:
280             ids = IDS_SERVICE_FAIL_STOP;
281             break;
282          default:
283             ids = IDS_SERVICE_FAIL_CONFIG;
284             break;
285          }
286
287       Message (MB_OK | MB_ICONHAND, IDS_SERVICE_ERROR, ids, TEXT("%08lX"), error);
288       }
289 }
290
291
292 void Advanced_OnOpenCPL (HWND hDlg)
293 {
294     SHELLEXECUTEINFO shellExecInfo;
295
296     memset(&shellExecInfo, 0, sizeof(shellExecInfo));
297     shellExecInfo.cbSize = sizeof(shellExecInfo);
298     shellExecInfo.nShow = SW_SHOWNORMAL;
299     shellExecInfo.hwnd = hDlg;
300     shellExecInfo.lpFile = "afs_config.exe";
301     ShellExecuteEx(&shellExecInfo);
302 }
303
304
305 void Advanced_OnStartup (HWND hDlg)
306 {
307     BOOL bSuccess  = FALSE;
308     g.fStartup = IsDlgButtonChecked (hDlg, IDC_STARTUP);
309
310     HKEY hk;
311     if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, TEXT(AFSREG_CLT_SVC_PARAM_SUBKEY), 0, NULL, 0,
312                          (IsWow64()?KEY_WOW64_64KEY:0)|KEY_WRITE, NULL, &hk, NULL) == 0)
313     {
314         DWORD dwSize = sizeof(g.fStartup);
315         DWORD dwType = REG_DWORD;
316         RegSetValueEx (hk, TEXT("ShowTrayIcon"), NULL, dwType, (PBYTE)&g.fStartup, dwSize);
317         RegCloseKey (hk);
318
319         bSuccess = Shortcut_FixStartup (cszSHORTCUT_NAME, g.fStartup);
320     }
321
322     if (!bSuccess) {
323         // Reset the state
324         g.fStartup = !g.fStartup;
325         CheckDlgButton(hDlg, IDC_STARTUP, g.fStartup);
326
327         // Report error to user
328         Message (MB_OK | MB_ICONHAND, IDS_STARTUP_CHANGE_TITLE, IDS_STARTUP_CHANGE_ERROR);
329     }
330 }
331