2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Winlogon
4 * FILE: base/system/winlogon/wlx.c
6 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Ge van Geldorp (gvg@reactos.com)
8 * Hervé Poussineau (hpoussin@reactos.org)
11 /* INCLUDES *****************************************************************/
15 #include <wine/debug.h>
17 WINE_DEFAULT_DEBUG_CHANNEL(winlogon
);
19 #define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \
20 DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \
21 DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
22 DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)
24 #define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
25 WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
26 WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
27 WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \
28 STANDARD_RIGHTS_REQUIRED)
30 #define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \
31 GENERIC_EXECUTE | GENERIC_ALL)
33 /* GLOBALS ******************************************************************/
35 static DLGPROC PreviousWindowProc
;
36 static UINT_PTR IdTimer
;
38 /* FUNCTIONS ****************************************************************/
40 static INT_PTR CALLBACK
47 if (uMsg
== WM_TIMER
&& (UINT_PTR
)wParam
== IdTimer
)
49 EndDialog(hwndDlg
, -1);
50 KillTimer(hwndDlg
, IdTimer
);
53 else if (uMsg
== WM_INITDIALOG
)
55 IdTimer
= SetTimer(hwndDlg
, 0, WLSession
->DialogTimeout
* 1000, NULL
);
56 return PreviousWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
58 else if (uMsg
== WM_NCDESTROY
)
61 ret
= PreviousWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
62 PreviousWindowProc
= NULL
;
67 return PreviousWindowProc(hwndDlg
, uMsg
, wParam
, lParam
);
80 TRACE("WlxUseCtrlAltDel()\n");
82 WlxSetOption(hWlx
, WLX_OPTION_USE_CTRL_ALT_DEL
, TRUE
, &OldValue
);
95 TRACE("WlxSetContextPointer(%p)\n", pWlxContext
);
97 WlxSetOption(hWlx
, WLX_OPTION_CONTEXT_POINTER
, (ULONG_PTR
)pWlxContext
, &OldValue
);
108 PWLSESSION Session
= (PWLSESSION
)hWlx
;
110 TRACE("WlxSasNotify(0x%lx)\n", dwSasType
);
112 if (dwSasType
== WLX_SAS_TYPE_CTRL_ALT_DEL
|| dwSasType
> WLX_SAS_TYPE_MAX_MSFT_VALUE
)
113 PostMessageW(Session
->SASWindow
, WLX_WM_SAS
, dwSasType
, 0);
124 PWLSESSION Session
= (PWLSESSION
)hWlx
;
126 TRACE("WlxSetTimeout(%lu)\n", Timeout
);
128 Session
->DialogTimeout
= Timeout
;
136 WlxAssignShellProtection(
142 UNREFERENCED_PARAMETER(hWlx
);
143 UNREFERENCED_PARAMETER(hToken
);
144 UNREFERENCED_PARAMETER(hProcess
);
145 UNREFERENCED_PARAMETER(hThread
);
162 UNREFERENCED_PARAMETER(hWlx
);
164 TRACE("WlxMessageBox()\n");
165 /* FIXME: Provide a custom window proc to be able to handle timeout */
166 return MessageBoxW(hwndOwner
, lpszText
, lpszTitle
, fuStyle
);
180 UNREFERENCED_PARAMETER(hWlx
);
182 TRACE("WlxDialogBox()\n");
184 if (PreviousWindowProc
!= NULL
)
186 PreviousWindowProc
= dlgprc
;
187 return (int)DialogBoxW((HINSTANCE
) hInst
, lpszTemplate
, hwndOwner
, DefaultWlxWindowProc
);
202 UNREFERENCED_PARAMETER(hWlx
);
204 TRACE("WlxDialogBoxParam()\n");
206 if (PreviousWindowProc
!= NULL
)
208 PreviousWindowProc
= dlgprc
;
209 return (int)DialogBoxParamW(hInst
, lpszTemplate
, hwndOwner
, DefaultWlxWindowProc
, dwInitParam
);
216 WlxDialogBoxIndirect(
219 LPCDLGTEMPLATE hDialogTemplate
,
223 UNREFERENCED_PARAMETER(hWlx
);
225 TRACE("WlxDialogBoxIndirect()\n");
227 if (PreviousWindowProc
!= NULL
)
229 PreviousWindowProc
= dlgprc
;
230 return (int)DialogBoxIndirectW(hInst
, hDialogTemplate
, hwndOwner
, DefaultWlxWindowProc
);
237 WlxDialogBoxIndirectParam(
240 LPCDLGTEMPLATE hDialogTemplate
,
245 UNREFERENCED_PARAMETER(hWlx
);
247 TRACE("WlxDialogBoxIndirectParam()\n");
249 if (PreviousWindowProc
!= NULL
)
251 PreviousWindowProc
= dlgprc
;
252 return (int)DialogBoxIndirectParamW(hInst
, hDialogTemplate
, hwndOwner
, DefaultWlxWindowProc
, dwInitParam
);
259 WlxSwitchDesktopToUser(
262 PWLSESSION Session
= (PWLSESSION
)hWlx
;
264 TRACE("WlxSwitchDesktopToUser()\n");
266 return (int)SwitchDesktop(Session
->ApplicationDesktop
);
273 WlxSwitchDesktopToWinlogon(
276 PWLSESSION Session
= (PWLSESSION
)hWlx
;
278 TRACE("WlxSwitchDesktopToWinlogon()\n");
280 return (int)SwitchDesktop(Session
->WinlogonDesktop
);
287 WlxChangePasswordNotify(
289 PWLX_MPR_NOTIFY_INFO pMprInfo
,
292 UNREFERENCED_PARAMETER(hWlx
);
293 UNREFERENCED_PARAMETER(pMprInfo
);
294 UNREFERENCED_PARAMETER(dwChangeInfo
);
306 PWLX_DESKTOP
* ppDesktop
)
308 UNREFERENCED_PARAMETER(hWlx
);
309 UNREFERENCED_PARAMETER(ppDesktop
);
321 PWLX_DESKTOP pDesktop
)
323 UNREFERENCED_PARAMETER(hWlx
);
324 UNREFERENCED_PARAMETER(pDesktop
);
334 WlxCreateUserDesktop(
338 PWSTR pszDesktopName
,
339 PWLX_DESKTOP
* ppDesktop
)
341 UNREFERENCED_PARAMETER(hWlx
);
342 UNREFERENCED_PARAMETER(hToken
);
343 UNREFERENCED_PARAMETER(Flags
);
344 UNREFERENCED_PARAMETER(pszDesktopName
);
345 UNREFERENCED_PARAMETER(ppDesktop
);
355 WlxChangePasswordNotifyEx(
357 PWLX_MPR_NOTIFY_INFO pMprInfo
,
362 UNREFERENCED_PARAMETER(hWlx
);
363 UNREFERENCED_PARAMETER(pMprInfo
);
364 UNREFERENCED_PARAMETER(dwChangeInfo
);
365 UNREFERENCED_PARAMETER(ProviderName
);
366 UNREFERENCED_PARAMETER(Reserved
);
378 PWLX_DESKTOP pDesktop
,
381 UNREFERENCED_PARAMETER(hWlx
);
382 UNREFERENCED_PARAMETER(pDesktop
);
383 UNREFERENCED_PARAMETER(hToken
);
399 PWLSESSION Session
= (PWLSESSION
)hWlx
;
401 TRACE("WlxSetOption(%lu)\n", Option
);
405 case WLX_OPTION_USE_CTRL_ALT_DEL
:
406 *OldValue
= (ULONG_PTR
)Session
->Gina
.UseCtrlAltDelete
;
407 Session
->Gina
.UseCtrlAltDelete
= (BOOL
)Value
;
409 case WLX_OPTION_CONTEXT_POINTER
:
410 *OldValue
= (ULONG_PTR
)Session
->Gina
.Context
;
411 Session
->Gina
.Context
= (PVOID
)Value
;
413 case WLX_OPTION_USE_SMART_CARD
:
430 PWLSESSION Session
= (PWLSESSION
)hWlx
;
432 TRACE("WlxGetOption(%lu)\n", Option
);
436 case WLX_OPTION_USE_CTRL_ALT_DEL
:
437 *Value
= (ULONG_PTR
)Session
->Gina
.UseCtrlAltDelete
;
439 case WLX_OPTION_CONTEXT_POINTER
:
441 *Value
= (ULONG_PTR
)Session
->Gina
.Context
;
444 case WLX_OPTION_USE_SMART_CARD
:
445 case WLX_OPTION_SMART_CARD_PRESENT
:
446 case WLX_OPTION_SMART_CARD_INFO
:
449 case WLX_OPTION_DISPATCH_TABLE_SIZE
:
451 switch (Session
->Gina
.Version
)
453 case WLX_VERSION_1_0
:
454 *Value
= sizeof(WLX_DISPATCH_VERSION_1_0
);
456 case WLX_VERSION_1_1
:
457 *Value
= sizeof(WLX_DISPATCH_VERSION_1_1
);
459 case WLX_VERSION_1_2
:
460 *Value
= sizeof(WLX_DISPATCH_VERSION_1_2
);
462 case WLX_VERSION_1_3
:
463 *Value
= sizeof(WLX_DISPATCH_VERSION_1_3
);
465 case WLX_VERSION_1_4
:
466 *Value
= sizeof(WLX_DISPATCH_VERSION_1_4
);
485 UNREFERENCED_PARAMETER(hWlx
);
494 WlxQueryClientCredentials(
495 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
)
497 UNREFERENCED_PARAMETER(pCred
);
507 WlxQueryInetConnectorCredentials(
508 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
)
510 UNREFERENCED_PARAMETER(pCred
);
530 WlxQueryTerminalServicesData(
532 PWLX_TERMINAL_SERVICES_DATA pTSData
,
536 UNREFERENCED_PARAMETER(hWlx
);
537 UNREFERENCED_PARAMETER(pTSData
);
538 UNREFERENCED_PARAMETER(UserName
);
539 UNREFERENCED_PARAMETER(Domain
);
549 WlxQueryConsoleSwitchCredentials(
550 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred
)
552 UNREFERENCED_PARAMETER(pCred
);
562 WlxQueryTsLogonCredentials(
563 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred
)
565 UNREFERENCED_PARAMETER(pCred
);
572 WLX_DISPATCH_VERSION_1_4 FunctionTable
= {
574 WlxSetContextPointer
,
577 WlxAssignShellProtection
,
581 WlxDialogBoxIndirect
,
582 WlxDialogBoxIndirectParam
,
583 WlxSwitchDesktopToUser
,
584 WlxSwitchDesktopToWinlogon
,
585 WlxChangePasswordNotify
,
588 WlxCreateUserDesktop
,
589 WlxChangePasswordNotifyEx
,
594 WlxQueryClientCredentials
,
595 WlxQueryInetConnectorCredentials
,
597 WlxQueryTerminalServicesData
,
598 WlxQueryConsoleSwitchCredentials
,
599 WlxQueryTsLogonCredentials
602 /******************************************************************************/
613 Status
= RegOpenKeyExW(
615 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
619 if (Status
!= ERROR_SUCCESS
)
622 wcsncpy(Path
, L
"msgina.dll", Len
);
626 Size
= Len
* sizeof(WCHAR
);
627 Status
= RegQueryValueExW(
634 if (Status
!= ERROR_SUCCESS
|| Type
!= REG_SZ
|| Size
== 0)
635 wcsncpy(Path
, L
"msgina.dll", Len
);
641 DefaultWlxScreenSaverNotify(
642 IN PVOID pWlxContext
,
643 IN OUT BOOL
*pSecure
)
646 *pSecure
= WLSession
->Gina
.Functions
.WlxIsLogoffOk(pWlxContext
);
652 IN OUT PGINAFUNCTIONS Functions
,
653 OUT DWORD
*DllVersion
,
654 OUT HMODULE
*GinaInstance
)
656 HMODULE hGina
= NULL
;
657 WCHAR GinaDll
[MAX_PATH
+ 1];
661 if (!GetGinaPath(GinaDll
, MAX_PATH
))
663 /* Terminate string */
664 GinaDll
[MAX_PATH
] = '\0';
666 hGina
= LoadLibraryW(GinaDll
);
670 Functions
->WlxNegotiate
= (PFWLXNEGOTIATE
)GetProcAddress(hGina
, "WlxNegotiate");
671 Functions
->WlxInitialize
= (PFWLXINITIALIZE
)GetProcAddress(hGina
, "WlxInitialize");
673 if (!Functions
->WlxInitialize
)
676 if (!Functions
->WlxNegotiate
)
678 /* Assume current version */
679 *DllVersion
= WLX_CURRENT_VERSION
;
683 TRACE("About to negociate with Gina %S. Winlogon uses version %x\n",
684 GinaDll
, WLX_CURRENT_VERSION
);
685 if (!Functions
->WlxNegotiate(WLX_CURRENT_VERSION
, DllVersion
))
689 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion
);
691 if (*DllVersion
>= WLX_VERSION_1_0
)
693 Functions
->WlxActivateUserShell
= (PFWLXACTIVATEUSERSHELL
)GetProcAddress(hGina
, "WlxActivateUserShell");
694 if (!Functions
->WlxActivateUserShell
) goto cleanup
;
695 Functions
->WlxDisplayLockedNotice
= (PFWLXDISPLAYLOCKEDNOTICE
)GetProcAddress(hGina
, "WlxDisplayLockedNotice");
696 if (!Functions
->WlxDisplayLockedNotice
) goto cleanup
;
697 Functions
->WlxDisplaySASNotice
= (PFWLXDISPLAYSASNOTICE
)GetProcAddress(hGina
, "WlxDisplaySASNotice");
698 if (!Functions
->WlxDisplaySASNotice
) goto cleanup
;
699 Functions
->WlxIsLockOk
= (PFWLXISLOCKOK
)GetProcAddress(hGina
, "WlxIsLockOk");
700 if (!Functions
->WlxIsLockOk
) goto cleanup
;
701 Functions
->WlxIsLogoffOk
= (PFWLXISLOGOFFOK
)GetProcAddress(hGina
, "WlxIsLogoffOk");
702 if (!Functions
->WlxIsLogoffOk
) goto cleanup
;
703 Functions
->WlxLoggedOnSAS
= (PFWLXLOGGEDONSAS
)GetProcAddress(hGina
, "WlxLoggedOnSAS");
704 if (!Functions
->WlxLoggedOnSAS
) goto cleanup
;
705 Functions
->WlxLoggedOutSAS
= (PFWLXLOGGEDOUTSAS
)GetProcAddress(hGina
, "WlxLoggedOutSAS");
706 if (!Functions
->WlxLoggedOutSAS
) goto cleanup
;
707 Functions
->WlxLogoff
= (PFWLXLOGOFF
)GetProcAddress(hGina
, "WlxLogoff");
708 if (!Functions
->WlxLogoff
) goto cleanup
;
709 Functions
->WlxShutdown
= (PFWLXSHUTDOWN
)GetProcAddress(hGina
, "WlxShutdown");
710 if (!Functions
->WlxShutdown
) goto cleanup
;
711 Functions
->WlxWkstaLockedSAS
= (PFWLXWKSTALOCKEDSAS
)GetProcAddress(hGina
, "WlxWkstaLockedSAS");
712 if (!Functions
->WlxWkstaLockedSAS
) goto cleanup
;
715 if (*DllVersion
>= WLX_VERSION_1_1
)
717 Functions
->WlxScreenSaverNotify
= (PFWLXSCREENSAVERNOTIFY
)GetProcAddress(hGina
, "WlxScreenSaverNotify");
718 Functions
->WlxStartApplication
= (PFWLXSTARTAPPLICATION
)GetProcAddress(hGina
, "WlxStartApplication");
721 if (*DllVersion
>= WLX_VERSION_1_3
)
723 Functions
->WlxDisplayStatusMessage
= (PFWLXDISPLAYSTATUSMESSAGE
)GetProcAddress(hGina
, "WlxDisplayStatusMessage");
724 if (!Functions
->WlxDisplayStatusMessage
) goto cleanup
;
725 Functions
->WlxGetStatusMessage
= (PFWLXGETSTATUSMESSAGE
)GetProcAddress(hGina
, "WlxGetStatusMessage");
726 if (!Functions
->WlxGetStatusMessage
) goto cleanup
;
727 Functions
->WlxNetworkProviderLoad
= (PFWLXNETWORKPROVIDERLOAD
)GetProcAddress(hGina
, "WlxNetworkProviderLoad");
728 if (!Functions
->WlxNetworkProviderLoad
) goto cleanup
;
729 Functions
->WlxRemoveStatusMessage
= (PFWLXREMOVESTATUSMESSAGE
)GetProcAddress(hGina
, "WlxRemoveStatusMessage");
730 if (!Functions
->WlxRemoveStatusMessage
) goto cleanup
;
733 /* Provide some default functions */
734 if (!Functions
->WlxScreenSaverNotify
)
735 Functions
->WlxScreenSaverNotify
= DefaultWlxScreenSaverNotify
;
746 *GinaInstance
= hGina
;
752 IN OUT PWLSESSION Session
)
754 DWORD GinaDllVersion
;
756 if (!LoadGina(&Session
->Gina
.Functions
, &GinaDllVersion
, &Session
->Gina
.hDllInstance
))
759 Session
->Gina
.Context
= NULL
;
760 Session
->Gina
.Version
= GinaDllVersion
;
761 Session
->Gina
.UseCtrlAltDelete
= FALSE
;
762 Session
->SuppressStatus
= FALSE
;
763 PreviousWindowProc
= NULL
;
765 TRACE("Calling WlxInitialize(\"%S\")\n", Session
->InteractiveWindowStationName
);
766 return Session
->Gina
.Functions
.WlxInitialize(
767 Session
->InteractiveWindowStationName
,
770 (PVOID
)&FunctionTable
,
771 &Session
->Gina
.Context
);
775 AddAceToWindowStation(
780 SECURITY_INFORMATION SecurityInformation
;
781 PACL pDefaultAcl
= NULL
;
782 PSECURITY_DESCRIPTOR WinstaSd
= NULL
;
783 PACCESS_ALLOWED_ACE Ace
= NULL
;
786 /* Allocate space for an ACL */
787 AclSize
= sizeof(ACL
)
788 + 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(Sid
));
789 pDefaultAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
792 ERR("WL: HeapAlloc() failed\n");
797 if (!InitializeAcl(pDefaultAcl
, AclSize
, ACL_REVISION
))
799 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
803 /* Initialize new security descriptor */
804 WinstaSd
= HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH
);
805 if (!InitializeSecurityDescriptor(WinstaSd
, SECURITY_DESCRIPTOR_REVISION
))
807 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
811 /* Allocate memory for access allowed ACE */
812 Ace
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ACCESS_ALLOWED_ACE
)+
813 GetLengthSid(Sid
) - sizeof(DWORD
));
815 /* Create the first ACE for the window station */
816 Ace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
817 Ace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
| OBJECT_INHERIT_ACE
;
818 Ace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
) + GetLengthSid(Sid
) - sizeof(DWORD
);
819 Ace
->Mask
= GENERIC_ACCESS
;
822 if (!CopySid(GetLengthSid(Sid
), &Ace
->SidStart
, Sid
))
824 ERR("WL: CopySid() failed (error %lu)\n", GetLastError());
828 /* Add the first ACE */
829 if (!AddAce(pDefaultAcl
, ACL_REVISION
, MAXDWORD
, (LPVOID
)Ace
, Ace
->Header
.AceSize
))
831 ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
835 /* Add the second ACE to the end of ACL */
836 Ace
->Header
.AceFlags
= NO_PROPAGATE_INHERIT_ACE
;
837 Ace
->Mask
= WINSTA_ALL
;
838 if (!AddAce(pDefaultAcl
, ACL_REVISION
, MAXDWORD
, (LPVOID
)Ace
, Ace
->Header
.AceSize
))
840 ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
844 /* Add ACL to winsta's security descriptor */
845 if (!SetSecurityDescriptorDacl(WinstaSd
, TRUE
, pDefaultAcl
, FALSE
))
847 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
851 /* Apply security to the window station */
852 SecurityInformation
= DACL_SECURITY_INFORMATION
;
853 if (!SetUserObjectSecurity(WinSta
, &SecurityInformation
, WinstaSd
))
855 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
859 /* Indicate success */
863 /* Free allocated stuff */
864 if (pDefaultAcl
) HeapFree(GetProcessHeap(), 0, pDefaultAcl
);
865 if (WinstaSd
) HeapFree(GetProcessHeap(), 0, WinstaSd
);
866 if (Ace
) HeapFree(GetProcessHeap(), 0, Ace
);
878 SECURITY_INFORMATION SecurityInformation
;
880 PSECURITY_DESCRIPTOR DesktopSd
= NULL
;
884 AclSize
= sizeof(ACL
)
885 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(WinlogonSid
);
887 /* Take user's sid into account */
889 AclSize
+= FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(UserSid
);
891 Acl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
894 ERR("WL: HeapAlloc() failed\n");
899 if (!InitializeAcl(Acl
, AclSize
, ACL_REVISION
))
901 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
905 /* Add full desktop access ACE for winlogon */
906 if (!AddAccessAllowedAce(Acl
, ACL_REVISION
, DESKTOP_ALL
, WinlogonSid
))
908 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
912 /* Add full desktop access ACE for a user (if provided) */
913 if (UserSid
&& !AddAccessAllowedAce(Acl
, ACL_REVISION
, DESKTOP_ALL
, UserSid
))
915 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
919 /* Initialize new security descriptor */
920 DesktopSd
= HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH
);
921 if (!InitializeSecurityDescriptor(DesktopSd
, SECURITY_DESCRIPTOR_REVISION
))
923 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
927 /* Add ACL to the security descriptor */
928 if (!SetSecurityDescriptorDacl(DesktopSd
, TRUE
, Acl
, FALSE
))
930 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
934 /* Apply security to the window station */
935 SecurityInformation
= DACL_SECURITY_INFORMATION
;
936 if (!SetUserObjectSecurity(Desktop
, &SecurityInformation
, DesktopSd
))
938 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
942 /* Indicate success */
946 /* Free allocated stuff */
947 if (Acl
) HeapFree(GetProcessHeap(), 0, Acl
);
948 if (DesktopSd
) HeapFree(GetProcessHeap(), 0, DesktopSd
);
954 CreateWindowStationAndDesktops(
955 IN OUT PWLSESSION Session
)
957 BYTE LocalSystemBuffer
[SECURITY_MAX_SID_SIZE
];
958 BYTE InteractiveBuffer
[SECURITY_MAX_SID_SIZE
];
959 PSID pLocalSystemSid
= (PSID
)&LocalSystemBuffer
;
960 PSID pInteractiveSid
= (PSID
)InteractiveBuffer
;
961 DWORD SidSize
, AclSize
;
962 PACL pDefaultAcl
= NULL
;
963 PACL pUserDesktopAcl
= NULL
;
964 SECURITY_ATTRIBUTES DefaultSecurity
;
965 SECURITY_ATTRIBUTES UserDesktopSecurity
;
969 * Prepare information for ACLs we will apply
971 SidSize
= SECURITY_MAX_SID_SIZE
;
972 if (!CreateWellKnownSid(WinLocalSystemSid
, NULL
, pLocalSystemSid
, &SidSize
))
974 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
977 SidSize
= SECURITY_MAX_SID_SIZE
;
978 if (!CreateWellKnownSid(WinInteractiveSid
, NULL
, pInteractiveSid
, &SidSize
))
980 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
984 AclSize
= sizeof(ACL
)
985 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(pLocalSystemSid
)
986 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(pInteractiveSid
);
987 pDefaultAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
988 pUserDesktopAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
989 if (!pDefaultAcl
|| !pUserDesktopAcl
)
991 ERR("WL: HeapAlloc() failed\n");
995 if (!InitializeAcl(pDefaultAcl
, AclSize
, ACL_REVISION
)
996 || !InitializeAcl(pUserDesktopAcl
, AclSize
, ACL_REVISION
))
998 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
1003 * Create default ACL (window station, winlogon desktop, screen saver desktop)
1005 if (!AddAccessAllowedAce(pDefaultAcl
, ACL_REVISION
, GENERIC_ALL
, pLocalSystemSid
)
1006 || !AddAccessAllowedAce(pDefaultAcl
, ACL_REVISION
, GENERIC_READ
, pInteractiveSid
))
1008 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1011 DefaultSecurity
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1012 DefaultSecurity
.lpSecurityDescriptor
= pDefaultAcl
;
1013 DefaultSecurity
.bInheritHandle
= TRUE
;
1016 * Create user desktop ACL
1018 if (!AddAccessAllowedAce(pUserDesktopAcl
, ACL_REVISION
, GENERIC_ALL
, pLocalSystemSid
)
1019 || !AddAccessAllowedAce(pUserDesktopAcl
, ACL_REVISION
, GENERIC_ALL
, pInteractiveSid
))
1021 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1024 UserDesktopSecurity
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1025 UserDesktopSecurity
.lpSecurityDescriptor
= pUserDesktopAcl
;
1026 UserDesktopSecurity
.bInheritHandle
= TRUE
;
1029 * Create the interactive window station
1031 Session
->InteractiveWindowStationName
= L
"WinSta0";
1032 Session
->InteractiveWindowStation
= CreateWindowStationW(
1033 Session
->InteractiveWindowStationName
,
1037 if (!Session
->InteractiveWindowStation
)
1039 ERR("WL: Failed to create window station (%lu)\n", GetLastError());
1042 if (!SetProcessWindowStation(Session
->InteractiveWindowStation
))
1044 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
1049 * Create the application desktop
1051 Session
->ApplicationDesktop
= CreateDesktopW(
1055 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
1057 &UserDesktopSecurity
);
1058 if (!Session
->ApplicationDesktop
)
1060 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
1065 * Create the winlogon desktop
1067 Session
->WinlogonDesktop
= CreateDesktopW(
1074 if (!Session
->WinlogonDesktop
)
1076 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
1081 * Create the screen saver desktop
1083 Session
->ScreenSaverDesktop
= CreateDesktopW(
1090 if(!Session
->ScreenSaverDesktop
)
1092 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
1096 /* FIXME: big HACK */
1097 CloseDesktop(Session
->WinlogonDesktop
);
1098 CloseDesktop(Session
->ScreenSaverDesktop
);
1099 Session
->WinlogonDesktop
= OpenDesktopW(L
"Default", 0, FALSE
, GENERIC_ALL
);
1100 Session
->ScreenSaverDesktop
= OpenDesktopW(L
"Default", 0, FALSE
, GENERIC_ALL
);
1103 * Switch to winlogon desktop
1105 if (!SetThreadDesktop(Session
->WinlogonDesktop
) ||
1106 !SwitchDesktop(Session
->WinlogonDesktop
))
1108 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
1117 if (Session
->ApplicationDesktop
)
1119 CloseDesktop(Session
->ApplicationDesktop
);
1120 Session
->ApplicationDesktop
= NULL
;
1122 if (Session
->WinlogonDesktop
)
1124 CloseDesktop(Session
->WinlogonDesktop
);
1125 Session
->WinlogonDesktop
= NULL
;
1127 if (Session
->ScreenSaverDesktop
)
1129 CloseDesktop(Session
->ScreenSaverDesktop
);
1130 Session
->ScreenSaverDesktop
= NULL
;
1132 if (Session
->InteractiveWindowStation
)
1134 CloseWindowStation(Session
->InteractiveWindowStation
);
1135 Session
->InteractiveWindowStation
= NULL
;
1138 HeapFree(GetProcessHeap(), 0, pDefaultAcl
);
1139 HeapFree(GetProcessHeap(), 0, pUserDesktopAcl
);