- Update KTHREAD and KUSER_SHARED_DATA to latest versions. This should make 2K3 drive...
[reactos.git] / reactos / subsys / win32k / ntuser / desktop.c
index 5574d9c..9c89b69 100644 (file)
  */
 
 /* INCLUDES ******************************************************************/
+
 #include <w32k.h>
 
-#if 0
-/* not yet defined in w32api... */
-NTSTATUS STDCALL
-ObFindHandleForObject(IN PEPROCESS Process,
-                      IN PVOID Object,
-                      IN POBJECT_TYPE ObjectType,
-                      IN POBJECT_HANDLE_INFORMATION HandleInformation,
-                      OUT PHANDLE Handle);
-#else
-#define ObFindHandleForObject(Process, Object, ObjectType, HandleInformation, Handle) \
-  (STATUS_UNSUCCESSFUL)
-#endif
+#define NDEBUG
+#include <debug.h>
 
 /* GLOBALS *******************************************************************/
 
 /* Currently active desktop */
 PDESKTOP_OBJECT InputDesktop = NULL;
-HDESK InputDesktopHandle = 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)
 {
-  return STATUS_SUCCESS;
+   /* Set Desktop Object Attributes */
+   ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP_OBJECT);
+   ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
+
+   return STATUS_SUCCESS;
 }
 
 NTSTATUS FASTCALL
 CleanupDesktopImpl(VOID)
 {
-  return STATUS_SUCCESS;
+   return STATUS_SUCCESS;
 }
 
 /* OBJECT CALLBACKS **********************************************************/
 
 NTSTATUS STDCALL
 IntDesktopObjectCreate(PVOID ObjectBody,
-                      PVOID Parent,
-                      PWSTR RemainingPath,
-                      struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+                       PVOID Parent,
+                       PWSTR RemainingPath,
+                       struct _OBJECT_ATTRIBUTES* ObjectAttributes)
 {
-  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
-  UNICODE_STRING UnicodeString;
-
-  if (RemainingPath == NULL)
-       {
-               return STATUS_SUCCESS;
-       }
+   PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
+   UNICODE_STRING UnicodeString;
 
-  if (wcschr((RemainingPath + 1), '\\') != NULL)
-       {
-               return STATUS_UNSUCCESSFUL;
-       }
+   DPRINT("Creating desktop (0x%X)  Name (%S)\n", Desktop, RemainingPath);
+   if (RemainingPath == NULL)
+   {
+      return STATUS_SUCCESS;
+   }
 
-  RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
+   if (wcschr((RemainingPath + 1), '\\') != NULL)
+   {
+      return STATUS_UNSUCCESSFUL;
+   }
 
-  DPRINT("Creating desktop (0x%X)  Name (%wZ)\n", Desktop, &UnicodeString);
+   RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
 
-  KeInitializeSpinLock(&Desktop->Lock);
-  InitializeListHead(&Desktop->ShellHookWindows);
+   InitializeListHead(&Desktop->ShellHookWindows);
 
-  Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
+   Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
 
-  /* Put the desktop on the window station's list of associcated desktops */
-  ExInterlockedInsertTailList(
-    &Desktop->WindowStation->DesktopListHead,
-    &Desktop->ListEntry,
-    &Desktop->WindowStation->Lock);
+   /* 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);
+   return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
 }
 
 VOID STDCALL
 IntDesktopObjectDelete(PVOID DeletedObject)
 {
-  PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
-  KIRQL OldIrql;
+   PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject;
 
-  DPRINT("Deleting desktop (0x%X)\n", Desktop);
+   DPRINT("Deleting desktop (0x%X)\n", Desktop);
 
-  /* Remove the desktop from the window station's list of associcated desktops */
-  KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql);
-  RemoveEntryList(&Desktop->ListEntry);
-  KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql);
+   /* Remove the desktop from the window station's list of associcated desktops */
+   RemoveEntryList(&Desktop->ListEntry);
 
-  RtlFreeUnicodeString(&Desktop->Name);
+   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'\\')
+   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)
       {
-        wl = (ULONG_PTR)c - (ULONG_PTR)DesktopPath->Buffer;
-        break;
+         if(*c == L'\\')
+         {
+            wl = (ULONG_PTR)c - (ULONG_PTR)DesktopPath->Buffer;
+            break;
+         }
+         l -= sizeof(WCHAR);
+         c++;
       }
-      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,
-                                UserMode,
-                                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,
+
+      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,
-                                 UserMode,
-                                 0,
+                                 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,
-                                 (HANDLE*)hDesktop);
+                                 NULL);
 
-    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;
+      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;
 }
 
 /*
@@ -316,12 +342,12 @@ IntValidateDesktopHandle(
    NTSTATUS Status;
 
    Status = ObReferenceObjectByHandle(
-      Desktop,
-      DesiredAccess,
-      ExDesktopObjectType,
-      AccessMode,
-      (PVOID*)Object,
-      NULL);
+               Desktop,
+               DesiredAccess,
+               ExDesktopObjectType,
+               AccessMode,
+               (PVOID*)Object,
+               NULL);
 
    if (!NT_SUCCESS(Status))
       SetLastNtError(Status);
@@ -332,37 +358,37 @@ IntValidateDesktopHandle(
 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(dc->w.hBitmap);
-    }
-    DC_UnlockDc(ScreenDeviceContext);
-  }
-  
-  if(Rect)
-  {
-    *Rect = *Ret;
-  }
+   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;
+   return InputDesktop;
 }
 
 /*
@@ -371,35 +397,35 @@ IntGetActiveDesktop(VOID)
 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;
+   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
@@ -428,8 +454,8 @@ IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
    {
       if(NewQueue->Desktop != NULL)
       {
-        DPRINT("Message Queue already attached to another desktop!\n");
-        return;
+         DPRINT("Message Queue already attached to another desktop!\n");
+         return;
       }
       IntReferenceMessageQueue(NewQueue);
       InterlockedExchange((LONG*)&NewQueue->Desktop, (LONG)pdo);
@@ -450,18 +476,32 @@ HWND FASTCALL IntGetDesktopWindow(VOID)
       DPRINT("No active desktop\n");
       return NULL;
    }
-  return pdo->DesktopWindow;
+   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)
-    {
+   PDESKTOP_OBJECT pdo = PsGetWin32Thread()->Desktop;
+   if (NULL == pdo)
+   {
       DPRINT1("Thread doesn't have a desktop\n");
       return NULL;
-    }
-  return pdo->DesktopWindow;
+   }
+   return pdo->DesktopWindow;
 }
 
 BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
@@ -478,7 +518,7 @@ BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
       QueryTable[0].EntryContext = &g_PaintDesktopVersion;
 
       /* Query the "PaintDesktopVersion" flag in the "Control Panel\Desktop" key */
-      Status = RtlQueryRegistryValues(RTL_REGISTRY_USER, 
+      Status = RtlQueryRegistryValues(RTL_REGISTRY_USER,
                                       L"Control Panel\\Desktop",
                                       QueryTable, NULL, NULL);
       if (!NT_SUCCESS(Status))
@@ -488,7 +528,7 @@ BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
          g_PaintDesktopVersion = FALSE;
          return FALSE;
       }
-    
+
       DPRINT("PaintDesktopVersion = %d\n", g_PaintDesktopVersion);
 
       return TRUE;
@@ -503,115 +543,129 @@ BOOL FASTCALL IntDesktopUpdatePerUserSettings(BOOL bEnable)
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 NTSTATUS FASTCALL
-IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
+co_IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
 {
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+   CSR_API_MESSAGE Request;
 
-  Request.Type = CSRSS_SHOW_DESKTOP;
-  Request.Data.ShowDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
-  Request.Data.ShowDesktopRequest.Width = Width;
-  Request.Data.ShowDesktopRequest.Height = Height;
+   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 CsrNotify(&Request, &Reply);
+   return co_CsrNotify(&Request);
 }
 
 NTSTATUS FASTCALL
 IntHideDesktop(PDESKTOP_OBJECT Desktop)
 {
 #if 0
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
+   CSRSS_API_REQUEST Request;
+   CSRSS_API_REPLY Reply;
 
-  Request.Type = CSRSS_HIDE_DESKTOP;
-  Request.Data.HideDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
+   Request.Type = CSRSS_HIDE_DESKTOP;
+   Request.Data.HideDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
 
-  return NotifyCsrss(&Request, &Reply);
+   return NotifyCsrss(&Request, &Reply);
 #else
-  PWINDOW_OBJECT DesktopWindow;
 
-  DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
-  if (! DesktopWindow)
-    {
+   PWINDOW_OBJECT DesktopWindow;
+
+   DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
+   if (! DesktopWindow)
+   {
       return ERROR_INVALID_WINDOW_HANDLE;
-    }
-  DesktopWindow->Style &= ~WS_VISIBLE;
+   }
+   DesktopWindow->Style &= ~WS_VISIBLE;
 
-  return STATUS_SUCCESS;
+   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 IntShellHookNotify(WPARAM Message, LPARAM lParam)
+VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
 {
-  PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
-  PLIST_ENTRY Entry, Entry2;
-  PSHELL_HOOK_WINDOW Current;
-  KIRQL OldLevel;
+   PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
+   HWND* HwndList;
 
-  static UINT MsgType = 0;
+   static UINT MsgType = 0;
 
-  if (!MsgType) {
+   if (!MsgType)
+   {
 
-    /* Too bad, this doesn't work.*/
+      /* Too bad, this doesn't work.*/
 #if 0
-    UNICODE_STRING Str;
-    RtlInitUnicodeString(&Str, L"SHELLHOOK");
-    MsgType = NtUserRegisterWindowMessage(&Str);
+      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;
-  }
-
-  /* We have to do some tricks because the list could change
-   * between calls, and we can't keep the lock during the call
-   */
-
-  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-  Entry = Desktop->ShellHookWindows.Flink;
-  while (Entry != &Desktop->ShellHookWindows) {
-    Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
-    KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-
-    DPRINT("Sending notify\n");
-    IntPostOrSendMessage(Current->hWnd,
-                         MsgType,
-                         Message,
-                         lParam);
-
-    /* Loop again to find the window we were sending to. If it doesn't
-     * exist anymore, we just stop. This could leave an infinite loop
-     * if a window is removed and readded to the list. That's quite
-     * unlikely though.
-     */
-
-    KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-    Entry2 = Desktop->ShellHookWindows.Flink;
-    while (Entry2 != Entry &&
-           Entry2 != &Desktop->ShellHookWindows) {
-      Entry2 = Entry2->Flink;
-    }
-
-    if (Entry2 == Entry)
-      Entry = Entry->Flink;
-    else
-      break;
-  }
-  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+
+      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
@@ -622,33 +676,28 @@ VOID IntShellHookNotify(WPARAM Message, LPARAM lParam)
  */
 BOOL IntRegisterShellHookWindow(HWND hWnd)
 {
-  PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
-  PSHELL_HOOK_WINDOW Entry;
-  KIRQL OldLevel;
+   PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+   PSHELL_HOOK_WINDOW Entry;
 
-  DPRINT("IntRegisterShellHookWindow\n");
+   DPRINT("IntRegisterShellHookWindow\n");
 
-  /* First deregister the window, so we can be sure it's never twice in the
-   * list.
-   */
-  IntDeRegisterShellHookWindow(hWnd);
+   /* First deregister the window, so we can be sure it's never twice in the
+    * list.
+    */
+   IntDeRegisterShellHookWindow(hWnd);
 
-  Entry = ExAllocatePoolWithTag(NonPagedPool,
-                                sizeof(SHELL_HOOK_WINDOW),
-                                TAG_WINSTA);
-  /* We have to walk this structure with while holding a spinlock, so we
-   * need NonPagedPool */
+   Entry = ExAllocatePoolWithTag(PagedPool,
+                                 sizeof(SHELL_HOOK_WINDOW),
+                                 TAG_WINSTA);
 
-  if (!Entry)
-    return FALSE;
+   if (!Entry)
+      return FALSE;
 
-  Entry->hWnd = hWnd;
+   Entry->hWnd = hWnd;
 
-  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-  InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
-  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+   InsertTailList(&Desktop->ShellHookWindows, &Entry->ListEntry);
 
-  return TRUE;
+   return TRUE;
 }
 
 /*
@@ -658,30 +707,28 @@ BOOL IntRegisterShellHookWindow(HWND hWnd)
  */
 BOOL IntDeRegisterShellHookWindow(HWND hWnd)
 {
-  PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
-  PLIST_ENTRY Entry;
-  PSHELL_HOOK_WINDOW Current;
-  KIRQL OldLevel;
-
-  KeAcquireSpinLock(&Desktop->Lock, &OldLevel);
-
-  Entry = Desktop->ShellHookWindows.Flink;
-  while (Entry != &Desktop->ShellHookWindows) {
-    Current = CONTAINING_RECORD(Entry, SHELL_HOOK_WINDOW, ListEntry);
-    if (Current->hWnd == hWnd) {
-      RemoveEntryList(Entry);
-      KeReleaseSpinLock(&Desktop->Lock, OldLevel);
-      ExFreePool(Entry);
-      return TRUE;
-    }
-    Entry = Entry->Flink;
-  }
+   PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+   PSHELL_HOOK_WINDOW Current;
 
-  KeReleaseSpinLock(&Desktop->Lock, OldLevel);
+   LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
+   {
+      if (Current->hWnd == hWnd)
+      {
+         RemoveEntryList(&Current->ListEntry);
+         ExFreePool(Current);
+         return TRUE;
+      }
+   }
 
-  return FALSE;
+   return FALSE;
 }
 
+
+
+
+/* SYSCALLS *******************************************************************/
+
+
 /*
  * NtUserCreateDesktop
  *
@@ -722,151 +769,154 @@ NtUserCreateDesktop(
    LPSECURITY_ATTRIBUTES lpSecurity,
    HWINSTA hWindowStation)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  PWINSTATION_OBJECT WinStaObject;
-  PDESKTOP_OBJECT DesktopObject;
-  UNICODE_STRING DesktopName;
-  NTSTATUS Status;
-  HDESK Desktop;
-  CSRSS_API_REQUEST Request;
-  CSRSS_API_REPLY Reply;
-  
-  DPRINT("CreateDesktop: %wZ\n", lpszDesktopName);
-
-  Status = IntValidateWindowStationHandle(
-    hWindowStation,
-    KernelMode,
-    0, /* FIXME - WINSTA_CREATEDESKTOP */
-    &WinStaObject);
-
-  if (! NT_SUCCESS(Status))
-    {
+   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);
+              hWindowStation, lpszDesktopName);
       SetLastNtError(Status);
-      return NULL;
-    }
-  
-  if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
-          lpszDesktopName))
-    {
+      RETURN( NULL);
+   }
+
+   if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
+                                     lpszDesktopName))
+   {
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
       ObDereferenceObject(WinStaObject);
-      return NULL;
-    }
-
-  ObDereferenceObject(WinStaObject);
-
-  /*
-   * Try to open already existing desktop
-   */
-
-  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,
-    UserMode,
-    dwDesiredAccess,
-    NULL,
-    (HANDLE*)&Desktop);
-
-  if (NT_SUCCESS(Status))
-    {
+      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))
-    {
+      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))
-    {
+      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 = CSRSS_CREATE_DESKTOP;
-  Status = CsrInsertObject((PVOID)DesktopObject,
-                           NULL,
-                           GENERIC_ALL,
-                           0,
-                           NULL,
-                           (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 = CsrNotify(&Request, &Reply);
-  if (! NT_SUCCESS(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( NULL);
+   }
+
+   RETURN( Desktop);
 
-  return Desktop;
+CLEANUP:
+   DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -902,6 +952,10 @@ NtUserOpenDesktop(
    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
@@ -909,27 +963,27 @@ NtUserOpenDesktop(
     */
 
    Status = IntValidateWindowStationHandle(
-      PsGetCurrentProcess()->Win32WindowStation,
-      KernelMode,
-      0,
-      &WinStaObject);
+               PsGetCurrentProcess()->Win32WindowStation,
+               KernelMode,
+               0,
+               &WinStaObject);
 
    if (!NT_SUCCESS(Status))
    {
       DPRINT1("Failed validation of window station handle (0x%X)\n",
               PsGetCurrentProcess()->Win32WindowStation);
       SetLastNtError(Status);
-      return 0;
+      RETURN( 0);
    }
 
    if (!IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
-       lpszDesktopName))
+                                    lpszDesktopName))
    {
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
       ObDereferenceObject(WinStaObject);
-      return 0;
+      RETURN( 0);
    }
+
    ObDereferenceObject(WinStaObject);
 
    DPRINT1("Trying to open desktop (%wZ)\n", &DesktopName);
@@ -943,25 +997,30 @@ NtUserOpenDesktop(
       NULL);
 
    Status = ObOpenObjectByName(
-      &ObjectAttributes,
-      ExDesktopObjectType,
-      NULL,
-      UserMode,
-      dwDesiredAccess,
-      NULL,
-      (HANDLE*)&Desktop);
+               &ObjectAttributes,
+               ExDesktopObjectType,
+               NULL,
+               UserMode,
+               dwDesiredAccess,
+               NULL,
+               (HANDLE*)&Desktop);
 
    if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
       ExFreePool(DesktopName.Buffer);
-      return 0;
+      RETURN( 0);
    }
 
    DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
    ExFreePool(DesktopName.Buffer);
 
-   return Desktop;
+   RETURN( Desktop);
+
+CLEANUP:
+   DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /*
@@ -978,7 +1037,7 @@ NtUserOpenDesktop(
  *
  *    dwDesiredAccess
  *       Requested type of access.
- * 
+ *
  * Return Value
  *    Handle to the input desktop or zero on failure.
  *
@@ -995,44 +1054,53 @@ NtUserOpenInputDesktop(
    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);
+               InputDesktopHandle,
+               UserMode,
+               0,
+               &Object);
 
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
-      return (HDESK)0;
+      RETURN((HDESK)0);
    }
 
    /* Create a new handle to the object */
 
    Status = ObOpenObjectByPointer(
-      Object,
-      0,
-      NULL,
-      dwDesiredAccess,
-      ExDesktopObjectType,
-      UserMode,
-      (HANDLE*)&Desktop);
+               Object,
+               0,
+               NULL,
+               dwDesiredAccess,
+               ExDesktopObjectType,
+               UserMode,
+               (HANDLE*)&Desktop);
 
    ObDereferenceObject(Object);
 
    if (NT_SUCCESS(Status))
    {
       DPRINT("Successfully opened input desktop\n");
-      return (HDESK)Desktop;
+      RETURN((HDESK)Desktop);
    }
 
    SetLastNtError(Status);
-   return (HDESK)0;
+   RETURN((HDESK)0);
+   
+CLEANUP:
+   DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 /*
@@ -1062,19 +1130,23 @@ 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);
+               hDesktop,
+               UserMode,
+               0,
+               &Object);
 
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    ObDereferenceObject(Object);
@@ -1085,35 +1157,19 @@ NtUserCloseDesktop(HDESK hDesktop)
    if (!NT_SUCCESS(Status))
    {
       SetLastNtError(Status);
-      return FALSE;
+      RETURN(FALSE);
    }
 
-   return TRUE;
-}
+   RETURN(TRUE);
 
+CLEANUP:
+   DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;     
+}
 
-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;
-}
 
 /*
  * NtUserPaintDesktop
@@ -1123,8 +1179,8 @@ static int GetSystemVersionString(LPWSTR buffer)
  * function is provided primarily for shell desktops.
  *
  * Parameters
- *    hDC 
- *       Handle to the device context. 
+ *    hDC
+ *       Handle to the device context.
  *
  * Status
  *    @implemented
@@ -1133,102 +1189,120 @@ static int GetSystemVersionString(LPWSTR buffer)
 BOOL STDCALL
 NtUserPaintDesktop(HDC hDC)
 {
-  RECT Rect;
-  HBRUSH DesktopBrush, PreviousBrush;
-  HWND hWndDesktop;
-  BOOL doPatBlt = TRUE;
-  int len;
+   RECT Rect;
+   HBRUSH DesktopBrush, PreviousBrush;
+   HWND hWndDesktop;
+   BOOL doPatBlt = TRUE;
+   PWINDOW_OBJECT WndDesktop;
+   int len;
+   DECLARE_RETURN(BOOL);
+   
+   UserEnterExclusive();
+   DPRINT("Enter NtUserPaintDesktop\n");
 
-  PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+   PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
 
-  IntGdiGetClipBox(hDC, &Rect);
+   IntGdiGetClipBox(hDC, &Rect);
 
-  hWndDesktop = IntGetDesktopWindow();
-  DesktopBrush = (HBRUSH)NtUserGetClassLong(hWndDesktop, GCL_HBRBACKGROUND, FALSE);
+   hWndDesktop = IntGetDesktopWindow();
+   if (!(WndDesktop = UserGetWindowObject(hWndDesktop)))
+      RETURN(FALSE);
 
-  /*
-   * Paint desktop background
-   */
+   DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
 
-  if(WinSta->hbmWallpaper != NULL)
-  {
-    PWINDOW_OBJECT DeskWin;
 
-    if((DeskWin = IntGetWindowObject(hWndDesktop)))
-    {
-      SIZE sz;
-      int x, y;
-      HDC hWallpaperDC;
-      
-      sz.cx = DeskWin->WindowRect.right - DeskWin->WindowRect.left;
-      sz.cy = DeskWin->WindowRect.bottom - DeskWin->WindowRect.top;
-      IntReleaseWindowObject(DeskWin);
+   /*
+    * Paint desktop background
+    */
 
-      x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
-      y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
-      
-      hWallpaperDC = NtGdiCreateCompatableDC(hDC);
-      if(hWallpaperDC != NULL)
+   if(WinSta->hbmWallpaper != NULL)
+   {
+      PWINDOW_OBJECT DeskWin;
+
+      if((DeskWin = UserGetWindowObject(hWndDesktop)))
+      {
+         SIZE sz;
+         int x, y;
+         HDC hWallpaperDC;
+
+         sz.cx = DeskWin->WindowRect.right - DeskWin->WindowRect.left;
+         sz.cy = DeskWin->WindowRect.bottom - DeskWin->WindowRect.top;
+
+
+         x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
+         y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
+
+         hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
+         if(hWallpaperDC != NULL)
+         {
+            HBITMAP hOldBitmap;
+
+            if(x > 0 || y > 0)
+            {
+               /* FIXME - clip out the bitmap */
+               PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
+               NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
+               NtGdiSelectObject(hDC, PreviousBrush);
+            }
+            else
+               doPatBlt = FALSE;
+
+            hOldBitmap = NtGdiSelectObject(hWallpaperDC, WinSta->hbmWallpaper);
+            NtGdiBitBlt(hDC, x, y, WinSta->cxWallpaper, WinSta->cyWallpaper, hWallpaperDC, 0, 0, SRCCOPY);
+            NtGdiSelectObject(hWallpaperDC, hOldBitmap);
+
+            NtGdiDeleteDC(hWallpaperDC);
+         }
+      }
+   }
+
+   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)
       {
-        HBITMAP hOldBitmap;
-
-        if(x > 0 || y > 0)
-        {
-          /* FIXME - clip out the bitmap */
-          PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
-          NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
-          NtGdiSelectObject(hDC, PreviousBrush);
-        }
-               else
-                 doPatBlt = FALSE;
-
-        hOldBitmap = NtGdiSelectObject(hWallpaperDC, WinSta->hbmWallpaper);
-        NtGdiBitBlt(hDC, x, y, WinSta->cxWallpaper, WinSta->cyWallpaper, hWallpaperDC, 0, 0, SRCCOPY);
-        NtGdiSelectObject(hWallpaperDC, hOldBitmap);
-        
-        NtGdiDeleteDC(hWallpaperDC);
+         if (!UserSystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0))
+         {
+            rect.right = UserGetSystemMetrics(SM_CXSCREEN);
+            rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
+         }
+
+         COLORREF color_old = NtGdiSetTextColor(hDC, RGB(255,255,255));
+         UINT align_old = NtGdiSetTextAlign(hDC, TA_RIGHT);
+         int 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);
       }
-    }
-  }
-
-  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 (!NtUserSystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0)) {
-               rect.right = NtUserGetSystemMetrics(SM_CXSCREEN);
-               rect.bottom = NtUserGetSystemMetrics(SM_CYSCREEN);
-         }
-
-         COLORREF color_old = NtGdiSetTextColor(hDC, RGB(255,255,255));
-         UINT align_old = NtGdiSetTextAlign(hDC, TA_RIGHT);
-         int 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;
+   }
+
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserPaintDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 
@@ -1253,33 +1327,37 @@ 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);
+               hDesktop,
+               UserMode,
+               0,
+               &DesktopObject);
 
-   if (!NT_SUCCESS(Status)) 
+   if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      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())
+         LogonProcess != NULL && LogonProcess != PsGetWin32Process())
    {
       ObDereferenceObject(DesktopObject);
       DPRINT1("Switching desktop 0x%x denied because the work station is locked!\n", hDesktop);
-      return FALSE;
+      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 */
@@ -1295,7 +1373,12 @@ NtUserSwitchDesktop(HDESK hDesktop)
 
    ObDereferenceObject(DesktopObject);
 
-   return TRUE;
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserSwitchDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;   
 }
 
 /*
@@ -1322,71 +1405,80 @@ NtUserResolveDesktopForWOW(DWORD Unknown0)
 HDESK STDCALL
 NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
 {
-  NTSTATUS Status;
-  PETHREAD Thread;
-  PDESKTOP_OBJECT DesktopObject;
-  HDESK Ret, hThreadDesktop;
-  OBJECT_HANDLE_INFORMATION HandleInformation;
-  
-  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 = Thread->Tcb.Win32Thread->hDesktop;
-    ObDereferenceObject(Thread);
-    return Ret;
-  }
-  
-  /* get the desktop handle and the desktop of the thread */
-  if(!(hThreadDesktop = Thread->Tcb.Win32Thread->hDesktop) ||
-     !(DesktopObject = 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);
-  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;
+   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;
 }
 
 /*
@@ -1402,18 +1494,22 @@ 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);
+               hDesktop,
+               UserMode,
+               0,
+               &DesktopObject);
 
-   if (!NT_SUCCESS(Status)) 
+   if (!NT_SUCCESS(Status))
    {
       DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
-      return FALSE;
+      RETURN(FALSE);
    }
 
    W32Thread = PsGetWin32Thread();
@@ -1428,7 +1524,12 @@ NtUserSetThreadDesktop(HDESK hDesktop)
    W32Thread->Desktop = DesktopObject;
    W32Thread->hDesktop = hDesktop;
 
-   return TRUE;
+   RETURN(TRUE);
+   
+CLEANUP:
+   DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
+   UserLeave();
+   END_CLEANUP;
 }
 
 /* EOF */