-
/*
- * 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
+ * FILE: subsystems/win32/win32k/ntuser/desktop.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
static
VOID
IntFreeDesktopHeap(
- IN OUT PDESKTOP_OBJECT Desktop
+ IN OUT PDESKTOP Desktop
);
/* GLOBALS *******************************************************************/
/* Currently active desktop */
-PDESKTOP_OBJECT InputDesktop = NULL;
+PDESKTOP InputDesktop = NULL;
HDESK InputDesktopHandle = NULL;
HDC ScreenDeviceContext = NULL;
BOOL g_PaintDesktopVersion = FALSE;
/* OBJECT CALLBACKS **********************************************************/
NTSTATUS
-NTAPI
+APIENTRY
IntDesktopObjectParse(IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
OUT PVOID *Object)
{
NTSTATUS Status;
- PDESKTOP_OBJECT Desktop;
+ PDESKTOP Desktop;
OBJECT_ATTRIBUTES ObjectAttributes;
PLIST_ENTRY NextEntry, ListHead;
PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
while (NextEntry != ListHead)
{
/* Get the current desktop */
- Desktop = CONTAINING_RECORD(NextEntry, DESKTOP_OBJECT, ListEntry);
+ Desktop = CONTAINING_RECORD(NextEntry, DESKTOP, ListEntry);
/* Get its name */
DesktopName = GET_DESKTOP_NAME(Desktop);
&ObjectAttributes,
KernelMode,
NULL,
- sizeof(DESKTOP_OBJECT),
+ sizeof(DESKTOP),
0,
0,
(PVOID)&Desktop);
if (!NT_SUCCESS(Status)) return Status;
/* Initialize shell hook window list and set the parent */
+ RtlZeroMemory(Desktop, sizeof(DESKTOP));
InitializeListHead(&Desktop->ShellHookWindows);
- Desktop->WindowStation = (PWINSTATION_OBJECT)ParseObject;
+ Desktop->rpwinstaParent = (PWINSTATION_OBJECT)ParseObject;
/* Put the desktop on the window station's list of associated desktops */
- InsertTailList(&Desktop->WindowStation->DesktopListHead,
+ InsertTailList(&Desktop->rpwinstaParent->DesktopListHead,
&Desktop->ListEntry);
/* Set the desktop object and return success */
return STATUS_SUCCESS;
}
-VOID STDCALL
+VOID APIENTRY
IntDesktopObjectDelete(PWIN32_DELETEMETHOD_PARAMETERS Parameters)
{
- PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)Parameters->Object;
+ PDESKTOP Desktop = (PDESKTOP)Parameters->Object;
DPRINT("Deleting desktop (0x%X)\n", Desktop);
IntFreeDesktopHeap(Desktop);
}
+NTSTATUS NTAPI
+IntDesktopOkToClose(PWIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters)
+{
+ PTHREADINFO pti;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ if( pti == NULL)
+ {
+ /* This happens when we leak desktop handles */
+ return TRUE;
+ }
+
+ /* Do not allow the current desktop or the initial desktop to be closed */
+ if( Parameters->Handle == pti->ppi->hdeskStartup ||
+ Parameters->Handle == pti->hdesk)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/* PRIVATE FUNCTIONS **********************************************************/
+INIT_FUNCTION
NTSTATUS
-FASTCALL
+NTAPI
InitDesktopImpl(VOID)
{
/* Set Desktop Object Attributes */
- ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP_OBJECT);
+ ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP);
ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
return STATUS_SUCCESS;
}
NULL,
(HANDLE*)hWinSta);
- RtlFreeUnicodeString(&FullName);
+ ExFreePoolWithTag(FullName.Buffer, TAG_STRING);
if(!NT_SUCCESS(Status))
{
NULL,
(HANDLE*)hDesktop);
- RtlFreeUnicodeString(&FullName);
+ ExFreePoolWithTag(FullName.Buffer, TAG_STRING);
if(!NT_SUCCESS(Status))
{
HDESK Desktop,
KPROCESSOR_MODE AccessMode,
ACCESS_MASK DesiredAccess,
- PDESKTOP_OBJECT *Object)
+ PDESKTOP *Object)
{
NTSTATUS 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
+PDESKTOP FASTCALL
IntGetActiveDesktop(VOID)
{
return InputDesktop;
* returns or creates a handle to the desktop object
*/
HDESK FASTCALL
-IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject)
+IntGetDesktopObjectHandle(PDESKTOP DesktopObject)
{
NTSTATUS Status;
HDESK Ret;
PUSER_MESSAGE_QUEUE FASTCALL
IntGetFocusMessageQueue(VOID)
{
- PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+ PDESKTOP pdo = IntGetActiveDesktop();
if (!pdo)
{
DPRINT("No active desktop\n");
IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
{
PUSER_MESSAGE_QUEUE Old;
- PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+ PDESKTOP pdo = IntGetActiveDesktop();
if (!pdo)
{
DPRINT("No active desktop\n");
HWND FASTCALL IntGetDesktopWindow(VOID)
{
- PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+ PDESKTOP pdo = IntGetActiveDesktop();
if (!pdo)
{
DPRINT("No active desktop\n");
return pdo->DesktopWindow;
}
-PWINDOW_OBJECT FASTCALL UserGetDesktopWindow(VOID)
+PWND FASTCALL UserGetDesktopWindow(VOID)
{
- PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
+ PDESKTOP pdo = IntGetActiveDesktop();
if (!pdo)
{
return UserGetWindowObject(pdo->DesktopWindow);
}
+HWND FASTCALL IntGetMessageWindow(VOID)
+{
+ PDESKTOP pdo = IntGetActiveDesktop();
+
+ if (!pdo)
+ {
+ DPRINT("No active desktop\n");
+ return NULL;
+ }
+ return pdo->spwndMessage->head.h;
+}
HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
{
- PDESKTOP_OBJECT pdo = PsGetCurrentThreadWin32Thread()->Desktop;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+ PDESKTOP pdo = pti->rpdesk;
if (NULL == pdo)
{
DPRINT1("Thread doesn't have a desktop\n");
QueryTable, NULL, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlQueryRegistryValues failed for PaintDesktopVersion (%x)\n",
+ DPRINT("RtlQueryRegistryValues failed for PaintDesktopVersion (%x)\n",
Status);
g_PaintDesktopVersion = FALSE;
return FALSE;
/* PUBLIC FUNCTIONS ***********************************************************/
+HDC FASTCALL
+UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd)
+{
+ PWND DesktopObject = 0;
+ HDC DesktopHDC = 0;
+
+ if (DcType == DC_TYPE_DIRECT)
+ {
+ DesktopObject = UserGetDesktopWindow();
+ DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
+ }
+ else
+ {
+ HDEV hDev;
+ hDev = (HDEV)pPrimarySurface;
+ DesktopHDC = IntGdiCreateDisplayDC(hDev, DcType, EmptyDC);
+ }
+
+ return DesktopHDC;
+}
+
VOID APIENTRY
UserRedrawDesktop()
{
- PWINDOW_OBJECT Window = NULL;
-
- UserEnterExclusive();
+ PWND Window = NULL;
+ HRGN hRgn;
Window = UserGetDesktopWindow();
+ hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
IntInvalidateWindows( Window,
- Window->UpdateRegion,
+ hRgn,
RDW_FRAME |
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
- UserLeave();
+
+ GreDeleteObject(hRgn);
}
NTSTATUS FASTCALL
-co_IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height)
+co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height)
{
CSR_API_MESSAGE Request;
}
NTSTATUS FASTCALL
-IntHideDesktop(PDESKTOP_OBJECT Desktop)
+IntHideDesktop(PDESKTOP Desktop)
{
#if 0
CSRSS_API_REQUEST Request;
return NotifyCsrss(&Request, &Reply);
#else
- PWINDOW_OBJECT DesktopWindow;
- PWINDOW DesktopWnd;
+ PWND DesktopWnd;
- DesktopWindow = IntGetWindowObject(Desktop->DesktopWindow);
- if (! DesktopWindow)
+ DesktopWnd = IntGetWindowObject(Desktop->DesktopWindow);
+ if (! DesktopWnd)
{
return ERROR_INVALID_WINDOW_HANDLE;
}
- DesktopWnd = DesktopWindow->Wnd;
- DesktopWnd->Style &= ~WS_VISIBLE;
+ DesktopWnd->style &= ~WS_VISIBLE;
return STATUS_SUCCESS;
#endif
static
HWND* FASTCALL
-UserBuildShellHookHwndList(PDESKTOP_OBJECT Desktop)
+UserBuildShellHookHwndList(PDESKTOP Desktop)
{
ULONG entries=0;
PSHELL_HOOK_WINDOW Current;
if (!entries) return NULL;
- list = ExAllocatePool(PagedPool, sizeof(HWND) * (entries + 1)); /* alloc one extra for nullterm */
+ list = ExAllocatePoolWithTag(PagedPool, sizeof(HWND) * (entries + 1), USERTAG_WINDOWLIST); /* alloc one extra for nullterm */
if (list)
{
HWND* cursor = list;
*/
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
{
- PDESKTOP_OBJECT Desktop = IntGetActiveDesktop();
+ PDESKTOP Desktop = IntGetActiveDesktop();
HWND* HwndList;
- static UINT MsgType = 0;
-
- if (!MsgType)
+ if (!gpsi->uiShellMsg)
{
/* Too bad, this doesn't work.*/
#if 0
UNICODE_STRING Str;
RtlInitUnicodeString(&Str, L"SHELLHOOK");
- MsgType = UserRegisterWindowMessage(&Str);
+ gpsi->uiShellMsg = UserRegisterWindowMessage(&Str);
#endif
- MsgType = IntAddAtom(L"SHELLHOOK");
+ gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK");
- DPRINT("MsgType = %x\n", MsgType);
- if (!MsgType)
- DPRINT1("LastError: %x\n", GetLastNtError());
+ DPRINT("MsgType = %x\n", gpsi->uiShellMsg);
+ if (!gpsi->uiShellMsg)
+ DPRINT1("LastError: %x\n", EngGetLastError());
}
if (!Desktop)
{
DPRINT("Sending notify\n");
co_IntPostOrSendMessage(*cursor,
- MsgType,
+ gpsi->uiShellMsg,
Message,
lParam);
}
*/
BOOL IntRegisterShellHookWindow(HWND hWnd)
{
- PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+ PDESKTOP Desktop = pti->rpdesk;
PSHELL_HOOK_WINDOW Entry;
DPRINT("IntRegisterShellHookWindow\n");
*/
BOOL IntDeRegisterShellHookWindow(HWND hWnd)
{
- PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+ PDESKTOP Desktop = pti->rpdesk;
PSHELL_HOOK_WINDOW Current;
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
}
static VOID
-IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop)
+IntFreeDesktopHeap(IN OUT PDESKTOP Desktop)
{
- if (Desktop->DesktopHeapSection != NULL)
+ if (Desktop->hsectionDesktop != NULL)
{
- ObDereferenceObject(Desktop->DesktopHeapSection);
- Desktop->DesktopHeapSection = NULL;
+ ObDereferenceObject(Desktop->hsectionDesktop);
+ Desktop->hsectionDesktop = NULL;
}
}
/* SYSCALLS *******************************************************************/
-
/*
* NtUserCreateDesktop
*
* Creates a new desktop.
*
* Parameters
- * lpszDesktopName
- * Name of the new desktop.
+ * poaAttribs
+ * Object Attributes.
+ *
+ * lpszDesktopDevice
+ * Name of the device.
+ *
+ * pDeviceMode
+ * Device Mode.
*
* 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
* @implemented
*/
-HDESK STDCALL
+HDESK APIENTRY
NtUserCreateDesktop(
- PUNICODE_STRING lpszDesktopName,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PUNICODE_STRING lpszDesktopDevice,
+ LPDEVMODEW lpdmw,
DWORD dwFlags,
- ACCESS_MASK dwDesiredAccess,
- LPSECURITY_ATTRIBUTES lpSecurity,
- HWINSTA hWindowStation)
+ ACCESS_MASK dwDesiredAccess)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PWINSTATION_OBJECT WinStaObject;
- PDESKTOP_OBJECT DesktopObject;
+ PDESKTOP DesktopObject;
UNICODE_STRING DesktopName;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
HDESK Desktop;
CSR_API_MESSAGE Request;
PVOID DesktopHeapSystemBase = NULL;
SIZE_T DesktopInfoSize;
- UNICODE_STRING SafeDesktopName;
ULONG DummyContext;
- ULONG_PTR HeapLimit = 4 * 1024 * 1024; /* FIXME */
+ ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */
+ UNICODE_STRING ClassName;
+ LARGE_STRING WindowName;
+ BOOL NoHooks = FALSE;
+ PWND pWnd = NULL;
+ CREATESTRUCTW Cs;
+ INT i;
+ PTHREADINFO ptiCurrent;
DECLARE_RETURN(HDESK);
-
- DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
+ DPRINT("Enter NtUserCreateDesktop\n");
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(lpszDesktopName != NULL)
- {
- Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName);
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( NULL);
- }
- }
- else
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+ if (ptiCurrent)
{
- RtlInitUnicodeString(&SafeDesktopName, NULL);
+ /* Turn off hooks when calling any CreateWindowEx from inside win32k. */
+ NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
+ ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
}
-
- if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
- &SafeDesktopName))
- {
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- ObDereferenceObject(WinStaObject);
- if (lpszDesktopName)
- RtlFreeUnicodeString(&SafeDesktopName);
- RETURN( NULL);
- }
- RtlFreeUnicodeString(&SafeDesktopName);
- ObDereferenceObject(WinStaObject);
+ DesktopName.Buffer = NULL;
/*
* 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,
+ ObjectAttributes,
ExDesktopObjectType,
- KernelMode,
+ UserMode,
NULL,
dwDesiredAccess,
(PVOID)&DummyContext,
if (!NT_SUCCESS(Status)) RETURN(NULL);
if (Status == STATUS_OBJECT_NAME_EXISTS)
{
- ExFreePool(DesktopName.Buffer);
RETURN( Desktop);
}
+ /* Capture desktop name */
+ _SEH2_TRY
+ {
+ ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
+
+ Status = IntSafeCopyUnicodeString(&DesktopName, ObjectAttributes->ObjectName);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed reading Object Attributes from user space.\n");
+ SetLastNtError(Status);
+ RETURN( NULL);
+ }
+
/* Reference the desktop */
Status = ObReferenceObjectByHandle(Desktop,
0,
NULL);
if (!NT_SUCCESS(Status)) RETURN(NULL);
- DesktopObject->DesktopHeapSection = NULL;
- DesktopObject->hDesktopHeap = UserCreateHeap(&DesktopObject->DesktopHeapSection,
+ DesktopObject->hsectionDesktop = NULL;
+ DesktopObject->pheapDesktop = UserCreateHeap(&DesktopObject->hsectionDesktop,
&DesktopHeapSystemBase,
- HeapLimit);
- if (DesktopObject->hDesktopHeap == NULL)
+ HeapSize);
+ if (DesktopObject->pheapDesktop == NULL)
{
ObDereferenceObject(DesktopObject);
DPRINT1("Failed to create desktop heap!\n");
RETURN(NULL);
}
- DesktopInfoSize = FIELD_OFFSET(DESKTOP,
- szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]);
+ DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName.Length;
- DesktopObject->DesktopInfo = RtlAllocateHeap(DesktopObject->hDesktopHeap,
- HEAP_NO_SERIALIZE,
- DesktopInfoSize);
+ DesktopObject->pDeskInfo = RtlAllocateHeap(DesktopObject->pheapDesktop,
+ HEAP_NO_SERIALIZE,
+ DesktopInfoSize);
- if (DesktopObject->DesktopInfo == NULL)
+ if (DesktopObject->pDeskInfo == NULL)
{
ObDereferenceObject(DesktopObject);
DPRINT1("Failed to create the DESKTOP structure!\n");
RETURN(NULL);
}
- RtlZeroMemory(DesktopObject->DesktopInfo,
+ RtlZeroMemory(DesktopObject->pDeskInfo,
DesktopInfoSize);
- DesktopObject->DesktopInfo->hKernelHeap = DesktopObject->hDesktopHeap;
- DesktopObject->DesktopInfo->HeapLimit = HeapLimit;
- RtlCopyMemory(DesktopObject->DesktopInfo->szDesktopName,
- lpszDesktopName->Buffer,
- lpszDesktopName->Length);
-
- // init desktop area
- DesktopObject->WorkArea.left = 0;
- DesktopObject->WorkArea.top = 0;
- DesktopObject->WorkArea.right = -1;
- DesktopObject->WorkArea.bottom = -1;
- IntGetDesktopWorkArea(DesktopObject, NULL);
+ DesktopObject->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
+ DesktopObject->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
+ RtlCopyMemory(DesktopObject->pDeskInfo->szDesktopName,
+ DesktopName.Buffer,
+ DesktopName.Length);
/* Initialize some local (to win32k) desktop state. */
+ InitializeListHead(&DesktopObject->PtiList);
DesktopObject->ActiveMessageQueue = NULL;
- ExFreePool(DesktopName.Buffer);
+ /* Setup Global Hooks. */
+ for (i = 0; i < NB_HOOKS; i++)
+ {
+ InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]);
+ }
+//// why is this here?
+#if 0
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to create desktop handle\n");
SetLastNtError(Status);
RETURN( NULL);
}
+#endif
+////
/*
- * Create a handle for CSRSS and notify CSRSS
+ * Create a handle for CSRSS and notify CSRSS for Creating Desktop Window.
+ *
+ * Honestly, I believe this is a cleverly written hack that allowed ReactOS
+ * to function at the beginning of the project by ramroding the GUI into
+ * operation and making the desktop window work from user space.
+ * (jt)
*/
Request.Type = MAKE_CSR_API(CREATE_DESKTOP, CSR_GUI);
Status = CsrInsertObject(Desktop,
SetLastNtError(Status);
RETURN( NULL);
}
+#if 0 // Turn on when server side proc is ready.
+ //
+ // Create desktop window.
+ //
+ ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_DESKTOP])));
+ ClassName.Length = 0;
+ RtlZeroMemory(&WindowName, sizeof(WindowName));
+
+ RtlZeroMemory(&Cs, sizeof(Cs));
+ Cs.x = UserGetSystemMetrics(SM_XVIRTUALSCREEN);
+ Cs.y = UserGetSystemMetrics(SM_YVIRTUALSCREEN);
+ Cs.cx = UserGetSystemMetrics(SM_CXVIRTUALSCREEN);
+ Cs.cy = UserGetSystemMetrics(SM_CYVIRTUALSCREEN);
+ Cs.style = WS_POPUP|WS_CLIPCHILDREN;
+ Cs.hInstance = hModClient; // Experimental mode... Move csr stuff to User32. hModuleWin; // Server side winproc!
+ Cs.lpszName = (LPCWSTR) &WindowName;
+ Cs.lpszClass = (LPCWSTR) &ClassName;
+
+ pWndDesktop = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName);
+ if (!pWnd)
+ {
+ DPRINT1("Failed to create Desktop window handle\n");
+ }
+ else
+ {
+ DesktopObject->pDeskInfo->spwnd = pWndDesktop;
+ }
+#endif
+
+ if (!ptiCurrent->rpdesk) IntSetThreadDesktop(Desktop,FALSE);
+ /*
+ Based on wine/server/window.c in get_desktop_window.
+ */
+
+ ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE])));
+ ClassName.Length = 0;
+ RtlZeroMemory(&WindowName, sizeof(WindowName));
+
+ RtlZeroMemory(&Cs, sizeof(Cs));
+ Cs.cx = Cs.cy = 100;
+ Cs.style = WS_POPUP|WS_CLIPCHILDREN;
+ Cs.hInstance = hModClient; // hModuleWin; // Server side winproc! Leave it to Timo to not pass on notes!
+ Cs.lpszName = (LPCWSTR) &WindowName;
+ Cs.lpszClass = (LPCWSTR) &ClassName;
+
+ pWnd = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName);
+ if (!pWnd)
+ {
+ DPRINT1("Failed to create Message window handle\n");
+ }
+ else
+ {
+ DesktopObject->spwndMessage = pWnd;
+ }
+
+ /* Now,,,
+ if !(WinStaObject->Flags & WSF_NOIO) is (not set) for desktop input output mode (see wiki)
+ Create Tooltip. Saved in DesktopObject->spwndTooltip.
+ Tooltip dwExStyle: WS_EX_TOOLWINDOW|WS_EX_TOPMOST
+ hWndParent are spwndMessage. Use hModuleWin for server side winproc!
+ The rest is same as message window.
+ http://msdn.microsoft.com/en-us/library/bb760250(VS.85).aspx
+ */
RETURN( Desktop);
CLEANUP:
+ if(DesktopName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
+ }
+ if (!NoHooks && ptiCurrent) ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
* @implemented
*/
-HDESK STDCALL
+HDESK APIENTRY
NtUserOpenDesktop(
- PUNICODE_STRING lpszDesktopName,
+ POBJECT_ATTRIBUTES ObjectAttributes,
DWORD dwFlags,
ACCESS_MASK dwDesiredAccess)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- HWINSTA WinSta;
- PWINSTATION_OBJECT WinStaObject;
- UNICODE_STRING DesktopName;
- UNICODE_STRING SafeDesktopName;
NTSTATUS Status;
HDESK Desktop;
- BOOL Result;
- 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(lpszDesktopName != NULL)
- {
- Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName);
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( NULL);
- }
- }
- else
- {
- RtlInitUnicodeString(&SafeDesktopName, NULL);
- }
-
- Result = IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
- &SafeDesktopName);
-
- RtlFreeUnicodeString(&SafeDesktopName);
- ObDereferenceObject(WinStaObject);
-
-
- if (!Result)
- {
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- RETURN( 0);
- }
-
-
- DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
-
- /* Initialize ObjectAttributes for the desktop object */
- InitializeObjectAttributes(
- &ObjectAttributes,
- &DesktopName,
- 0,
- NULL,
- NULL);
Status = ObOpenObjectByName(
- &ObjectAttributes,
+ ObjectAttributes,
ExDesktopObjectType,
- KernelMode,
+ UserMode,
NULL,
dwDesiredAccess,
NULL,
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);
-
-CLEANUP:
- DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ return Desktop;
}
/*
* @implemented
*/
-HDESK STDCALL
+HDESK APIENTRY
NtUserOpenInputDesktop(
DWORD dwFlags,
BOOL fInherit,
ACCESS_MASK dwDesiredAccess)
{
- PDESKTOP_OBJECT Object;
+ PDESKTOP Object;
NTSTATUS Status;
HDESK Desktop;
DECLARE_RETURN(HDESK);
* @implemented
*/
-BOOL STDCALL
+BOOL APIENTRY
NtUserCloseDesktop(HDESK hDesktop)
{
- PDESKTOP_OBJECT Object;
+ PDESKTOP Object;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
* @implemented
*/
-BOOL STDCALL
+BOOL APIENTRY
NtUserPaintDesktop(HDC hDC)
{
- RECT Rect;
+ RECTL Rect;
HBRUSH DesktopBrush, PreviousBrush;
HWND hWndDesktop;
BOOL doPatBlt = TRUE;
- PWINDOW_OBJECT WndDesktop;
+ PWND WndDesktop;
int len;
COLORREF color_old;
UINT align_old;
int mode_old;
- PWINSTATION_OBJECT WinSta = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
+ PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
+ PWINSTATION_OBJECT WinSta = pti->rpdesk->rpwinstaParent;
DECLARE_RETURN(BOOL);
UserEnterExclusive();
RETURN(FALSE);
}
- DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->Class, GCL_HBRBACKGROUND, FALSE);
+ DesktopBrush = (HBRUSH)WndDesktop->pcls->hbrBackground;
/*
if (WinSta->hbmWallpaper != NULL)
{
- PWINDOW_OBJECT DeskWin;
+ PWND DeskWin;
DeskWin = UserGetWindowObject(hWndDesktop);
int x, y;
HDC hWallpaperDC;
- sz.cx = DeskWin->Wnd->WindowRect.right - DeskWin->Wnd->WindowRect.left;
- sz.cy = DeskWin->Wnd->WindowRect.bottom - DeskWin->Wnd->WindowRect.top;
+ sz.cx = DeskWin->rcWindow.right - DeskWin->rcWindow.left;
+ sz.cy = DeskWin->rcWindow.bottom - DeskWin->rcWindow.top;
if (WinSta->WallpaperMode == wmStretch ||
WinSta->WallpaperMode == wmTile)
if (g_PaintDesktopVersion)
{
static WCHAR s_wszVersion[256] = {0};
- RECT rect;
+ RECTL rect;
if (*s_wszVersion)
{
align_old = IntGdiSetTextAlign(hDC, TA_RIGHT);
mode_old = IntGdiSetBkMode(hDC, TRANSPARENT);
- NtGdiExtTextOutW(hDC, rect.right-16, rect.bottom-48, 0, NULL, s_wszVersion, len, NULL, 0);
+ GreExtTextOutW(hDC, rect.right-16, rect.bottom-48, 0, NULL, s_wszVersion, len, NULL, 0);
IntGdiSetBkMode(hDC, mode_old);
IntGdiSetTextAlign(hDC, align_old);
* @unimplemented
*/
-BOOL STDCALL
+BOOL APIENTRY
NtUserSwitchDesktop(HDESK hDesktop)
{
- PDESKTOP_OBJECT DesktopObject;
+ PDESKTOP DesktopObject;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
* 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) &&
+ if((DesktopObject->rpwinstaParent->Flags & WSS_LOCKED) &&
LogonProcess != NULL && LogonProcess != PsGetCurrentProcessWin32Process())
{
ObDereferenceObject(DesktopObject);
RETURN(FALSE);
}
- /* FIXME: Fail if the desktop belong to an invisible window station */
+ if(DesktopObject->rpwinstaParent != InputWindowStation)
+ {
+ ObDereferenceObject(DesktopObject);
+ DPRINT1("Switching desktop 0x%x denied because desktop doesn't belong to the interactive winsta!\n", hDesktop);
+ RETURN(FALSE);
+ }
+
/* 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;
+ InputWindowStation->ActiveDesktop = DesktopObject;
/* Set the global state. */
InputDesktop = DesktopObject;
InputDesktopHandle = hDesktop;
- InputWindowStation = DesktopObject->WindowStation;
ObDereferenceObject(DesktopObject);
END_CLEANUP;
}
-/*
- * NtUserResolveDesktopForWOW
- *
- * Status
- * @unimplemented
- */
-
-DWORD STDCALL
-NtUserResolveDesktopForWOW(DWORD Unknown0)
-{
- UNIMPLEMENTED
- return 0;
-}
-
/*
* NtUserGetThreadDesktop
*
* @implemented
*/
-HDESK STDCALL
+HDESK APIENTRY
NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
{
NTSTATUS Status;
PETHREAD Thread;
- PDESKTOP_OBJECT DesktopObject;
+ PDESKTOP DesktopObject;
HDESK Ret, hThreadDesktop;
OBJECT_HANDLE_INFORMATION HandleInformation;
DECLARE_RETURN(HDESK);
if(!dwThreadId)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(0);
}
Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &Thread);
if(!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(0);
}
{
/* just return the handle, we queried the desktop handle of a thread running
in the same context */
- Ret = ((PW32THREAD)Thread->Tcb.Win32Thread)->hDesktop;
+ Ret = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk;
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))
+ if(!(hThreadDesktop = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk) ||
+ !(DesktopObject = ((PTHREADINFO)Thread->Tcb.Win32Thread)->rpdesk))
{
ObDereferenceObject(Thread);
DPRINT1("Desktop information of thread 0x%x broken!?\n", dwThreadId);
}
static NTSTATUS
-IntUnmapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
+IntUnmapDesktopView(IN PDESKTOP DesktopObject)
{
- PW32THREADINFO ti;
- PW32HEAP_USER_MAPPING HeapMapping, *PrevLink = &PsGetCurrentProcessWin32Process()->HeapMappings.Next;
+ PTHREADINFO ti;
+ PPROCESSINFO CurrentWin32Process;
+ PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
NTSTATUS Status = STATUS_SUCCESS;
TRACE("DO %p\n");
+ CurrentWin32Process = PsGetCurrentProcessWin32Process();
+ PrevLink = &CurrentWin32Process->HeapMappings.Next;
+
/* unmap if we're the last thread using the desktop */
HeapMapping = *PrevLink;
while (HeapMapping != NULL)
{
- if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
+ if (HeapMapping->KernelMapping == (PVOID)DesktopObject->pheapDesktop)
{
if (--HeapMapping->Count == 0)
{
ti = GetW32ThreadInfo();
if (ti != NULL)
{
- if (ti->Desktop == DesktopObject->DesktopInfo)
- {
- ti->Desktop = NULL;
- ti->DesktopHeapBase = NULL;
- ti->DesktopHeapLimit = 0;
- ti->DesktopHeapDelta = 0;
- }
+ GetWin32ClientInfo()->pDeskInfo = NULL;
}
+ GetWin32ClientInfo()->ulClientDelta = 0;
return Status;
}
static NTSTATUS
-IntMapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
+IntMapDesktopView(IN PDESKTOP DesktopObject)
{
- PW32THREADINFO ti;
- PW32HEAP_USER_MAPPING HeapMapping, *PrevLink = &PsGetCurrentProcessWin32Process()->HeapMappings.Next;
+ PPROCESSINFO CurrentWin32Process;
+ PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
PVOID UserBase = NULL;
SIZE_T ViewSize = 0;
LARGE_INTEGER Offset;
NTSTATUS Status;
+ CurrentWin32Process = PsGetCurrentProcessWin32Process();
+ PrevLink = &CurrentWin32Process->HeapMappings.Next;
+
/* find out if another thread already mapped the desktop heap */
HeapMapping = *PrevLink;
while (HeapMapping != NULL)
{
- if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
+ if (HeapMapping->KernelMapping == (PVOID)DesktopObject->pheapDesktop)
{
HeapMapping->Count++;
return STATUS_SUCCESS;
}
/* we're the first, map the heap */
- DPRINT("Noone mapped the desktop heap %p yet, so - map it!\n", DesktopObject->hDesktopHeap);
+ DPRINT("Noone mapped the desktop heap %p yet, so - map it!\n", DesktopObject->pheapDesktop);
Offset.QuadPart = 0;
- Status = MmMapViewOfSection(DesktopObject->DesktopHeapSection,
+ Status = MmMapViewOfSection(DesktopObject->hsectionDesktop,
PsGetCurrentProcess(),
&UserBase,
0,
}
HeapMapping->Next = NULL;
- HeapMapping->KernelMapping = (PVOID)DesktopObject->hDesktopHeap;
+ HeapMapping->KernelMapping = (PVOID)DesktopObject->pheapDesktop;
HeapMapping->UserMapping = UserBase;
HeapMapping->Limit = ViewSize;
HeapMapping->Count = 1;
ObReferenceObject(DesktopObject);
- /* create a W32THREADINFO structure if not already done, or update it */
- ti = GetW32ThreadInfo();
- if (ti != NULL)
- {
- if (ti->Desktop == NULL)
- {
- ti->Desktop = DesktopObject->DesktopInfo;
- ti->DesktopHeapBase = DesktopObject->hDesktopHeap;
- ti->DesktopHeapLimit = ViewSize;
- ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
- }
- }
-
return STATUS_SUCCESS;
}
BOOL
-IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject,
+IntSetThreadDesktop(IN HDESK hDesktop,
IN BOOL FreeOnFailure)
{
- PDESKTOP_OBJECT OldDesktop;
- PW32THREAD W32Thread;
+ PDESKTOP DesktopObject = NULL, OldDesktop;
+ HDESK hOldDesktop;
+ PTHREADINFO W32Thread;
NTSTATUS Status;
BOOL MapHeap;
+ CLIENTTHREADINFO ctiSave;
- DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure);
+ DPRINT("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure);
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
W32Thread = PsGetCurrentThreadWin32Thread();
- if (W32Thread->Desktop != DesktopObject)
+ if(hDesktop != NULL)
{
- OldDesktop = W32Thread->Desktop;
-
- if (!IsListEmpty(&W32Thread->WindowListHead))
+ /* Validate the new desktop. */
+ Status = IntValidateDesktopHandle(
+ hDesktop,
+ UserMode,
+ 0,
+ &DesktopObject);
+
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("Attempted to change thread desktop although the thread has windows!\n");
- SetLastWin32Error(ERROR_BUSY);
+ DPRINT1("Validation of desktop handle (0x%X) failed\n", hDesktop);
return FALSE;
}
- W32Thread->Desktop = DesktopObject;
-
- if (MapHeap && DesktopObject != NULL)
+ if (W32Thread->rpdesk == DesktopObject)
{
- Status = IntMapDesktopView(DesktopObject);
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return FALSE;
- }
+ /* Nothing to do */
+ ObDereferenceObject(DesktopObject);
+ return TRUE;
}
- if (W32Thread->Desktop == NULL)
- {
- PW32THREADINFO ti = GetW32ThreadInfo();
- if (ti != NULL)
- {
- ti->Desktop = NULL;
- ti->DesktopHeapDelta = 0;
- }
- }
+ }
- if (OldDesktop != NULL &&
- !IntCheckProcessDesktopClasses(OldDesktop->DesktopInfo,
- FreeOnFailure))
- {
- DPRINT1("Failed to move process classes to shared heap!\n");
+ if (!IsListEmpty(&W32Thread->WindowListHead))
+ {
+ DPRINT1("Attempted to change thread desktop although the thread has windows!\n");
+ EngSetLastError(ERROR_BUSY);
+ return FALSE;
+ }
+
+ OldDesktop = W32Thread->rpdesk;
+ hOldDesktop = W32Thread->hdesk;
- /* failed to move desktop classes to the shared heap,
- unmap the view and return the error */
- if (MapHeap && DesktopObject != NULL)
- IntUnmapDesktopView(DesktopObject);
+ W32Thread->rpdesk = DesktopObject;
+ W32Thread->hdesk = hDesktop;
+ if (MapHeap && DesktopObject != NULL)
+ {
+ Status = IntMapDesktopView(DesktopObject);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
return FALSE;
}
+ W32Thread->pDeskInfo = DesktopObject->pDeskInfo;
+ }
+
+ RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO));
- if (DesktopObject != NULL)
+ if (W32Thread->pcti && OldDesktop && NtCurrentTeb())
+ {
+ RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
+ DPRINT("Free ClientThreadInfo\n");
+ DesktopHeapFree(OldDesktop, W32Thread->pcti);
+ W32Thread->pcti = NULL;
+ }
+
+ if (!W32Thread->pcti && DesktopObject && NtCurrentTeb())
+ {
+ DPRINT("Allocate ClientThreadInfo\n");
+ W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
+ sizeof(CLIENTTHREADINFO));
+ RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO));
+ }
+
+ if (NtCurrentTeb())
+ {
+ PCLIENTINFO pci = GetWin32ClientInfo();
+ pci->ulClientDelta = DesktopHeapGetUserDelta();
+ if (DesktopObject)
{
- ObReferenceObject(DesktopObject);
+ pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
+ if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta);
}
+ }
- if (OldDesktop != NULL)
- {
- if (MapHeap)
- {
- IntUnmapDesktopView(OldDesktop);
- }
+ if (OldDesktop != NULL &&
+ !IntCheckProcessDesktopClasses(OldDesktop,
+ FreeOnFailure))
+ {
+ DPRINT1("Failed to move process classes to shared heap!\n");
+
+ /* failed to move desktop classes to the shared heap,
+ unmap the view and return the error */
+ if (MapHeap && DesktopObject != NULL)
+ IntUnmapDesktopView(DesktopObject);
+
+ return FALSE;
+ }
+
+ /* Remove the thread from the old desktop's list */
+ RemoveEntryList(&W32Thread->PtiLink);
- ObDereferenceObject(OldDesktop);
+ if (DesktopObject != NULL)
+ {
+ ObReferenceObject(DesktopObject);
+ /* Insert into new desktop's list */
+ InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink);
+ }
+
+ /* Close the old desktop */
+ if (OldDesktop != NULL)
+ {
+ if (MapHeap)
+ {
+ IntUnmapDesktopView(OldDesktop);
}
+
+ ObDereferenceObject(OldDesktop);
+ }
+
+ if (hOldDesktop != NULL)
+ {
+ ZwClose(hOldDesktop);
}
return TRUE;
* @implemented
*/
-BOOL STDCALL
+BOOL APIENTRY
NtUserSetThreadDesktop(HDESK hDesktop)
{
- PDESKTOP_OBJECT DesktopObject;
- NTSTATUS Status;
- DECLARE_RETURN(BOOL);
+ BOOL ret;
UserEnterExclusive();
- DPRINT("Enter NtUserSetThreadDesktop\n");
- /* Validate the new desktop. */
- Status = IntValidateDesktopHandle(
- hDesktop,
- UserMode,
- 0,
- &DesktopObject);
+ ret = IntSetThreadDesktop(hDesktop, FALSE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
- RETURN(FALSE);
- }
-
- /* FIXME: Should check here to see if the thread has any windows. */
-
- if (!IntSetThreadDesktop(DesktopObject,
- FALSE))
- {
- RETURN(FALSE);
- }
-
- RETURN(TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+
+ return ret;
}
/* EOF */