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