mirror of
https://github.com/reactos/reactos.git
synced 2025-06-02 07:56:16 +00:00
[win32k]
- SetThreadDesktop: Actually set hdesk in PTHREADINFO Now GetThreadDesktop doesn't return 0 svn path=/trunk/; revision=51086
This commit is contained in:
parent
1ba1132e21
commit
b75783bd61
3 changed files with 114 additions and 128 deletions
|
@ -102,7 +102,7 @@ IntHideDesktop(PDESKTOP Desktop);
|
||||||
HDESK FASTCALL
|
HDESK FASTCALL
|
||||||
IntGetDesktopObjectHandle(PDESKTOP DesktopObject);
|
IntGetDesktopObjectHandle(PDESKTOP DesktopObject);
|
||||||
|
|
||||||
BOOL IntSetThreadDesktop(IN PDESKTOP DesktopObject,
|
BOOL IntSetThreadDesktop(IN HDESK hDesktop,
|
||||||
IN BOOL FreeOnFailure);
|
IN BOOL FreeOnFailure);
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
|
|
|
@ -237,26 +237,11 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
||||||
|
|
||||||
if (hDesk != NULL)
|
if (hDesk != NULL)
|
||||||
{
|
{
|
||||||
PDESKTOP DesktopObject;
|
|
||||||
Win32Thread->rpdesk = NULL;
|
Win32Thread->rpdesk = NULL;
|
||||||
Status = ObReferenceObjectByHandle(hDesk,
|
Win32Thread->hdesk = NULL;
|
||||||
0,
|
if (!IntSetThreadDesktop(hDesk, FALSE))
|
||||||
ExDesktopObjectType,
|
|
||||||
KernelMode,
|
|
||||||
(PVOID*)&DesktopObject,
|
|
||||||
NULL);
|
|
||||||
NtClose(hDesk);
|
|
||||||
if(NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
if (!IntSetThreadDesktop(DesktopObject,
|
|
||||||
FALSE))
|
|
||||||
{
|
|
||||||
DPRINT1("Unable to set thread desktop\n");
|
DPRINT1("Unable to set thread desktop\n");
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1055,7 +1055,7 @@ NtUserCreateDesktop(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ptiCurrent->rpdesk) IntSetThreadDesktop(DesktopObject,FALSE);
|
if (!ptiCurrent->rpdesk) IntSetThreadDesktop(Desktop,FALSE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Based on wine/server/window.c in get_desktop_window.
|
Based on wine/server/window.c in get_desktop_window.
|
||||||
|
@ -1795,105 +1795,131 @@ IntMapDesktopView(IN PDESKTOP DesktopObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
IntSetThreadDesktop(IN PDESKTOP DesktopObject,
|
IntSetThreadDesktop(IN HDESK hDesktop,
|
||||||
IN BOOL FreeOnFailure)
|
IN BOOL FreeOnFailure)
|
||||||
{
|
{
|
||||||
PDESKTOP OldDesktop;
|
PDESKTOP DesktopObject, OldDesktop;
|
||||||
|
HDESK hOldDesktop;
|
||||||
PTHREADINFO W32Thread;
|
PTHREADINFO W32Thread;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL MapHeap;
|
BOOL MapHeap;
|
||||||
CLIENTTHREADINFO ctiSave;
|
CLIENTTHREADINFO ctiSave;
|
||||||
|
|
||||||
DPRINT("IntSetThreadDesktop() DO=%p, FOF=%d\n", DesktopObject, FreeOnFailure);
|
DPRINT("IntSetThreadDesktop() , FOF=%d\n", FreeOnFailure);
|
||||||
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
|
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
|
||||||
W32Thread = PsGetCurrentThreadWin32Thread();
|
W32Thread = PsGetCurrentThreadWin32Thread();
|
||||||
|
|
||||||
|
/* Validate the new desktop. */
|
||||||
|
Status = IntValidateDesktopHandle(
|
||||||
|
hDesktop,
|
||||||
|
UserMode,
|
||||||
|
0,
|
||||||
|
&DesktopObject);
|
||||||
|
|
||||||
if (W32Thread->rpdesk != DesktopObject)
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
OldDesktop = W32Thread->rpdesk;
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsListEmpty(&W32Thread->WindowListHead))
|
if (W32Thread->rpdesk == DesktopObject)
|
||||||
|
{
|
||||||
|
/* Nothing to do */
|
||||||
|
ObDereferenceObject(DesktopObject);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
W32Thread->rpdesk = DesktopObject;
|
||||||
|
W32Thread->hdesk = hDesktop;
|
||||||
|
|
||||||
|
if (MapHeap && DesktopObject != NULL)
|
||||||
|
{
|
||||||
|
Status = IntMapDesktopView(DesktopObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Attempted to change thread desktop although the thread has windows!\n");
|
SetLastNtError(Status);
|
||||||
EngSetLastError(ERROR_BUSY);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
W32Thread->pDeskInfo = DesktopObject->pDeskInfo;
|
||||||
|
}
|
||||||
|
|
||||||
W32Thread->rpdesk = DesktopObject;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
|
||||||
|
if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if (MapHeap && DesktopObject != NULL)
|
||||||
|
IntUnmapDesktopView(DesktopObject);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the thread from the old desktop's list */
|
||||||
|
RemoveEntryList(&W32Thread->PtiLink);
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
Status = IntMapDesktopView(DesktopObject);
|
IntUnmapDesktopView(OldDesktop);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
W32Thread->pDeskInfo = DesktopObject->pDeskInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlZeroMemory(&ctiSave, sizeof(CLIENTTHREADINFO));
|
ObDereferenceObject(OldDesktop);
|
||||||
|
}
|
||||||
if (W32Thread->pcti && OldDesktop && NtCurrentTeb())
|
|
||||||
{
|
if (hOldDesktop != NULL)
|
||||||
RtlCopyMemory(&ctiSave, W32Thread->pcti, sizeof(CLIENTTHREADINFO));
|
{
|
||||||
DPRINT("Free ClientThreadInfo\n");
|
ZwClose(hOldDesktop);
|
||||||
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)
|
|
||||||
{
|
|
||||||
pci->pDeskInfo = (PVOID)((ULONG_PTR)DesktopObject->pDeskInfo - pci->ulClientDelta);
|
|
||||||
if (W32Thread->pcti) pci->pClientThreadInfo = (PVOID)((ULONG_PTR)W32Thread->pcti - pci->ulClientDelta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (DesktopObject != NULL)
|
|
||||||
{
|
|
||||||
ObReferenceObject(DesktopObject);
|
|
||||||
/* Insert into new desktop's list */
|
|
||||||
InsertTailList(&DesktopObject->PtiList, &W32Thread->PtiLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OldDesktop != NULL)
|
|
||||||
{
|
|
||||||
if (MapHeap)
|
|
||||||
{
|
|
||||||
IntUnmapDesktopView(OldDesktop);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObDereferenceObject(OldDesktop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1909,40 +1935,15 @@ IntSetThreadDesktop(IN PDESKTOP DesktopObject,
|
||||||
BOOL APIENTRY
|
BOOL APIENTRY
|
||||||
NtUserSetThreadDesktop(HDESK hDesktop)
|
NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
{
|
{
|
||||||
PDESKTOP DesktopObject;
|
BOOL ret;
|
||||||
NTSTATUS Status;
|
|
||||||
DECLARE_RETURN(BOOL);
|
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
DPRINT("Enter NtUserSetThreadDesktop\n");
|
|
||||||
|
ret = IntSetThreadDesktop(hDesktop, FALSE);
|
||||||
/* 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. */
|
|
||||||
|
|
||||||
if (!IntSetThreadDesktop(DesktopObject,
|
|
||||||
FALSE))
|
|
||||||
{
|
|
||||||
RETURN(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN(TRUE);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserSetThreadDesktop, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
END_CLEANUP;
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue