-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS user32.dll
- * FILE: lib/user32/misc/winsta.c
- * PURPOSE: Window stations
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * UPDATE HISTORY:
- * 04-06-2001 CSH Created
+/*
+ * PROJECT: ReactOS user32.dll
+ * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Window stations
+ * COPYRIGHT: Copyright 2001-2018 Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * Copyright 2011-2018 Giannis Adamopoulos
*/
#include <user32.h>
-#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(winsta);
-
/*
* @implemented
*/
-HWINSTA WINAPI
-CreateWindowStationA(LPCSTR lpwinsta,
- DWORD dwReserved,
- ACCESS_MASK dwDesiredAccess,
- LPSECURITY_ATTRIBUTES lpsa)
+HWINSTA
+WINAPI
+CreateWindowStationA(
+ IN LPCSTR lpwinsta OPTIONAL,
+ IN DWORD dwReserved,
+ IN ACCESS_MASK dwDesiredAccess,
+ IN LPSECURITY_ATTRIBUTES lpsa OPTIONAL)
{
- UNICODE_STRING WindowStationNameU;
HWINSTA hWinSta;
+ UNICODE_STRING WindowStationNameU;
if (lpwinsta)
{
dwDesiredAccess,
lpsa);
- /* Free the string, if it was allocated */
+ /* Free the string if it was allocated */
if (lpwinsta) RtlFreeUnicodeString(&WindowStationNameU);
return hWinSta;
/*
* @implemented
*/
-HWINSTA WINAPI
-CreateWindowStationW(LPCWSTR lpwinsta,
- DWORD dwReserved,
- ACCESS_MASK dwDesiredAccess,
- LPSECURITY_ATTRIBUTES lpsa)
+HWINSTA
+WINAPI
+CreateWindowStationW(
+ IN LPCWSTR lpwinsta OPTIONAL,
+ IN DWORD dwReserved,
+ IN ACCESS_MASK dwDesiredAccess,
+ IN LPSECURITY_ATTRIBUTES lpsa OPTIONAL)
{
- UNICODE_STRING WindowStationName;
- UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hWindowStationsDir;
- NTSTATUS Status;
- HWINSTA hwinsta;
-
- /* Open WindowStations directory */
- InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationsDir,
- OBJ_CASE_INSENSITIVE,
- 0,
- 0);
-
- Status = NtOpenDirectoryObject(&hWindowStationsDir,
- DIRECTORY_CREATE_OBJECT,
- &ObjectAttributes);
- if(!NT_SUCCESS(Status))
- {
- ERR("Failed to open WindowStations directory\n");
- return NULL;
- }
-
- RtlInitUnicodeString(&WindowStationName, lpwinsta);
-
- /* Create the window station object */
- InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationName,
- OBJ_CASE_INSENSITIVE,
- hWindowStationsDir,
- 0);
-
- /* Check if the handle should be inheritable */
- if (lpsa && lpsa->bInheritHandle)
- {
- ObjectAttributes.Attributes |= OBJ_INHERIT;
- }
-
- hwinsta = NtUserCreateWindowStation(&ObjectAttributes,
- dwDesiredAccess,
- 0, 0, 0, 0, 0);
-
- NtClose(hWindowStationsDir);
-
- return hwinsta;
+ NTSTATUS Status;
+ HWINSTA hWinSta;
+ UNICODE_STRING WindowStationName;
+ UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hWindowStationsDir;
+
+ /* Open WindowStations directory */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &WindowStationsDir,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenDirectoryObject(&hWindowStationsDir,
+ DIRECTORY_CREATE_OBJECT,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Failed to open WindowStations directory\n");
+ return NULL;
+ }
+
+ RtlInitUnicodeString(&WindowStationName, lpwinsta);
+
+ /* Create the window station object */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &WindowStationName,
+ OBJ_CASE_INSENSITIVE,
+ hWindowStationsDir,
+ NULL);
+
+ /* Check if the handle should be inheritable */
+ if (lpsa && lpsa->bInheritHandle)
+ {
+ ObjectAttributes.Attributes |= OBJ_INHERIT;
+ }
+
+ hWinSta = NtUserCreateWindowStation(&ObjectAttributes,
+ dwDesiredAccess,
+ 0, 0, 0, 0, 0);
+
+ NtClose(hWindowStationsDir);
+
+ return hWinSta;
}
/*
* Common code for EnumDesktopsA/W and EnumWindowStationsA/W
*/
-BOOL FASTCALL
+BOOL
+FASTCALL
EnumNamesW(HWINSTA WindowStation,
NAMEENUMPROCW EnumFunc,
- LPARAM Context,
+ LPARAM Context,
BOOL Desktops)
{
- char Buffer[256];
- PVOID NameList;
- PWCHAR Name;
- NTSTATUS Status;
- ULONG RequiredSize;
- ULONG CurrentEntry, EntryCount;
- BOOL Ret;
-
- /*
- * Check parameters
- */
- if (NULL == WindowStation && Desktops)
- {
- WindowStation = GetProcessWindowStation();
- }
-
- /*
- * Try with fixed-size buffer
- */
- Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
- if (NT_SUCCESS(Status))
- {
- /* Fixed-size buffer is large enough */
- NameList = (PWCHAR) Buffer;
- }
- else if (Status == STATUS_BUFFER_TOO_SMALL)
- {
- /* Allocate a larger buffer */
- NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
- if (NULL == NameList)
- {
- return FALSE;
- }
- /* Try again */
- Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
- if (! NT_SUCCESS(Status))
- {
- HeapFree(GetProcessHeap(), 0, NameList);
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
- }
- else
- {
- /* Some unrecognized error occured */
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
-
- /*
- * Enum the names one by one
- */
- EntryCount = *((DWORD *) NameList);
- Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
- Ret = TRUE;
- for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
- {
- Ret = (*EnumFunc)(Name, Context);
- Name += wcslen(Name) + 1;
- }
-
- /*
- * Cleanup
- */
- if (NameList != Buffer)
- {
- HeapFree(GetProcessHeap(), 0, NameList);
- }
-
- return Ret;
-}
+ CHAR Buffer[256];
+ PVOID NameList;
+ PWCHAR Name;
+ NTSTATUS Status;
+ ULONG RequiredSize;
+ ULONG CurrentEntry, EntryCount;
+ BOOL Ret;
+
+ /* Check parameters */
+ if (WindowStation == NULL && Desktops)
+ {
+ WindowStation = GetProcessWindowStation();
+ }
+ /* Try with fixed-size buffer */
+ Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
+ if (NT_SUCCESS(Status))
+ {
+ /* Fixed-size buffer is large enough */
+ NameList = (PWCHAR) Buffer;
+ }
+ else if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* Allocate a larger buffer */
+ NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
+ if (NameList == NULL)
+ return FALSE;
+
+ /* Try again */
+ Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ HeapFree(GetProcessHeap(), 0, NameList);
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Some unrecognized error occured */
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ /* Enum the names one by one */
+ EntryCount = *((DWORD *) NameList);
+ Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
+ Ret = TRUE;
+ for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
+ {
+ Ret = (*EnumFunc)(Name, Context);
+ Name += wcslen(Name) + 1;
+ }
+
+ /* Cleanup */
+ if (NameList != Buffer)
+ {
+ HeapFree(GetProcessHeap(), 0, NameList);
+ }
+
+ return Ret;
+}
/* For W->A conversion */
typedef struct tagENUMNAMESASCIICONTEXT
{
- NAMEENUMPROCA UserEnumFunc;
- LPARAM UserContext;
+ NAMEENUMPROCA UserEnumFunc;
+ LPARAM UserContext;
} ENUMNAMESASCIICONTEXT, *PENUMNAMESASCIICONTEXT;
/*
* Callback used by Ascii versions. Converts the Unicode name to
* Ascii and then calls the user callback
*/
-BOOL CALLBACK
+BOOL
+CALLBACK
EnumNamesCallback(LPWSTR Name, LPARAM Param)
{
- PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
- char FixedNameA[32];
- LPSTR NameA;
- int Len;
- BOOL Ret;
-
- /*
- * Determine required size of Ascii string and see if we can use
- * fixed buffer
- */
- Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
- if (Len <= 0)
- {
- /* Some strange error occured */
- return FALSE;
- }
- else if (Len <= sizeof(FixedNameA))
- {
- /* Fixed-size buffer is large enough */
- NameA = FixedNameA;
- }
- else
- {
- /* Allocate a larger buffer */
- NameA = HeapAlloc(GetProcessHeap(), 0, Len);
- if (NULL == NameA)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- }
-
- /*
- * Do the Unicode ->Ascii conversion
- */
- if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
- {
- /* Something went wrong, clean up */
- if (NameA != FixedNameA)
- {
- HeapFree(GetProcessHeap(), 0, NameA);
- }
- return FALSE;
- }
-
- /*
- * Call user callback
- */
- Ret = Context->UserEnumFunc(NameA, Context->UserContext);
-
- /*
- * Clean up
- */
- if (NameA != FixedNameA)
- {
- HeapFree(GetProcessHeap(), 0, NameA);
- }
-
- return Ret;
+ PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
+ CHAR FixedNameA[32];
+ LPSTR NameA;
+ INT Len;
+ BOOL Ret;
+
+ /*
+ * Determine required size of Ascii string and see
+ * if we can use fixed buffer.
+ */
+ Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
+ if (Len <= 0)
+ {
+ /* Some strange error occured */
+ return FALSE;
+ }
+ else if (Len <= sizeof(FixedNameA))
+ {
+ /* Fixed-size buffer is large enough */
+ NameA = FixedNameA;
+ }
+ else
+ {
+ /* Allocate a larger buffer */
+ NameA = HeapAlloc(GetProcessHeap(), 0, Len);
+ if (NULL == NameA)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ }
+
+ /* Do the Unicode ->Ascii conversion */
+ if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
+ {
+ /* Something went wrong, clean up */
+ if (NameA != FixedNameA)
+ {
+ HeapFree(GetProcessHeap(), 0, NameA);
+ }
+ return FALSE;
+ }
+
+ /* Call user callback */
+ Ret = Context->UserEnumFunc(NameA, Context->UserContext);
+
+ /* Cleanup */
+ if (NameA != FixedNameA)
+ {
+ HeapFree(GetProcessHeap(), 0, NameA);
+ }
+
+ return Ret;
}
/*
* Common code for EnumDesktopsA and EnumWindowStationsA
*/
-BOOL FASTCALL
+BOOL
+FASTCALL
EnumNamesA(HWINSTA WindowStation,
NAMEENUMPROCA EnumFunc,
- LPARAM Context,
+ LPARAM Context,
BOOL Desktops)
{
- ENUMNAMESASCIICONTEXT PrivateContext;
+ ENUMNAMESASCIICONTEXT PrivateContext;
- PrivateContext.UserEnumFunc = EnumFunc;
- PrivateContext.UserContext = Context;
+ PrivateContext.UserEnumFunc = EnumFunc;
+ PrivateContext.UserContext = Context;
- return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
+ return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
}
/*
* @implemented
*/
-BOOL WINAPI
-EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
- LPARAM Context)
+BOOL
+WINAPI
+EnumWindowStationsA(
+ IN WINSTAENUMPROCA EnumFunc,
+ IN LPARAM Context)
{
- return EnumNamesA(NULL, EnumFunc, Context, FALSE);
+ return EnumNamesA(NULL, EnumFunc, Context, FALSE);
}
/*
* @implemented
*/
-BOOL WINAPI
-EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
- LPARAM Context)
+BOOL
+WINAPI
+EnumWindowStationsW(
+ IN WINSTAENUMPROCW EnumFunc,
+ IN LPARAM Context)
{
- return EnumNamesW(NULL, EnumFunc, Context, FALSE);
+ return EnumNamesW(NULL, EnumFunc, Context, FALSE);
+}
+
+
+/*
+ * @unimplemented on Win32k side
+ */
+BOOL
+WINAPI
+GetWinStationInfo(PVOID pUnknown)
+{
+ return (BOOL)NtUserCallOneParam((DWORD_PTR)pUnknown, ONEPARAM_ROUTINE_GETWINSTAINFO);
}
/*
* @implemented
*/
-HWINSTA WINAPI
-OpenWindowStationA(LPCSTR lpszWinSta,
- BOOL fInherit,
- ACCESS_MASK dwDesiredAccess)
+HWINSTA
+WINAPI
+OpenWindowStationA(
+ IN LPCSTR lpszWinSta,
+ IN BOOL fInherit,
+ IN ACCESS_MASK dwDesiredAccess)
{
- UNICODE_STRING WindowStationNameU;
HWINSTA hWinSta;
+ UNICODE_STRING WindowStationNameU;
if (lpszWinSta)
{
fInherit,
dwDesiredAccess);
- /* Free the string, if it was allocated */
+ /* Free the string if it was allocated */
if (lpszWinSta) RtlFreeUnicodeString(&WindowStationNameU);
return hWinSta;
/*
* @implemented
*/
-HWINSTA WINAPI
-OpenWindowStationW(LPCWSTR lpszWinSta,
- BOOL fInherit,
- ACCESS_MASK dwDesiredAccess)
+HWINSTA
+WINAPI
+OpenWindowStationW(
+ IN LPCWSTR lpszWinSta,
+ IN BOOL fInherit,
+ IN ACCESS_MASK dwDesiredAccess)
{
- UNICODE_STRING WindowStationName;
- UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hWindowStationsDir;
- NTSTATUS Status;
- HWINSTA hwinsta;
-
- /* Open WindowStations directory */
- InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationsDir,
- OBJ_CASE_INSENSITIVE,
- 0,
- 0);
-
- Status = NtOpenDirectoryObject(&hWindowStationsDir,
- DIRECTORY_TRAVERSE,
- &ObjectAttributes);
- if(!NT_SUCCESS(Status))
- {
- ERR("Failed to open WindowStations directory\n");
- return NULL;
- }
-
- /* Open the window station object */
- RtlInitUnicodeString(&WindowStationName, lpszWinSta);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationName,
- OBJ_CASE_INSENSITIVE,
- hWindowStationsDir,
- 0);
-
- if( fInherit == TRUE )
- {
- ObjectAttributes.Attributes |= OBJ_INHERIT;
- }
-
- hwinsta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess);
-
- NtClose(hWindowStationsDir);
-
- return hwinsta;
+ NTSTATUS Status;
+ HWINSTA hWinSta;
+ UNICODE_STRING WindowStationName;
+ UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hWindowStationsDir;
+
+ /* Open WindowStations directory */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &WindowStationsDir,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenDirectoryObject(&hWindowStationsDir,
+ DIRECTORY_TRAVERSE,
+ &ObjectAttributes);
+ if(!NT_SUCCESS(Status))
+ {
+ ERR("Failed to open WindowStations directory\n");
+ return NULL;
+ }
+
+ /* Open the window station object */
+ RtlInitUnicodeString(&WindowStationName, lpszWinSta);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &WindowStationName,
+ OBJ_CASE_INSENSITIVE,
+ hWindowStationsDir,
+ NULL);
+
+ /* Check if the handle should be inheritable */
+ if (fInherit)
+ {
+ ObjectAttributes.Attributes |= OBJ_INHERIT;
+ }
+
+ hWinSta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess);
+
+ NtClose(hWindowStationsDir);
+
+ return hWinSta;
}
/*
- * @unimplemented
+ * @implemented
*/
-DWORD
+BOOL
WINAPI
SetWindowStationUser(
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3,
- DWORD Unknown4
- )
+ IN HWINSTA hWindowStation,
+ IN PLUID pluid,
+ IN PSID psid OPTIONAL,
+ IN DWORD size)
{
- return NtUserSetWindowStationUser(Unknown1, Unknown2, Unknown3, Unknown4);
+ BOOL Success;
+
+ Success = NtUserSetWindowStationUser(hWindowStation, pluid, psid, size);
+ if (Success)
+ {
+ /* Signal log-on/off to WINSRV */
+
+ /* User is logging on if *pluid != LuidNone, otherwise it is a log-off */
+ LUID LuidNone = {0, 0};
+ BOOL IsLogon = (pluid && !RtlEqualLuid(pluid, &LuidNone));
+
+ Logon(IsLogon);
+ }
+
+ return Success;
}
/* EOF */
-