xref: /reactos/dll/win32/msgina/tui.c (revision c2c66aff)
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
TUIInitialize(IN OUT PGINA_CONTEXT pgContext)13 TUIInitialize(
14     IN OUT PGINA_CONTEXT pgContext)
15 {
16     TRACE("TUIInitialize(%p)\n", pgContext);
17 
18     return AllocConsole();
19 }
20 
21 static BOOL
TUIDisplayStatusMessage(IN PGINA_CONTEXT pgContext,IN HDESK hDesktop,IN DWORD dwOptions,IN PWSTR pTitle,IN PWSTR pMessage)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
TUIRemoveStatusMessage(IN PGINA_CONTEXT pgContext)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
DisplayResourceText(IN UINT uIdResourceText,IN BOOL AddNewLine)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
TUIDisplaySASNotice(IN OUT PGINA_CONTEXT pgContext)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
TUILoggedOnSAS(IN OUT PGINA_CONTEXT pgContext,IN DWORD dwSasType)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
ReadString(IN UINT uIdResourcePrompt,IN OUT PWSTR Buffer,IN DWORD BufferLength,IN BOOL ShowString)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
TUILoggedOutSAS(IN OUT PGINA_CONTEXT pgContext)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
TUILockedSAS(IN OUT PGINA_CONTEXT pgContext)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
TUIDisplayLockedNotice(IN OUT PGINA_CONTEXT pgContext)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