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 #define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \
16 DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \
17 DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
18 DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)
20 #define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
21 WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
22 WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
23 WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \
24 STANDARD_RIGHTS_REQUIRED)
26 #define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \
27 GENERIC_EXECUTE | GENERIC_ALL)
29 typedef struct _DIALOG_LIST_ENTRY
35 } DIALOG_LIST_ENTRY
, *PDIALOG_LIST_ENTRY
;
37 /* GLOBALS ******************************************************************/
39 //static UINT_PTR IdTimer;
40 static LIST_ENTRY DialogListHead
;
42 /* FUNCTIONS ****************************************************************/
45 InitDialogListHead(VOID
)
47 InitializeListHead(&DialogListHead
);
53 AddDialogListEntry(VOID
)
55 PDIALOG_LIST_ENTRY ListEntry
;
57 ListEntry
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DIALOG_LIST_ENTRY
));
58 if (ListEntry
== NULL
)
61 TRACE("Add entry %p\n", ListEntry
);
63 InsertHeadList(&DialogListHead
,
72 RemoveDialogListEntry(PDIALOG_LIST_ENTRY ListEntry
)
74 TRACE("Remove entry %p\n", ListEntry
);
76 RemoveEntryList(&ListEntry
->Entry
);
77 RtlFreeHeap(RtlGetProcessHeap(), 0, ListEntry
);
83 GetDialogListEntry(HWND hwndDlg
)
85 PDIALOG_LIST_ENTRY Current
;
86 PLIST_ENTRY ListEntry
;
88 ListEntry
= DialogListHead
.Flink
;
89 while (ListEntry
!= &DialogListHead
)
91 Current
= CONTAINING_RECORD(ListEntry
,
94 if (Current
->hWnd
== hwndDlg
)
96 TRACE("Found entry: %p\n", Current
);
100 ListEntry
= ListEntry
->Flink
;
103 TRACE("Found no entry!\n");
109 GetTopDialogWindow(VOID
)
111 PDIALOG_LIST_ENTRY Current
;
112 PLIST_ENTRY ListEntry
;
114 ListEntry
= DialogListHead
.Flink
;
115 if (ListEntry
!= &DialogListHead
)
117 Current
= CONTAINING_RECORD(ListEntry
,
121 TRACE("Found entry: %p window %p\n", Current
, Current
->hWnd
);
122 return Current
->hWnd
;
125 TRACE("Found no window\n");
133 DefaultWlxWindowProc(
139 PDIALOG_LIST_ENTRY ListEntry
;
142 if (uMsg
== WM_INITDIALOG
)
144 ListEntry
= (PDIALOG_LIST_ENTRY
)lParam
;
146 TRACE("Set dialog handle: %p\n", hwndDlg
);
147 ListEntry
->hWnd
= hwndDlg
;
148 lParam
= ListEntry
->lParam
;
149 // SetTopTimeout(hWnd);
153 ListEntry
= GetDialogListEntry(hwndDlg
);
154 if (ListEntry
== NULL
)
158 if (uMsg
== WLX_WM_SAS
)
160 EndDialog(hwndDlg
, WLX_DLG_SAS
);
164 ret
= ListEntry
->DlgProc(hwndDlg
, uMsg
, wParam
, lParam
);
169 if (uMsg == WM_TIMER && (UINT_PTR)wParam == IdTimer)
171 EndDialog(hwndDlg, -1);
172 KillTimer(hwndDlg, IdTimer);
175 else if (uMsg == WM_INITDIALOG)
177 IdTimer = SetTimer(hwndDlg, 0, WLSession->DialogTimeout * 1000, NULL);
178 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
180 else if (uMsg == WM_NCDESTROY)
183 ret = PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
184 PreviousWindowProc = NULL;
189 return PreviousWindowProc(hwndDlg, uMsg, wParam, lParam);
204 TRACE("WlxUseCtrlAltDel()\n");
206 WlxSetOption(hWlx
, WLX_OPTION_USE_CTRL_ALT_DEL
, TRUE
, &OldValue
);
214 WlxSetContextPointer(
220 TRACE("WlxSetContextPointer(%p)\n", pWlxContext
);
222 WlxSetOption(hWlx
, WLX_OPTION_CONTEXT_POINTER
, (ULONG_PTR
)pWlxContext
, &OldValue
);
234 PWLSESSION Session
= (PWLSESSION
)hWlx
;
236 TRACE("WlxSasNotify(0x%lx)\n", dwSasType
);
238 if (dwSasType
== WLX_SAS_TYPE_CTRL_ALT_DEL
|| dwSasType
> WLX_SAS_TYPE_MAX_MSFT_VALUE
)
239 PostMessageW(Session
->SASWindow
, WLX_WM_SAS
, dwSasType
, 0);
251 PWLSESSION Session
= (PWLSESSION
)hWlx
;
253 TRACE("WlxSetTimeout(%lu)\n", Timeout
);
255 Session
->DialogTimeout
= Timeout
;
264 WlxAssignShellProtection(
270 UNREFERENCED_PARAMETER(hWlx
);
271 UNREFERENCED_PARAMETER(hToken
);
272 UNREFERENCED_PARAMETER(hProcess
);
273 UNREFERENCED_PARAMETER(hThread
);
291 UNREFERENCED_PARAMETER(hWlx
);
293 TRACE("WlxMessageBox()\n");
294 /* FIXME: Provide a custom window proc to be able to handle timeout */
295 return MessageBoxW(hwndOwner
, lpszText
, lpszTitle
, fuStyle
);
310 UNREFERENCED_PARAMETER(hWlx
);
312 TRACE("WlxDialogBox()\n");
314 return (int)WlxDialogBoxParam(hWlx
, hInst
, lpszTemplate
, hwndOwner
, dlgprc
, 0);
330 PDIALOG_LIST_ENTRY ListEntry
;
333 UNREFERENCED_PARAMETER(hWlx
);
335 TRACE("WlxDialogBoxParam()\n");
337 ListEntry
= AddDialogListEntry();
338 if (ListEntry
== NULL
)
341 ListEntry
->DlgProc
= dlgprc
;
342 ListEntry
->lParam
= dwInitParam
;
344 ret
= (int)DialogBoxParamW(hInst
, lpszTemplate
, hwndOwner
, DefaultWlxWindowProc
, (LPARAM
)ListEntry
);
346 RemoveDialogListEntry(ListEntry
);
356 WlxDialogBoxIndirect(
359 LPCDLGTEMPLATE hDialogTemplate
,
363 UNREFERENCED_PARAMETER(hWlx
);
365 TRACE("WlxDialogBoxIndirect()\n");
367 return (int)WlxDialogBoxIndirectParam(hWlx
, hInst
, hDialogTemplate
, hwndOwner
, dlgprc
, 0);
375 WlxDialogBoxIndirectParam(
378 LPCDLGTEMPLATE hDialogTemplate
,
383 PDIALOG_LIST_ENTRY ListEntry
;
386 UNREFERENCED_PARAMETER(hWlx
);
388 TRACE("WlxDialogBoxIndirectParam()\n");
390 ListEntry
= AddDialogListEntry();
391 if (ListEntry
== NULL
)
394 ListEntry
->DlgProc
= dlgprc
;
395 ListEntry
->lParam
= dwInitParam
;
397 ret
= (int)DialogBoxIndirectParamW(hInst
, hDialogTemplate
, hwndOwner
, DefaultWlxWindowProc
, (LPARAM
)ListEntry
);
399 RemoveDialogListEntry(ListEntry
);
409 WlxSwitchDesktopToUser(
412 PWLSESSION Session
= (PWLSESSION
)hWlx
;
414 TRACE("WlxSwitchDesktopToUser()\n");
416 return (int)SwitchDesktop(Session
->ApplicationDesktop
);
424 WlxSwitchDesktopToWinlogon(
427 PWLSESSION Session
= (PWLSESSION
)hWlx
;
429 TRACE("WlxSwitchDesktopToWinlogon()\n");
431 return (int)SwitchDesktop(Session
->WinlogonDesktop
);
439 WlxChangePasswordNotify(
441 PWLX_MPR_NOTIFY_INFO pMprInfo
,
444 UNREFERENCED_PARAMETER(hWlx
);
445 UNREFERENCED_PARAMETER(pMprInfo
);
446 UNREFERENCED_PARAMETER(dwChangeInfo
);
459 PWLX_DESKTOP
* ppDesktop
)
461 UNREFERENCED_PARAMETER(hWlx
);
462 UNREFERENCED_PARAMETER(ppDesktop
);
475 PWLX_DESKTOP pDesktop
)
477 UNREFERENCED_PARAMETER(hWlx
);
478 UNREFERENCED_PARAMETER(pDesktop
);
489 WlxCreateUserDesktop(
493 PWSTR pszDesktopName
,
494 PWLX_DESKTOP
* ppDesktop
)
496 UNREFERENCED_PARAMETER(hWlx
);
497 UNREFERENCED_PARAMETER(hToken
);
498 UNREFERENCED_PARAMETER(Flags
);
499 UNREFERENCED_PARAMETER(pszDesktopName
);
500 UNREFERENCED_PARAMETER(ppDesktop
);
511 WlxChangePasswordNotifyEx(
513 PWLX_MPR_NOTIFY_INFO pMprInfo
,
518 UNREFERENCED_PARAMETER(hWlx
);
519 UNREFERENCED_PARAMETER(pMprInfo
);
520 UNREFERENCED_PARAMETER(dwChangeInfo
);
521 UNREFERENCED_PARAMETER(ProviderName
);
522 UNREFERENCED_PARAMETER(Reserved
);
535 PWLX_DESKTOP pDesktop
,
538 UNREFERENCED_PARAMETER(hWlx
);
539 UNREFERENCED_PARAMETER(pDesktop
);
540 UNREFERENCED_PARAMETER(hToken
);
557 PWLSESSION Session
= (PWLSESSION
)hWlx
;
559 TRACE("WlxSetOption(%lu)\n", Option
);
563 case WLX_OPTION_USE_CTRL_ALT_DEL
:
564 *OldValue
= (ULONG_PTR
)Session
->Gina
.UseCtrlAltDelete
;
565 Session
->Gina
.UseCtrlAltDelete
= (BOOL
)Value
;
567 case WLX_OPTION_CONTEXT_POINTER
:
568 *OldValue
= (ULONG_PTR
)Session
->Gina
.Context
;
569 Session
->Gina
.Context
= (PVOID
)Value
;
571 case WLX_OPTION_USE_SMART_CARD
:
589 PWLSESSION Session
= (PWLSESSION
)hWlx
;
591 TRACE("WlxGetOption(%lu)\n", Option
);
595 case WLX_OPTION_USE_CTRL_ALT_DEL
:
596 *Value
= (ULONG_PTR
)Session
->Gina
.UseCtrlAltDelete
;
598 case WLX_OPTION_CONTEXT_POINTER
:
600 *Value
= (ULONG_PTR
)Session
->Gina
.Context
;
603 case WLX_OPTION_USE_SMART_CARD
:
604 case WLX_OPTION_SMART_CARD_PRESENT
:
605 case WLX_OPTION_SMART_CARD_INFO
:
608 case WLX_OPTION_DISPATCH_TABLE_SIZE
:
610 switch (Session
->Gina
.Version
)
612 case WLX_VERSION_1_0
:
613 *Value
= sizeof(WLX_DISPATCH_VERSION_1_0
);
615 case WLX_VERSION_1_1
:
616 *Value
= sizeof(WLX_DISPATCH_VERSION_1_1
);
618 case WLX_VERSION_1_2
:
619 *Value
= sizeof(WLX_DISPATCH_VERSION_1_2
);
621 case WLX_VERSION_1_3
:
622 *Value
= sizeof(WLX_DISPATCH_VERSION_1_3
);
624 case WLX_VERSION_1_4
:
625 *Value
= sizeof(WLX_DISPATCH_VERSION_1_4
);
645 UNREFERENCED_PARAMETER(hWlx
);
655 WlxQueryClientCredentials(
656 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
)
658 UNREFERENCED_PARAMETER(pCred
);
669 WlxQueryInetConnectorCredentials(
670 PWLX_CLIENT_CREDENTIALS_INFO_V1_0 pCred
)
672 UNREFERENCED_PARAMETER(pCred
);
694 WlxQueryTerminalServicesData(
696 PWLX_TERMINAL_SERVICES_DATA pTSData
,
700 UNREFERENCED_PARAMETER(hWlx
);
701 UNREFERENCED_PARAMETER(pTSData
);
702 UNREFERENCED_PARAMETER(UserName
);
703 UNREFERENCED_PARAMETER(Domain
);
714 WlxQueryConsoleSwitchCredentials(
715 PWLX_CONSOLESWITCH_CREDENTIALS_INFO_V1_0 pCred
)
717 UNREFERENCED_PARAMETER(pCred
);
728 WlxQueryTsLogonCredentials(
729 PWLX_CLIENT_CREDENTIALS_INFO_V2_0 pCred
)
731 UNREFERENCED_PARAMETER(pCred
);
738 WLX_DISPATCH_VERSION_1_4 FunctionTable
= {
740 WlxSetContextPointer
,
743 WlxAssignShellProtection
,
747 WlxDialogBoxIndirect
,
748 WlxDialogBoxIndirectParam
,
749 WlxSwitchDesktopToUser
,
750 WlxSwitchDesktopToWinlogon
,
751 WlxChangePasswordNotify
,
754 WlxCreateUserDesktop
,
755 WlxChangePasswordNotifyEx
,
760 WlxQueryClientCredentials
,
761 WlxQueryInetConnectorCredentials
,
763 WlxQueryTerminalServicesData
,
764 WlxQueryConsoleSwitchCredentials
,
765 WlxQueryTsLogonCredentials
768 /******************************************************************************/
780 Status
= RegOpenKeyExW(
782 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
786 if (Status
!= ERROR_SUCCESS
)
789 wcsncpy(Path
, L
"msgina.dll", Len
);
793 Size
= Len
* sizeof(WCHAR
);
794 Status
= RegQueryValueExW(
801 if (Status
!= ERROR_SUCCESS
|| Type
!= REG_SZ
|| Size
== 0)
802 wcsncpy(Path
, L
"msgina.dll", Len
);
810 DefaultWlxScreenSaverNotify(
811 IN PVOID pWlxContext
,
812 IN OUT BOOL
*pSecure
)
815 *pSecure
= WLSession
->Gina
.Functions
.WlxIsLogoffOk(pWlxContext
);
822 IN OUT PGINAFUNCTIONS Functions
,
823 OUT DWORD
*DllVersion
,
824 OUT HMODULE
*GinaInstance
)
826 HMODULE hGina
= NULL
;
827 WCHAR GinaDll
[MAX_PATH
+ 1];
831 if (!GetGinaPath(GinaDll
, MAX_PATH
))
833 /* Terminate string */
834 GinaDll
[MAX_PATH
] = '\0';
836 hGina
= LoadLibraryW(GinaDll
);
840 Functions
->WlxNegotiate
= (PFWLXNEGOTIATE
)GetProcAddress(hGina
, "WlxNegotiate");
841 Functions
->WlxInitialize
= (PFWLXINITIALIZE
)GetProcAddress(hGina
, "WlxInitialize");
843 if (!Functions
->WlxInitialize
)
846 if (!Functions
->WlxNegotiate
)
848 /* Assume current version */
849 *DllVersion
= WLX_CURRENT_VERSION
;
853 TRACE("About to negotiate with Gina %S. Winlogon uses version %x\n",
854 GinaDll
, WLX_CURRENT_VERSION
);
855 if (!Functions
->WlxNegotiate(WLX_CURRENT_VERSION
, DllVersion
))
859 TRACE("Gina uses WLX_VERSION %lx\n", *DllVersion
);
861 if (*DllVersion
>= WLX_VERSION_1_0
)
863 Functions
->WlxActivateUserShell
= (PFWLXACTIVATEUSERSHELL
)GetProcAddress(hGina
, "WlxActivateUserShell");
864 if (!Functions
->WlxActivateUserShell
) goto cleanup
;
865 Functions
->WlxDisplayLockedNotice
= (PFWLXDISPLAYLOCKEDNOTICE
)GetProcAddress(hGina
, "WlxDisplayLockedNotice");
866 if (!Functions
->WlxDisplayLockedNotice
) goto cleanup
;
867 Functions
->WlxDisplaySASNotice
= (PFWLXDISPLAYSASNOTICE
)GetProcAddress(hGina
, "WlxDisplaySASNotice");
868 if (!Functions
->WlxDisplaySASNotice
) goto cleanup
;
869 Functions
->WlxIsLockOk
= (PFWLXISLOCKOK
)GetProcAddress(hGina
, "WlxIsLockOk");
870 if (!Functions
->WlxIsLockOk
) goto cleanup
;
871 Functions
->WlxIsLogoffOk
= (PFWLXISLOGOFFOK
)GetProcAddress(hGina
, "WlxIsLogoffOk");
872 if (!Functions
->WlxIsLogoffOk
) goto cleanup
;
873 Functions
->WlxLoggedOnSAS
= (PFWLXLOGGEDONSAS
)GetProcAddress(hGina
, "WlxLoggedOnSAS");
874 if (!Functions
->WlxLoggedOnSAS
) goto cleanup
;
875 Functions
->WlxLoggedOutSAS
= (PFWLXLOGGEDOUTSAS
)GetProcAddress(hGina
, "WlxLoggedOutSAS");
876 if (!Functions
->WlxLoggedOutSAS
) goto cleanup
;
877 Functions
->WlxLogoff
= (PFWLXLOGOFF
)GetProcAddress(hGina
, "WlxLogoff");
878 if (!Functions
->WlxLogoff
) goto cleanup
;
879 Functions
->WlxShutdown
= (PFWLXSHUTDOWN
)GetProcAddress(hGina
, "WlxShutdown");
880 if (!Functions
->WlxShutdown
) goto cleanup
;
881 Functions
->WlxWkstaLockedSAS
= (PFWLXWKSTALOCKEDSAS
)GetProcAddress(hGina
, "WlxWkstaLockedSAS");
882 if (!Functions
->WlxWkstaLockedSAS
) goto cleanup
;
885 if (*DllVersion
>= WLX_VERSION_1_1
)
887 Functions
->WlxScreenSaverNotify
= (PFWLXSCREENSAVERNOTIFY
)GetProcAddress(hGina
, "WlxScreenSaverNotify");
888 Functions
->WlxStartApplication
= (PFWLXSTARTAPPLICATION
)GetProcAddress(hGina
, "WlxStartApplication");
891 if (*DllVersion
>= WLX_VERSION_1_3
)
893 Functions
->WlxDisplayStatusMessage
= (PFWLXDISPLAYSTATUSMESSAGE
)GetProcAddress(hGina
, "WlxDisplayStatusMessage");
894 if (!Functions
->WlxDisplayStatusMessage
) goto cleanup
;
895 Functions
->WlxGetStatusMessage
= (PFWLXGETSTATUSMESSAGE
)GetProcAddress(hGina
, "WlxGetStatusMessage");
896 if (!Functions
->WlxGetStatusMessage
) goto cleanup
;
897 Functions
->WlxNetworkProviderLoad
= (PFWLXNETWORKPROVIDERLOAD
)GetProcAddress(hGina
, "WlxNetworkProviderLoad");
898 if (!Functions
->WlxNetworkProviderLoad
) goto cleanup
;
899 Functions
->WlxRemoveStatusMessage
= (PFWLXREMOVESTATUSMESSAGE
)GetProcAddress(hGina
, "WlxRemoveStatusMessage");
900 if (!Functions
->WlxRemoveStatusMessage
) goto cleanup
;
903 /* Provide some default functions */
904 if (!Functions
->WlxScreenSaverNotify
)
905 Functions
->WlxScreenSaverNotify
= DefaultWlxScreenSaverNotify
;
916 *GinaInstance
= hGina
;
922 IN OUT PWLSESSION Session
)
924 DWORD GinaDllVersion
;
926 if (!LoadGina(&Session
->Gina
.Functions
, &GinaDllVersion
, &Session
->Gina
.hDllInstance
))
929 Session
->Gina
.Context
= NULL
;
930 Session
->Gina
.Version
= GinaDllVersion
;
931 Session
->Gina
.UseCtrlAltDelete
= FALSE
;
932 Session
->SuppressStatus
= FALSE
;
934 TRACE("Calling WlxInitialize(\"%S\")\n", Session
->InteractiveWindowStationName
);
935 return Session
->Gina
.Functions
.WlxInitialize(
936 Session
->InteractiveWindowStationName
,
939 (PVOID
)&FunctionTable
,
940 &Session
->Gina
.Context
);
944 AddAceToWindowStation(
949 SECURITY_INFORMATION SecurityInformation
;
950 PACL pDefaultAcl
= NULL
;
951 PSECURITY_DESCRIPTOR WinstaSd
= NULL
;
952 PACCESS_ALLOWED_ACE Ace
= NULL
;
955 /* Allocate space for an ACL */
956 AclSize
= sizeof(ACL
)
957 + 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(Sid
));
958 pDefaultAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
961 ERR("WL: HeapAlloc() failed\n");
966 if (!InitializeAcl(pDefaultAcl
, AclSize
, ACL_REVISION
))
968 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
972 /* Initialize new security descriptor */
973 WinstaSd
= HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH
);
974 if (!InitializeSecurityDescriptor(WinstaSd
, SECURITY_DESCRIPTOR_REVISION
))
976 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
980 /* Allocate memory for access allowed ACE */
981 Ace
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ACCESS_ALLOWED_ACE
)+
982 GetLengthSid(Sid
) - sizeof(DWORD
));
984 /* Create the first ACE for the window station */
985 Ace
->Header
.AceType
= ACCESS_ALLOWED_ACE_TYPE
;
986 Ace
->Header
.AceFlags
= CONTAINER_INHERIT_ACE
| INHERIT_ONLY_ACE
| OBJECT_INHERIT_ACE
;
987 Ace
->Header
.AceSize
= sizeof(ACCESS_ALLOWED_ACE
) + GetLengthSid(Sid
) - sizeof(DWORD
);
988 Ace
->Mask
= GENERIC_ACCESS
;
991 if (!CopySid(GetLengthSid(Sid
), &Ace
->SidStart
, Sid
))
993 ERR("WL: CopySid() failed (error %lu)\n", GetLastError());
997 /* Add the first ACE */
998 if (!AddAce(pDefaultAcl
, ACL_REVISION
, MAXDWORD
, (LPVOID
)Ace
, Ace
->Header
.AceSize
))
1000 ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
1004 /* Add the second ACE to the end of ACL */
1005 Ace
->Header
.AceFlags
= NO_PROPAGATE_INHERIT_ACE
;
1006 Ace
->Mask
= WINSTA_ALL
;
1007 if (!AddAce(pDefaultAcl
, ACL_REVISION
, MAXDWORD
, (LPVOID
)Ace
, Ace
->Header
.AceSize
))
1009 ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
1013 /* Add ACL to winsta's security descriptor */
1014 if (!SetSecurityDescriptorDacl(WinstaSd
, TRUE
, pDefaultAcl
, FALSE
))
1016 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
1020 /* Apply security to the window station */
1021 SecurityInformation
= DACL_SECURITY_INFORMATION
;
1022 if (!SetUserObjectSecurity(WinSta
, &SecurityInformation
, WinstaSd
))
1024 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
1028 /* Indicate success */
1032 /* Free allocated stuff */
1033 if (pDefaultAcl
) HeapFree(GetProcessHeap(), 0, pDefaultAcl
);
1034 if (WinstaSd
) HeapFree(GetProcessHeap(), 0, WinstaSd
);
1035 if (Ace
) HeapFree(GetProcessHeap(), 0, Ace
);
1043 IN PSID WinlogonSid
,
1047 SECURITY_INFORMATION SecurityInformation
;
1049 PSECURITY_DESCRIPTOR DesktopSd
= NULL
;
1053 AclSize
= sizeof(ACL
)
1054 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(WinlogonSid
);
1056 /* Take user's sid into account */
1058 AclSize
+= FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(UserSid
);
1060 Acl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
1063 ERR("WL: HeapAlloc() failed\n");
1067 /* Initialize ACL */
1068 if (!InitializeAcl(Acl
, AclSize
, ACL_REVISION
))
1070 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
1074 /* Add full desktop access ACE for winlogon */
1075 if (!AddAccessAllowedAce(Acl
, ACL_REVISION
, DESKTOP_ALL
, WinlogonSid
))
1077 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1081 /* Add full desktop access ACE for a user (if provided) */
1082 if (UserSid
&& !AddAccessAllowedAce(Acl
, ACL_REVISION
, DESKTOP_ALL
, UserSid
))
1084 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1088 /* Initialize new security descriptor */
1089 DesktopSd
= HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH
);
1090 if (!InitializeSecurityDescriptor(DesktopSd
, SECURITY_DESCRIPTOR_REVISION
))
1092 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
1096 /* Add ACL to the security descriptor */
1097 if (!SetSecurityDescriptorDacl(DesktopSd
, TRUE
, Acl
, FALSE
))
1099 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
1103 /* Apply security to the window station */
1104 SecurityInformation
= DACL_SECURITY_INFORMATION
;
1105 if (!SetUserObjectSecurity(Desktop
, &SecurityInformation
, DesktopSd
))
1107 ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
1111 /* Indicate success */
1115 /* Free allocated stuff */
1116 if (Acl
) HeapFree(GetProcessHeap(), 0, Acl
);
1117 if (DesktopSd
) HeapFree(GetProcessHeap(), 0, DesktopSd
);
1123 CreateWindowStationAndDesktops(
1124 IN OUT PWLSESSION Session
)
1126 BYTE LocalSystemBuffer
[SECURITY_MAX_SID_SIZE
];
1127 BYTE InteractiveBuffer
[SECURITY_MAX_SID_SIZE
];
1128 PSID pLocalSystemSid
= (PSID
)&LocalSystemBuffer
;
1129 PSID pInteractiveSid
= (PSID
)InteractiveBuffer
;
1130 DWORD SidSize
, AclSize
;
1131 PACL pDefaultAcl
= NULL
;
1132 PACL pUserDesktopAcl
= NULL
;
1133 SECURITY_DESCRIPTOR DefaultSecurityDescriptor
;
1134 SECURITY_ATTRIBUTES DefaultSecurity
;
1135 SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor
;
1136 SECURITY_ATTRIBUTES UserDesktopSecurity
;
1140 * Prepare information for ACLs we will apply
1142 SidSize
= SECURITY_MAX_SID_SIZE
;
1143 if (!CreateWellKnownSid(WinLocalSystemSid
, NULL
, pLocalSystemSid
, &SidSize
))
1145 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
1148 SidSize
= SECURITY_MAX_SID_SIZE
;
1149 if (!CreateWellKnownSid(WinInteractiveSid
, NULL
, pInteractiveSid
, &SidSize
))
1151 ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
1155 AclSize
= sizeof(ACL
)
1156 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(pLocalSystemSid
)
1157 + FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(pInteractiveSid
);
1158 pDefaultAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
1159 pUserDesktopAcl
= HeapAlloc(GetProcessHeap(), 0, AclSize
);
1160 if (!pDefaultAcl
|| !pUserDesktopAcl
)
1162 ERR("WL: HeapAlloc() failed\n");
1166 if (!InitializeAcl(pDefaultAcl
, AclSize
, ACL_REVISION
)
1167 || !InitializeAcl(pUserDesktopAcl
, AclSize
, ACL_REVISION
))
1169 ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
1174 * Create default ACL (window station, winlogon desktop, screen saver desktop)
1176 if (!AddAccessAllowedAce(pDefaultAcl
, ACL_REVISION
, GENERIC_ALL
, pLocalSystemSid
)
1177 || !AddAccessAllowedAce(pDefaultAcl
, ACL_REVISION
, GENERIC_READ
, pInteractiveSid
))
1179 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1184 * Create the default security descriptor
1186 if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor
, SECURITY_DESCRIPTOR_REVISION
))
1188 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
1192 if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor
, TRUE
, pDefaultAcl
, FALSE
))
1194 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
1198 DefaultSecurity
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1199 DefaultSecurity
.lpSecurityDescriptor
= &DefaultSecurityDescriptor
;
1200 DefaultSecurity
.bInheritHandle
= TRUE
;
1203 * Create user desktop ACL
1205 if (!AddAccessAllowedAce(pUserDesktopAcl
, ACL_REVISION
, GENERIC_ALL
, pLocalSystemSid
)
1206 || !AddAccessAllowedAce(pUserDesktopAcl
, ACL_REVISION
, GENERIC_ALL
, pInteractiveSid
))
1208 ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
1213 * Create the user desktop security descriptor
1215 if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor
, SECURITY_DESCRIPTOR_REVISION
))
1217 ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
1221 if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor
, TRUE
, pUserDesktopAcl
, FALSE
))
1223 ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
1227 UserDesktopSecurity
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
1228 UserDesktopSecurity
.lpSecurityDescriptor
= &UserDesktopSecurityDescriptor
;
1229 UserDesktopSecurity
.bInheritHandle
= TRUE
;
1232 * Create the interactive window station
1234 Session
->InteractiveWindowStationName
= L
"WinSta0";
1235 Session
->InteractiveWindowStation
= CreateWindowStationW(
1236 Session
->InteractiveWindowStationName
,
1240 if (!Session
->InteractiveWindowStation
)
1242 ERR("WL: Failed to create window station (%lu)\n", GetLastError());
1245 if (!SetProcessWindowStation(Session
->InteractiveWindowStation
))
1247 ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
1252 * Create the application desktop
1254 Session
->ApplicationDesktop
= CreateDesktopW(
1258 0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
1260 &UserDesktopSecurity
);
1261 if (!Session
->ApplicationDesktop
)
1263 ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
1268 * Create the winlogon desktop
1270 Session
->WinlogonDesktop
= CreateDesktopW(
1277 if (!Session
->WinlogonDesktop
)
1279 ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
1284 * Create the screen saver desktop
1286 Session
->ScreenSaverDesktop
= CreateDesktopW(
1293 if(!Session
->ScreenSaverDesktop
)
1295 ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
1300 * Switch to winlogon desktop
1302 if (!SetThreadDesktop(Session
->WinlogonDesktop
) ||
1303 !SwitchDesktop(Session
->WinlogonDesktop
))
1305 ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
1314 if (Session
->ApplicationDesktop
)
1316 CloseDesktop(Session
->ApplicationDesktop
);
1317 Session
->ApplicationDesktop
= NULL
;
1319 if (Session
->WinlogonDesktop
)
1321 CloseDesktop(Session
->WinlogonDesktop
);
1322 Session
->WinlogonDesktop
= NULL
;
1324 if (Session
->ScreenSaverDesktop
)
1326 CloseDesktop(Session
->ScreenSaverDesktop
);
1327 Session
->ScreenSaverDesktop
= NULL
;
1329 if (Session
->InteractiveWindowStation
)
1331 CloseWindowStation(Session
->InteractiveWindowStation
);
1332 Session
->InteractiveWindowStation
= NULL
;
1335 HeapFree(GetProcessHeap(), 0, pDefaultAcl
);
1336 HeapFree(GetProcessHeap(), 0, pUserDesktopAcl
);