[WIN32SS:NTUSER] Update SetWindowStationUser() and NtUserSetWindowStationUser() proto...
[reactos.git] / win32ss / user / user32 / misc / winsta.c
index b38732d..24f6d89 100644 (file)
@@ -1,31 +1,28 @@
-/* $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)
     {
@@ -42,7 +39,7 @@ CreateWindowStationA(LPCSTR lpwinsta,
                                    dwDesiredAccess,
                                    lpsa);
 
-    /* Free the string, if it was allocated */
+    /* Free the string if it was allocated */
     if (lpwinsta) RtlFreeUnicodeString(&WindowStationNameU);
 
     return hWinSta;
@@ -52,265 +49,271 @@ CreateWindowStationA(LPCSTR lpwinsta,
 /*
  * @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)
     {
@@ -326,7 +329,7 @@ OpenWindowStationA(LPCSTR lpszWinSta,
                                  fInherit,
                                  dwDesiredAccess);
 
-    /* Free the string, if it was allocated */
+    /* Free the string if it was allocated */
     if (lpszWinSta) RtlFreeUnicodeString(&WindowStationNameU);
 
     return hWinSta;
@@ -336,70 +339,85 @@ OpenWindowStationA(LPCSTR lpszWinSta,
 /*
  * @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 */
-