f6bc70aaec0d9829e2062ef14b709c1d2dc72eb9
[reactos.git] / reactos / dll / win32 / msgina / msgina.c
1 /*
2 * ReactOS GINA
3 * Copyright (C) 2003-2004, 2006 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * PROJECT: ReactOS msgina.dll
21 * FILE: dll/win32/msgina/msgina.c
22 * PURPOSE: ReactOS Logon GINA DLL
23 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * Hervé Poussineau (hpoussin@reactos.org)
25 */
26
27 #include "msgina.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(msgina);
30
31 HINSTANCE hDllInstance;
32
33 extern GINA_UI GinaGraphicalUI;
34 extern GINA_UI GinaTextUI;
35 static PGINA_UI pGinaUI;
36
37 /*
38 * @implemented
39 */
40 BOOL WINAPI
41 WlxNegotiate(
42 IN DWORD dwWinlogonVersion,
43 OUT PDWORD pdwDllVersion)
44 {
45 TRACE("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion);
46
47 if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3))
48 return FALSE;
49
50 *pdwDllVersion = WLX_VERSION_1_3;
51
52 return TRUE;
53 }
54
55 static LONG
56 ReadRegSzKey(
57 IN HKEY hKey,
58 IN LPCWSTR pszKey,
59 OUT LPWSTR* pValue)
60 {
61 LONG rc;
62 DWORD dwType;
63 DWORD cbData = 0;
64 LPWSTR Value;
65
66 if (!pValue)
67 return ERROR_INVALID_PARAMETER;
68
69 *pValue = NULL;
70 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
71 if (rc != ERROR_SUCCESS)
72 return rc;
73 if (dwType != REG_SZ)
74 return ERROR_FILE_NOT_FOUND;
75 Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
76 if (!Value)
77 return ERROR_NOT_ENOUGH_MEMORY;
78 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
79 if (rc != ERROR_SUCCESS)
80 {
81 HeapFree(GetProcessHeap(), 0, Value);
82 return rc;
83 }
84 /* NULL-terminate the string */
85 Value[cbData / sizeof(WCHAR)] = '\0';
86
87 *pValue = Value;
88 return ERROR_SUCCESS;
89 }
90
91 static VOID
92 ChooseGinaUI(VOID)
93 {
94 HKEY ControlKey = NULL;
95 LPWSTR SystemStartOptions = NULL;
96 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
97 BOOL ConsoleBoot = FALSE;
98 LONG rc;
99
100 rc = RegOpenKeyExW(
101 HKEY_LOCAL_MACHINE,
102 L"SYSTEM\\CurrentControlSet\\Control",
103 0,
104 KEY_QUERY_VALUE,
105 &ControlKey);
106
107 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
108 if (rc != ERROR_SUCCESS)
109 goto cleanup;
110
111 /* Check for CONSOLE switch in SystemStartOptions */
112 CurrentOption = SystemStartOptions;
113 while (CurrentOption)
114 {
115 NextOption = wcschr(CurrentOption, L' ');
116 if (NextOption)
117 *NextOption = L'\0';
118 if (wcsicmp(CurrentOption, L"CONSOLE") == 0)
119 {
120 TRACE("Found %S. Switching to console boot\n", CurrentOption);
121 ConsoleBoot = TRUE;
122 goto cleanup;
123 }
124 CurrentOption = NextOption ? NextOption + 1 : NULL;
125 }
126
127 cleanup:
128 if (ConsoleBoot)
129 pGinaUI = &GinaTextUI;
130 else
131 pGinaUI = &GinaGraphicalUI;
132
133 if (ControlKey != NULL)
134 RegCloseKey(ControlKey);
135 HeapFree(GetProcessHeap(), 0, SystemStartOptions);
136 }
137
138 /*
139 * @implemented
140 */
141 BOOL WINAPI
142 WlxInitialize(
143 LPWSTR lpWinsta,
144 HANDLE hWlx,
145 PVOID pvReserved,
146 PVOID pWinlogonFunctions,
147 PVOID *pWlxContext)
148 {
149 PGINA_CONTEXT pgContext;
150
151 UNREFERENCED_PARAMETER(pvReserved);
152
153 pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT));
154 if(!pgContext)
155 {
156 WARN("LocalAlloc() failed\n");
157 return FALSE;
158 }
159
160 /* Return the context to winlogon */
161 *pWlxContext = (PVOID)pgContext;
162 pgContext->hDllInstance = hDllInstance;
163
164 /* Save pointer to dispatch table */
165 pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions;
166
167 /* Save the winlogon handle used to call the dispatch functions */
168 pgContext->hWlx = hWlx;
169
170 /* Save window station */
171 pgContext->station = lpWinsta;
172
173 /* Clear status window handle */
174 pgContext->hStatusWindow = 0;
175
176 /* Notify winlogon that we will use the default SAS */
177 pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx);
178
179 /* Locates the authentification package */
180 //LsaRegisterLogonProcess(...);
181
182 /* Check autologon settings the first time */
183 pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY;
184
185 ChooseGinaUI();
186 return pGinaUI->Initialize(pgContext);
187 }
188
189 /*
190 * @implemented
191 */
192 BOOL
193 WINAPI
194 WlxScreenSaverNotify(
195 PVOID pWlxContext,
196 BOOL *pSecure)
197 {
198 #if 0
199 WCHAR szBuffer[2];
200 HKEY hKey;
201 DWORD bufferSize = sizeof(szBuffer);
202 DWORD varType = REG_SZ;
203 LONG rc;
204
205 TRACE("(%p %p)\n", pWlxContext, pSecure);
206
207 *pSecure = TRUE;
208
209 /*
210 * Policy setting:
211 * HKLM\Software\Policies\Microsoft\Windows\Control Panel\Desktop : ScreenSaverIsSecure
212 * User setting:
213 * HKCU\Control Panel\Desktop : ScreenSaverIsSecure
214 */
215
216 rc = RegOpenKeyExW(HKEY_CURRENT_USER,
217 L"Control Panel\\Desktop",
218 0,
219 KEY_QUERY_VALUE,
220 &hKey);
221 TRACE("RegOpenKeyExW: %ld\n", rc);
222 if (rc == ERROR_SUCCESS)
223 {
224 rc = RegQueryValueExW(hKey,
225 L"ScreenSaverIsSecure",
226 NULL,
227 &varType,
228 (LPBYTE)szBuffer,
229 &bufferSize);
230
231 TRACE("RegQueryValueExW: %ld\n", rc);
232
233 if (rc == ERROR_SUCCESS)
234 {
235 TRACE("szBuffer: \"%S\"\n", szBuffer);
236 *pSecure = _wtoi(szBuffer);
237 }
238
239 RegCloseKey(hKey);
240 }
241
242 TRACE("*pSecure: %ld\n", *pSecure);
243 #endif
244
245 *pSecure = FALSE;
246
247 return TRUE;
248 }
249
250 /*
251 * @implemented
252 */
253 BOOL WINAPI
254 WlxStartApplication(
255 PVOID pWlxContext,
256 PWSTR pszDesktopName,
257 PVOID pEnvironment,
258 PWSTR pszCmdLine)
259 {
260 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
261 STARTUPINFOW StartupInfo;
262 PROCESS_INFORMATION ProcessInformation;
263 WCHAR CurrentDirectory[MAX_PATH];
264 HANDLE hAppToken;
265 UINT len;
266 BOOL ret;
267
268 len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH);
269 if (len == 0 || len > MAX_PATH)
270 {
271 ERR("GetWindowsDirectoryW() failed\n");
272 return FALSE;
273 }
274
275 ret = DuplicateTokenEx(pgContext->UserToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hAppToken);
276 if (!ret)
277 {
278 ERR("DuplicateTokenEx() failed with error %lu\n", GetLastError());
279 return FALSE;
280 }
281
282 ZeroMemory(&StartupInfo, sizeof(StartupInfo));
283 ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
284 StartupInfo.cb = sizeof(StartupInfo);
285 StartupInfo.lpTitle = pszCmdLine;
286 StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
287 StartupInfo.wShowWindow = SW_SHOW;
288 StartupInfo.lpDesktop = pszDesktopName;
289
290 len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH);
291 if (len == 0 || len > MAX_PATH)
292 {
293 ERR("GetWindowsDirectoryW() failed\n");
294 return FALSE;
295 }
296 ret = CreateProcessAsUserW(
297 hAppToken,
298 pszCmdLine,
299 NULL,
300 NULL,
301 NULL,
302 FALSE,
303 CREATE_UNICODE_ENVIRONMENT,
304 pEnvironment,
305 CurrentDirectory,
306 &StartupInfo,
307 &ProcessInformation);
308 CloseHandle(ProcessInformation.hProcess);
309 CloseHandle(ProcessInformation.hThread);
310 CloseHandle(hAppToken);
311 if (!ret)
312 ERR("CreateProcessAsUserW() failed with error %lu\n", GetLastError());
313 return ret;
314 }
315
316 /*
317 * @implemented
318 */
319 BOOL WINAPI
320 WlxActivateUserShell(
321 PVOID pWlxContext,
322 PWSTR pszDesktopName,
323 PWSTR pszMprLogonScript,
324 PVOID pEnvironment)
325 {
326 HKEY hKey;
327 DWORD BufSize, ValueType;
328 WCHAR pszUserInitApp[MAX_PATH + 1];
329 WCHAR pszExpUserInitApp[MAX_PATH];
330 DWORD len;
331 LONG rc;
332
333 TRACE("WlxActivateUserShell()\n");
334
335 UNREFERENCED_PARAMETER(pszMprLogonScript);
336
337 /* Get the path of userinit */
338 rc = RegOpenKeyExW(
339 HKEY_LOCAL_MACHINE,
340 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
341 0,
342 KEY_QUERY_VALUE,
343 &hKey);
344 if (rc != ERROR_SUCCESS)
345 {
346 WARN("RegOpenKeyExW() failed with error %lu\n", rc);
347 return FALSE;
348 }
349
350 /* Query userinit application */
351 BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL);
352 rc = RegQueryValueExW(
353 hKey,
354 L"Userinit",
355 NULL,
356 &ValueType,
357 (LPBYTE)pszUserInitApp,
358 &BufSize);
359 RegCloseKey(hKey);
360 if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ))
361 {
362 WARN("RegQueryValueExW() failed with error %lu\n", rc);
363 return FALSE;
364 }
365 pszUserInitApp[MAX_PATH] = UNICODE_NULL;
366
367 len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH);
368 if (len > MAX_PATH)
369 {
370 WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len);
371 return FALSE;
372 }
373
374 /* Start userinit app */
375 return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp);
376 }
377
378 /*
379 * @implemented
380 */
381 int WINAPI
382 WlxLoggedOnSAS(
383 PVOID pWlxContext,
384 DWORD dwSasType,
385 PVOID pReserved)
386 {
387 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
388 INT SasAction = WLX_SAS_ACTION_NONE;
389
390 TRACE("WlxLoggedOnSAS(0x%lx)\n", dwSasType);
391
392 UNREFERENCED_PARAMETER(pReserved);
393
394 switch (dwSasType)
395 {
396 case WLX_SAS_TYPE_CTRL_ALT_DEL:
397 case WLX_SAS_TYPE_TIMEOUT:
398 {
399 SasAction = pGinaUI->LoggedOnSAS(pgContext, dwSasType);
400 break;
401 }
402 case WLX_SAS_TYPE_SC_INSERT:
403 {
404 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n");
405 break;
406 }
407 case WLX_SAS_TYPE_SC_REMOVE:
408 {
409 FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n");
410 break;
411 }
412 default:
413 {
414 WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType);
415 break;
416 }
417 }
418
419 return SasAction;
420 }
421
422 /*
423 * @implemented
424 */
425 BOOL WINAPI
426 WlxDisplayStatusMessage(
427 IN PVOID pWlxContext,
428 IN HDESK hDesktop,
429 IN DWORD dwOptions,
430 IN PWSTR pTitle,
431 IN PWSTR pMessage)
432 {
433 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
434
435 TRACE("WlxDisplayStatusMessage(\"%S\")\n", pMessage);
436
437 return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage);
438 }
439
440 /*
441 * @implemented
442 */
443 BOOL WINAPI
444 WlxRemoveStatusMessage(
445 IN PVOID pWlxContext)
446 {
447 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
448
449 TRACE("WlxRemoveStatusMessage()\n");
450
451 return pGinaUI->RemoveStatusMessage(pgContext);
452 }
453
454 static PWSTR
455 DuplicationString(PWSTR Str)
456 {
457 DWORD cb;
458 PWSTR NewStr;
459
460 if (Str == NULL) return NULL;
461
462 cb = (wcslen(Str) + 1) * sizeof(WCHAR);
463 if ((NewStr = LocalAlloc(LMEM_FIXED, cb)))
464 memcpy(NewStr, Str, cb);
465 return NewStr;
466 }
467
468 BOOL
469 DoLoginTasks(
470 IN OUT PGINA_CONTEXT pgContext,
471 IN PWSTR UserName,
472 IN PWSTR Domain,
473 IN PWSTR Password)
474 {
475 LPWSTR ProfilePath = NULL;
476 LPWSTR lpEnvironment = NULL;
477 TOKEN_STATISTICS Stats;
478 PWLX_PROFILE_V2_0 pProfile = NULL;
479 DWORD cbStats, cbSize;
480 DWORD dwLength;
481 BOOL bResult;
482
483 if (!LogonUserW(UserName, Domain, Password,
484 LOGON32_LOGON_INTERACTIVE,
485 LOGON32_PROVIDER_DEFAULT,
486 &pgContext->UserToken))
487 {
488 WARN("LogonUserW() failed\n");
489 goto cleanup;
490 }
491
492 /* Store the logon time in the context */
493 GetLocalTime(&pgContext->LogonTime);
494
495 /* Store user and domain in the context */
496 wcscpy(pgContext->UserName, UserName);
497 if (Domain == NULL || wcslen(Domain) == 0)
498 {
499 dwLength = 256;
500 GetComputerNameW(pgContext->Domain, &dwLength);
501 }
502 else
503 {
504 wcscpy(pgContext->Domain, Domain);
505 }
506
507 /* Get profile path */
508 cbSize = 0;
509 bResult = GetProfilesDirectoryW(NULL, &cbSize);
510 if (!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
511 {
512 ProfilePath = HeapAlloc(GetProcessHeap(), 0, cbSize * sizeof(WCHAR));
513 if (!ProfilePath)
514 {
515 WARN("HeapAlloc() failed\n");
516 goto cleanup;
517 }
518 bResult = GetProfilesDirectoryW(ProfilePath, &cbSize);
519 }
520 if (!bResult)
521 {
522 WARN("GetUserProfileDirectoryW() failed\n");
523 goto cleanup;
524 }
525
526 /* Allocate memory for profile */
527 pProfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLX_PROFILE_V2_0));
528 if (!pProfile)
529 {
530 WARN("HeapAlloc() failed\n");
531 goto cleanup;
532 }
533 pProfile->dwType = WLX_PROFILE_TYPE_V2_0;
534 pProfile->pszProfile = ProfilePath;
535
536 lpEnvironment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
537 (wcslen(pgContext->Domain)+ 14 + 1) * sizeof(WCHAR));
538 if (!lpEnvironment)
539 {
540 WARN("HeapAlloc() failed\n");
541 goto cleanup;
542 }
543
544 wsprintfW(lpEnvironment, L"LOGONSERVER=\\\\%s", pgContext->Domain);
545
546 pProfile->pszEnvironment = lpEnvironment;
547
548 if (!GetTokenInformation(pgContext->UserToken,
549 TokenStatistics,
550 (PVOID)&Stats,
551 sizeof(TOKEN_STATISTICS),
552 &cbStats))
553 {
554 WARN("Couldn't get Authentication id from user token!\n");
555 goto cleanup;
556 }
557
558 *pgContext->pAuthenticationId = Stats.AuthenticationId;
559 pgContext->pMprNotifyInfo->pszUserName = DuplicationString(UserName);
560 pgContext->pMprNotifyInfo->pszDomain = DuplicationString(Domain);
561 pgContext->pMprNotifyInfo->pszPassword = DuplicationString(Password);
562 pgContext->pMprNotifyInfo->pszOldPassword = NULL;
563 *pgContext->pdwOptions = 0;
564 *pgContext->pProfile = pProfile;
565 return TRUE;
566
567 cleanup:
568 if (pProfile)
569 {
570 HeapFree(GetProcessHeap(), 0, pProfile->pszEnvironment);
571 }
572 HeapFree(GetProcessHeap(), 0, pProfile);
573 HeapFree(GetProcessHeap(), 0, ProfilePath);
574 return FALSE;
575 }
576
577 static BOOL
578 DoAutoLogon(
579 IN PGINA_CONTEXT pgContext)
580 {
581 HKEY WinLogonKey = NULL;
582 LPWSTR AutoLogon = NULL;
583 LPWSTR AutoCount = NULL;
584 LPWSTR IgnoreShiftOverride = NULL;
585 LPWSTR UserName = NULL;
586 LPWSTR DomainName = NULL;
587 LPWSTR Password = NULL;
588 BOOL result = FALSE;
589 LONG rc;
590
591 TRACE("DoAutoLogon(): AutoLogonState = %lu\n",
592 pgContext->AutoLogonState);
593
594 if (pgContext->AutoLogonState == AUTOLOGON_DISABLED)
595 return FALSE;
596
597 rc = RegOpenKeyExW(
598 HKEY_LOCAL_MACHINE,
599 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon",
600 0,
601 KEY_QUERY_VALUE,
602 &WinLogonKey);
603 if (rc != ERROR_SUCCESS)
604 goto cleanup;
605
606 if (pgContext->AutoLogonState == AUTOLOGON_CHECK_REGISTRY)
607 {
608 /* Set it by default to disabled, we might reenable it again later */
609 pgContext->AutoLogonState = AUTOLOGON_DISABLED;
610
611 rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon);
612 if (rc != ERROR_SUCCESS)
613 goto cleanup;
614 if (wcscmp(AutoLogon, L"1") != 0)
615 goto cleanup;
616
617 rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount);
618 if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0)
619 goto cleanup;
620 else if (rc != ERROR_FILE_NOT_FOUND)
621 goto cleanup;
622
623 rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName);
624 if (rc == ERROR_SUCCESS)
625 {
626 if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0)
627 goto cleanup;
628 }
629 else if (GetKeyState(VK_SHIFT) < 0)
630 {
631 /* User pressed SHIFT */
632 goto cleanup;
633 }
634
635 pgContext->AutoLogonState = AUTOLOGON_ONCE;
636 result = TRUE;
637 }
638 else /* pgContext->AutoLogonState == AUTOLOGON_ONCE */
639 {
640 pgContext->AutoLogonState = AUTOLOGON_DISABLED;
641
642 rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName);
643 if (rc != ERROR_SUCCESS)
644 goto cleanup;
645 rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName);
646 if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND)
647 goto cleanup;
648 rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password);
649 if (rc != ERROR_SUCCESS)
650 goto cleanup;
651
652 result = DoLoginTasks(pgContext, UserName, DomainName, Password);
653
654 if (result == TRUE)
655 NotifyBootConfigStatus(TRUE);
656 }
657
658 cleanup:
659 if (WinLogonKey != NULL)
660 RegCloseKey(WinLogonKey);
661 HeapFree(GetProcessHeap(), 0, AutoLogon);
662 HeapFree(GetProcessHeap(), 0, AutoCount);
663 HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride);
664 HeapFree(GetProcessHeap(), 0, UserName);
665 HeapFree(GetProcessHeap(), 0, DomainName);
666 HeapFree(GetProcessHeap(), 0, Password);
667 TRACE("DoAutoLogon(): AutoLogonState = %lu, returning %d\n",
668 pgContext->AutoLogonState, result);
669 return result;
670 }
671
672 /*
673 * @implemented
674 */
675 VOID WINAPI
676 WlxDisplaySASNotice(
677 IN PVOID pWlxContext)
678 {
679 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
680
681 TRACE("WlxDisplaySASNotice(%p)\n", pWlxContext);
682
683 if (GetSystemMetrics(SM_REMOTESESSION))
684 {
685 /* User is remotely logged on. Don't display a notice */
686 pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
687 return;
688 }
689
690 if (DoAutoLogon(pgContext))
691 {
692 /* Don't display the window, we want to do an automatic logon */
693 pgContext->AutoLogonState = AUTOLOGON_ONCE;
694 pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL);
695 return;
696 }
697 else
698 pgContext->AutoLogonState = AUTOLOGON_DISABLED;
699
700 pGinaUI->DisplaySASNotice(pgContext);
701
702 TRACE("WlxDisplaySASNotice() done\n");
703 }
704
705 /*
706 * @implemented
707 */
708 INT WINAPI
709 WlxLoggedOutSAS(
710 IN PVOID pWlxContext,
711 IN DWORD dwSasType,
712 OUT PLUID pAuthenticationId,
713 IN OUT PSID pLogonSid,
714 OUT PDWORD pdwOptions,
715 OUT PHANDLE phToken,
716 OUT PWLX_MPR_NOTIFY_INFO pMprNotifyInfo,
717 OUT PVOID *pProfile)
718 {
719 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
720 INT res;
721
722 TRACE("WlxLoggedOutSAS()\n");
723
724 UNREFERENCED_PARAMETER(dwSasType);
725 UNREFERENCED_PARAMETER(pLogonSid);
726
727 pgContext->pAuthenticationId = pAuthenticationId;
728 pgContext->pdwOptions = pdwOptions;
729 pgContext->pMprNotifyInfo = pMprNotifyInfo;
730 pgContext->pProfile = pProfile;
731
732 if (0 == GetSystemMetrics(SM_REMOTESESSION) &&
733 DoAutoLogon(pgContext))
734 {
735 /* User is local and registry contains information
736 * to log on him automatically */
737 *phToken = pgContext->UserToken;
738 return WLX_SAS_ACTION_LOGON;
739 }
740
741 res = pGinaUI->LoggedOutSAS(pgContext);
742 *phToken = pgContext->UserToken;
743 return res;
744 }
745
746 /*
747 * @implemented
748 */
749 int WINAPI
750 WlxWkstaLockedSAS(
751 PVOID pWlxContext,
752 DWORD dwSasType)
753 {
754 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
755
756 TRACE("WlxWkstaLockedSAS()\n");
757
758 UNREFERENCED_PARAMETER(dwSasType);
759
760 return pGinaUI->LockedSAS(pgContext);
761 }
762
763
764 /*
765 * @implemented
766 */
767 VOID
768 WINAPI
769 WlxDisplayLockedNotice(PVOID pWlxContext)
770 {
771 PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
772
773 TRACE("WlxDisplayLockedNotice()\n");
774
775 pGinaUI->DisplayLockedNotice(pgContext);
776 }
777
778
779 /*
780 * @implemented
781 */
782 BOOL WINAPI
783 WlxIsLogoffOk(
784 PVOID pWlxContext)
785 {
786 TRACE("WlxIsLogoffOk()\n");
787 UNREFERENCED_PARAMETER(pWlxContext);
788 return TRUE;
789 }
790
791 BOOL WINAPI
792 DllMain(
793 IN HINSTANCE hinstDLL,
794 IN DWORD dwReason,
795 IN LPVOID lpvReserved)
796 {
797 UNREFERENCED_PARAMETER(lpvReserved);
798
799 if (dwReason == DLL_PROCESS_ATTACH)
800 hDllInstance = hinstDLL;
801
802 return TRUE;
803 }