ReactOS 0.4.17-dev-683-g0dafdc5
winsta.c File Reference
#include <win32k.h>
Include dependency graph for winsta.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserWinsta)
 
NTSTATUS NTAPI InitWindowStationImpl (VOID)
 
NTSTATUS NTAPI UserCreateWinstaDirectory (VOID)
 
NTSTATUS NTAPI IntWinStaObjectDelete (_In_ PVOID Parameters)
 
NTSTATUS NTAPI IntWinStaObjectParse (_In_ PVOID Parameters)
 
NTSTATUS NTAPI IntWinStaOkToClose (_In_ PVOID Parameters)
 
NTSTATUS FASTCALL IntValidateWindowStationHandle (HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
 
BOOL FASTCALL co_IntInitializeDesktopGraphics (VOID)
 
VOID FASTCALL IntEndDesktopGraphics (VOID)
 
HDC FASTCALL IntGetScreenDC (VOID)
 
BOOL FASTCALL CheckWinstaAttributeAccess (ACCESS_MASK DesiredAccess)
 
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation (HWINSTA *phWinSta OPTIONAL)
 
static NTSTATUS IntCreateDesktopSwitchEvent (VOID)
 Creates the global per-session \BaseNamedObjects\WinSta0_DesktopSwitch event.
 
NTSTATUS FASTCALL IntCreateWindowStation (OUT HWINSTA *phWinSta, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE OwnerMode, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
 
static VOID FreeUserModeWindowStationName (IN OUT PUNICODE_STRING WindowStationName, IN PUNICODE_STRING TebStaticUnicodeString, IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
 
static NTSTATUS BuildUserModeWindowStationName (IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes, IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes, OUT PUNICODE_STRING *WindowStationName, OUT PUNICODE_STRING *TebStaticUnicodeString)
 
HWINSTA APIENTRY NtUserCreateWindowStation (IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
 
HWINSTA APIENTRY NtUserOpenWindowStation (IN POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK dwDesiredAccess)
 
BOOL APIENTRY NtUserCloseWindowStation (HWINSTA hWinSta)
 
BOOL APIENTRY NtUserGetObjectInformation (HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength, PDWORD nLengthNeeded)
 
BOOL APIENTRY NtUserSetObjectInformation (HANDLE hObject, DWORD nIndex, PVOID pvInformation, DWORD nLength)
 
HWINSTA FASTCALL UserGetProcessWindowStation (VOID)
 
HWINSTA APIENTRY NtUserGetProcessWindowStation (VOID)
 
BOOL FASTCALL UserSetProcessWindowStation (HWINSTA hWindowStation)
 
BOOL APIENTRY NtUserSetProcessWindowStation (HWINSTA hWindowStation)
 
BOOL APIENTRY NtUserLockWindowStation (HWINSTA hWindowStation)
 
BOOL APIENTRY NtUserUnlockWindowStation (HWINSTA hWindowStation)
 
static NTSTATUS FASTCALL BuildWindowStationNameList (ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
 
static NTSTATUS FASTCALL BuildDesktopNameList (HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
 
NTSTATUS APIENTRY NtUserBuildNameList (HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
 
BOOL APIENTRY NtUserSetLogonNotifyWindow (HWND hWnd)
 
BOOL APIENTRY NtUserLockWorkStation (VOID)
 
BOOL NTAPI NtUserSetWindowStationUser (IN HWINSTA hWindowStation, IN PLUID pluid, IN PSID psid OPTIONAL, IN DWORD size)
 

Variables

PWINSTATION_OBJECT InputWindowStation = NULL
 
HWND hwndSAS = NULL
 
UNICODE_STRING gustrWindowStationsDir
 
HANDLE ghWinStaDir
 

Function Documentation

◆ BuildDesktopNameList()

static NTSTATUS FASTCALL BuildDesktopNameList ( HWINSTA  hWindowStation,
ULONG  dwSize,
PVOID  lpBuffer,
PULONG  pRequiredSize 
)
static

Definition at line 2039 of file winsta.c.

2044{
2046 PWINSTATION_OBJECT WindowStation;
2047 PLIST_ENTRY DesktopEntry;
2048 PDESKTOP DesktopObject;
2049 DWORD EntryCount;
2051 WCHAR NullWchar;
2052 UNICODE_STRING DesktopName;
2053
2054 Status = IntValidateWindowStationHandle(hWindowStation,
2055 UserMode,
2056 0,
2057 &WindowStation,
2058 NULL);
2059 if (! NT_SUCCESS(Status))
2060 {
2061 return Status;
2062 }
2063
2064 /*
2065 * Count the required size of buffer.
2066 */
2067 ReturnLength = sizeof(DWORD);
2068 EntryCount = 0;
2069 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
2070 DesktopEntry != &WindowStation->DesktopListHead;
2071 DesktopEntry = DesktopEntry->Flink)
2072 {
2073 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
2074 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
2075 ReturnLength += DesktopName.Length + sizeof(WCHAR);
2076 EntryCount++;
2077 }
2078 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
2079 if (NULL != pRequiredSize)
2080 {
2081 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
2082 if (! NT_SUCCESS(Status))
2083 {
2084 ObDereferenceObject(WindowStation);
2086 }
2087 }
2088
2089 /*
2090 * Check if the supplied buffer is large enough.
2091 */
2092 if (dwSize < ReturnLength)
2093 {
2094 ObDereferenceObject(WindowStation);
2096 }
2097
2098 /*
2099 * Generate the resulting buffer contents.
2100 */
2101 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
2102 if (! NT_SUCCESS(Status))
2103 {
2104 ObDereferenceObject(WindowStation);
2105 return Status;
2106 }
2107 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
2108
2109 NullWchar = L'\0';
2110 for (DesktopEntry = WindowStation->DesktopListHead.Flink;
2111 DesktopEntry != &WindowStation->DesktopListHead;
2112 DesktopEntry = DesktopEntry->Flink)
2113 {
2114 DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP, ListEntry);
2115 RtlInitUnicodeString(&DesktopName, DesktopObject->pDeskInfo->szDesktopName);
2116 Status = MmCopyToCaller(lpBuffer, DesktopName.Buffer, DesktopName.Length);
2117 if (! NT_SUCCESS(Status))
2118 {
2119 ObDereferenceObject(WindowStation);
2120 return Status;
2121 }
2122 lpBuffer = (PVOID) ((PCHAR)lpBuffer + DesktopName.Length);
2123 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
2124 if (! NT_SUCCESS(Status))
2125 {
2126 ObDereferenceObject(WindowStation);
2127 return Status;
2128 }
2129 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
2130 }
2131
2132 /*
2133 * Clean up and return
2134 */
2135 ObDereferenceObject(WindowStation);
2136 return STATUS_SUCCESS;
2137}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:24
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define UserMode
Definition: asm.h:39
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DWORD
Definition: nt_native.h:44
NTSTATUS FASTCALL IntValidateWindowStationHandle(HWINSTA WindowStation, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PWINSTATION_OBJECT *Object, POBJECT_HANDLE_INFORMATION pObjectHandleInfo)
Definition: winsta.c:244
short WCHAR
Definition: pedump.c:58
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR szDesktopName[1]
Definition: ntuser.h:158
PDESKTOPINFO pDeskInfo
Definition: desktop.h:8
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY DesktopListHead
Definition: winsta.h:19
void * PVOID
Definition: typedefs.h:50
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by NtUserBuildNameList().

◆ BuildUserModeWindowStationName()

static NTSTATUS BuildUserModeWindowStationName ( IN OUT POBJECT_ATTRIBUTES  UserModeObjectAttributes,
IN OUT POBJECT_ATTRIBUTES  LocalObjectAttributes,
OUT PUNICODE_STRING WindowStationName,
OUT PUNICODE_STRING TebStaticUnicodeString 
)
static

Definition at line 845 of file winsta.c.

850{
852 SIZE_T MemSize;
853
854 LUID CallerLuid;
855 PTEB Teb;
856 USHORT StrSize;
857
858 *WindowStationName = NULL;
859 *TebStaticUnicodeString = NULL;
860
861 /* Retrieve the current process LUID */
862 Status = GetProcessLuid(NULL, NULL, &CallerLuid);
863 if (!NT_SUCCESS(Status))
864 {
865 ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n", Status);
866 return Status;
867 }
868
869 /* Compute the needed string size */
870 MemSize = _scwprintf(L"%wZ\\Service-0x%x-%x$",
872 CallerLuid.HighPart,
873 CallerLuid.LowPart);
874 MemSize = MemSize * sizeof(WCHAR) + sizeof(UNICODE_NULL);
875 if (MemSize > MAXUSHORT)
876 {
877 ERR("Window station name length is too long.\n");
879 }
880 StrSize = (USHORT)MemSize;
881
882 /*
883 * Check whether it's short enough so that we can use the static buffer
884 * in the TEB. Otherwise continue with virtual memory allocation.
885 */
886 Teb = NtCurrentTeb();
887 if (Teb && (StrSize <= sizeof(Teb->StaticUnicodeBuffer)))
888 {
889 /* We can use the TEB's static unicode string */
892
893 /* Remember the TEB's static unicode string address for later */
894 *TebStaticUnicodeString = &Teb->StaticUnicodeString;
895
896 *WindowStationName = *TebStaticUnicodeString;
897 (*WindowStationName)->Length = 0;
898 }
899 else
900 {
901 /* The TEB's static unicode string is too small, allocate some user-mode virtual memory */
902 MemSize += ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID));
903
904 /* Allocate the memory in user-mode */
905 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
906 (PVOID*)WindowStationName,
907 0,
908 &MemSize,
911 if (!NT_SUCCESS(Status))
912 {
913 ERR("ZwAllocateVirtualMemory() failed, Status 0x%08lx\n", Status);
914 return Status;
915 }
916
917 RtlInitEmptyUnicodeString(*WindowStationName,
918 (PWCHAR)((ULONG_PTR)*WindowStationName +
919 ALIGN_UP(sizeof(UNICODE_STRING), sizeof(PVOID))),
920 StrSize);
921 }
922
923 /* Build a valid window station name from the LUID */
924 Status = RtlStringCbPrintfW((*WindowStationName)->Buffer,
925 (*WindowStationName)->MaximumLength,
926 L"%wZ\\Service-0x%x-%x$",
928 CallerLuid.HighPart,
929 CallerLuid.LowPart);
930 if (!NT_SUCCESS(Status))
931 {
932 ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
933 goto Quit;
934 }
935 (*WindowStationName)->Length = (USHORT)(wcslen((*WindowStationName)->Buffer) * sizeof(WCHAR));
936
937 /* Try to update the user's UserModeObjectAttributes */
939 {
940 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
941 *LocalObjectAttributes = *UserModeObjectAttributes;
942
943 UserModeObjectAttributes->ObjectName = *WindowStationName;
944 UserModeObjectAttributes->RootDirectory = NULL;
945
947 }
949 {
951 }
952 _SEH2_END;
953
954Quit:
955 if (!NT_SUCCESS(Status))
956 {
957 /* Release the window station name */
958 FreeUserModeWindowStationName(*WindowStationName,
959 *TebStaticUnicodeString,
960 NULL, NULL);
961 }
962
963 return Status;
964}
#define ERR(fmt,...)
Definition: precomp.h:57
_ACRTIMP int __cdecl _scwprintf(const wchar_t *,...)
Definition: wcs.c:1678
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define NtCurrentTeb
#define ASSERT(a)
Definition: mode.c:44
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define MEM_COMMIT
Definition: nt_native.h:1316
#define UNICODE_NULL
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
static VOID FreeUserModeWindowStationName(IN OUT PUNICODE_STRING WindowStationName, IN PUNICODE_STRING TebStaticUnicodeString, IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes OPTIONAL, IN POBJECT_ATTRIBUTES LocalObjectAttributes OPTIONAL)
Definition: winsta.c:811
UNICODE_STRING gustrWindowStationsDir
Definition: winsta.c:27
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
LONG HighPart
DWORD LowPart
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
NTSTATUS GetProcessLuid(IN PETHREAD Thread OPTIONAL, IN PEPROCESS Process OPTIONAL, OUT PLUID Luid)
Definition: misc.c:814
#define ZwCurrentProcess()

Referenced by NtUserCreateWindowStation(), and NtUserOpenWindowStation().

◆ BuildWindowStationNameList()

static NTSTATUS FASTCALL BuildWindowStationNameList ( ULONG  dwSize,
PVOID  lpBuffer,
PULONG  pRequiredSize 
)
static

Definition at line 1851 of file winsta.c.

1855{
1859 char InitialBuffer[256], *Buffer;
1861 DWORD EntryCount;
1863 WCHAR NullWchar;
1864
1865 //
1866 // FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
1867 // with judicious parameters one can create window stations elsewhere
1868 // than in Windows\WindowStations directory, Win32k definitely MUST
1869 // maintain a list of window stations it has created, and not rely
1870 // on the enumeration of Windows\WindowStations !!!
1871 //
1872
1873 /*
1874 * Try to open the directory.
1875 */
1879 NULL,
1880 NULL);
1881
1885
1886 if (!NT_SUCCESS(Status))
1887 {
1888 return Status;
1889 }
1890
1891 /* First try to query the directory using a fixed-size buffer */
1892 Context = 0;
1893 Buffer = NULL;
1894 Status = ZwQueryDirectoryObject(DirectoryHandle,
1895 InitialBuffer,
1896 sizeof(InitialBuffer),
1897 FALSE,
1898 TRUE,
1899 &Context,
1900 &ReturnLength);
1901 if (NT_SUCCESS(Status))
1902 {
1903 if (STATUS_NO_MORE_ENTRIES == ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1904 FALSE, &Context, NULL))
1905 {
1906 /* Our fixed-size buffer is large enough */
1907 Buffer = InitialBuffer;
1908 }
1909 }
1910
1911 if (NULL == Buffer)
1912 {
1913 /* Need a larger buffer, check how large exactly */
1914 Status = ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE, TRUE, &Context,
1915 &ReturnLength);
1916 if (!NT_SUCCESS(Status))
1917 {
1918 ERR("ZwQueryDirectoryObject failed\n");
1920 return Status;
1921 }
1922
1925 if (NULL == Buffer)
1926 {
1928 return STATUS_NO_MEMORY;
1929 }
1930
1931 /* We should have a sufficiently large buffer now */
1932 Context = 0;
1933 Status = ZwQueryDirectoryObject(DirectoryHandle, Buffer, BufferSize,
1935 if (! NT_SUCCESS(Status) ||
1936 STATUS_NO_MORE_ENTRIES != ZwQueryDirectoryObject(DirectoryHandle, NULL, 0, FALSE,
1937 FALSE, &Context, NULL))
1938 {
1939 /* Something went wrong, maybe someone added a directory entry? Just give up. */
1943 }
1944 }
1945
1947
1948 /*
1949 * Count the required size of buffer.
1950 */
1951 ReturnLength = sizeof(DWORD);
1952 EntryCount = 0;
1954 0 != DirEntry->Name.Length;
1955 DirEntry++)
1956 {
1957 ReturnLength += DirEntry->Name.Length + sizeof(WCHAR);
1958 EntryCount++;
1959 }
1960 TRACE("Required size: %lu Entry count: %lu\n", ReturnLength, EntryCount);
1961 if (NULL != pRequiredSize)
1962 {
1963 Status = MmCopyToCaller(pRequiredSize, &ReturnLength, sizeof(ULONG));
1964 if (! NT_SUCCESS(Status))
1965 {
1966 if (Buffer != InitialBuffer)
1967 {
1969 }
1971 }
1972 }
1973
1974 /*
1975 * Check if the supplied buffer is large enough.
1976 */
1977 if (dwSize < ReturnLength)
1978 {
1979 if (Buffer != InitialBuffer)
1980 {
1982 }
1984 }
1985
1986 /*
1987 * Generate the resulting buffer contents.
1988 */
1989 Status = MmCopyToCaller(lpBuffer, &EntryCount, sizeof(DWORD));
1990 if (! NT_SUCCESS(Status))
1991 {
1992 if (Buffer != InitialBuffer)
1993 {
1995 }
1996 return Status;
1997 }
1998 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(DWORD));
1999
2000 NullWchar = L'\0';
2002 0 != DirEntry->Name.Length;
2003 DirEntry++)
2004 {
2005 Status = MmCopyToCaller(lpBuffer, DirEntry->Name.Buffer, DirEntry->Name.Length);
2006 if (! NT_SUCCESS(Status))
2007 {
2008 if (Buffer != InitialBuffer)
2009 {
2011 }
2012 return Status;
2013 }
2014 lpBuffer = (PVOID) ((PCHAR) lpBuffer + DirEntry->Name.Length);
2015 Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
2016 if (! NT_SUCCESS(Status))
2017 {
2018 if (Buffer != InitialBuffer)
2019 {
2021 }
2022 return Status;
2023 }
2024 lpBuffer = (PVOID) ((PCHAR) lpBuffer + sizeof(WCHAR));
2025 }
2026
2027 /*
2028 * Clean up
2029 */
2030 if (Buffer != InitialBuffer)
2031 {
2033 }
2034
2035 return STATUS_SUCCESS;
2036}
static HANDLE DirectoryHandle
Definition: ObType.cpp:48
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define BufferSize
Definition: mmc.h:75
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define DIRECTORY_QUERY
Definition: nt_native.h:1257
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:285
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ PVOID Context
Definition: storport.h:2269
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define TAG_WINSTA
Definition: tags.h:11

Referenced by NtUserBuildNameList().

◆ CheckWinstaAttributeAccess()

BOOL FASTCALL CheckWinstaAttributeAccess ( ACCESS_MASK  DesiredAccess)

Definition at line 400 of file winsta.c.

401{
404 {
405 if (!(ppi->W32PF_flags & W32PF_IOWINSTA))
406 {
407 ERR("Requires Interactive Window Station\n");
409 return FALSE;
410 }
412 {
413 ERR("Access Denied\n");
415 return FALSE;
416 }
417 }
418 return TRUE;
419}
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
HANDLE gpidLogon
Definition: simplecall.c:15
ACCESS_MASK amwinsta
Definition: win32.h:269
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
#define W32PF_IOWINSTA
Definition: win32.h:23
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21
#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
Definition: winerror.h:1285

Referenced by NtUserGetClipCursor(), NtUserSetSystemCursor(), and UserClipCursor().

◆ co_IntInitializeDesktopGraphics()

BOOL FASTCALL co_IntInitializeDesktopGraphics ( VOID  )

Definition at line 274 of file winsta.c.

275{
276 TEXTMETRICW tmw;
277 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
278 PDESKTOP pdesk;
279 LONG lRet;
280
282 if (lRet != DISP_CHANGE_SUCCESSFUL && !gbBaseVideo)
283 {
284 ERR("Failed to initialize graphics, switching to base video\n");
290 }
291 if (lRet != DISP_CHANGE_SUCCESSFUL)
292 {
293 ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
294 return FALSE;
295 }
296
299 {
301 return FALSE;
302 }
304
306 {
307 return FALSE;
308 }
309
311
314
315 /* Update the system metrics */
316 InitMetrics();
317
318 /* Set new size of the monitor */
320
321 /* Update the SERVERINFO */
326 gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
329 {
330 gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
331 }
332 else
333 {
334 gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
335 }
336 // Font is realized and this dc was previously set to internal DC_ATTR.
337 gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
338 gpsi->tmSysFont = tmw;
339
340 /* Put the pointer in the center of the screen */
341 gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2;
342 gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
343
344 /* Attach monitor */
346
347 /* Setup the cursor */
349
350 /* Setup the icons */
352
353 /* Setup Menu */
354 MenuInit();
355
356 /* Show the desktop */
357 pdesk = IntGetActiveDesktop();
358 ASSERT(pdesk);
359 co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
360
361 /* HACK: display wallpaper on all secondary displays */
362 {
363 PGRAPHICS_DEVICE pGraphicsDevice;
364 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
365 UNICODE_STRING DisplayName;
366 HDC hdc;
367 ULONG iDevNum;
368
369 for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum)) != NULL; iDevNum++)
370 {
371 RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
372 hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
374 }
375 }
376
377 return TRUE;
378}
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner)
Definition: dclife.c:455
HDC FASTCALL IntGdiCreateDC(PUNICODE_STRING Driver, PUNICODE_STRING pustrDevice, PVOID pUMdhpdev, CONST PDEVMODEW pdmInit, BOOL CreateAsIC)
Definition: dclife.c:1040
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
PSERVERINFO gpsi
Definition: imm.c:18
#define PUSIF_PALETTEDISPLAY
Definition: ntuser.h:993
HDC hSystemBM
Definition: stockobj.c:52
PMDEVOBJ gpmdev
Definition: mdevobj.c:14
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
#define GDI_OBJ_HMGR_PUBLIC
Definition: ntgdihdl.h:116
LONG PDEVOBJ_lChangeDisplaySettings(_In_opt_ PUNICODE_STRING pustrDeviceName, _In_opt_ PDEVMODEW RequestedMode, _In_opt_ PMDEVOBJ pmdevOld, _Out_ PMDEVOBJ *ppmdevNew, _In_ BOOL bSearchClosestMode)
Definition: pdevobj.c:849
long LONG
Definition: pedump.c:60
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI INT APIENTRY NtGdiGetDeviceCaps(_In_ HDC hdc, _In_ INT i)
__kernel_entry W32KAPI HANDLE APIENTRY NtGdiGetStockObject(_In_ INT iObject)
__kernel_entry W32KAPI HFONT APIENTRY NtGdiSelectFont(_In_ HDC hdc, _In_ HFONT hf)
Definition: dcobjs.c:597
ULONG ulVertRes
Definition: winddi.h:883
ULONG ulHorzRes
Definition: winddi.h:882
WCHAR szWinDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:60
PPDEVOBJ ppdevGlobal
Definition: mdevobj.h:16
GDIINFO gdiinfo
Definition: pdevobj.h:123
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum)
Definition: device.c:795
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:182
BOOL FASTCALL IntCreatePrimarySurface(VOID)
Definition: device.c:17
VOID FASTCALL IntDestroyPrimarySurface(VOID)
Definition: device.c:32
DWORD FASTCALL IntGetCharDimensions(_In_ HDC hdc, _Out_opt_ PTEXTMETRICW ptm, _Out_opt_ PDWORD height)
Definition: font.c:337
BOOL APIENTRY co_IntLoadDefaultCursors(VOID)
Definition: callback.c:471
BOOL FASTCALL co_IntSetWndIcons(VOID)
Definition: callback.c:1101
PDESKTOP FASTCALL IntGetActiveDesktop(VOID)
Definition: desktop.c:1286
HDC ScreenDeviceContext
Definition: desktop.c:52
NTSTATUS FASTCALL co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height, BOOL bRedraw)
Definition: desktop.c:1633
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1853
BOOL gbBaseVideo
Definition: display.c:12
BOOL MenuInit(VOID)
Definition: menu.c:359
BOOL NTAPI InitMetrics(VOID)
Definition: metric.c:40
NTSTATUS NTAPI UserAttachMonitor(IN HDEV hDev)
Definition: monitor.c:129
NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev)
Definition: monitor.c:225
#define RASTERCAPS
Definition: wingdi.h:745
#define LOGPIXELSY
Definition: wingdi.h:719
#define PLANES
Definition: wingdi.h:721
#define SYSTEM_FONT
Definition: wingdi.h:911
#define BITSPIXEL
Definition: wingdi.h:720
#define RC_PALETTE
Definition: wingdi.h:790
#define SM_CYSCREEN
Definition: winuser.h:971
#define DISP_CHANGE_SUCCESSFUL
Definition: winuser.h:190
#define SM_CXSCREEN
Definition: winuser.h:970

Referenced by co_AddGuiApp().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserWinsta  )

◆ FreeUserModeWindowStationName()

static VOID FreeUserModeWindowStationName ( IN OUT PUNICODE_STRING  WindowStationName,
IN PUNICODE_STRING  TebStaticUnicodeString,
IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes  OPTIONAL,
IN POBJECT_ATTRIBUTES LocalObjectAttributes  OPTIONAL 
)
static

Definition at line 811 of file winsta.c.

816{
817 SIZE_T MemSize = 0;
818
819 /* Try to restore the user's UserModeObjectAttributes */
820 if (UserModeObjectAttributes && LocalObjectAttributes)
821 {
823 {
824 ProbeForWrite(UserModeObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
825 *UserModeObjectAttributes = *LocalObjectAttributes;
826 }
828 {
829 NOTHING;
830 }
831 _SEH2_END;
832 }
833
834 /* Free the user-mode memory */
835 if (WindowStationName && (WindowStationName != TebStaticUnicodeString))
836 {
837 ZwFreeVirtualMemory(ZwCurrentProcess(),
838 (PVOID*)&WindowStationName,
839 &MemSize,
841 }
842}
#define NOTHING
Definition: input_list.c:10
#define MEM_RELEASE
Definition: nt_native.h:1319

Referenced by BuildUserModeWindowStationName(), NtUserCreateWindowStation(), and NtUserOpenWindowStation().

◆ InitWindowStationImpl()

NTSTATUS NTAPI InitWindowStationImpl ( VOID  )

Definition at line 35 of file winsta.c.

36{
37 GENERIC_MAPPING IntWindowStationMapping = { WINSTA_READ,
41
42 /* Set Winsta Object Attributes */
44 ExWindowStationObjectType->TypeInfo.GenericMapping = IntWindowStationMapping;
46
47 return STATUS_SUCCESS;
48}
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:379
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:386
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:411
POBJECT_TYPE ExWindowStationObjectType
Definition: win32k.c:21
#define WINSTA_WRITE
Definition: security.h:48
#define WINSTA_READ
Definition: security.h:42
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define WINSTA_EXECUTE
Definition: security.h:53
struct _WINSTATION_OBJECT WINSTATION_OBJECT

Referenced by DriverEntry().

◆ IntCreateDesktopSwitchEvent()

static NTSTATUS IntCreateDesktopSwitchEvent ( VOID  )
static

Creates the global per-session \BaseNamedObjects\WinSta0_DesktopSwitch event.

Definition at line 440 of file winsta.c.

441{
444 HANDLE BnoHandle, EventHandle;
446 SECURITY_DESCRIPTOR EventSd;
448 WCHAR BnoBuffer[50];
449
450 /* We must not be called more than once */
454
455 /* Open the per-session BaseNamedObjects directory */
456 SessionId = PsGetCurrentProcessSessionId(); // gSessionId
457 if (SessionId)
458 {
459 RtlStringCbPrintfW(BnoBuffer, sizeof(BnoBuffer),
460 L"\\Sessions\\%lu\\BaseNamedObjects",
461 /*SESSION_DIR,*/ SessionId);
462 RtlInitUnicodeString(&Name, BnoBuffer);
463 }
464 else
465 {
466 RtlInitUnicodeString(&Name, L"\\BaseNamedObjects");
467 }
469 &Name,
471 NULL,
472 NULL);
473 Status = ZwOpenDirectoryObject(&BnoHandle,
476 if (!NT_SUCCESS(Status))
477 {
478 ERR("Failed to open '%wZ', Status 0x%08lx\n", &Name, Status);
479 return Status;
480 }
481
482 /* Build a security descriptor for SYNCHRONIZE world-access for the event */
483 // TODO: Modularize together with some functions in security.c
484 {
485 PACL Dacl;
487
488 /* Initialize the absolute security descriptor */
491 {
492 ERR("Failed to initialize absolute SD, Status 0x%08lx\n", Status);
493 goto Quit;
494 }
495
496 DaclSize = sizeof(ACL) +
498
499 /* Allocate memory for the DACL */
501 if (!Dacl)
502 {
503 ERR("Failed to allocate memory for service DACL!\n");
505 goto Quit;
506 }
507
508 /* Now create the DACL */
510 if (!NT_SUCCESS(Status))
511 {
512 ERR("Failed to create service DACL, Status 0x%08lx\n", Status);
514 goto Quit;
515 }
516
517 /* Everyone has the right to synchronize with the desktop switch event */
520 if (!NT_SUCCESS(Status))
521 {
522 ERR("Failed to set up window station ACE for authenticated user, Status 0x%08lx\n", Status);
524 goto Quit;
525 }
526
527 /* Set the DACL for the absolute SD */
530 {
531 ERR("Failed to set up DACL for absolute SD, Status 0x%08lx\n", Status);
533 goto Quit;
534 }
535
536 /* No need for a SACL */
539
540 /* This descriptor is ownerless */
543
544 /* This descriptor has no primary group */
547 }
548
549 /* Create or open the named event in the BNO directory */
550 RtlInitUnicodeString(&Name, L"WinSta0_DesktopSwitch");
551
552 /*
553 * Create and obtain a user-mode handle to the switch event in the CSRSS
554 * process, so as to make it its owner and ensure the event name persists.
555 * Then, retrieve a pointer to the underlying event object.
556 *
557 * (*ALTERNATIVELY*, we could instead:
558 * create and obtain a kernel-mode handle to the event, and retrieve a
559 * pointer to the underlying event object. Only then, duplicate the handle
560 * into the CSRSS process to ensure the event name persists.)
561 */
562 {
564
568 &Name,
569 /* No OBJ_KERNEL_HANDLE: directly create a user-mode handle */
571 BnoHandle,
572 &EventSd);
573 Status = ZwCreateEvent(&EventHandle,
577 FALSE);
578 if (!NT_SUCCESS(Status))
579 {
580 ERR("Event '%wZ' creation failed, Status 0x%08lx\n", &Name, Status);
581 }
582 else
583 {
584 /* Reference the object and keep it global */
588 UserMode, // We use a user-mode handle
590 NULL);
591 if (NT_SUCCESS(Status))
592 {
593 /* We succeeded, keep the handle around to ensure the object name persists */
595 /*
596 * *ALTERNATIVELY*, we would duplicate the handle in the CSRSS process:
597 *
598 * KAPC_STATE ApcState;
599 * KeStackAttachProcess(&gpepCSRSS->Pcb, &ApcState);
600 * Status = ObOpenObjectByPointer(gpDesktopSwitchEvent,
601 * 0,
602 * NULL,
603 * EVENT_ALL_ACCESS,
604 * NULL,
605 * KernelMode,
606 * &ghDesktopSwitchEvent);
607 * KeUnstackDetachProcess(&ApcState);
608 *
609 * then close the original kernel handle:
610 * ObCloseHandle(EventHandle, KernelMode);
611 */
612 }
613 else
614 {
615 /* We failed, close the handle */
616 ERR("Failed to reference the event object, Status 0x%08lx\n", Status);
618 }
619 }
621 }
622
623 /* We are done with the SD DACL */
625Quit:
626 /* We don't need the BNO handle anymore */
627 ObCloseHandle(BnoHandle, KernelMode);
628
629 return Status;
630}
PEPROCESS gpepCSRSS
Definition: csr.c:15
LPWSTR Name
Definition: desk.c:124
ULONG SessionId
Definition: dllmain.c:28
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
struct _ACL ACL
#define KernelMode
Definition: asm.h:38
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1625
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1626
#define SYNCHRONIZE
Definition: nt_native.h:61
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1259
@ NotificationEvent
NTSYSAPI NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
NTSYSAPI NTSTATUS NTAPI RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN SaclPresent, IN PACL Sacl, IN BOOLEAN SaclDefaulted)
Definition: sd.c:342
POBJECT_TYPE ExEventObjectType
Definition: event.c:18
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1769
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3406
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:493
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define OBJ_OPENIF
Definition: winternl.h:229
PSE_EXPORTS SeExports
Definition: semgr.c:21
KPROCESS Pcb
Definition: pstypes.h:1369
PSID SeWorldSid
Definition: setypes.h:1232
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
PKEVENT gpDesktopSwitchEvent
WinSta0_DesktopSwitch legacy (NT 3.5+) event.
Definition: desktop.c:56
HANDLE ghDesktopSwitchEvent
WinSta0_DesktopSwitch handle in the CSRSS process.
Definition: desktop.c:57
#define USERTAG_SECURITY
Definition: tags.h:275
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR, PSID, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857
KAPC_STATE
Definition: ketypes.h:1727
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39

Referenced by IntCreateWindowStation().

◆ IntCreateWindowStation()

NTSTATUS FASTCALL IntCreateWindowStation ( OUT HWINSTA *  phWinSta,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN KPROCESSOR_MODE  AccessMode,
IN KPROCESSOR_MODE  OwnerMode,
IN ACCESS_MASK  dwDesiredAccess,
DWORD  Unknown2,
DWORD  Unknown3,
DWORD  Unknown4,
DWORD  Unknown5,
DWORD  Unknown6 
)

Definition at line 665 of file winsta.c.

676{
678 HWINSTA hWinSta;
679 PWINSTATION_OBJECT WindowStation;
680
681 TRACE("IntCreateWindowStation called\n");
682
683 ASSERT(phWinSta);
684 *phWinSta = NULL;
685
689 NULL,
690 dwDesiredAccess,
691 NULL,
692 (PVOID*)&hWinSta);
693 if (NT_SUCCESS(Status))
694 {
695 TRACE("IntCreateWindowStation opened window station '%wZ'\n",
696 ObjectAttributes->ObjectName);
697 *phWinSta = hWinSta;
698 return Status;
699 }
700
701 /*
702 * No existing window station found, try to create a new one.
703 */
704
705 /* Create the window station object */
709 OwnerMode,
710 NULL,
711 sizeof(WINSTATION_OBJECT),
712 0,
713 0,
714 (PVOID*)&WindowStation);
715 if (!NT_SUCCESS(Status))
716 {
717 ERR("ObCreateObject failed for window station '%wZ', Status 0x%08lx\n",
718 ObjectAttributes->ObjectName, Status);
720 return Status;
721 }
722 RtlZeroMemory(WindowStation, sizeof(WINSTATION_OBJECT));
723
724 /* Assign the session ID to the window station */
725 WindowStation->dwSessionId = PsGetCurrentProcessSessionId(); // gSessionId
726
727 /* Initialize the window station */
728 InitializeListHead(&WindowStation->DesktopListHead);
729 Status = RtlCreateAtomTable(37, &WindowStation->AtomTable);
730 if (!NT_SUCCESS(Status))
731 {
732 ERR("RtlCreateAtomTable failed for window station '%wZ', Status 0x%08lx\n",
733 ObjectAttributes->ObjectName, Status);
734 ObDereferenceObject(WindowStation);
736 return Status;
737 }
738
740 {
741 ERR("Initializing input window station\n");
742
743 /* Only Winlogon can create the interactive window station */
745
746 InputWindowStation = WindowStation;
747 WindowStation->Flags &= ~WSS_NOIO;
748 }
749 else
750 {
751 WindowStation->Flags |= WSS_NOIO;
752 }
753
754 /* Create the global WinSta0_DesktopSwitch event
755 * only when creating the interactive WinSta0 */
756 if (InputWindowStation == WindowStation)
757 {
759 if (!NT_SUCCESS(Status))
760 {
761 ObDereferenceObject(WindowStation);
763 return Status;
764 }
765 }
766
767 Status = ObInsertObject(WindowStation,
768 NULL,
769 dwDesiredAccess,
770 0,
771 NULL,
772 (PVOID*)&hWinSta);
773 if (!NT_SUCCESS(Status))
774 {
775 ERR("ObInsertObject failed for window station, Status 0x%08lx\n", Status);
776 /* WindowStation is dereferenced on ObInsertObject() failure */
778 return Status;
779 }
780
781 // FIXME! TODO: Add this new window station to a linked list
782
783 if (InputWindowStation == WindowStation)
784 {
785 ERR("Initializing input window station\n");
786
788
791
792 /* Desktop functions require the desktop thread running so wait for it to initialize */
793 UserLeaveCo();
796 UserMode,
797 FALSE,
798 NULL);
799 UserEnterCo();
800 }
801
802 TRACE("IntCreateWindowStation created window station '%wZ' object 0x%p handle 0x%p\n",
803 ObjectAttributes->ObjectName, WindowStation, hWinSta);
804
805 *phWinSta = hWinSta;
807 return STATUS_SUCCESS;
808}
BOOL UserCreateSystemThread(DWORD Type)
Definition: csr.c:247
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSYSAPI NTSTATUS NTAPI RtlCreateAtomTable(_In_ ULONG TableSize, _Inout_ PRTL_ATOM_TABLE *AtomTable)
PWINSTATION_OBJECT InputWindowStation
Definition: winsta.c:21
static NTSTATUS IntCreateDesktopSwitchEvent(VOID)
Creates the global per-session \BaseNamedObjects\WinSta0_DesktopSwitch event.
Definition: winsta.c:440
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2957
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2554
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:1040
DWORD dwSessionId
Definition: winsta.h:17
PRTL_ATOM_TABLE AtomTable
Definition: winsta.h:20
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define UserEnterCo
Definition: ntuser.h:3
#define UserLeaveCo
Definition: ntuser.h:4
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:30
#define ST_DESKTOP_THREAD
Definition: csr.h:36
#define ST_RIT
Definition: csr.h:35
BOOL InitCursorImpl(VOID)
Definition: cursoricon.c:64
PKEVENT gpDesktopThreadStartedEvent
Definition: desktop.c:55
#define WSS_NOIO
Definition: winsta.h:9
@ UserRequest
Definition: ketypes.h:473
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396

Referenced by IntResolveDesktop(), and NtUserCreateWindowStation().

◆ IntEndDesktopGraphics()

VOID FASTCALL IntEndDesktopGraphics ( VOID  )

Definition at line 381 of file winsta.c.

382{
384 { // No need to allocate a new dcattr.
388 }
391}
#define GDI_OBJ_HMGR_POWNED
Definition: ntgdihdl.h:117
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
NTSTATUS FASTCALL IntHideDesktop(PDESKTOP Desktop)
Definition: desktop.c:1651

Referenced by RemoveGuiApp().

◆ IntGetProcessWindowStation()

PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation ( HWINSTA *phWinSta  OPTIONAL)

Definition at line 422 of file winsta.c.

423{
424 PWINSTATION_OBJECT pWinSta;
426 HWINSTA hWinSta = ppi->hwinsta;
427 if (phWinSta)
428 *phWinSta = hWinSta;
429 IntValidateWindowStationHandle(hWinSta, UserMode, 0, &pWinSta, 0);
430 return pWinSta;
431}
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:800
HWINSTA hwinsta
Definition: win32.h:268

Referenced by NtUserActivateKeyboardLayout(), NtUserGetImeInfoEx(), NtUserGetKeyboardLayoutList(), NtUserLoadKeyboardLayoutEx(), NtUserSetImeInfoEx(), NtUserUnloadKeyboardLayout(), and UserSetDefaultInputLang().

◆ IntGetScreenDC()

HDC FASTCALL IntGetScreenDC ( VOID  )

Definition at line 394 of file winsta.c.

395{
396 return ScreenDeviceContext;
397}

Referenced by co_MsqInsertMouseMessage(), MsqCleanupMessageQueue(), UserSetCursor(), and UserShowCursor().

◆ IntValidateWindowStationHandle()

NTSTATUS FASTCALL IntValidateWindowStationHandle ( HWINSTA  WindowStation,
KPROCESSOR_MODE  AccessMode,
ACCESS_MASK  DesiredAccess,
PWINSTATION_OBJECT Object,
POBJECT_HANDLE_INFORMATION  pObjectHandleInfo 
)

Definition at line 244 of file winsta.c.

250{
252
253 if (WindowStation == NULL)
254 {
255 ERR("Invalid window station handle\n");
258 }
259
260 Status = ObReferenceObjectByHandle(WindowStation,
264 (PVOID*)Object,
265 pObjectHandleInfo);
266
267 if (!NT_SUCCESS(Status))
269
270 return Status;
271}
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by BuildDesktopNameList(), IntGetProcessWindowStation(), IntGetWinStaForCbAccess(), NtUserCloseWindowStation(), NtUserLockWindowStation(), NtUserSetShellWindowEx(), NtUserSetWindowsHookEx(), NtUserSetWindowStationUser(), NtUserUnlockWindowStation(), UserCreateMenu(), UserGetShellWindow(), and UserSetProcessWindowStation().

◆ IntWinStaObjectDelete()

NTSTATUS NTAPI IntWinStaObjectDelete ( _In_ PVOID  Parameters)

Definition at line 99 of file winsta.c.

101{
103 PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeleteParameters->Object;
104
105 TRACE("Deleting window station 0x%p\n", WinSta);
106
107 WinSta->Flags |= WSS_DYING;
108
109 if (WinSta == InputWindowStation)
110 {
111 ERR("WARNING: Deleting the interactive window station '%wZ'!\n",
113
114 /* The window station must NOT be tagged as non-interactive */
115 ASSERT(!(WinSta->Flags & WSS_NOIO));
116
117 /* Only Winlogon can close and delete the interactive window station */
119
121
122 /* Signal and cleanup the global desktop-switch event */
124 {
126
130
131 /* Close the handle in the CSRSS process */
137 }
138 }
139
141
143
145
146 return STATUS_SUCCESS;
147}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:100
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:97
NTSYSAPI NTSTATUS NTAPI RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable)
Definition: atom.c:204
struct tagKL * spklList
Definition: winsta.h:23
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
VOID NTAPI UserEmptyClipboardData(PWINSTATION_OBJECT pWinSta)
Definition: clipboard.c:354
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
Definition: object.c:857
struct _WINSTATION_OBJECT * PWINSTATION_OBJECT
#define WSS_DYING
Definition: winsta.h:11
#define EVENT_INCREMENT
Definition: iotypes.h:597

Referenced by DriverEntry().

◆ IntWinStaObjectParse()

NTSTATUS NTAPI IntWinStaObjectParse ( _In_ PVOID  Parameters)

Definition at line 151 of file winsta.c.

153{
156
157 /* Assume we don't find anything */
158 *ParseParameters->Object = NULL;
159
160 /* Check for an empty name */
161 if (!RemainingName->Length)
162 {
163 /* Make sure this is a window station, can't parse a desktop now */
164 if (ParseParameters->ObjectType != ExWindowStationObjectType)
165 {
166 /* Fail */
168 }
169
170 /* Reference the window station and return */
171 ObReferenceObject(ParseParameters->ParseObject);
172 *ParseParameters->Object = ParseParameters->ParseObject;
173 return STATUS_SUCCESS;
174 }
175
176 /* Check for leading slash */
177 if (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
178 {
179 /* Skip it */
180 RemainingName->Buffer++;
181 RemainingName->Length -= sizeof(WCHAR);
182 RemainingName->MaximumLength -= sizeof(WCHAR);
183 }
184
185 /* Check if there is still a slash */
187 {
188 /* In this case, fail */
190 }
191
192 /*
193 * Check if we are parsing a desktop.
194 */
195 if (ParseParameters->ObjectType == ExDesktopObjectType)
196 {
197 /* Then call the desktop parse routine */
198 return IntDesktopObjectParse(ParseParameters->ParseObject,
199 ParseParameters->ObjectType,
200 ParseParameters->AccessState,
201 ParseParameters->AccessMode,
202 ParseParameters->Attributes,
203 ParseParameters->CompleteName,
205 ParseParameters->Context,
206 ParseParameters->SecurityQos,
207 ParseParameters->Object);
208 }
209
210 /* Should hopefully never get here */
212}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: d3dkmdt.h:46
#define wcschr
Definition: compat.h:17
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:387
PUNICODE_STRING RemainingName
Definition: pstypes.h:1784
_Out_ PUNICODE_STRING CompleteName
Definition: pstypes.h:1783
PSECURITY_QUALITY_OF_SERVICE SecurityQos
Definition: pstypes.h:1786
KPROCESSOR_MODE AccessMode
Definition: pstypes.h:1781
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
NTSTATUS APIENTRY IntDesktopObjectParse(IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
Definition: desktop.c:63
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by DriverEntry().

◆ IntWinStaOkToClose()

NTSTATUS NTAPI IntWinStaOkToClose ( _In_ PVOID  Parameters)

Definition at line 216 of file winsta.c.

218{
220 PPROCESSINFO ppi;
221
223
224 if (ppi && (OkToCloseParameters->Handle == ppi->hwinsta))
225 {
227 }
228
229 return STATUS_SUCCESS;
230}
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by DriverEntry().

◆ NtUserBuildNameList()

NTSTATUS APIENTRY NtUserBuildNameList ( HWINSTA  hWindowStation,
ULONG  dwSize,
PVOID  lpBuffer,
PULONG  pRequiredSize 
)

Definition at line 2165 of file winsta.c.

2170{
2171 /* The WindowStation name list and desktop name list are build in completely
2172 different ways. Call the appropriate function */
2173 return NULL == hWindowStation ? BuildWindowStationNameList(dwSize, lpBuffer, pRequiredSize) :
2174 BuildDesktopNameList(hWindowStation, dwSize, lpBuffer, pRequiredSize);
2175}
static NTSTATUS FASTCALL BuildWindowStationNameList(ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:1851
static NTSTATUS FASTCALL BuildDesktopNameList(HWINSTA hWindowStation, ULONG dwSize, PVOID lpBuffer, PULONG pRequiredSize)
Definition: winsta.c:2039

Referenced by EnumNamesW().

◆ NtUserCloseWindowStation()

BOOL APIENTRY NtUserCloseWindowStation ( HWINSTA  hWinSta)

Definition at line 1254 of file winsta.c.

1256{
1259
1260 TRACE("NtUserCloseWindowStation called (%p)\n", hWinSta);
1261
1262 if (hWinSta == UserGetProcessWindowStation())
1263 {
1264 ERR("Attempted to close process window station\n");
1265 return FALSE;
1266 }
1267
1269 UserMode,
1270 0,
1271 &Object,
1272 NULL);
1273 if (!NT_SUCCESS(Status))
1274 {
1275 ERR("Validation of window station handle (%p) failed\n", hWinSta);
1276 return FALSE;
1277 }
1278
1280
1281 TRACE("Closing window station handle (%p)\n", hWinSta);
1282
1283 Status = ObCloseHandle(hWinSta, UserMode);
1284 if (!NT_SUCCESS(Status))
1285 {
1287 return FALSE;
1288 }
1289
1290 return TRUE;
1291}
HWINSTA FASTCALL UserGetProcessWindowStation(VOID)
Definition: winsta.c:1586

Referenced by CloseWindowStation().

◆ NtUserCreateWindowStation()

HWINSTA APIENTRY NtUserCreateWindowStation ( IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN ACCESS_MASK  dwDesiredAccess,
DWORD  Unknown2,
DWORD  Unknown3,
DWORD  Unknown4,
DWORD  Unknown5,
DWORD  Unknown6 
)

Definition at line 968 of file winsta.c.

976{
978 HWINSTA hWinSta = NULL;
979 OBJECT_ATTRIBUTES LocalObjectAttributes;
980 PUNICODE_STRING WindowStationName = NULL;
981 PUNICODE_STRING TebStaticUnicodeString = NULL;
982 KPROCESSOR_MODE OwnerMode = UserMode;
983
984 TRACE("NtUserCreateWindowStation called\n");
985
986 /* Capture the object attributes and the window station name */
988 {
990 LocalObjectAttributes = *ObjectAttributes;
991 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
992 {
993 ERR("Invalid ObjectAttributes length!\n");
996 }
997
998 /*
999 * Check whether the caller provided a window station name together
1000 * with a RootDirectory handle.
1001 *
1002 * If the caller did not provide a window station name, build a new one
1003 * based on the logon session identifier for the calling process.
1004 * The new name is allocated in user-mode, as the rest of ObjectAttributes
1005 * already is, so that the validation performed by the Object Manager
1006 * can be done adequately.
1007 */
1008 if ((LocalObjectAttributes.ObjectName == NULL ||
1009 LocalObjectAttributes.ObjectName->Buffer == NULL ||
1010 LocalObjectAttributes.ObjectName->Length == 0 ||
1011 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
1012 /* &&
1013 LocalObjectAttributes.RootDirectory == NULL */)
1014 {
1015 /* No, build the new window station name */
1017 &LocalObjectAttributes,
1018 &WindowStationName,
1019 &TebStaticUnicodeString);
1020 if (!NT_SUCCESS(Status))
1021 {
1022 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
1024 }
1025 OwnerMode = KernelMode;
1026 }
1027 }
1029 {
1031 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
1032 }
1033 _SEH2_END;
1034
1035 if (!NT_SUCCESS(Status))
1036 {
1038 return NULL;
1039 }
1040
1042
1043 /* Create the window station */
1044 Status = IntCreateWindowStation(&hWinSta,
1046 UserMode,
1047 OwnerMode,
1048 dwDesiredAccess,
1049 Unknown2,
1050 Unknown3,
1051 Unknown4,
1052 Unknown5,
1053 Unknown6);
1054 UserLeave();
1055
1056 if (NT_SUCCESS(Status))
1057 {
1058 TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
1059 ObjectAttributes->ObjectName, hWinSta);
1060 }
1061 else
1062 {
1063 ASSERT(hWinSta == NULL);
1064 ERR("NtUserCreateWindowStation failed to create window station '%wZ', Status 0x%08lx\n",
1065 ObjectAttributes->ObjectName, Status);
1066 }
1067
1068 /* Try to restore the user's ObjectAttributes and release the window station name */
1069 FreeUserModeWindowStationName(WindowStationName,
1070 TebStaticUnicodeString,
1071 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
1072 &LocalObjectAttributes);
1073
1074 if (!NT_SUCCESS(Status))
1075 {
1076 ASSERT(hWinSta == NULL);
1078 }
1079
1080 return hWinSta;
1081}
PRTL_UNICODE_STRING_BUFFER PULONG PULONG Unknown4
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD IN DWORD Unknown6
Definition: conport.c:40
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD IN DWORD IN DWORD Unknown5
Definition: conport.c:39
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:37
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static NTSTATUS BuildUserModeWindowStationName(IN OUT POBJECT_ATTRIBUTES UserModeObjectAttributes, IN OUT POBJECT_ATTRIBUTES LocalObjectAttributes, OUT PUNICODE_STRING *WindowStationName, OUT PUNICODE_STRING *TebStaticUnicodeString)
Definition: winsta.c:845
NTSTATUS FASTCALL IntCreateWindowStation(OUT HWINSTA *phWinSta, IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE OwnerMode, IN ACCESS_MASK dwDesiredAccess, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4, DWORD Unknown5, DWORD Unknown6)
Definition: winsta.c:665
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define _SEH2_LEAVE
Definition: pseh2_64.h:206
PUNICODE_STRING ObjectName
Definition: umtypes.h:187
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7

Referenced by CreateWindowStationW().

◆ NtUserGetObjectInformation()

BOOL APIENTRY NtUserGetObjectInformation ( HANDLE  hObject,
DWORD  nIndex,
PVOID  pvInformation,
DWORD  nLength,
PDWORD  nLengthNeeded 
)

Definition at line 1333 of file winsta.c.

1339{
1341 PWINSTATION_OBJECT WinStaObject = NULL;
1342 PDESKTOP DesktopObject = NULL;
1343 POBJECT_HEADER ObjectHeader;
1344 POBJECT_HEADER_NAME_INFO NameInfo;
1345 OBJECT_HANDLE_INFORMATION HandleInfo;
1346 USEROBJECTFLAGS ObjectFlags;
1347 PUNICODE_STRING pStrNameU = NULL;
1348 PVOID pvData = NULL;
1349 SIZE_T nDataSize = 0;
1350
1351 _SEH2_TRY
1352 {
1353 if (nLengthNeeded)
1354 ProbeForWrite(nLengthNeeded, sizeof(*nLengthNeeded), 1);
1355 ProbeForWrite(pvInformation, nLength, 1);
1356 }
1358 {
1360 return FALSE;
1361 }
1362 _SEH2_END;
1363
1364 /* Try window station */
1365 TRACE("Trying to open window station 0x%p\n", hObject);
1367 0,
1369 UserMode,
1370 (PVOID*)&WinStaObject,
1371 &HandleInfo);
1372
1374 {
1375 /* Try desktop */
1376 TRACE("Trying to open desktop %p\n", hObject);
1377 WinStaObject = NULL;
1379 UserMode,
1380 0,
1381 &DesktopObject);
1382 }
1383
1384 if (!NT_SUCCESS(Status))
1385 {
1386 ERR("Failed: 0x%x\n", Status);
1387 goto Exit;
1388 }
1389
1390 TRACE("WinSta or Desktop opened!\n");
1391
1392 /* Get data */
1393 switch (nIndex)
1394 {
1395 case UOI_FLAGS:
1396 {
1397 ObjectFlags.fReserved = FALSE;
1398 ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
1399
1400 ObjectFlags.dwFlags = 0;
1401 if (WinStaObject != NULL)
1402 {
1403 if (!(WinStaObject->Flags & WSS_NOIO))
1404 ObjectFlags.dwFlags |= WSF_VISIBLE;
1405 }
1406 else if (DesktopObject != NULL)
1407 {
1408 FIXME("Setting DF_ALLOWOTHERACCOUNTHOOK is unimplemented.\n");
1409 }
1410 else
1411 {
1412 ERR("No associated WinStaObject nor DesktopObject!\n");
1413 }
1414
1415 pvData = &ObjectFlags;
1416 nDataSize = sizeof(ObjectFlags);
1418 break;
1419 }
1420
1421 case UOI_NAME:
1422 {
1423 if (WinStaObject != NULL)
1424 {
1425 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1426 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
1427
1428 if (NameInfo && (NameInfo->Name.Length > 0))
1429 {
1430 /* Named window station */
1431 pStrNameU = &NameInfo->Name;
1432 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1433 }
1434 else
1435 {
1436 /* Unnamed window station (should never happen!) */
1437 ASSERT(FALSE);
1438 pStrNameU = NULL;
1439 nDataSize = sizeof(UNICODE_NULL);
1440 }
1442 }
1443 else if (DesktopObject != NULL)
1444 {
1445 pvData = DesktopObject->pDeskInfo->szDesktopName;
1446 nDataSize = (wcslen(DesktopObject->pDeskInfo->szDesktopName) + 1) * sizeof(WCHAR);
1448 }
1449 else
1450 {
1452 }
1453 break;
1454 }
1455
1456 case UOI_TYPE:
1457 {
1458 if (WinStaObject != NULL)
1459 {
1460 ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
1461 pStrNameU = &ObjectHeader->Type->Name;
1462 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1464 }
1465 else if (DesktopObject != NULL)
1466 {
1467 ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
1468 pStrNameU = &ObjectHeader->Type->Name;
1469 nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
1471 }
1472 else
1473 {
1475 }
1476 break;
1477 }
1478
1479 case UOI_USER_SID:
1481 ERR("UOI_USER_SID unimplemented!\n");
1482 break;
1483
1484 default:
1486 break;
1487 }
1488
1489Exit:
1490 if ((Status == STATUS_SUCCESS) && (nLength < nDataSize))
1492
1493 _SEH2_TRY
1494 {
1495 if (nLengthNeeded)
1496 *nLengthNeeded = nDataSize;
1497
1498 /* Try to copy data to caller */
1499 if (Status == STATUS_SUCCESS && (nDataSize > 0))
1500 {
1501 TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
1502 if (pvData)
1503 {
1504 /* Copy the data */
1505 RtlCopyMemory(pvInformation, pvData, nDataSize);
1506 }
1507 else if (pStrNameU)
1508 {
1509 /* Copy and NULL-terminate the string */
1510 RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
1511 ((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
1512 }
1513 else
1514 {
1515 /* Zero the memory */
1516 RtlZeroMemory(pvInformation, nDataSize);
1517 }
1518 }
1519 }
1521 {
1523 }
1524 _SEH2_END;
1525
1526 /* Release objects */
1527 if (DesktopObject != NULL)
1528 ObDereferenceObject(DesktopObject);
1529 if (WinStaObject != NULL)
1530 ObDereferenceObject(WinStaObject);
1531
1532 if (!NT_SUCCESS(Status))
1533 {
1535 return FALSE;
1536 }
1537
1538 return TRUE;
1539}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
_In_ LPWSTR _In_ DWORD _In_ LPCVOID pvData
Definition: netsh.h:116
#define OBJ_INHERIT
Definition: winternl.h:225
static void Exit(void)
Definition: sock.c:1330
UNICODE_STRING Name
Definition: obtypes.h:454
POBJECT_TYPE Type
Definition: obtypes.h:514
UNICODE_STRING Name
Definition: obtypes.h:404
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSTATUS FASTCALL IntValidateDesktopHandle(HDESK Desktop, KPROCESSOR_MODE AccessMode, ACCESS_MASK DesiredAccess, PDESKTOP *Object)
Definition: desktop.c:1261
WINBASEAPI _In_ DWORD nLength
Definition: wincon.h:682
#define UOI_NAME
Definition: winuser.h:1095
#define UOI_TYPE
Definition: winuser.h:1096
#define UOI_USER_SID
Definition: winuser.h:1097
#define WSF_VISIBLE
Definition: winuser.h:2488
#define UOI_FLAGS
Definition: winuser.h:1094

Referenced by GetUserObjectInformationW().

◆ NtUserGetProcessWindowStation()

HWINSTA APIENTRY NtUserGetProcessWindowStation ( VOID  )

Definition at line 1608 of file winsta.c.

1609{
1611}

Referenced by CreateDesktopW(), and GetProcessWindowStation().

◆ NtUserLockWindowStation()

BOOL APIENTRY NtUserLockWindowStation ( HWINSTA  hWindowStation)

Definition at line 1771 of file winsta.c.

1772{
1775
1776 TRACE("About to set process window station with handle (%p)\n",
1777 hWindowStation);
1778
1780 {
1781 ERR("Unauthorized process attempted to lock the window station!\n");
1783 return FALSE;
1784 }
1785
1786 Status = IntValidateWindowStationHandle(hWindowStation,
1787 UserMode,
1788 0,
1789 &Object,
1790 NULL);
1791 if (!NT_SUCCESS(Status))
1792 {
1793 TRACE("Validation of window station handle (%p) failed\n",
1794 hWindowStation);
1796 return FALSE;
1797 }
1798
1799 Object->Flags |= WSS_LOCKED;
1800
1802 return TRUE;
1803}
#define WSS_LOCKED
Definition: winsta.h:7

Referenced by LockWindowStation().

◆ NtUserLockWorkStation()

BOOL APIENTRY NtUserLockWorkStation ( VOID  )

Definition at line 2206 of file winsta.c.

2207{
2208 BOOL ret;
2210
2212
2213 if (pti->rpdesk == IntGetActiveDesktop())
2214 {
2216 }
2217 else
2218 {
2219 ret = FALSE;
2220 }
2221
2222 UserLeave();
2223
2224 return ret;
2225}
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
HWND hwndSAS
Definition: winsta.c:24
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define LN_LOCK_WORKSTATION
Definition: undocuser.h:119
#define WM_LOGONNOTIFY
Definition: undocuser.h:39
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395

Referenced by LockWorkStation().

◆ NtUserOpenWindowStation()

HWINSTA APIENTRY NtUserOpenWindowStation ( IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN ACCESS_MASK  dwDesiredAccess 
)

Definition at line 1108 of file winsta.c.

1111{
1113 HWINSTA hWinSta = NULL;
1114 OBJECT_ATTRIBUTES LocalObjectAttributes;
1115 PUNICODE_STRING WindowStationName = NULL;
1116 PUNICODE_STRING TebStaticUnicodeString = NULL;
1117 KPROCESSOR_MODE OwnerMode = UserMode;
1118
1119 TRACE("NtUserOpenWindowStation called\n");
1120
1121 /* Capture the object attributes and the window station name */
1122 _SEH2_TRY
1123 {
1125 LocalObjectAttributes = *ObjectAttributes;
1126 if (LocalObjectAttributes.Length != sizeof(OBJECT_ATTRIBUTES))
1127 {
1128 ERR("Invalid ObjectAttributes length!\n");
1131 }
1132
1133 /*
1134 * Check whether the caller did not provide a window station name,
1135 * or provided the special "Service-0x00000000-00000000$" name.
1136 *
1137 * NOTE: On Windows, the special "Service-0x00000000-00000000$" string
1138 * is used instead of an empty name (observed when API-monitoring
1139 * OpenWindowStation() called with an empty window station name).
1140 */
1141 if ((LocalObjectAttributes.ObjectName == NULL ||
1142 LocalObjectAttributes.ObjectName->Buffer == NULL ||
1143 LocalObjectAttributes.ObjectName->Length == 0 ||
1144 LocalObjectAttributes.ObjectName->Buffer[0] == UNICODE_NULL)
1145 /* &&
1146 LocalObjectAttributes.RootDirectory == NULL */)
1147 {
1148 /* No, remember that for later */
1149 LocalObjectAttributes.ObjectName = NULL;
1150 }
1151 if (LocalObjectAttributes.ObjectName &&
1152 LocalObjectAttributes.ObjectName->Length ==
1153 sizeof(L"Service-0x00000000-00000000$") - sizeof(UNICODE_NULL) &&
1154 _wcsnicmp(LocalObjectAttributes.ObjectName->Buffer,
1155 L"Service-0x00000000-00000000$",
1156 LocalObjectAttributes.ObjectName->Length / sizeof(WCHAR)) == 0)
1157 {
1158 /* No, remember that for later */
1159 LocalObjectAttributes.ObjectName = NULL;
1160 }
1161
1162 /*
1163 * If the caller did not provide a window station name, build a new one
1164 * based on the logon session identifier for the calling process.
1165 * The new name is allocated in user-mode, as the rest of ObjectAttributes
1166 * already is, so that the validation performed by the Object Manager
1167 * can be done adequately.
1168 */
1169 if (!LocalObjectAttributes.ObjectName)
1170 {
1171 /* No, build the new window station name */
1173 &LocalObjectAttributes,
1174 &WindowStationName,
1175 &TebStaticUnicodeString);
1176 if (!NT_SUCCESS(Status))
1177 {
1178 ERR("BuildUserModeWindowStationName() failed, Status 0x%08lx\n", Status);
1180 }
1181 OwnerMode = KernelMode;
1182 }
1183 }
1185 {
1187 ERR("ObjectAttributes capture failed, Status 0x%08lx\n", Status);
1188 }
1189 _SEH2_END;
1190
1191 if (!NT_SUCCESS(Status))
1192 {
1194 return NULL;
1195 }
1196
1197 /* Open the window station */
1200 UserMode,
1201 NULL,
1202 dwDesiredAccess,
1203 NULL,
1204 (PVOID*)&hWinSta);
1205 if (NT_SUCCESS(Status))
1206 {
1207 TRACE("NtUserOpenWindowStation opened window station '%wZ' with handle 0x%p\n",
1208 ObjectAttributes->ObjectName, hWinSta);
1209 }
1210 else
1211 {
1212 ASSERT(hWinSta == NULL);
1213 ERR("NtUserOpenWindowStation failed to open window station '%wZ', Status 0x%08lx\n",
1214 ObjectAttributes->ObjectName, Status);
1215 }
1216
1217 /* Try to restore the user's ObjectAttributes and release the window station name */
1218 FreeUserModeWindowStationName(WindowStationName,
1219 TebStaticUnicodeString,
1220 (OwnerMode == KernelMode ? ObjectAttributes : NULL),
1221 &LocalObjectAttributes);
1222
1223 if (!NT_SUCCESS(Status))
1224 {
1225 ASSERT(hWinSta == NULL);
1227 }
1228
1229 return hWinSta;
1230}
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200

Referenced by OpenWindowStationW().

◆ NtUserSetLogonNotifyWindow()

BOOL APIENTRY NtUserSetLogonNotifyWindow ( HWND  hWnd)

Definition at line 2181 of file winsta.c.

2182{
2183 BOOL Ret = FALSE;
2184
2186
2187 if (!IntIsWindow(hWnd))
2188 goto Leave;
2189
2191 {
2193 goto Leave;
2194 }
2195
2196 hwndSAS = hWnd;
2197 Ret = TRUE;
2198
2199Leave:
2200 UserLeave();
2201 return Ret;
2202}
HWND hWnd
Definition: settings.c:17
BOOL FASTCALL IntIsWindow(HWND hWnd)
Definition: window.c:177

Referenced by SetLogonNotifyWindow().

◆ NtUserSetObjectInformation()

BOOL APIENTRY NtUserSetObjectInformation ( HANDLE  hObject,
DWORD  nIndex,
PVOID  pvInformation,
DWORD  nLength 
)

Definition at line 1572 of file winsta.c.

1577{
1578 /* FIXME: ZwQueryObject */
1579 /* FIXME: ZwSetInformationObject */
1581 return FALSE;
1582}
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

◆ NtUserSetProcessWindowStation()

BOOL APIENTRY NtUserSetProcessWindowStation ( HWINSTA  hWindowStation)

Definition at line 1749 of file winsta.c.

1750{
1751 BOOL ret;
1752
1754
1755 ret = UserSetProcessWindowStation(hWindowStation);
1756
1757 UserLeave();
1758
1759 return ret;
1760}
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation)
Definition: winsta.c:1614

Referenced by SetProcessWindowStation().

◆ NtUserSetWindowStationUser()

BOOL NTAPI NtUserSetWindowStationUser ( IN HWINSTA  hWindowStation,
IN PLUID  pluid,
IN PSID psid  OPTIONAL,
IN DWORD  size 
)

Definition at line 2229 of file winsta.c.

2234{
2235 BOOL Ret = FALSE;
2237 PWINSTATION_OBJECT WindowStation = NULL;
2238 LUID luidUser;
2239
2241
2243 {
2245 goto Leave;
2246 }
2247
2248 /* Validate the window station */
2249 Status = IntValidateWindowStationHandle(hWindowStation,
2250 UserMode,
2251 0,
2252 &WindowStation,
2253 NULL);
2254 if (!NT_SUCCESS(Status))
2255 {
2256 goto Leave;
2257 }
2258
2259 /* Capture the user LUID */
2260 _SEH2_TRY
2261 {
2262 ProbeForRead(pluid, sizeof(LUID), 1);
2263 luidUser = *pluid;
2264 }
2266 {
2268 _SEH2_YIELD(goto Leave);
2269 }
2270 _SEH2_END;
2271
2272 /* Reset the window station user LUID */
2273 RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
2274
2275 /* Reset the window station user SID */
2276 if (WindowStation->psidUser)
2277 {
2279 WindowStation->psidUser = NULL;
2280 }
2281
2282 /* Copy the new user SID if one has been provided */
2283 if (psid)
2284 {
2286 if (WindowStation->psidUser == NULL)
2287 {
2289 goto Leave;
2290 }
2291
2293 _SEH2_TRY
2294 {
2295 ProbeForRead(psid, size, 1);
2296 RtlCopyMemory(WindowStation->psidUser, psid, size);
2297 }
2299 {
2301 }
2302 _SEH2_END;
2303
2304 if (!NT_SUCCESS(Status))
2305 {
2307 WindowStation->psidUser = NULL;
2308 goto Leave;
2309 }
2310 }
2311
2312 /* Copy the new user LUID */
2313 WindowStation->luidUser = luidUser;
2314
2315 Ret = TRUE;
2316
2317Leave:
2318 if (WindowStation)
2319 ObDereferenceObject(WindowStation);
2320
2321 UserLeave();
2322 return Ret;
2323}
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
GLsizeiptr size
Definition: glext.h:5919
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
PVOID psidUser
Definition: winsta.h:39

Referenced by SetWindowStationUser().

◆ NtUserUnlockWindowStation()

BOOL APIENTRY NtUserUnlockWindowStation ( HWINSTA  hWindowStation)

Definition at line 1814 of file winsta.c.

1815{
1818 BOOL Ret;
1819
1820 TRACE("About to set process window station with handle (%p)\n",
1821 hWindowStation);
1822
1824 {
1825 ERR("Unauthorized process attempted to unlock the window station!\n");
1827 return FALSE;
1828 }
1829
1830 Status = IntValidateWindowStationHandle(hWindowStation,
1831 UserMode,
1832 0,
1833 &Object,
1834 NULL);
1835 if (!NT_SUCCESS(Status))
1836 {
1837 TRACE("Validation of window station handle (%p) failed\n",
1838 hWindowStation);
1840 return FALSE;
1841 }
1842
1843 Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
1844 Object->Flags &= ~WSS_LOCKED;
1845
1847 return Ret;
1848}

Referenced by UnlockWindowStation().

◆ UserCreateWinstaDirectory()

NTSTATUS NTAPI UserCreateWinstaDirectory ( VOID  )

Definition at line 52 of file winsta.c.

53{
57 WCHAR wstrWindowStationsDir[MAX_PATH];
58
59 /* Create the WindowStations directory and cache its path for later use */
61 if (SessionId == 0)
62 {
65 }
66 else
67 {
68 Status = RtlStringCbPrintfW(wstrWindowStationsDir,
69 sizeof(wstrWindowStationsDir),
70 L"%ws\\%lu%ws",
74 if (!NT_SUCCESS(Status))
75 return Status;
76
77 if (!RtlCreateUnicodeString(&gustrWindowStationsDir, wstrWindowStationsDir))
79 }
80
84 NULL,
85 NULL);
87 if (!NT_SUCCESS(Status))
88 ERR("Could not create %wZ directory (Status 0x%X)\n", &gustrWindowStationsDir, Status);
89 else
90 TRACE("Created directory %wZ for session %lu\n", &gustrWindowStationsDir, SessionId);
91
92 return Status;
93}
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define MAX_PATH
Definition: compat.h:34
#define SESSION_DIR
Definition: dllmain.c:38
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
HANDLE ghWinStaDir
Definition: winsta.c:28
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WINSTA_OBJ_DIR
Definition: winsta.h:3

Referenced by UserInitialize().

◆ UserGetProcessWindowStation()

HWINSTA FASTCALL UserGetProcessWindowStation ( VOID  )

Definition at line 1586 of file winsta.c.

1587{
1589
1590 return ppi->hwinsta;
1591}

Referenced by IntGetWinStaForCbAccess(), NtUserCloseWindowStation(), and NtUserGetProcessWindowStation().

◆ UserSetProcessWindowStation()

BOOL FASTCALL UserSetProcessWindowStation ( HWINSTA  hWindowStation)

Definition at line 1614 of file winsta.c.

1615{
1617 PPROCESSINFO ppi;
1618 OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
1619 PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
1620 HWINSTA hCacheWinSta;
1621
1623
1624 /* Reference the new window station */
1625 if (hWindowStation != NULL)
1626 {
1627 Status = IntValidateWindowStationHandle(hWindowStation,
1628 UserMode,
1629 0,
1630 &NewWinSta,
1631 &ObjectHandleInfo);
1632 if (!NT_SUCCESS(Status))
1633 {
1634 TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
1636 return FALSE;
1637 }
1638 }
1639
1640 OldWinSta = ppi->prpwinsta;
1641 hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
1642
1643 /* Dereference the previous window station */
1644 if (OldWinSta != NULL)
1645 {
1646 ObDereferenceObject(OldWinSta);
1647 }
1648
1649 /*
1650 * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
1651 */
1652
1653 /* Close the cached EPROCESS window station handle if needed */
1654 if (hCacheWinSta != NULL)
1655 {
1656 /* Reference the window station */
1657 Status = ObReferenceObjectByHandle(hCacheWinSta,
1658 0,
1660 UserMode,
1661 (PVOID*)&OldWinSta,
1662 NULL);
1663 if (!NT_SUCCESS(Status))
1664 {
1665 ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
1666 /* We failed, reset the cache */
1667 hCacheWinSta = NULL;
1668 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1669 }
1670 else
1671 {
1672 /*
1673 * Close the old handle and reset the cache only
1674 * if we are setting a different window station.
1675 */
1676 if (NewWinSta != OldWinSta)
1677 {
1678 ObCloseHandle(hCacheWinSta, UserMode);
1679 hCacheWinSta = NULL;
1680 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1681 }
1682
1683 /* Dereference the window station */
1684 ObDereferenceObject(OldWinSta);
1685 }
1686 }
1687
1688 /* Duplicate and save a new cached EPROCESS window station handle */
1689 if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
1690 {
1691 Status = ZwDuplicateObject(ZwCurrentProcess(),
1692 hWindowStation,
1694 (PHANDLE)&hCacheWinSta,
1695 0,
1696 0,
1698 if (!NT_SUCCESS(Status))
1699 {
1700 ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
1701 }
1702 else
1703 {
1704 PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
1705 }
1706 }
1707
1708 ppi->prpwinsta = NewWinSta;
1709 ppi->hwinsta = hWindowStation;
1710 ppi->amwinsta = hWindowStation != NULL ? ObjectHandleInfo.GrantedAccess : 0;
1711 TRACE("WS : Granted Access 0x%08lx\n",ppi->amwinsta);
1712
1714 {
1715 ppi->W32PF_flags |= W32PF_READSCREENACCESSGRANTED;
1716 }
1717 else
1718 {
1719 ppi->W32PF_flags &= ~W32PF_READSCREENACCESSGRANTED;
1720 }
1721
1722 if (NewWinSta && !(NewWinSta->Flags & WSS_NOIO))
1723 {
1724 ppi->W32PF_flags |= W32PF_IOWINSTA;
1725 }
1726 else /* Might be closed if the handle is NULL */
1727 {
1728 ppi->W32PF_flags &= ~W32PF_IOWINSTA;
1729 }
1730 return TRUE;
1731}
VOID NTAPI PsSetProcessWindowStation(PEPROCESS Process, PVOID WindowStation)
Definition: process.c:1314
PVOID NTAPI PsGetProcessWin32WindowStation(PEPROCESS Process)
Definition: process.c:1203
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
struct _WINSTATION_OBJECT * prpwinsta
Definition: win32.h:267
#define W32PF_READSCREENACCESSGRANTED
Definition: win32.h:8
#define WINSTA_READSCREEN
Definition: winuser.h:415
#define DUPLICATE_SAME_ACCESS

Referenced by InitThreadCallback(), NtUserSetProcessWindowStation(), RawInputThreadMain(), and UserProcessDestroy().

Variable Documentation

◆ ghWinStaDir

HANDLE ghWinStaDir

Definition at line 28 of file winsta.c.

Referenced by UserCreateWinstaDirectory().

◆ gustrWindowStationsDir

◆ hwndSAS

◆ InputWindowStation