[MSGINA]
[reactos.git] / reactos / dll / win32 / msgina / tui.c
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, 256))
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
203 TRACE("TUILoggedOutSAS()\n");
204
205 /* Ask the user for credentials */
206 if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE))
207 return WLX_SAS_ACTION_NONE;
208 if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE))
209 return WLX_SAS_ACTION_NONE;
210
211 if (DoLoginTasks(pgContext, UserName, NULL, Password))
212 return WLX_SAS_ACTION_LOGON;
213 else
214 return WLX_SAS_ACTION_NONE;
215 }
216
217 static INT
218 TUILockedSAS(
219 IN OUT PGINA_CONTEXT pgContext)
220 {
221 HANDLE hToken;
222 WCHAR UserName[256];
223 WCHAR Password[256];
224 NTSTATUS SubStatus;
225 NTSTATUS Status;
226
227 TRACE("TUILockedSAS()\n");
228
229 UNREFERENCED_PARAMETER(pgContext);
230
231 if (!DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE))
232 return WLX_SAS_ACTION_UNLOCK_WKSTA;
233
234 /* Ask the user for credentials */
235 if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE))
236 return WLX_SAS_ACTION_NONE;
237 if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE))
238 return WLX_SAS_ACTION_NONE;
239
240 Status = ConnectToLsa(pgContext);
241 if (!NT_SUCCESS(Status))
242 {
243 WARN("ConnectToLsa() failed\n");
244 return WLX_SAS_ACTION_NONE;
245 }
246
247 Status = MyLogonUser(pgContext->LsaHandle,
248 pgContext->AuthenticationPackage,
249 UserName,
250 NULL,
251 Password,
252 &hToken,
253 &SubStatus);
254 if (!NT_SUCCESS(Status))
255 {
256 WARN("MyLogonUser() failed\n");
257 return WLX_SAS_ACTION_NONE;
258 }
259
260 CloseHandle(hToken);
261 return WLX_SAS_ACTION_UNLOCK_WKSTA;
262 }
263
264 static VOID
265 TUIDisplayLockedNotice(
266 IN OUT PGINA_CONTEXT pgContext)
267 {
268 }
269
270 GINA_UI GinaTextUI = {
271 TUIInitialize,
272 TUIDisplayStatusMessage,
273 TUIRemoveStatusMessage,
274 TUIDisplaySASNotice,
275 TUILoggedOnSAS,
276 TUILoggedOutSAS,
277 TUILockedSAS,
278 TUIDisplayLockedNotice,
279 };