xref: /reactos/dll/win32/msgina/tui.c (revision 40462c92)
1 /*
2  * PROJECT:         ReactOS msgina.dll
3  * FILE:            dll/win32/msgina/tui.c
4  * PURPOSE:         ReactOS Logon GINA DLL
5  * PROGRAMMER:      Herv� Poussineau (hpoussin@reactos.org)
6  */
7 
8 #include "msgina.h"
9 
10 #include <wincon.h>
11 
12 static BOOL
13 TUIInitialize(
14     IN OUT PGINA_CONTEXT pgContext)
15 {
16     TRACE("TUIInitialize(%p)\n", pgContext);
17 
18     return AllocConsole();
19 }
20 
21 static BOOL
22 TUIDisplayStatusMessage(
23     IN PGINA_CONTEXT pgContext,
24     IN HDESK hDesktop,
25     IN DWORD dwOptions,
26     IN PWSTR pTitle,
27     IN PWSTR pMessage)
28 {
29     static LPCWSTR newLine = L"\n";
30     DWORD result;
31 
32     TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage);
33 
34     UNREFERENCED_PARAMETER(pgContext);
35     UNREFERENCED_PARAMETER(hDesktop);
36     UNREFERENCED_PARAMETER(dwOptions);
37     UNREFERENCED_PARAMETER(pTitle);
38 
39     return
40         WriteConsoleW(
41             GetStdHandle(STD_OUTPUT_HANDLE),
42             pMessage,
43             wcslen(pMessage),
44             &result,
45             NULL) &&
46         WriteConsoleW(
47             GetStdHandle(STD_OUTPUT_HANDLE),
48             newLine,
49             wcslen(newLine),
50             &result,
51             NULL);
52 }
53 
54 static BOOL
55 TUIRemoveStatusMessage(
56     IN PGINA_CONTEXT pgContext)
57 {
58     UNREFERENCED_PARAMETER(pgContext);
59 
60     /* Nothing to do */
61     return TRUE;
62 }
63 
64 static BOOL
65 DisplayResourceText(
66     IN UINT uIdResourceText,
67     IN BOOL AddNewLine)
68 {
69     WCHAR Prompt[256];
70     static LPCWSTR newLine = L"\n";
71     DWORD count;
72 
73     if (0 == LoadStringW(hDllInstance, uIdResourceText, Prompt, _countof(Prompt)))
74         return FALSE;
75     if (!WriteConsoleW(
76         GetStdHandle(STD_OUTPUT_HANDLE),
77         Prompt, wcslen(Prompt),
78         &count, NULL))
79     {
80         return FALSE;
81     }
82     if (AddNewLine)
83     {
84         if (!WriteConsoleW(
85             GetStdHandle(STD_OUTPUT_HANDLE),
86             newLine, wcslen(newLine),
87             &count, NULL))
88         {
89             return FALSE;
90         }
91     }
92     return TRUE;
93 }
94 
95 static VOID
96 TUIDisplaySASNotice(
97     IN OUT PGINA_CONTEXT pgContext)
98 {
99     TRACE("TUIDisplaySASNotice()\n");
100 
101     UNREFERENCED_PARAMETER(pgContext);
102 
103     DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE);
104     DisplayResourceText(IDS_PRESSCTRLALTDELETE, TRUE);
105 }
106 
107 static INT
108 TUILoggedOnSAS(
109     IN OUT PGINA_CONTEXT pgContext,
110     IN DWORD dwSasType)
111 {
112     TRACE("TUILoggedOnSAS()\n");
113 
114     UNREFERENCED_PARAMETER(pgContext);
115 
116     if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL)
117     {
118         /* Nothing to do for WLX_SAS_TYPE_TIMEOUT */
119         return WLX_SAS_ACTION_NONE;
120     }
121 
122     FIXME("FIXME: TUILoggedOnSAS(): Let's suppose the user wants to log off...\n");
123     return WLX_SAS_ACTION_LOGOFF;
124 }
125 
126 static BOOL
127 ReadString(
128     IN UINT uIdResourcePrompt,
129     IN OUT PWSTR Buffer,
130     IN DWORD BufferLength,
131     IN BOOL ShowString)
132 {
133     DWORD count, i;
134     WCHAR charToDisplay[] = { 0, UNICODE_NULL };
135 
136     if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0))
137         return FALSE;
138 
139     if (!FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)))
140         return FALSE;
141 
142     if (!DisplayResourceText(uIdResourcePrompt, FALSE))
143         return FALSE;
144 
145     i = 0;
146     for (;;)
147     {
148         WCHAR readChar;
149         if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &readChar, 1, &count, NULL))
150             return FALSE;
151         if (readChar == '\r' || readChar == '\n')
152         {
153             /* End of string */
154             charToDisplay[0] = L'\n';
155             WriteConsoleW(
156                 GetStdHandle(STD_OUTPUT_HANDLE),
157                 charToDisplay,
158                 wcslen(charToDisplay),
159                 &count,
160                 NULL);
161             break;
162         }
163         if (ShowString)
164         {
165             /* Display the char */
166             charToDisplay[0] = readChar;
167             WriteConsoleW(
168                 GetStdHandle(STD_OUTPUT_HANDLE),
169                 charToDisplay,
170                 wcslen(charToDisplay),
171                 &count,
172                 NULL);
173         }
174         Buffer[i++] = readChar;
175         /* FIXME: buffer overflow if the user writes too many chars! */
176         UNREFERENCED_PARAMETER(BufferLength);
177         /* FIXME: handle backspace */
178     }
179     Buffer[i] = UNICODE_NULL;
180 
181     if (!ShowString)
182     {
183         /* Still display the \n */
184         static LPCWSTR newLine = L"\n";
185         DWORD result;
186         WriteConsoleW(
187             GetStdHandle(STD_OUTPUT_HANDLE),
188             newLine,
189             wcslen(newLine),
190             &result,
191             NULL);
192     }
193     return TRUE;
194 }
195 
196 static INT
197 TUILoggedOutSAS(
198     IN OUT PGINA_CONTEXT pgContext)
199 {
200     WCHAR UserName[256];
201     WCHAR Password[256];
202     NTSTATUS Status;
203     NTSTATUS SubStatus = STATUS_SUCCESS;
204 
205     TRACE("TUILoggedOutSAS()\n");
206 
207     /* Ask the user for credentials */
208     if (!ReadString(IDS_ASKFORUSER, UserName, _countof(UserName), TRUE))
209         return WLX_SAS_ACTION_NONE;
210     if (!ReadString(IDS_ASKFORPASSWORD, Password, _countof(Password), FALSE))
211         return WLX_SAS_ACTION_NONE;
212 
213     Status = DoLoginTasks(pgContext, UserName, NULL, Password, &SubStatus);
214     if (Status == STATUS_SUCCESS)
215     {
216         if (CreateProfile(pgContext, UserName, NULL, Password))
217             return WLX_SAS_ACTION_LOGON;
218     }
219 
220     return WLX_SAS_ACTION_NONE;
221 }
222 
223 static INT
224 TUILockedSAS(
225     IN OUT PGINA_CONTEXT pgContext)
226 {
227     HANDLE hToken;
228     WCHAR UserName[256];
229     WCHAR Password[256];
230     NTSTATUS SubStatus;
231     NTSTATUS Status;
232 
233     TRACE("TUILockedSAS()\n");
234 
235     UNREFERENCED_PARAMETER(pgContext);
236 
237     if (!DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE))
238         return WLX_SAS_ACTION_UNLOCK_WKSTA;
239 
240     /* Ask the user for credentials */
241     if (!ReadString(IDS_ASKFORUSER, UserName, _countof(UserName), TRUE))
242         return WLX_SAS_ACTION_NONE;
243     if (!ReadString(IDS_ASKFORPASSWORD, Password, _countof(Password), FALSE))
244         return WLX_SAS_ACTION_NONE;
245 
246     Status = ConnectToLsa(pgContext);
247     if (!NT_SUCCESS(Status))
248     {
249         WARN("ConnectToLsa() failed\n");
250         return WLX_SAS_ACTION_NONE;
251     }
252 
253     Status = MyLogonUser(pgContext->LsaHandle,
254                          pgContext->AuthenticationPackage,
255                          UserName,
256                          NULL,
257                          Password,
258                          &hToken,
259                          &SubStatus);
260     if (!NT_SUCCESS(Status))
261     {
262         WARN("MyLogonUser() failed\n");
263         return WLX_SAS_ACTION_NONE;
264     }
265 
266     CloseHandle(hToken);
267     return WLX_SAS_ACTION_UNLOCK_WKSTA;
268 }
269 
270 static VOID
271 TUIDisplayLockedNotice(
272     IN OUT PGINA_CONTEXT pgContext)
273 {
274 }
275 
276 GINA_UI GinaTextUI = {
277     TUIInitialize,
278     TUIDisplayStatusMessage,
279     TUIRemoveStatusMessage,
280     TUIDisplaySASNotice,
281     TUILoggedOnSAS,
282     TUILoggedOutSAS,
283     TUILockedSAS,
284     TUIDisplayLockedNotice,
285 };
286