1 /*
2  * PROJECT:     ReactOS Services
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        base/applications/mscutils/servman/propsheet_logon.c
5  * PURPOSE:     Logon property page
6  * COPYRIGHT:   Eric Kohl
7  */
8 
9 #include "precomp.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 #define DEFAULT_PASSWORD L"               "
15 
16 typedef struct _LOGONDATA
17 {
18     ENUM_SERVICE_STATUS_PROCESS *pService;
19     LPQUERY_SERVICE_CONFIG pServiceConfig;
20     WCHAR szAccountName[64];
21     WCHAR szPassword1[64];
22     WCHAR szPassword2[64];
23     INT nInteractive;
24     BOOL bInitialized;
25     BOOL bLocalSystem;
26     BOOL bAccountChanged;
27 } LOGONDATA, *PLOGONDATA;
28 
29 
30 static
31 VOID
32 SetControlStates(
33     HWND hwndDlg,
34     PLOGONDATA pLogonData,
35     BOOL bLocalSystem)
36 {
37     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_INTERACTIVE), bLocalSystem);
38     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_ACCOUNTNAME), !bLocalSystem);
39     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_SEARCH), FALSE /*!bLocalSystem*/);
40     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_PW1TEXT), !bLocalSystem);
41     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_PASSWORD1), !bLocalSystem);
42     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_PW2TEXT), !bLocalSystem);
43     EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_PASSWORD2), !bLocalSystem);
44 
45     if (bLocalSystem)
46     {
47         SendDlgItemMessageW(hwndDlg, IDC_LOGON_INTERACTIVE, BM_SETCHECK, (WPARAM)pLogonData->nInteractive, 0);
48 
49         if (pLogonData->bInitialized == TRUE)
50         {
51             GetDlgItemText(hwndDlg, IDC_LOGON_ACCOUNTNAME, pLogonData->szAccountName, 64);
52             GetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD1, pLogonData->szPassword1, 64);
53             GetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD2, pLogonData->szPassword2, 64);
54         }
55 
56         SetDlgItemText(hwndDlg, IDC_LOGON_ACCOUNTNAME, L"");
57         SetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD1, L"");
58         SetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD2, L"");
59     }
60     else
61     {
62         if (pLogonData->bInitialized == TRUE)
63             pLogonData->nInteractive = SendDlgItemMessageW(hwndDlg, IDC_LOGON_INTERACTIVE, BM_GETCHECK, 0, 0);
64         SendDlgItemMessageW(hwndDlg, IDC_LOGON_INTERACTIVE, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
65 
66         SetDlgItemText(hwndDlg, IDC_LOGON_ACCOUNTNAME, pLogonData->szAccountName);
67         SetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD1, pLogonData->szPassword1);
68         SetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD2, pLogonData->szPassword2);
69     }
70 
71     pLogonData->bLocalSystem = bLocalSystem;
72 }
73 
74 
75 static
76 BOOL
77 SetServiceAccount(
78     LPWSTR lpServiceName,
79     DWORD dwServiceType,
80     LPWSTR lpStartName,
81     LPWSTR lpPassword)
82 {
83     SC_HANDLE hSCManager;
84     SC_HANDLE hSc;
85     SC_LOCK scLock;
86     BOOL bRet = FALSE;
87 
88     hSCManager = OpenSCManagerW(NULL,
89                                 NULL,
90                                 SC_MANAGER_LOCK);
91     if (hSCManager)
92     {
93         scLock = LockServiceDatabase(hSCManager);
94         if (scLock)
95         {
96             hSc = OpenServiceW(hSCManager,
97                                lpServiceName,
98                                SERVICE_CHANGE_CONFIG);
99             if (hSc)
100             {
101                 if (ChangeServiceConfigW(hSc,
102                                          dwServiceType,
103                                          SERVICE_NO_CHANGE,
104                                          SERVICE_NO_CHANGE,
105                                          NULL,
106                                          NULL,
107                                          NULL,
108                                          NULL,
109                                          lpStartName,
110                                          lpPassword,
111                                          NULL))
112                 {
113                     bRet = TRUE;
114                 }
115 
116                 CloseServiceHandle(hSc);
117             }
118 
119             UnlockServiceDatabase(scLock);
120         }
121 
122         CloseServiceHandle(hSCManager);
123     }
124 
125     if (!bRet)
126         GetError();
127 
128     return bRet;
129 }
130 
131 
132 static
133 BOOL
134 OnQueryInitialFocus(
135     HWND hwndDlg,
136     PLOGONDATA pLogonData)
137 {
138     HWND hwnd = GetDlgItem(hwndDlg, pLogonData->bLocalSystem ? IDC_LOGON_SYSTEMACCOUNT : IDC_LOGON_THISACCOUNT);
139 
140     SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)hwnd);
141 
142     return TRUE;
143 }
144 
145 
146 static
147 BOOL
148 OnApply(
149     HWND hwndDlg,
150     PLOGONDATA pLogonData)
151 {
152     WCHAR szAccountName[64];
153     WCHAR szPassword1[64];
154     WCHAR szPassword2[64];
155     DWORD dwServiceType = SERVICE_NO_CHANGE;
156     BOOL bRet = TRUE;
157 
158     if (!pLogonData->bAccountChanged)
159         return TRUE;
160 
161     if (SendDlgItemMessageW(hwndDlg, IDC_LOGON_SYSTEMACCOUNT, BM_GETCHECK, 0, 0) == BST_CHECKED)
162     {
163         /* System account selected */
164         wcscpy(szAccountName, L"LocalSystem");
165         wcscpy(szPassword1, L"");
166         wcscpy(szPassword2, L"");
167 
168         /* Handle the interactive flag */
169         dwServiceType = pLogonData->pServiceConfig->dwServiceType;
170         if (SendDlgItemMessageW(hwndDlg, IDC_LOGON_INTERACTIVE, BM_GETCHECK, 0, 0) == BST_CHECKED)
171             dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
172         else
173             dwServiceType &= ~SERVICE_INTERACTIVE_PROCESS;
174     }
175     else
176     {
177         /* Other account selected */
178         GetDlgItemText(hwndDlg, IDC_LOGON_ACCOUNTNAME, szAccountName, 64);
179         GetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD1, szPassword1, 64);
180         GetDlgItemText(hwndDlg, IDC_LOGON_PASSWORD2, szPassword2, 64);
181 
182         if (wcscmp(szPassword1, szPassword2))
183         {
184             ResourceMessageBox(GetModuleHandle(NULL), hwndDlg, MB_OK | MB_ICONWARNING, IDS_APPNAME, IDS_NOT_SAME_PASSWORD);
185             return FALSE;
186         }
187 
188         if (!wcscmp(szPassword1, DEFAULT_PASSWORD))
189         {
190             ResourceMessageBox(GetModuleHandle(NULL), hwndDlg, MB_OK | MB_ICONWARNING, IDS_APPNAME, IDS_INVALID_PASSWORD);
191             return FALSE;
192         }
193     }
194 
195 
196     bRet = SetServiceAccount(pLogonData->pService->lpServiceName,
197                              dwServiceType,
198                              szAccountName,
199                              szPassword1);
200     if (bRet == FALSE)
201     {
202 
203     }
204 
205     if (bRet == TRUE)
206     {
207         pLogonData->bAccountChanged = FALSE;
208 
209     }
210 
211     return bRet;
212 }
213 
214 
215 /*
216  * Logon Property dialog callback.
217  * Controls messages to the Logon dialog
218  */
219 INT_PTR
220 CALLBACK
221 LogonPageProc(
222     HWND hwndDlg,
223     UINT uMsg,
224     WPARAM wParam,
225     LPARAM lParam)
226 {
227     PLOGONDATA pLogonData;
228 
229     /* Get the window context */
230     pLogonData = (PLOGONDATA)GetWindowLongPtr(hwndDlg,
231                                               GWLP_USERDATA);
232     if (pLogonData == NULL && uMsg != WM_INITDIALOG)
233     {
234         return FALSE;
235     }
236 
237     switch (uMsg)
238     {
239         case WM_INITDIALOG:
240             pLogonData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LOGONDATA));
241             if (pLogonData != NULL)
242             {
243                 SetWindowLongPtr(hwndDlg,
244                                  GWLP_USERDATA,
245                                  (LONG_PTR)pLogonData);
246 
247                 pLogonData->bInitialized = FALSE;
248                 pLogonData->pService = ((PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam))->pService;
249 
250                 pLogonData->pServiceConfig = GetServiceConfig(pLogonData->pService->lpServiceName);
251                 if (pLogonData->pServiceConfig != NULL)
252                 {
253                     wcscpy(pLogonData->szPassword1, DEFAULT_PASSWORD);
254                     wcscpy(pLogonData->szPassword2, DEFAULT_PASSWORD);
255 
256                     if (pLogonData->pServiceConfig->lpServiceStartName == NULL ||
257                         _wcsicmp(pLogonData->pServiceConfig->lpServiceStartName, L"LocalSystem") == 0)
258                     {
259                         SendDlgItemMessageW(hwndDlg, IDC_LOGON_SYSTEMACCOUNT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
260                         if (pLogonData->pServiceConfig->dwServiceType & SERVICE_INTERACTIVE_PROCESS) {
261                             pLogonData->nInteractive = BST_CHECKED;
262                             SendDlgItemMessageW(hwndDlg, IDC_LOGON_INTERACTIVE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
263                         }
264                         SetControlStates(hwndDlg, pLogonData, TRUE);
265                     }
266                     else
267                     {
268                         wcscpy(pLogonData->szAccountName, pLogonData->pServiceConfig->lpServiceStartName);
269                         SendDlgItemMessageW(hwndDlg, IDC_LOGON_THISACCOUNT, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
270                         SetControlStates(hwndDlg, pLogonData, FALSE);
271                     }
272                 }
273 
274                 pLogonData->bInitialized = TRUE;
275             }
276 
277             EnableWindow(GetDlgItem(hwndDlg, IDC_LOGON_HWPROFILE), FALSE);
278             break;
279 
280         case WM_DESTROY:
281             if (pLogonData->pServiceConfig)
282                 HeapFree(GetProcessHeap(), 0, pLogonData->pServiceConfig);
283 
284             HeapFree(GetProcessHeap(), 0, pLogonData);
285             break;
286 
287         case WM_COMMAND:
288             switch(LOWORD(wParam))
289             {
290                 case IDC_LOGON_SYSTEMACCOUNT:
291                     if (HIWORD(wParam) == BN_CLICKED)
292                     {
293                         if (pLogonData->bInitialized)
294                         {
295                             pLogonData->bAccountChanged = TRUE;
296                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
297                         }
298                         SetControlStates(hwndDlg, pLogonData, TRUE);
299                     }
300                     break;
301 
302                 case IDC_LOGON_THISACCOUNT:
303                     if (HIWORD(wParam) == BN_CLICKED)
304                     {
305                         if (pLogonData->bInitialized)
306                         {
307                             pLogonData->bAccountChanged = TRUE;
308                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
309                         }
310                         SetControlStates(hwndDlg, pLogonData, FALSE);
311                     }
312                     break;
313 
314                 case IDC_LOGON_INTERACTIVE:
315                     if (HIWORD(wParam) == BN_CLICKED)
316                     {
317                         if (pLogonData->bInitialized)
318                         {
319                             pLogonData->bAccountChanged = TRUE;
320                             PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
321                         }
322                     }
323                     break;
324 
325                 case IDC_LOGON_ACCOUNTNAME:
326                 case IDC_LOGON_PASSWORD1:
327                 case IDC_LOGON_PASSWORD2:
328                     if (HIWORD(wParam) == EN_CHANGE && pLogonData->bInitialized)
329                     {
330                         pLogonData->bAccountChanged = TRUE;
331                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
332                     }
333                     break;
334             }
335             break;
336 
337         case WM_NOTIFY:
338             switch (((LPNMHDR)lParam)->code)
339             {
340                 case PSN_QUERYINITIALFOCUS:
341                     return OnQueryInitialFocus(hwndDlg, pLogonData);
342 
343                 case PSN_APPLY:
344                     return OnApply(hwndDlg, pLogonData);
345             }
346             break;
347     }
348 
349     return FALSE;
350 }
351