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 */
return pdo->DesktopWindow;
}
-PWINDOW_OBJECT FASTCALL UserGetDesktopWindow(VOID)
+PWND FASTCALL UserGetDesktopWindow(VOID)
{
PDESKTOP pdo = IntGetActiveDesktop();
HWND FASTCALL IntGetMessageWindow(VOID)
{
PDESKTOP pdo = IntGetActiveDesktop();
-
+
if (!pdo)
{
DPRINT("No active 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;
HDC FASTCALL
UserGetDesktopDC(ULONG DcType, BOOL EmptyDC, BOOL ValidatehWnd)
{
- PWINDOW_OBJECT DesktopObject = 0;
+ PWND DesktopObject = 0;
HDC DesktopHDC = 0;
if (DcType == DC_TYPE_DIRECT)
- {
+ {
DesktopObject = UserGetDesktopWindow();
DesktopHDC = (HDC)UserGetWindowDC(DesktopObject);
}
VOID APIENTRY
UserRedrawDesktop()
{
- PWINDOW_OBJECT Window = NULL;
+ PWND Window = NULL;
+ HRGN hRgn;
Window = UserGetDesktopWindow();
+ hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
IntInvalidateWindows( Window,
- Window->hrgnUpdate,
+ hRgn,
RDW_FRAME |
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
+
+ GreDeleteObject(hRgn);
}
return NotifyCsrss(&Request, &Reply);
#else
- PWINDOW_OBJECT DesktopWindow;
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;
return STATUS_SUCCESS;
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;
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);
}
HDESK APIENTRY
NtUserCreateDesktop(
- POBJECT_ATTRIBUTES poa,
+ POBJECT_ATTRIBUTES ObjectAttributes,
PUNICODE_STRING lpszDesktopDevice,
LPDEVMODEW lpdmw,
DWORD dwFlags,
ACCESS_MASK dwDesiredAccess)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PTHREADINFO W32Thread;
- PWINSTATION_OBJECT WinStaObject;
PDESKTOP DesktopObject;
UNICODE_STRING DesktopName;
NTSTATUS Status = STATUS_SUCCESS;
CSR_API_MESSAGE Request;
PVOID DesktopHeapSystemBase = NULL;
SIZE_T DesktopInfoSize;
- UNICODE_STRING SafeDesktopName;
ULONG DummyContext;
ULONG_PTR HeapSize = 4 * 1024 * 1024; /* FIXME */
- HWINSTA hWindowStation = NULL ;
- PUNICODE_STRING lpszDesktopName = NULL;
- UNICODE_STRING ClassName, MenuName;
+ 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();
- _SEH2_TRY
- {
- ProbeForRead( poa,
- sizeof(OBJECT_ATTRIBUTES),
- 1);
-
- hWindowStation = poa->RootDirectory;
- lpszDesktopName = poa->ObjectName;
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status =_SEH2_GetExceptionCode();
- }
- _SEH2_END
-
- if (! NT_SUCCESS(Status))
+ ptiCurrent = PsGetCurrentThreadWin32Thread();
+ if (ptiCurrent)
{
- DPRINT1("Failed reading Object Attributes from user space.\n");
- SetLastNtError(Status);
- RETURN( NULL);
+ /* Turn off hooks when calling any CreateWindowEx from inside win32k. */
+ NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
+ ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
}
-
- 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
- {
- RtlInitUnicodeString(&SafeDesktopName, NULL);
- }
-
- if (! IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
- &SafeDesktopName))
- {
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
- ObDereferenceObject(WinStaObject);
- if (lpszDesktopName)
- ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING);
- RETURN( NULL);
- }
- if (lpszDesktopName)
- ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING);
- 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)
{
- ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
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,
RETURN(NULL);
}
- DesktopInfoSize = FIELD_OFFSET(DESKTOPINFO,
- szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]);
+ DesktopInfoSize = sizeof(DESKTOPINFO) + DesktopName.Length;
DesktopObject->pDeskInfo = RtlAllocateHeap(DesktopObject->pheapDesktop,
- HEAP_NO_SERIALIZE,
- DesktopInfoSize);
+ HEAP_NO_SERIALIZE,
+ DesktopInfoSize);
if (DesktopObject->pDeskInfo == NULL)
{
DesktopObject->pDeskInfo->pvDesktopBase = DesktopHeapSystemBase;
DesktopObject->pDeskInfo->pvDesktopLimit = (PVOID)((ULONG_PTR)DesktopHeapSystemBase + HeapSize);
RtlCopyMemory(DesktopObject->pDeskInfo->szDesktopName,
- lpszDesktopName->Buffer,
- lpszDesktopName->Length);
+ DesktopName.Buffer,
+ DesktopName.Length);
/* Initialize some local (to win32k) desktop state. */
InitializeListHead(&DesktopObject->PtiList);
DesktopObject->ActiveMessageQueue = NULL;
- ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING);
+ /* 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 for Creating Desktop Window.
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));
- W32Thread = PsGetCurrentThreadWin32Thread();
+ 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 (!W32Thread->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE);
+ 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(&MenuName, sizeof(MenuName));
RtlZeroMemory(&WindowName, sizeof(WindowName));
- pWnd = co_IntCreateWindowEx( 0,
- &ClassName,
- &WindowName,
- (WS_POPUP|WS_CLIPCHILDREN),
- 0,
- 0,
- 100,
- 100,
- NULL,
- NULL,
- hModClient,
- NULL,
- 0,
- TRUE);
+ 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");
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;
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);
-
- if (lpszDesktopName)
- ExFreePoolWithTag(SafeDesktopName.Buffer, TAG_STRING);
- 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;
}
/*
HBRUSH DesktopBrush, PreviousBrush;
HWND hWndDesktop;
BOOL doPatBlt = TRUE;
- PWINDOW_OBJECT WndDesktop;
+ PWND WndDesktop;
int len;
COLORREF color_old;
UINT align_old;
RETURN(FALSE);
}
- DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Wnd->pcls, 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->rcWindow.right - DeskWin->Wnd->rcWindow.left;
- sz.cy = DeskWin->Wnd->rcWindow.bottom - DeskWin->Wnd->rcWindow.top;
+ sz.cx = DeskWin->rcWindow.right - DeskWin->rcWindow.left;
+ sz.cy = DeskWin->rcWindow.bottom - DeskWin->rcWindow.top;
if (WinSta->WallpaperMode == wmStretch ||
WinSta->WallpaperMode == wmTile)
END_CLEANUP;
}
-/*
- * NtUserResolveDesktopForWOW
- *
- * Status
- * @unimplemented
- */
-
-DWORD APIENTRY
-NtUserResolveDesktopForWOW(DWORD Unknown0)
-{
- UNIMPLEMENTED
- return 0;
-}
-
/*
* NtUserGetThreadDesktop
*
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);
}
static NTSTATUS
IntMapDesktopView(IN PDESKTOP DesktopObject)
{
- PTHREADINFO ti;
PPROCESSINFO CurrentWin32Process;
PW32HEAP_USER_MAPPING HeapMapping, *PrevLink;
PVOID UserBase = NULL;
ObReferenceObject(DesktopObject);
- /* create a W32THREADINFO structure if not already done, or update it */
- ti = GetW32ThreadInfo();
- GetWin32ClientInfo()->ulClientDelta = DesktopHeapGetUserDelta();
- if (ti != NULL)
- {
- if (GetWin32ClientInfo()->pDeskInfo == NULL)
- {
- GetWin32ClientInfo()->pDeskInfo =
- (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo -
- GetWin32ClientInfo()->ulClientDelta);
- }
- }
-
return STATUS_SUCCESS;
}
BOOL
-IntSetThreadDesktop(IN PDESKTOP DesktopObject,
+IntSetThreadDesktop(IN HDESK hDesktop,
IN BOOL FreeOnFailure)
{
- PDESKTOP OldDesktop;
+ 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->rpdesk != DesktopObject)
+ if(hDesktop != NULL)
{
- OldDesktop = W32Thread->rpdesk;
-
- 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->rpdesk = 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;
}
- /* Hack for system threads */
- if (NtCurrentTeb())
- {
- PCLIENTINFO pci = GetWin32ClientInfo();
- pci->ulClientDelta = DesktopHeapGetUserDelta();
- if (DesktopObject)
- {
- pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
- }
- }
+ }
- if (OldDesktop != NULL &&
- !IntCheckProcessDesktopClasses(OldDesktop,
- 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;
+ }
- /* failed to move desktop classes to the shared heap,
- unmap the view and return the error */
- if (MapHeap && DesktopObject != NULL)
- IntUnmapDesktopView(DesktopObject);
+ OldDesktop = W32Thread->rpdesk;
+ hOldDesktop = W32Thread->hdesk;
+ 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 (W32Thread->pcti && OldDesktop && NtCurrentTeb())
+ {
+ RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
+ DPRINT("Free ClientThreadInfo\n");
+ DesktopHeapFree(OldDesktop, W32Thread->pcti);
+ W32Thread->pcti = NULL;
+ }
- /* Remove the thread from the old desktop's list */
- RemoveEntryList(&W32Thread->PtiLink);
+ if (!W32Thread->pcti && DesktopObject && NtCurrentTeb())
+ {
+ DPRINT("Allocate ClientThreadInfo\n");
+ W32Thread->pcti = DesktopHeapAlloc( DesktopObject,
+ sizeof(CLIENTTHREADINFO));
+ RtlCopyMemory(W32Thread->pcti, &ctiSave, sizeof(CLIENTTHREADINFO));
+ }
- if (DesktopObject != NULL)
+ if (NtCurrentTeb())
+ {
+ PCLIENTINFO pci = GetWin32ClientInfo();
+ pci->ulClientDelta = DesktopHeapGetUserDelta();
+ if (DesktopObject)
{
- ObReferenceObject(DesktopObject);
- /* Insert into new desktop's list */
- InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink);
+ 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;
BOOL APIENTRY
NtUserSetThreadDesktop(HDESK hDesktop)
{
- PDESKTOP DesktopObject;
- NTSTATUS Status;
- DECLARE_RETURN(BOOL);
+ BOOL ret;
UserEnterExclusive();
- DPRINT("Enter NtUserSetThreadDesktop\n");
-
- /* Validate the new desktop. */
- Status = IntValidateDesktopHandle(
- hDesktop,
- UserMode,
- 0,
- &DesktopObject);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
- RETURN(FALSE);
- }
- /* FIXME: Should check here to see if the thread has any windows. */
+ ret = IntSetThreadDesktop(hDesktop, FALSE);
- if (!IntSetThreadDesktop(DesktopObject,
- FALSE))
- {
- RETURN(FALSE);
- }
-
- RETURN(TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+
+ return ret;
}
/* EOF */