Create a branch for network fixes.
[reactos.git] / base / system / winlogon / wlx.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/wlx.c
5 * PURPOSE: Logon
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Ge van Geldorp (gvg@reactos.com)
8 * Hervé Poussineau (hpoussin@reactos.org)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include "winlogon.h"
14
15 #include <wine/debug.h>
16
17 WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
18
19 /* GLOBALS ******************************************************************/
20
21 static DLGPROC PreviousWindowProc;
22 static UINT_PTR IdTimer;
23
24 /* FUNCTIONS ****************************************************************/
25
26 static BOOL CALLBACK
27 DefaultWlxWindowProc(
28 IN HWND hwndDlg,
29 IN UINT uMsg,
30 IN WPARAM wParam,
31 IN LPARAM lParam)
32 {
33 if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer)
34 {
35 EndDialog(hwndDlg, -1);
36 KillTimer(hwndDlg, IdTimer);
37 return TRUE;
38 }
39 else if (uMsg == WM_INITDIALOG)
40 {
41 IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL);
42 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);;
43 }
44 else if (uMsg == WM_NCDESTROY)
45 {
46 BOOL ret;
47 ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
48 PreviousWindowProc = NULL;
49 return ret;
50 }
51 else
52 {
53 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
54 }
55 }
56
57 /*
58 * @implemented
59 */
60 VOID WINAPI
61 WlxUseCtrlAltDel(
62 HANDLE hWlx)
63 {
64 ULONG_PTR OldValue;
65
66 TRACE("WlxUseCtrlAltDel()\n");
67
68 WlxSetOption(hWlx, WLX_OPTION_USE_CTRL_ALT_DEL, TRUE, &OldValue);
69 }
70
71 /*
72 * @implemented
73 */
74 VOID WINAPI
75 WlxSetContextPointer(
76 HANDLE hWlx,
77 PVOID pWlxContext)
78 {
79 ULONG_PTR OldValue;
80
81 TRACE("WlxSetContextPointer(%p)\n", pWlxContext);
82
83 WlxSetOption(hWlx, WLX_OPTION_CONTEXT_POINTER, (ULONG_PTR)pWlxContext, &OldValue);
84 }
85
86 /*
87 * @implemented
88 */
89 VOID WINAPI
90 WlxSasNotify(
91 HANDLE hWlx,
92 DWORD dwSasType)
93 {
94 PWLSESSION Session = (PWLSESSION)hWlx;
95
96 TRACE("WlxSasNotify(0x%lx)\n", dwSasType);
97
98 if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL || dwSasType > WLX_SAS_TYPE_MAX_MSFT_VALUE)
99 PostMessageW(Session->SASWindow, WLX_WM_SAS, dwSasType, 0);
100 }
101
102 /*
103 * @implemented
104 */
105 BOOL WINAPI
106 WlxSetTimeout(
107 HANDLE hWlx,
108 DWORD Timeout)
109 {
110 PWLSESSION Session = (PWLSESSION)hWlx;
111
112 TRACE("WlxSetTimeout(%lu)\n", Timeout);
113
114 Session->DialogTimeout = Timeout;
115 return TRUE;
116 }
117
118 /*
119 * @unimplemented
120 */
121 int WINAPI
122 WlxAssignShellProtection(
123 HANDLE hWlx,
124 HANDLE hToken,
125 HANDLE hProcess,
126 HANDLE hThread)
127 {
128 UNREFERENCED_PARAMETER(hWlx);
129 UNREFERENCED_PARAMETER(hToken);
130 UNREFERENCED_PARAMETER(hProcess);
131 UNREFERENCED_PARAMETER(hThread);
132
133 UNIMPLEMENTED;
134 return 0;
135 }
136
137 /*
138 * @implemented
139 */
140 int WINAPI
141 WlxMessageBox(
142 HANDLE hWlx,
143 HWND hwndOwner,
144 LPWSTR lpszText,
145 LPWSTR lpszTitle,
146 UINT fuStyle)
147 {
148 UNREFERENCED_PARAMETER(hWlx);
149
150 TRACE("WlxMessageBox()\n");
151 /* FIXME: Provide a custom window proc to be able to handle timeout */
152 return MessageBoxW(hwndOwner, lpszText, lpszTitle, fuStyle);
153 }
154
155 /*
156 * @implemented
157 */
158 int WINAPI
159 WlxDialogBox(
160 HANDLE hWlx,
161 HANDLE hInst,
162 LPWSTR lpszTemplate,
163 HWND hwndOwner,
164 DLGPROC dlgprc)
165 {
166 UNREFERENCED_PARAMETER(hWlx);
167
168 TRACE("WlxDialogBox()\n");
169
170 if (PreviousWindowProc != NULL)
171 return -1;
172 PreviousWindowProc = dlgprc;
173 return (int)DialogBoxW((HINSTANCE) hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc);
174 }
175
176 /*
177 * @implemented
178 */
179 int WINAPI
180 WlxDialogBoxParam(
181 HANDLE hWlx,
182 HANDLE hInst,
183 LPWSTR lpszTemplate,
184 HWND hwndOwner,
185 DLGPROC dlgprc,
186 LPARAM dwInitParam)
187 {
188 UNREFERENCED_PARAMETER(hWlx);
189
190 TRACE("WlxDialogBoxParam()\n");
191
192 if (PreviousWindowProc != NULL)
193 return -1;
194 PreviousWindowProc = dlgprc;
195 return (int)DialogBoxParamW(hInst, lpszTemplate, hwndOwner, DefaultWlxWindowProc, dwInitParam);
196 }
197
198 /*
199 * @implemented
200 */
201 int WINAPI
202 WlxDialogBoxIndirect(
203 HANDLE hWlx,
204 HANDLE hInst,
205 LPCDLGTEMPLATE hDialogTemplate,
206 HWND hwndOwner,
207 DLGPROC dlgprc)
208 {
209 UNREFERENCED_PARAMETER(hWlx);
210
211 TRACE("WlxDialogBoxIndirect()\n");
212
213 if (PreviousWindowProc != NULL)
214 return -1;
215 PreviousWindowProc = dlgprc;
216 return (int)DialogBoxIndirectW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc);
217 }
218
219 /*
220 * @implemented
221 */
222 int WINAPI
223 WlxDialogBoxIndirectParam(
224 HANDLE hWlx,
225 HANDLE hInst,
226 LPCDLGTEMPLATE hDialogTemplate,
227 HWND hwndOwner,
228 DLGPROC dlgprc,
229 LPARAM dwInitParam)
230 {
231 UNREFERENCED_PARAMETER(hWlx);
232
233 TRACE("WlxDialogBoxIndirectParam()\n");
234
235 if (PreviousWindowProc != NULL)
236 return -1;
237 PreviousWindowProc = dlgprc;
238 return (int)DialogBoxIndirectParamW(hInst, hDialogTemplate, hwndOwner, DefaultWlxWindowProc, dwInitParam);
239 }
240
241 /*
242 * @implemented
243 */
244 int WINAPI
245 WlxSwitchDesktopToUser(
246 HANDLE hWlx)
247 {
248 PWLSESSION Session = (PWLSESSION)hWlx;
249
250 TRACE("WlxSwitchDesktopToUser()\n");
251
252 return (int)SwitchDesktop(Session->ApplicationDesktop);
253 }
254
255 /*
256 * @implemented
257 */
258 int WINAPI
259 WlxSwitchDesktopToWinlogon(
260 HANDLE hWlx)
261 {
262 PWLSESSION Session = (PWLSESSION)hWlx;
263
264 TRACE("WlxSwitchDesktopToWinlogon()\n");
265
266 return (int)SwitchDesktop(Session->WinlogonDesktop);
267 }
268
269 /*
270 * @unimplemented
271 */
272 int WINAPI
273 WlxChangePasswordNotify(
274 HANDLE hWlx,
275 PWLX_MPR_NOTIFY_INFO pMprInfo,
276 DWORD dwChangeInfo)
277 {
278 UNREFERENCED_PARAMETER(hWlx);
279 UNREFERENCED_PARAMETER(pMprInfo);
280 UNREFERENCED_PARAMETER(dwChangeInfo);
281
282 UNIMPLEMENTED;
283 return 0;
284 }
285
286 /*
287 * @unimplemented
288 */
289 BOOL WINAPI
290 WlxGetSourceDesktop(
291 HANDLE hWlx,
292 PWLX_DESKTOP* ppDesktop)
293 {
294 UNREFERENCED_PARAMETER(hWlx);
295 UNREFERENCED_PARAMETER(ppDesktop);
296
297 UNIMPLEMENTED;
298 return FALSE;
299 }
300
301 /*
302 * @unimplemented
303 */
304 BOOL WINAPI
305 WlxSetReturnDesktop(
306 HANDLE hWlx,
307 PWLX_DESKTOP pDesktop)
308 {
309 UNREFERENCED_PARAMETER(hWlx);
310 UNREFERENCED_PARAMETER(pDesktop);
311
312 UNIMPLEMENTED;
313 return FALSE;
314 }
315
316 /*
317 * @unimplemented
318 */
319 BOOL WINAPI
320 WlxCreateUserDesktop(
321 HANDLE hWlx,
322 HANDLE hToken,
323 DWORD Flags,
324 PWSTR pszDesktopName,
325 PWLX_DESKTOP* ppDesktop)
326 {
327 UNREFERENCED_PARAMETER(hWlx);
328 UNREFERENCED_PARAMETER(hToken);
329 UNREFERENCED_PARAMETER(Flags);
330 UNREFERENCED_PARAMETER(pszDesktopName);
331 UNREFERENCED_PARAMETER(ppDesktop);
332
333 UNIMPLEMENTED;
334 return FALSE;
335 }
336
337 /*
338 * @unimplemented
339 */
340 int WINAPI
341 WlxChangePasswordNotifyEx(
342 HANDLE hWlx,
343 PWLX_MPR_NOTIFY_INFO pMprInfo,
344 DWORD dwChangeInfo,
345 PWSTR ProviderName,
346 PVOID Reserved)
347 {
348 UNREFERENCED_PARAMETER(hWlx);
349 UNREFERENCED_PARAMETER(pMprInfo);
350 UNREFERENCED_PARAMETER(dwChangeInfo);
351 UNREFERENCED_PARAMETER(ProviderName);
352 UNREFERENCED_PARAMETER(Reserved);
353
354 UNIMPLEMENTED;
355 return 0;
356 }
357
358 /*
359 * @unimplemented
360 */
361 BOOL WINAPI
362 WlxCloseUserDesktop(
363 HANDLE hWlx,
364 PWLX_DESKTOP pDesktop,
365 HANDLE hToken)
366 {
367 UNREFERENCED_PARAMETER(hWlx);
368 UNREFERENCED_PARAMETER(pDesktop);
369 UNREFERENCED_PARAMETER(hToken);
370
371 UNIMPLEMENTED;
372 return FALSE;
373 }
374
375 /*
376 * @implemented
377 */
378 BOOL WINAPI
379 WlxSetOption(
380 HANDLE hWlx,
381 DWORD Option,
382 ULONG_PTR Value,
383 ULONG_PTR* OldValue)
384 {
385 PWLSESSION Session = (PWLSESSION)hWlx;
386
387 TRACE("WlxSetOption(%lu)\n", Option);
388
389 switch (Option)
390 {
391 case WLX_OPTION_USE_CTRL_ALT_DEL:
392 *OldValue = (ULONG_PTR)Session->Gina.UseCtrlAltDelete;
393 Session->Gina.UseCtrlAltDelete = (BOOL)Value;
394 return TRUE;
395 case WLX_OPTION_CONTEXT_POINTER:
396 *OldValue = (ULONG_PTR)Session->Gina.Context;
397 Session->Gina.Context = (PVOID)Value;
398 return TRUE;
399 case WLX_OPTION_USE_SMART_CARD:
400 UNIMPLEMENTED;
401 return FALSE;
402 }
403
404 return FALSE;
405 }
406
407 /*
408 * @implemented
409 */
410 BOOL WINAPI
411 WlxGetOption(
412 HANDLE hWlx,
413 DWORD Option,
414 ULONG_PTR* Value)
415 {
416 PWLSESSION Session = (PWLSESSION)hWlx;
417
418 TRACE("WlxGetOption(%lu)\n", Option);
419
420 switch (Option)
421 {
422 case WLX_OPTION_USE_CTRL_ALT_DEL:
423 *Value = (ULONG_PTR)Session->Gina.UseCtrlAltDelete;
424 return TRUE;
425 case WLX_OPTION_CONTEXT_POINTER:
426 {
427 *Value = (ULONG_PTR)Session->Gina.Context;
428 return TRUE;
429 }
430 case WLX_OPTION_USE_SMART_CARD:
431 case WLX_OPTION_SMART_CARD_PRESENT:
432 case WLX_OPTION_SMART_CARD_INFO:
433 UNIMPLEMENTED;
434 return FALSE;
435 case WLX_OPTION_DISPATCH_TABLE_SIZE:
436 {
437 switch (Session->Gina.Version)
438 {
439 case WLX_VERSION_1_0:
440 *Value = sizeof(WLX_DISPATCH_VERSION_1_0);
441 break;
442 case WLX_VERSION_1_1:
443 *Value = sizeof(WLX_DISPATCH_VERSION_1_1);
444 break;
445 case WLX_VERSION_1_2:
446 *Value = sizeof(WLX_DISPATCH_VERSION_1_2);
447 break;
448 case WLX_VERSION_1_3:
449 *Value = sizeof(WLX_DISPATCH_VERSION_1_3);
450 break;
451 case WLX_VERSION_1_4:
452 *Value = sizeof(WLX_DISPATCH_VERSION_1_4);
453 break;
454 default:
455 return FALSE;
456 }
457 return TRUE;
458 }
459 }
460
461 return FALSE;
462 }
463
464 /*
465 * @unimplemented
466 */
467 VOID WINAPI
468 WlxWin31Migrate(
469 HANDLE hWlx)
470 {
471 UNREFERENCED_PARAMETER(hWlx);
472
473 UNIMPLEMENTED;
474 }
475
476 /*
477 * @unimplemented
478 */
479 BOOL WINAPI
480 WlxQueryClientCredentials(
481 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
482 {
483 UNREFERENCED_PARAMETER(pCred);
484
485 UNIMPLEMENTED;
486 return FALSE;
487 }
488
489 /*
490 * @unimplemented
491 */
492 BOOL WINAPI
493 WlxQueryInetConnectorCredentials(
494 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred)
495 {
496 UNREFERENCED_PARAMETER(pCred);
497
498 UNIMPLEMENTED;
499 return FALSE;
500 }
501
502 /*
503 * @unimplemented
504 */
505 BOOL WINAPI
506 WlxDisconnect(VOID)
507 {
508 UNIMPLEMENTED;
509 return FALSE;
510 }
511
512 /*
513 * @unimplemented
514 */
515 DWORD WINAPI
516 WlxQueryTerminalServicesData(
517 HANDLE hWlx,
518 PWLX_TERMINAL_SERVICES_DATA pTSData,
519 WCHAR* UserName,
520 WCHAR* Domain)
521 {
522 UNREFERENCED_PARAMETER(hWlx);
523 UNREFERENCED_PARAMETER(pTSData);
524 UNREFERENCED_PARAMETER(UserName);
525 UNREFERENCED_PARAMETER(Domain);
526
527 UNIMPLEMENTED;
528 return 0;
529 }
530
531 /*
532 * @unimplemented
533 */
534 DWORD WINAPI
535 WlxQueryConsoleSwitchCredentials(
536 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred)
537 {
538 UNREFERENCED_PARAMETER(pCred);
539
540 UNIMPLEMENTED;
541 return 0;
542 }
543
544 /*
545 * @unimplemented
546 */
547 BOOL WINAPI
548 WlxQueryTsLogonCredentials(
549 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred)
550 {
551 UNREFERENCED_PARAMETER(pCred);
552
553 UNIMPLEMENTED;
554 return FALSE;
555 }
556
557 static
558 WLX_DISPATCH_VERSION_1_4 FunctionTable = {
559 WlxUseCtrlAltDel,
560 WlxSetContextPointer,
561 WlxSasNotify,
562 WlxSetTimeout,
563 WlxAssignShellProtection,
564 WlxMessageBox,
565 WlxDialogBox,
566 WlxDialogBoxParam,
567 WlxDialogBoxIndirect,
568 WlxDialogBoxIndirectParam,
569 WlxSwitchDesktopToUser,
570 WlxSwitchDesktopToWinlogon,
571 WlxChangePasswordNotify,
572 WlxGetSourceDesktop,
573 WlxSetReturnDesktop,
574 WlxCreateUserDesktop,
575 WlxChangePasswordNotifyEx,
576 WlxCloseUserDesktop,
577 WlxSetOption,
578 WlxGetOption,
579 WlxWin31Migrate,
580 WlxQueryClientCredentials,
581 WlxQueryInetConnectorCredentials,
582 WlxDisconnect,
583 WlxQueryTerminalServicesData,
584 WlxQueryConsoleSwitchCredentials,
585 WlxQueryTsLogonCredentials
586 };
587
588 /******************************************************************************/
589
590 static BOOL
591 GetGinaPath(
592 OUT LPWSTR Path,
593 IN DWORD Len)
594 {
595 LONG Status;
596 DWORD Type, Size;
597 HKEY hKey;
598
599 Status = RegOpenKeyExW(
600 HKEY_LOCAL_MACHINE,
601 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
602 0,
603 KEY_QUERY_VALUE,
604 &hKey);
605 if (Status != ERROR_SUCCESS)
606 {
607 /* Default value */
608 wcsncpy(Path, L"msgina.dll", Len);
609 return TRUE;
610 }
611
612 Size = Len * sizeof(WCHAR);
613 Status = RegQueryValueExW(
614 hKey,
615 L"GinaDLL",
616 NULL,
617 &Type,
618 (LPBYTE)Path,
619 &Size);
620 if (Status != ERROR_SUCCESS || Type != REG_SZ || Size == 0)
621 wcsncpy(Path, L"msgina.dll", Len);
622 RegCloseKey(hKey);
623 return TRUE;
624 }
625
626 static BOOL WINAPI
627 DefaultWlxScreenSaverNotify(
628 IN PVOID pWlxContext,
629 IN OUT BOOL *pSecure)
630 {
631 if (*pSecure)
632 *pSecure = WLSession->Gina.Functions.WlxIsLogoffOk(pWlxContext);
633 return TRUE;
634 }
635
636 static BOOL
637 LoadGina(
638 IN OUT PGINAFUNCTIONS Functions,
639 OUT DWORD *DllVersion,
640 OUT HMODULE *GinaInstance)
641 {
642 HMODULE hGina = NULL;
643 WCHAR GinaDll[MAX_PATH + 1];
644 BOOL ret = FALSE;
645
646 GinaDll[0] = '\0';
647 if (!GetGinaPath(GinaDll, MAX_PATH))
648 goto cleanup;
649 /* Terminate string */
650 GinaDll[MAX_PATH] = '\0';
651
652 hGina = LoadLibraryW(GinaDll);
653 if (!hGina)
654 goto cleanup;
655
656 Functions->WlxNegotiate = (PFWLXNEGOTIATE)GetProcAddress(hGina, "WlxNegotiate");
657 Functions->WlxInitialize = (PFWLXINITIALIZE)GetProcAddress(hGina, "WlxInitialize");
658
659 if (!Functions->WlxInitialize)
660 goto cleanup;
661
662 if (!Functions->WlxNegotiate)
663 {
664 /* Assume current version */
665 *DllVersion = WLX_CURRENT_VERSION;
666 }
667 else
668 {
669 TRACE("About to negociate with Gina %S. Winlogon uses version %x\n",
670 GinaDll, WLX_CURRENT_VERSION);
671 if (!Functions->WlxNegotiate(WLX_CURRENT_VERSION, DllVersion))
672 goto cleanup;
673 }
674
675 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion);
676
677 if (*DllVersion >= WLX_VERSION_1_0)
678 {
679 Functions->WlxActivateUserShell = (PFWLXACTIVATEUSERSHELL)GetProcAddress(hGina, "WlxActivateUserShell");
680 if (!Functions->WlxActivateUserShell) goto cleanup;
681 Functions->WlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE)GetProcAddress(hGina, "WlxDisplayLockedNotice");
682 if (!Functions->WlxDisplayLockedNotice) goto cleanup;
683 Functions->WlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE)GetProcAddress(hGina, "WlxDisplaySASNotice");
684 if (!Functions->WlxDisplaySASNotice) goto cleanup;
685 Functions->WlxIsLockOk = (PFWLXISLOCKOK)GetProcAddress(hGina, "WlxIsLockOk");
686 if (!Functions->WlxIsLockOk) goto cleanup;
687 Functions->WlxIsLogoffOk = (PFWLXISLOGOFFOK)GetProcAddress(hGina, "WlxIsLogoffOk");
688 if (!Functions->WlxIsLogoffOk) goto cleanup;
689 Functions->WlxLoggedOnSAS = (PFWLXLOGGEDONSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
690 if (!Functions->WlxLoggedOnSAS) goto cleanup;
691 Functions->WlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
692 if (!Functions->WlxLoggedOutSAS) goto cleanup;
693 Functions->WlxLogoff = (PFWLXLOGOFF)GetProcAddress(hGina, "WlxLogoff");
694 if (!Functions->WlxLogoff) goto cleanup;
695 Functions->WlxShutdown = (PFWLXSHUTDOWN)GetProcAddress(hGina, "WlxShutdown");
696 if (!Functions->WlxShutdown) goto cleanup;
697 Functions->WlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
698 if (!Functions->WlxWkstaLockedSAS) goto cleanup;
699 }
700
701 if (*DllVersion >= WLX_VERSION_1_1)
702 {
703 Functions->WlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY)GetProcAddress(hGina, "WlxScreenSaverNotify");
704 Functions->WlxStartApplication = (PFWLXSTARTAPPLICATION)GetProcAddress(hGina, "WlxStartApplication");
705 }
706
707 if (*DllVersion >= WLX_VERSION_1_3)
708 {
709 Functions->WlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hGina, "WlxDisplayStatusMessage");
710 if (!Functions->WlxDisplayStatusMessage) goto cleanup;
711 Functions->WlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hGina, "WlxGetStatusMessage");
712 if (!Functions->WlxGetStatusMessage) goto cleanup;
713 Functions->WlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hGina, "WlxNetworkProviderLoad");
714 if (!Functions->WlxNetworkProviderLoad) goto cleanup;
715 Functions->WlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE)GetProcAddress(hGina, "WlxRemoveStatusMessage");
716 if (!Functions->WlxRemoveStatusMessage) goto cleanup;
717 }
718
719 /* Provide some default functions */
720 if (!Functions->WlxScreenSaverNotify)
721 Functions->WlxScreenSaverNotify = DefaultWlxScreenSaverNotify;
722
723 ret = TRUE;
724
725 cleanup:
726 if (!ret)
727 {
728 if (hGina)
729 FreeLibrary(hGina);
730 }
731 else
732 *GinaInstance = hGina;
733 return ret;
734 }
735
736 BOOL
737 GinaInit(
738 IN OUT PWLSESSION Session)
739 {
740 DWORD GinaDllVersion;
741
742 if (!LoadGina(&Session->Gina.Functions, &GinaDllVersion, &Session->Gina.hDllInstance))
743 return FALSE;
744
745 Session->Gina.Context = NULL;
746 Session->Gina.Version = GinaDllVersion;
747 Session->Gina.UseCtrlAltDelete = FALSE;
748 Session->SuppressStatus = FALSE;
749 PreviousWindowProc = NULL;
750
751 TRACE("Calling WlxInitialize(\"%S\")\n", Session->InteractiveWindowStationName);
752 return Session->Gina.Functions.WlxInitialize(
753 Session->InteractiveWindowStationName,
754 (HANDLE)Session,
755 NULL,
756 (PVOID)&FunctionTable,
757 &Session->Gina.Context);
758 }
759
760 BOOL
761 CreateWindowStationAndDesktops(
762 IN OUT PWLSESSION Session)
763 {
764 BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE];
765 BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE];
766 PSID pLocalSystemSid = (PSID)&LocalSystemBuffer;
767 PSID pInteractiveSid = (PSID)InteractiveBuffer;
768 DWORD SidSize, AclSize;
769 PACL pDefaultAcl = NULL;
770 PACL pUserDesktopAcl = NULL;
771 SECURITY_ATTRIBUTES DefaultSecurity;
772 SECURITY_ATTRIBUTES UserDesktopSecurity;
773 BOOL ret = FALSE;
774
775 /*
776 * Prepare information for ACLs we will apply
777 */
778 SidSize = SECURITY_MAX_SID_SIZE;
779 if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize))
780 {
781 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
782 goto cleanup;
783 }
784 SidSize = SECURITY_MAX_SID_SIZE;
785 if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize))
786 {
787 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
788 goto cleanup;
789 }
790
791 AclSize = sizeof(ACL)
792 + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid)
793 + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid);
794 pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
795 pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
796 if (!pDefaultAcl || !pUserDesktopAcl)
797 {
798 ERR("WL: HeapAlloc() failed\n");
799 goto cleanup;
800 }
801
802 if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION)
803 || !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION))
804 {
805 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
806 goto cleanup;
807 }
808
809 /*
810 * Create default ACL (window station, winlogon desktop, screen saver desktop)
811 */
812 if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
813 || !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid))
814 {
815 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
816 goto cleanup;
817 }
818 DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
819 DefaultSecurity.lpSecurityDescriptor = pDefaultAcl;
820 DefaultSecurity.bInheritHandle = TRUE;
821
822 /*
823 * Create user desktop ACL
824 */
825 if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
826 || !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid))
827 {
828 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
829 goto cleanup;
830 }
831 UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
832 UserDesktopSecurity.lpSecurityDescriptor = pUserDesktopAcl;
833 UserDesktopSecurity.bInheritHandle = TRUE;
834
835 /*
836 * Create the interactive window station
837 */
838 Session->InteractiveWindowStationName = L"WinSta0";
839 Session->InteractiveWindowStation = CreateWindowStationW(
840 Session->InteractiveWindowStationName,
841 0,
842 WINSTA_CREATEDESKTOP,
843 &DefaultSecurity);
844 if (!Session->InteractiveWindowStation)
845 {
846 ERR("WL: Failed to create window station (%lu)\n", GetLastError());
847 goto cleanup;
848 }
849 if (!SetProcessWindowStation(Session->InteractiveWindowStation))
850 {
851 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
852 goto cleanup;
853 }
854
855 /*
856 * Create the application desktop
857 */
858 Session->ApplicationDesktop = CreateDesktopW(
859 L"Default",
860 NULL,
861 NULL,
862 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
863 GENERIC_ALL,
864 &UserDesktopSecurity);
865 if (!Session->ApplicationDesktop)
866 {
867 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
868 goto cleanup;
869 }
870
871 /*
872 * Create the winlogon desktop
873 */
874 Session->WinlogonDesktop = CreateDesktopW(
875 L"Winlogon",
876 NULL,
877 NULL,
878 0,
879 GENERIC_ALL,
880 &DefaultSecurity);
881 if (!Session->WinlogonDesktop)
882 {
883 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
884 goto cleanup;
885 }
886
887 /*
888 * Create the screen saver desktop
889 */
890 Session->ScreenSaverDesktop = CreateDesktopW(
891 L"Screen-Saver",
892 NULL,
893 NULL,
894 0,
895 GENERIC_ALL,
896 &DefaultSecurity);
897 if(!Session->ScreenSaverDesktop)
898 {
899 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
900 goto cleanup;
901 }
902
903 /* FIXME: big HACK */
904 CloseDesktop(Session->WinlogonDesktop);
905 CloseDesktop(Session->ScreenSaverDesktop);
906 Session->WinlogonDesktop = OpenDesktopW(L"Default", 0, FALSE, GENERIC_ALL);
907 Session->ScreenSaverDesktop = OpenDesktopW(L"Default", 0, FALSE, GENERIC_ALL);
908
909 /*
910 * Switch to winlogon desktop
911 */
912 if (!SetThreadDesktop(Session->WinlogonDesktop) ||
913 !SwitchDesktop(Session->WinlogonDesktop))
914 {
915 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
916 goto cleanup;
917 }
918
919 ret = TRUE;
920
921 cleanup:
922 if (!ret)
923 {
924 if (Session->ApplicationDesktop)
925 {
926 CloseDesktop(Session->ApplicationDesktop);
927 Session->ApplicationDesktop = NULL;
928 }
929 if (Session->WinlogonDesktop)
930 {
931 CloseDesktop(Session->WinlogonDesktop);
932 Session->WinlogonDesktop = NULL;
933 }
934 if (Session->ScreenSaverDesktop)
935 {
936 CloseDesktop(Session->ScreenSaverDesktop);
937 Session->ScreenSaverDesktop = NULL;
938 }
939 if (Session->InteractiveWindowStation)
940 {
941 CloseWindowStation(Session->InteractiveWindowStation);
942 Session->InteractiveWindowStation = NULL;
943 }
944 }
945 HeapFree(GetProcessHeap(), 0, pDefaultAcl);
946 HeapFree(GetProcessHeap(), 0, pUserDesktopAcl);
947 return ret;
948 }