Moved win32k
[reactos.git] / reactos / subsys / win32k / ntuser / desktop.c
diff --git a/reactos/subsys/win32k/ntuser/desktop.c b/reactos/subsys/win32k/ntuser/desktop.c
deleted file mode 100644 (file)
index 4a2167b..0000000
+++ /dev/null
@@ -1,1614 +0,0 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  $Id$
- *
- *  COPYRIGHT:        See COPYING in the top level directory
- *  PROJECT:          ReactOS kernel
- *  PURPOSE:          Desktops
- *  FILE:             subsys/win32k/ntuser/desktop.c
- *  PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
- *  REVISION HISTORY:
- *       06-06-2001  CSH  Created
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <w32k.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS *******************************************************************/
-
-/* Currently active desktop */
-PDESKTOP_OBJECT InputDesktop = NULL;
-HDESK InputDesktopHandle = NULL;
-HDC ScreenDeviceContext = NULL;
-
-BOOL g_PaintDesktopVersion = FALSE;
-
-/* INITALIZATION FUNCTIONS ****************************************************/
-
-static GENERIC_MAPPING IntDesktopMapping =
-   {
-      STANDARD_RIGHTS_READ     | DESKTOP_ENUMERATE       | DESKTOP_READOBJECTS,
-      STANDARD_RIGHTS_WRITE    | DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW    | DESKTOP_HOOKCONTROL   |
-      DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD   | DESKTOP_WRITEOBJECTS,
-      STANDARD_RIGHTS_EXECUTE  | DESKTOP_SWITCHDESKTOP,
-      STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU      | DESKTOP_CREATEWINDOW    | DESKTOP_ENUMERATE     |
-      DESKTOP_HOOKCONTROL     | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
-      DESKTOP_READOBJECTS     | DESKTOP_SWITCHDESKTOP   | DESKTOP_WRITEOBJECTS
-   };
-
-NTSTATUS FASTCALL
-InitDesktopImpl(VOID)
-{
-   /* Set Desktop Object Attributes */
-   ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP_OBJECT);
-   ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
-
-   return STATUS_SUCCESS;
-}
-
-NTSTATUS FASTCALL
-CleanupDesktopImpl(VOID)
-{
-   return STATUS_SUCCESS;
-}
-
-/* OBJECT CALLBACKS **********************************************************/
-
-NTSTATUS STDCALL
-IntDesktopObjectCreate(PVOID ObjectBody,
-                       PVOID Parent,
-                       PWSTR RemainingPath,
-                       struct _OBJECT_ATTRIBUTES* ObjectAttributes)
-{
-   PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
-   UNICODE_STRING UnicodeString;
-
-   DPRINT("Creating desktop (0x%X)  Name (%S)\n", Desktop, RemainingPath);
-   if (RemainingPath == NULL)
-   {
-      return STATUS_SUCCESS;
-   }
-
-   if (wcschr((RemainingPath + 1), '\\') != NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
-
-   InitializeListHead(&Desktop->ShellHookWindows);
-
-   Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
-
-   /* Put the desktop on the window station's list of associcated desktops */
-//   ExInterlocked
-   InsertTailList(
-      &Desktop->WindowStation->DesktopListHead,
-      &Desktop->ListEntry);//,
-//      &Desktop->WindowStation->Lock);
-
-   return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
-}
-
-VOID STDCALL
-IntDesktopObjectDelete(PVOID DeletedObject)
-{
-   PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
-
-   DPRINT("Deleting desktop (0x%X)\n", Desktop);
-
-   /* Remove the desktop from the window station's list of associcated desktops */
-   RemoveEntryList(&Desktop->ListEntry);
-
-   RtlFreeUnicodeString(&Desktop->Name);
-}
-
-/* PRIVATE FUNCTIONS **********************************************************/
-
-static int GetSystemVersionString(LPWSTR buffer)
-{
-   RTL_OSVERSIONINFOEXW versionInfo;
-   int len;
-
-   versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
-
-   if (!NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&versionInfo)))
-      return 0;
-
-   if (versionInfo.dwMajorVersion <= 4)
-      len = swprintf(buffer,
-                     L"ReactOS Version %d.%d %s Build %d",
-                     versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
-                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
-   else
-      len = swprintf(buffer,
-                     L"ReactOS %s (Build %d)",
-                     versionInfo.szCSDVersion, versionInfo.dwBuildNumber&0xFFFF);
-
-   return len;
-}
-
-
-NTSTATUS FASTCALL
-IntParseDesktopPath(PEPROCESS Process,
-                    PUNICODE_STRING DesktopPath,
-                    HWINSTA *hWinSta,
-                    HDESK *hDesktop)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   UNICODE_STRING WinSta, Desktop, FullName;
-   BOOL DesktopPresent = FALSE;
-   BOOL WinStaPresent = FALSE;
-   NTSTATUS Status;
-
-   ASSERT(hWinSta);
-
-   *hWinSta = NULL;
-
-   if(hDesktop != NULL)
-   {
-      *hDesktop = NULL;
-   }
-
-   RtlInitUnicodeString(&WinSta, NULL);
-   RtlInitUnicodeString(&Desktop, NULL);
-
-   if(DesktopPath != NULL && DesktopPath->Buffer != NULL && DesktopPath->Length > sizeof(WCHAR))
-   {
-      PWCHAR c = DesktopPath->Buffer;
-      USHORT wl = 0;
-      USHORT l = DesktopPath->Length;
-
-      /*
-       * Parse the desktop path string which can be in the form "WinSta\Desktop"
-       * or just "Desktop". In latter case WinSta0 will be used.
-       */
-
-      while(l > 0)
-      {
-         if(*c == L'\\')
-         {
-            wl = (ULONG_PTR)c - (ULONG_PTR)DesktopPath->Buffer;
-            break;
-         }
-         l -= sizeof(WCHAR);
-         c++;
-      }
-
-      if(wl > 0)
-      {
-         WinSta.Length = wl;
-         WinSta.MaximumLength = wl + sizeof(WCHAR);
-         WinSta.Buffer = DesktopPath->Buffer;
-
-         WinStaPresent = TRUE;
-         c++;
-      }
-
-      Desktop.Length = DesktopPath->Length - wl;
-      if(wl > 0)
-      {
-         Desktop.Length -= sizeof(WCHAR);
-      }
-      if(Desktop.Length > 0)
-      {
-         Desktop.MaximumLength = Desktop.Length + sizeof(WCHAR);
-         Desktop.Buffer = ((wl > 0) ? c : DesktopPath->Buffer);
-         DesktopPresent = TRUE;
-      }
-   }
-
-   if(!WinStaPresent)
-   {
-      /* search the process handle table for (inherited) window station
-         handles, use a more appropriate one than WinSta0 if possible. */
-      Status = ObFindHandleForObject(Process,
-                                     NULL,
-                                     ExWindowStationObjectType,
-                                     NULL,
-                                     (PHANDLE)hWinSta);
-      if(!NT_SUCCESS(Status))
-      {
-         /* we had no luck searching for opened handles, use WinSta0 now */
-         RtlInitUnicodeString(&WinSta, L"WinSta0");
-      }
-   }
-
-   if(!DesktopPresent && hDesktop != NULL)
-   {
-      /* search the process handle table for (inherited) desktop
-         handles, use a more appropriate one than Default if possible. */
-      Status = ObFindHandleForObject(Process,
-                                     NULL,
-                                     ExDesktopObjectType,
-                                     NULL,
-                                     (PHANDLE)hDesktop);
-      if(!NT_SUCCESS(Status))
-      {
-         /* we had no luck searching for opened handles, use Desktop now */
-         RtlInitUnicodeString(&Desktop, L"Default");
-      }
-   }
-
-   if(*hWinSta == NULL)
-   {
-      if(!IntGetFullWindowStationName(&FullName, &WinSta, NULL))
-      {
-         return STATUS_INSUFFICIENT_RESOURCES;
-      }
-
-      /* open the window station */
-      InitializeObjectAttributes(&ObjectAttributes,
-                                 &FullName,
-                                 OBJ_CASE_INSENSITIVE,
-                                 NULL,
-                                 NULL);
-
-      Status = ObOpenObjectByName(&ObjectAttributes,
-                                  ExWindowStationObjectType,
-                                  NULL,
-                                  KernelMode,
-                                  0,
-                                  NULL,
-                                  (HANDLE*)hWinSta);
-
-      RtlFreeUnicodeString(&FullName);
-
-      if(!NT_SUCCESS(Status))
-      {
-         SetLastNtError(Status);
-         DPRINT("Failed to reference window station %wZ PID: %d!\n", &WinSta, PsGetCurrentProcessId());
-         return Status;
-      }
-   }
-
-   if(hDesktop != NULL && *hDesktop == NULL)
-   {
-      if(!IntGetFullWindowStationName(&FullName, &WinSta, &Desktop))
-      {
-         NtClose(*hWinSta);
-         *hWinSta = NULL;
-         return STATUS_INSUFFICIENT_RESOURCES;
-      }
-
-      /* open the desktop object */
-      InitializeObjectAttributes(&ObjectAttributes,
-                                 &FullName,
-                                 OBJ_CASE_INSENSITIVE,
-                                 NULL,
-                                 NULL);
-
-      Status = ObOpenObjectByName(&ObjectAttributes,
-                                  ExDesktopObjectType,
-                                  NULL,
-                                  KernelMode,
-                                  0,
-                                  NULL,
-                                  (HANDLE*)hDesktop);
-
-      RtlFreeUnicodeString(&FullName);
-
-      if(!NT_SUCCESS(Status))
-      {
-         *hDesktop = NULL;
-         NtClose(*hWinSta);
-         *hWinSta = NULL;
-         SetLastNtError(Status);
-         DPRINT("Failed to reference desktop %wZ PID: %d!\n", &Desktop, PsGetCurrentProcessId());
-         return Status;
-      }
-   }
-
-   return STATUS_SUCCESS;
-}
-
-/*
- * IntValidateDesktopHandle
- *
- * Validates the desktop handle.
- *
- * Remarks
- *    If the function succeeds, the handle remains referenced. If the
- *    fucntion fails, last error is set.
- */
-
-NTSTATUS FASTCALL
-IntValidateDesktopHandle(
-   HDESK Desktop,
-   KPROCESSOR_MODE AccessMode,
-   ACCESS_MASK DesiredAccess,
-   PDESKTOP_OBJECT *Object)
-{
-   NTSTATUS Status;
-
-   Status = ObReferenceObjectByHandle(
-               Desktop,
-               DesiredAccess,
-               ExDesktopObjectType,
-               AccessMode,
-               (PVOID*)Object,
-               NULL);
-
-   if (!NT_SUCCESS(Status))
-      SetLastNtError(Status);
-
-   return Status;
-}
-
-VOID FASTCALL
-IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect)
-{
-   PRECT Ret;
-
-   ASSERT(Desktop);
-
-   Ret = &Desktop->WorkArea;
-   if((Ret->right == -1) && ScreenDeviceContext)
-   {
-      PDC dc;
-      BITMAPOBJ *BitmapObj;
-      dc = DC_LockDc(ScreenDeviceContext);
-      /* FIXME - Handle dc == NULL!!!! */
-      BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
-      if(BitmapObj)
-      {
-         Ret->right = BitmapObj->SurfObj.sizlBitmap.cx;
-         Ret->bottom = BitmapObj->SurfObj.sizlBitmap.cy;
-         BITMAPOBJ_UnlockBitmap(BitmapObj);
-      }
-      DC_UnlockDc(dc);
-   }
-
-   if(Rect)
-   {
-      *Rect = *Ret;
-   }
-}
-
-PDESKTOP_OBJECT FASTCALL
-IntGetActiveDesktop(VOID)
-{
-   return InputDesktop;
-}
-
-/*
- * returns or creates a handle to the desktop object
- */
-HDESK FASTCALL
-IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject)
-{
-   NTSTATUS Status;
-   HDESK Ret;
-
-   ASSERT(DesktopObject);
-
-   Status = ObFindHandleForObject(PsGetCurrentProcess(),
-                                  DesktopObject,
-                                  ExDesktopObjectType,
-                                  NULL,
-                                  (PHANDLE)&Ret);
-
-   if(!NT_SUCCESS(Status))
-   {
-      Status = ObOpenObjectByPointer(DesktopObject,
-                                     0,
-                                     NULL,
-                                     0,
-                                     ExDesktopObjectType,
-                                     UserMode,
-                                     (PHANDLE)&Ret);
-      if(!NT_SUCCESS(Status))
-      {
-         /* unable to create a handle */
-         DPRINT1("Unable to create a desktop handle\n");
-         return NULL;
-      }
-   }
-
-   return Ret;
-}
-
-PUSER_MESSAGE_QUEUE FASTCALL
-IntGetFocusMessageQueue(VOID)
-{
-   PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
-   if (!pdo)
-   {
-      DPRINT("No active desktop\n");
-      return(NULL);
-   }
-   return (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
-}
-
-VOID FASTCALL
-IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
-{
-   PUSER_MESSAGE_QUEUE Old;
-   PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
-   if (!pdo)
-   {
-      DPRINT("No active desktop\n");
-      return;
-   }
-   if(NewQueue != NULL)
-   {
-      if(NewQueue->Desktop != NULL)
-      {
-         DPRINT("Message Queue already attached to another desktop!\n");
-         return;
-      }
-      IntReferenceMessageQueue(NewQueue);
-      InterlockedExchange((LONG*)&NewQueue->Desktop, (LONG)pdo);
-   }
-   Old = (PUSER_MESSAGE_QUEUE)InterlockedExchange((LONG*)&pdo->ActiveMessageQueue, (LONG)NewQueue);
-   if(Old != NULL)
-   {
-      InterlockedExchange((LONG*)&Old->Desktop, 0);
-      IntDereferenceMessageQueue(Old);
-   }
-}
-
-HWND FASTCALL IntGetDesktopWindow(VOID)
-{
-   PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
-   if (!pdo)
-   {
-      DPRINT("No active desktop\n");
-      return NULL;
-   }
-   return pdo->DesktopWindow;
-}
-
-PWINDOW_OBJECT FASTCALL UserGetDesktopWindow(VOID)
-{
-   PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
-
-   if (!pdo)
-   {
-      DPRINT("No active desktop\n");
-      return NULL;
-   }
-
-   return UserGetWindowObject(pdo->DesktopWindow);
-}
-
-
-HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
-{
-   PDESKTOP_OBJECT pdo = PsGetWin32Thread()->Desktop;
-   if (NULL == pdo)
-   {
-      DPRINT1("Thread doesn't have a desktop\n");
-      return NULL;
-   }
-   return pdo->DesktopWindow;
-}
-
-BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
-{
-   if (bEnable)
-   {
-      RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-      NTSTATUS Status;
-
-      RtlZeroMemory(QueryTable, sizeof(QueryTable));
-
-      QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
-      QueryTable[0].Name = L"PaintDesktopVersion";
-      QueryTable[0].EntryContext = &g_PaintDesktopVersion;
-
-      /* Query the "PaintDesktopVersion" flag in the "Control Panel\Desktop" key */
-      Status = RtlQueryRegistryValues(RTL_REGISTRY_USER,
-                                      L"Control Panel\\Desktop",
-                                      QueryTable, NULL, NULL);
-      if (!NT_SUCCESS(Status))
-      {
-         DPRINT1("RtlQueryRegistryValues failed for PaintDesktopVersion (%x)\n",
-                 Status);
-         g_PaintDesktopVersion = FALSE;
-         return FALSE;
-      }
-
-      DPRINT("PaintDesktopVersion = %d\n", g_PaintDesktopVersion);
-
-      return TRUE;
-   }
-   else
-   {
-      g_PaintDesktopVersion = FALSE;
-      return TRUE;
-   }
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-NTSTATUS FASTCALL
-co_IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
-{
-   CSR_API_MESSAGE Request;
-
-   Request.Type = MAKE_CSR_API(SHOW_DESKTOP, CSR_GUI);
-   Request.Data.ShowDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
-   Request.Data.ShowDesktopRequest.Width = Width;
-   Request.Data.ShowDesktopRequest.Height = Height;
-
-   return co_CsrNotify(&Request);
-}
-
-NTSTATUS FASTCALL
-IntHideDesktop(PDESKTOP_OBJECT Desktop)
-{
-#if 0
-   CSRSS_API_REQUEST Request;
-   CSRSS_API_REPLY Reply;
-
-   Request.Type = CSRSS_HIDE_DESKTOP;
-   Request.Data.HideDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
-
-   return NotifyCsrss(&Request, &Reply);
-#else
-
-   PWINDOW_OBJECT DesktopWindow;
-
-   DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
-   if (! DesktopWindow)
-   {
-      return ERROR_INVALID_WINDOW_HANDLE;
-   }
-   DesktopWindow->Style &= ~WS_VISIBLE;
-
-   return STATUS_SUCCESS;
-#endif
-}
-
-
-
-
-static
-HWND* FASTCALL
-UserBuildShellHookHwndList(PDESKTOP_OBJECT Desktop)
-{
-   ULONG entries=0;
-   PSHELL_HOOK_WINDOW Current;
-   HWND* list;
-   
-   /* fixme: if we save nb elements in desktop, we dont have to loop to find nb entries */
-   LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
-      entries++;
-
-   if (!entries) return NULL;
-
-   list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
-   if (list)
-   {
-      HWND* cursor = list;
-      
-      LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
-         *cursor++ = Current->hWnd;
-   
-      *cursor = NULL; /* nullterm list */
-   }
-
-   return list;
-}
-
-/*
- * Send the Message to the windows registered for ShellHook
- * notifications. The lParam contents depend on the Message. See
- * MSDN for more details (RegisterShellHookWindow)
- */
-VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
-{
-   PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
-   HWND* HwndList;
-
-   static UINT MsgType = 0;
-
-   if (!MsgType)
-   {
-
-      /* Too bad, this doesn't work.*/
-#if 0
-      UNICODE_STRING Str;
-      RtlInitUnicodeString(&Str, L"SHELLHOOK");
-      MsgType = UserRegisterWindowMessage(&Str);
-#endif
-
-      MsgType = IntAddAtom(L"SHELLHOOK");
-
-      DPRINT("MsgType = %x\n", MsgType);
-      if (!MsgType)
-         DPRINT1("LastError: %x\n", GetLastNtError());
-   }
-
-   if (!Desktop)
-   {
-      DPRINT1("IntShellHookNotify: No desktop!\n");
-      return;
-   }
-
-   HwndList = UserBuildShellHookHwndList(Desktop);
-   if (HwndList)
-   {
-      HWND* cursor = HwndList;
-      
-      for (; *cursor; cursor++)
-      {
-         DPRINT("Sending notify\n");
-         co_IntPostOrSendMessage(*cursor,
-                                 MsgType,
-                                 Message,
-                                 lParam);
-      }
-
-      ExFreePool(HwndList);
-   }
-   
-}
-
-/*
- * Add the window to the ShellHookWindows list. The windows
- * on that list get notifications that are important to shell
- * type applications.
- *
- * TODO: Validate the window? I'm not sure if sending these messages to
- * an unsuspecting application that is not your own is a nice thing to do.
- */
-BOOL IntRegisterShellHookWindow(HWND hWnd)
-{
-   PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
-   PSHELL_HOOK_WINDOW Entry;
-
-   DPRINT("IntRegisterShellHookWindow\n");
-
-   /* First deregister the window, so we can be sure it's never twice in the
-    * list.
-    */
-   IntDeRegisterShellHookWindow(hWnd);
-
-   Entry = ExAllocatePoolWithTag(PagedPool,
-                                 sizeof(SHELL_HOOK_WINDOW),
-                                 TAG_WINSTA);
-
-   if (!Entry)
-      return FALSE;
-
-   Entry->hWnd = hWnd;
-
-   InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
-
-   return TRUE;
-}
-
-/*
- * Remove the window from the ShellHookWindows list. The windows
- * on that list get notifications that are important to shell
- * type applications.
- */
-BOOL IntDeRegisterShellHookWindow(HWND hWnd)
-{
-   PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
-   PSHELL_HOOK_WINDOW Current;
-
-   LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
-   {
-      if (Current->hWnd == hWnd)
-      {
-         RemoveEntryList(&Current->ListEntry);
-         ExFreePool(Current);
-         return TRUE;
-      }
-   }
-
-   return FALSE;
-}
-
-
-
-
-/* SYSCALLS *******************************************************************/
-
-
-/*
- * NtUserCreateDesktop
- *
- * Creates a new desktop.
- *
- * Parameters
- *    lpszDesktopName
- *       Name of the new desktop.
- *
- *    dwFlags
- *       Interaction flags.
- *
- *    dwDesiredAccess
- *       Requested type of access.
- *
- *    lpSecurity
- *       Security descriptor.
- *
- *    hWindowStation
- *       Handle to window station on which to create the desktop.
- *
- * Return Value
- *    If the function succeeds, the return value is a handle to the newly
- *    created desktop. If the specified desktop already exists, the function
- *    succeeds and returns a handle to the existing desktop. When you are
- *    finished using the handle, call the CloseDesktop function to close it.
- *    If the function fails, the return value is NULL.
- *
- * Status
- *    @implemented
- */
-
-HDESK STDCALL
-NtUserCreateDesktop(
-   PUNICODE_STRING lpszDesktopName,
-   DWORD dwFlags,
-   ACCESS_MASK dwDesiredAccess,
-   LPSECURITY_ATTRIBUTES lpSecurity,
-   HWINSTA hWindowStation)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   PWINSTATION_OBJECT WinStaObject;
-   PDESKTOP_OBJECT DesktopObject;
-   UNICODE_STRING DesktopName;
-   NTSTATUS Status;
-   HDESK Desktop;
-   CSR_API_MESSAGE Request;
-   DECLARE_RETURN(HDESK);
-
-   DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
-   UserEnterExclusive();
-
-   Status = IntValidateWindowStationHandle(
-               hWindowStation,
-               KernelMode,
-               0, /* FIXME - WINSTA_CREATEDESKTOP */
-               &WinStaObject);
-
-   if (! NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed validation of window station handle (0x%X), cannot create desktop %wZ\n",
-              hWindowStation, lpszDesktopName);
-      SetLastNtError(Status);
-      RETURN( NULL);
-   }
-
-   if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
-                                     lpszDesktopName))
-   {
-      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      ObDereferenceObject(WinStaObject);
-      RETURN( NULL);
-   }
-
-   ObDereferenceObject(WinStaObject);
-
-   /*
-    * Try to open already existing desktop
-    */
-
-   DPRINT1("Trying to open desktop (%wZ)\n", &DesktopName);
-
-   /* Initialize ObjectAttributes for the desktop object */
-   InitializeObjectAttributes(
-      &ObjectAttributes,
-      &DesktopName,
-      0,
-      NULL,
-      NULL);
-
-   Status = ObOpenObjectByName(
-               &ObjectAttributes,
-               ExDesktopObjectType,
-               NULL,
-               KernelMode,
-               dwDesiredAccess,
-               NULL,
-               (HANDLE*)&Desktop);
-
-   if (NT_SUCCESS(Status))
-   {
-      DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
-      ExFreePool(DesktopName.Buffer);
-      RETURN( Desktop);
-   }
-
-   /*
-    * No existing desktop found, try to create new one
-    */
-
-   Status = ObCreateObject(
-               KernelMode,
-               ExDesktopObjectType,
-               &ObjectAttributes,
-               ExGetPreviousMode(),
-               NULL,
-               sizeof(DESKTOP_OBJECT),
-               0,
-               0,
-               (PVOID*)&DesktopObject);
-
-   if (! NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed creating desktop (%wZ)\n", &DesktopName);
-      ExFreePool(DesktopName.Buffer);
-      SetLastNtError(STATUS_UNSUCCESSFUL);
-      RETURN( NULL);
-   }
-
-   // init desktop area
-   DesktopObject->WorkArea.left = 0;
-   DesktopObject->WorkArea.top = 0;
-   DesktopObject->WorkArea.right = -1;
-   DesktopObject->WorkArea.bottom = -1;
-   IntGetDesktopWorkArea(DesktopObject, NULL);
-
-   /* Initialize some local (to win32k) desktop state. */
-   DesktopObject->ActiveMessageQueue = NULL;
-
-   Status = ObInsertObject(
-               (PVOID)DesktopObject,
-               NULL,
-               STANDARD_RIGHTS_REQUIRED,
-               0,
-               NULL,
-               (HANDLE*)&Desktop);
-
-   ObDereferenceObject(DesktopObject);
-   ExFreePool(DesktopName.Buffer);
-
-   if (! NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed to create desktop handle\n");
-      SetLastNtError(Status);
-      RETURN( NULL);
-   }
-
-   /*
-    * Create a handle for CSRSS and notify CSRSS
-    */
-   Request.Type = MAKE_CSR_API(CREATE_DESKTOP, CSR_GUI);
-   Status = CsrInsertObject(Desktop,
-                            GENERIC_ALL,
-                            (HANDLE*)&Request.Data.CreateDesktopRequest.DesktopHandle);
-   if (! NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed to create desktop handle for CSRSS\n");
-      ZwClose(Desktop);
-      SetLastNtError(Status);
-      RETURN( NULL);
-   }
-
-   Status = co_CsrNotify(&Request);
-   if (! NT_SUCCESS(Status))
-   {
-      CsrCloseHandle(Request.Data.CreateDesktopRequest.DesktopHandle);
-      DPRINT1("Failed to notify CSRSS about new desktop\n");
-      ZwClose(Desktop);
-      SetLastNtError(Status);
-      RETURN( NULL);
-   }
-
-   RETURN( Desktop);
-
-CLEANUP:
-   DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/*
- * NtUserOpenDesktop
- *
- * Opens an existing desktop.
- *
- * Parameters
- *    lpszDesktopName
- *       Name of the existing desktop.
- *
- *    dwFlags
- *       Interaction flags.
- *
- *    dwDesiredAccess
- *       Requested type of access.
- *
- * Return Value
- *    Handle to the desktop or zero on failure.
- *
- * Status
- *    @implemented
- */
-
-HDESK STDCALL
-NtUserOpenDesktop(
-   PUNICODE_STRING lpszDesktopName,
-   DWORD dwFlags,
-   ACCESS_MASK dwDesiredAccess)
-{
-   OBJECT_ATTRIBUTES ObjectAttributes;
-   HWINSTA WinSta;
-   PWINSTATION_OBJECT WinStaObject;
-   UNICODE_STRING DesktopName;
-   NTSTATUS Status;
-   HDESK Desktop;
-   DECLARE_RETURN(HDESK);
-
-   DPRINT("Enter NtUserOpenDesktop: %wZ\n", lpszDesktopName);
-   UserEnterExclusive();
-
-   /*
-    * Validate the window station handle and compose the fully
-    * qualified desktop name
-    */
-
-   WinSta = UserGetProcessWindowStation();
-   Status = IntValidateWindowStationHandle(
-               WinSta,
-               KernelMode,
-               0,
-               &WinStaObject);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT1("Failed validation of window station handle (0x%X)\n", WinSta);
-      SetLastNtError(Status);
-      RETURN( 0);
-   }
-
-   if (!IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
-                                    lpszDesktopName))
-   {
-      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      ObDereferenceObject(WinStaObject);
-      RETURN( 0);
-   }
-
-   ObDereferenceObject(WinStaObject);
-
-   DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
-
-   /* Initialize ObjectAttributes for the desktop object */
-   InitializeObjectAttributes(
-      &ObjectAttributes,
-      &DesktopName,
-      0,
-      NULL,
-      NULL);
-
-   Status = ObOpenObjectByName(
-               &ObjectAttributes,
-               ExDesktopObjectType,
-               NULL,
-               KernelMode,
-               dwDesiredAccess,
-               NULL,
-               (HANDLE*)&Desktop);
-
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      ExFreePool(DesktopName.Buffer);
-      RETURN( 0);
-   }
-
-   DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
-   ExFreePool(DesktopName.Buffer);
-
-   RETURN( Desktop);
-
-CLEANUP:
-   DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/*
- * NtUserOpenInputDesktop
- *
- * Opens the input (interactive) desktop.
- *
- * Parameters
- *    dwFlags
- *       Interaction flags.
- *
- *    fInherit
- *       Inheritance option.
- *
- *    dwDesiredAccess
- *       Requested type of access.
- *
- * Return Value
- *    Handle to the input desktop or zero on failure.
- *
- * Status
- *    @implemented
- */
-
-HDESK STDCALL
-NtUserOpenInputDesktop(
-   DWORD dwFlags,
-   BOOL fInherit,
-   ACCESS_MASK dwDesiredAccess)
-{
-   PDESKTOP_OBJECT Object;
-   NTSTATUS Status;
-   HDESK Desktop;
-   DECLARE_RETURN(HDESK);
-
-   DPRINT("Enter NtUserOpenInputDesktop\n");
-   UserEnterExclusive();
-
-   DPRINT("About to open input desktop\n");
-
-   /* Get a pointer to the desktop object */
-
-   Status = IntValidateDesktopHandle(
-               InputDesktopHandle,
-               UserMode,
-               0,
-               &Object);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
-      RETURN((HDESK)0);
-   }
-
-   /* Create a new handle to the object */
-
-   Status = ObOpenObjectByPointer(
-               Object,
-               0,
-               NULL,
-               dwDesiredAccess,
-               ExDesktopObjectType,
-               UserMode,
-               (HANDLE*)&Desktop);
-
-   ObDereferenceObject(Object);
-
-   if (NT_SUCCESS(Status))
-   {
-      DPRINT("Successfully opened input desktop\n");
-      RETURN((HDESK)Desktop);
-   }
-
-   SetLastNtError(Status);
-   RETURN((HDESK)0);
-   
-CLEANUP:
-   DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;   
-}
-
-/*
- * NtUserCloseDesktop
- *
- * Closes a desktop handle.
- *
- * Parameters
- *    hDesktop
- *       Handle to the desktop.
- *
- * Return Value
- *   Status
- *
- * Remarks
- *   The desktop handle can be created with NtUserCreateDesktop or
- *   NtUserOpenDesktop. This function will fail if any thread in the calling
- *   process is using the specified desktop handle or if the handle refers
- *   to the initial desktop of the calling process.
- *
- * Status
- *    @implemented
- */
-
-BOOL STDCALL
-NtUserCloseDesktop(HDESK hDesktop)
-{
-   PDESKTOP_OBJECT Object;
-   NTSTATUS Status;
-   DECLARE_RETURN(BOOL);
-
-   DPRINT("Enter NtUserCloseDesktop\n");
-   UserEnterExclusive();
-
-   DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
-
-   Status = IntValidateDesktopHandle(
-               hDesktop,
-               UserMode,
-               0,
-               &Object);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      RETURN(FALSE);
-   }
-
-   ObDereferenceObject(Object);
-
-   DPRINT("Closing desktop handle (0x%X)\n", hDesktop);
-
-   Status = ZwClose(hDesktop);
-   if (!NT_SUCCESS(Status))
-   {
-      SetLastNtError(Status);
-      RETURN(FALSE);
-   }
-
-   RETURN(TRUE);
-
-CLEANUP:
-   DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;     
-}
-
-
-
-
-/*
- * NtUserPaintDesktop
- *
- * The NtUserPaintDesktop function fills the clipping region in the
- * specified device context with the desktop pattern or wallpaper. The
- * function is provided primarily for shell desktops.
- *
- * Parameters
- *    hDC
- *       Handle to the device context.
- *
- * Status
- *    @implemented
- */
-
-BOOL STDCALL
-NtUserPaintDesktop(HDC hDC)
-{
-   RECT Rect;
-   HBRUSH DesktopBrush, PreviousBrush;
-   HWND hWndDesktop;
-   BOOL doPatBlt = TRUE;
-   PWINDOW_OBJECT WndDesktop;
-   int len;
-   COLORREF color_old;
-   UINT align_old;
-   int mode_old;
-   PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
-   DECLARE_RETURN(BOOL);
-
-   UserEnterExclusive();
-   DPRINT("Enter NtUserPaintDesktop\n");
-
-
-   IntGdiGetClipBox(hDC, &Rect);
-
-   hWndDesktop = IntGetDesktopWindow();
-   
-   WndDesktop = UserGetWindowObject(hWndDesktop);
-   if (!WndDesktop)
-   {
-      RETURN(FALSE);
-   }
-
-   DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
-
-
-   /*
-    * Paint desktop background
-    */
-
-   if (WinSta->hbmWallpaper != NULL)
-   {
-      PWINDOW_OBJECT DeskWin;
-
-      DeskWin = UserGetWindowObject(hWndDesktop);
-      
-      if (DeskWin)
-      {
-         SIZE sz;
-         int x, y;
-         HDC hWallpaperDC;
-
-         sz.cx = DeskWin->WindowRect.right - DeskWin->WindowRect.left;
-         sz.cy = DeskWin->WindowRect.bottom - DeskWin->WindowRect.top;
-         if (WinSta->WallpaperMode == wmStretch ||
-             WinSta->WallpaperMode == wmTile)
-         {
-            x = 0;
-            y = 0;
-         }
-         else
-         {
-            /* Find the upper left corner, can be negtive if the bitmap is bigger then the screen */
-            x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
-            y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
-         }
-         hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
-         if(hWallpaperDC != NULL)
-         {
-            HBITMAP hOldBitmap;
-            /* fill in the area that the bitmap is not going to cover */
-            if (x > 0 || y > 0)
-            {
-               /* FIXME - clip out the bitmap 
-                                            can be replaced with "NtGdiPatBlt(hDC, x, y, WinSta->cxWallpaper, WinSta->cyWallpaper, PATCOPY | DSTINVERT);"
-                                            once we support DSTINVERT */
-              PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
-              NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
-              NtGdiSelectObject(hDC, PreviousBrush);
-            }
-            /*Do not fill the background after it is painted no matter the size of the picture */
-            doPatBlt = FALSE;
-            hOldBitmap = NtGdiSelectObject(hWallpaperDC, WinSta->hbmWallpaper);
-            if (WinSta->WallpaperMode == wmStretch)
-            {
-                if(Rect.right && Rect.bottom)
-                       NtGdiStretchBlt(hDC,
-                                x,
-                                y,
-                                sz.cx,
-                                sz.cy,
-                                hWallpaperDC,
-                                0,
-                                0,
-                                WinSta->cxWallpaper, 
-                                WinSta->cyWallpaper, 
-                                SRCCOPY,
-                                0);
-                                
-            }
-            else if (WinSta->WallpaperMode == wmTile)
-            {
-                /* paint the bitmap across the screen then down */
-                for(y = 0; y < Rect.bottom; y += WinSta->cyWallpaper)
-                {
-                    for(x = 0; x < Rect.right; x += WinSta->cxWallpaper)
-                    {
-                        NtGdiBitBlt(hDC, 
-                                    x, 
-                                    y, 
-                                    WinSta->cxWallpaper, 
-                                    WinSta->cyWallpaper, 
-                                    hWallpaperDC, 
-                                    0, 
-                                    0, 
-                                    SRCCOPY,
-                                    0,
-                                    0);
-                    }
-                }
-            }
-            else
-            {
-                NtGdiBitBlt(hDC, 
-                            x, 
-                            y, 
-                            WinSta->cxWallpaper, 
-                            WinSta->cyWallpaper, 
-                            hWallpaperDC, 
-                            0, 
-                            0, 
-                            SRCCOPY,
-                            0,
-                            0);
-            } 
-            NtGdiSelectObject(hWallpaperDC, hOldBitmap); 
-            NtGdiDeleteObjectApp(hWallpaperDC);
-         }
-      }
-   }
-
-   /* Back ground is set to none, clear the screen */
-   if (doPatBlt)
-   {
-      PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
-      NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
-      NtGdiSelectObject(hDC, PreviousBrush);
-   }
-
-   /*
-    * Display system version on the desktop background
-    */
-
-   if (g_PaintDesktopVersion)
-   {
-      static WCHAR s_wszVersion[256] = {0};
-      RECT rect;
-
-      if (*s_wszVersion)
-      {
-         len = wcslen(s_wszVersion);
-      }
-      else
-      {
-         len = GetSystemVersionString(s_wszVersion);
-      }
-
-      if (len)
-      {
-         if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0))
-         {
-            rect.right = UserGetSystemMetrics(SM_CXSCREEN);
-            rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
-         }
-
-         color_old = NtGdiSetTextColor(hDC, RGB(255,255,255));
-         align_old = NtGdiSetTextAlign(hDC, TA_RIGHT);
-         mode_old = NtGdiSetBkMode(hDC, TRANSPARENT);
-
-         NtGdiTextOut(hDC, rect.right-16, rect.bottom-48, s_wszVersion, len);
-
-         NtGdiSetBkMode(hDC, mode_old);
-         NtGdiSetTextAlign(hDC, align_old);
-         NtGdiSetTextColor(hDC, color_old);
-      }
-   }
-
-   RETURN(TRUE);
-   
-CLEANUP:
-   DPRINT("Leave NtUserPaintDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;   
-}
-
-
-/*
- * NtUserSwitchDesktop
- *
- * Sets the current input (interactive) desktop.
- *
- * Parameters
- *    hDesktop
- *       Handle to desktop.
- *
- * Return Value
- *    Status
- *
- * Status
- *    @unimplemented
- */
-
-BOOL STDCALL
-NtUserSwitchDesktop(HDESK hDesktop)
-{
-   PDESKTOP_OBJECT DesktopObject;
-   NTSTATUS Status;
-   DECLARE_RETURN(BOOL);
-   
-   UserEnterExclusive();
-   DPRINT("Enter NtUserSwitchDesktop\n");
-
-   DPRINT("About to switch desktop (0x%X)\n", hDesktop);
-
-   Status = IntValidateDesktopHandle(
-               hDesktop,
-               UserMode,
-               0,
-               &DesktopObject);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      RETURN(FALSE);
-   }
-
-   /*
-    * Don't allow applications switch the desktop if it's locked, unless the caller
-    * is the logon application itself
-    */
-   if((DesktopObject->WindowStation->Flags & WSS_LOCKED) &&
-         LogonProcess != NULL && LogonProcess != PsGetWin32Process())
-   {
-      ObDereferenceObject(DesktopObject);
-      DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
-      RETURN(FALSE);
-   }
-
-   /* FIXME: Fail if the desktop belong to an invisible window station */
-   /* FIXME: Fail if the process is associated with a secured
-             desktop such as Winlogon or Screen-Saver */
-   /* FIXME: Connect to input device */
-
-   /* Set the active desktop in the desktop's window station. */
-   DesktopObject->WindowStation->ActiveDesktop = DesktopObject;
-
-   /* Set the global state. */
-   InputDesktop = DesktopObject;
-   InputDesktopHandle = hDesktop;
-   InputWindowStation = DesktopObject->WindowStation;
-
-   ObDereferenceObject(DesktopObject);
-
-   RETURN(TRUE);
-   
-CLEANUP:
-   DPRINT("Leave NtUserSwitchDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;   
-}
-
-/*
- * NtUserResolveDesktopForWOW
- *
- * Status
- *    @unimplemented
- */
-
-DWORD STDCALL
-NtUserResolveDesktopForWOW(DWORD Unknown0)
-{
-   UNIMPLEMENTED
-   return 0;
-}
-
-/*
- * NtUserGetThreadDesktop
- *
- * Status
- *    @implemented
- */
-
-HDESK STDCALL
-NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
-{
-   NTSTATUS Status;
-   PETHREAD Thread;
-   PDESKTOP_OBJECT DesktopObject;
-   HDESK Ret, hThreadDesktop;
-   OBJECT_HANDLE_INFORMATION HandleInformation;
-   DECLARE_RETURN(HDESK);
-   
-   UserEnterExclusive();
-   DPRINT("Enter NtUserGetThreadDesktop\n");
-
-   if(!dwThreadId)
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN(0);
-   }
-
-   Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
-   if(!NT_SUCCESS(Status))
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      RETURN(0);
-   }
-
-   if(Thread->ThreadsProcess == PsGetCurrentProcess())
-   {
-      /* just return the handle, we queried the desktop handle of a thread running
-         in the same context */
-      Ret = ((PW32THREAD)Thread->Tcb.Win32Thread)->hDesktop;
-      ObDereferenceObject(Thread);
-      RETURN(Ret);
-   }
-
-   /* get the desktop handle and the desktop of the thread */
-   if(!(hThreadDesktop = ((PW32THREAD)Thread->Tcb.Win32Thread)->hDesktop) ||
-         !(DesktopObject = ((PW32THREAD)Thread->Tcb.Win32Thread)->Desktop))
-   {
-      ObDereferenceObject(Thread);
-      DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
-      RETURN(NULL);
-   }
-
-   /* we could just use DesktopObject instead of looking up the handle, but latter
-      may be a bit safer (e.g. when the desktop is being destroyed */
-   /* switch into the context of the thread we're trying to get the desktop from,
-      so we can use the handle */
-   KeAttachProcess(&Thread->ThreadsProcess->Pcb);
-   Status = ObReferenceObjectByHandle(hThreadDesktop,
-                                      GENERIC_ALL,
-                                      ExDesktopObjectType,
-                                      UserMode,
-                                      (PVOID*)&DesktopObject,
-                                      &HandleInformation);
-   KeDetachProcess();
-
-   /* the handle couldn't be found, there's nothing to get... */
-   if(!NT_SUCCESS(Status))
-   {
-      ObDereferenceObject(Thread);
-      RETURN(NULL);
-   }
-
-   /* lookup our handle table if we can find a handle to the desktop object,
-      if not, create one */
-   Ret = IntGetDesktopObjectHandle(DesktopObject);
-
-   /* all done, we got a valid handle to the desktop */
-   ObDereferenceObject(DesktopObject);
-   ObDereferenceObject(Thread);
-   RETURN(Ret);
-   
-CLEANUP:
-   DPRINT("Leave NtUserGetThreadDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/*
- * NtUserSetThreadDesktop
- *
- * Status
- *    @implemented
- */
-
-BOOL STDCALL
-NtUserSetThreadDesktop(HDESK hDesktop)
-{
-   PW32THREAD W32Thread;
-   PDESKTOP_OBJECT DesktopObject;
-   NTSTATUS Status;
-   DECLARE_RETURN(BOOL);
-   
-   UserEnterExclusive();
-   DPRINT("Enter NtUserSetThreadDesktop\n");
-   
-   /* Validate the new desktop. */
-   Status = IntValidateDesktopHandle(
-               hDesktop,
-               UserMode,
-               0,
-               &DesktopObject);
-
-   if (!NT_SUCCESS(Status))
-   {
-      DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      RETURN(FALSE);
-   }
-
-   W32Thread = PsGetWin32Thread();
-
-   /* FIXME: Should check here to see if the thread has any windows. */
-
-   if (W32Thread->Desktop != NULL)
-   {
-      ObDereferenceObject(W32Thread->Desktop);
-   }
-
-   W32Thread->Desktop = DesktopObject;
-   W32Thread->hDesktop = hDesktop;
-
-   RETURN(TRUE);
-   
-CLEANUP:
-   DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/* EOF */