fixed GetThreadDesktop() (not fully working yet because it requires a ObFindHandleForObject() implementation in case the requested thread doesn't belong to the calling process)

svn path=/trunk/; revision=9315
This commit is contained in:
Thomas Bluemel 2004-05-05 22:47:06 +00:00
parent 879f672ffe
commit bcde8100ea
5 changed files with 121 additions and 32 deletions

View file

@ -10,6 +10,7 @@ typedef struct _W32THREAD
LIST_ENTRY WindowListHead;
struct _KBDTABLES* KeyboardLayout;
struct _DESKTOP_OBJECT* Desktop;
HANDLE hDesktop;
DWORD MessagePumpHookValue;
BOOLEAN IsExiting;
} W32THREAD, *PW32THREAD;
@ -29,6 +30,7 @@ typedef struct _W32PROCESS
LIST_ENTRY CursorIconListHead;
struct _KBDTABLES* KeyboardLayout;
struct _WINSTATION_OBJECT* WindowStation;
HANDLE hWindowStation;
WORD GDIObjects;
WORD UserObjects;
BOOLEAN CreatedWindowOrDC;

View file

@ -45,8 +45,6 @@ typedef struct _SYSTEM_CURSORINFO
typedef struct _WINSTATION_OBJECT
{
HANDLE Self;
CSHORT Type;
CSHORT Size;
KSPIN_LOCK Lock;
@ -68,8 +66,6 @@ typedef struct _WINSTATION_OBJECT
typedef struct _DESKTOP_OBJECT
{
HANDLE Self;
CSHORT Type;
CSHORT Size;
LIST_ENTRY ListEntry;

View file

@ -46,6 +46,16 @@ IntShowDesktop(PDESKTOP_OBJECT Desktop, ULONG Width, ULONG Height);
NTSTATUS FASTCALL
IntHideDesktop(PDESKTOP_OBJECT Desktop);
HDESK FASTCALL
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
NTSTATUS FASTCALL
IntValidateDesktopHandle(
HDESK Desktop,
KPROCESSOR_MODE AccessMode,
ACCESS_MASK DesiredAccess,
PDESKTOP_OBJECT *Object);
#define IntIsActiveDesktop(Desktop) \
((Desktop)->WindowStation->ActiveDesktop == (Desktop))

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dllmain.c,v 1.70 2004/05/01 16:43:14 weiden Exp $
/* $Id: dllmain.c,v 1.71 2004/05/05 22:47:06 weiden Exp $
*
* Entry Point for win32k.sys
*/
@ -182,6 +182,7 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
/* By default threads get assigned their process's desktop. */
Win32Thread->Desktop = NULL;
Win32Thread->hDesktop = NULL;
if (Process->Win32Desktop != NULL)
{
Status = ObReferenceObjectByHandle(Process->Win32Desktop,
@ -194,6 +195,8 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
{
DbgPrint("Win32K: Failed to reference a desktop for thread.\n");
}
Win32Thread->hDesktop = Process->Win32Desktop;
}
}
else

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: desktop.c,v 1.11 2004/05/01 16:43:15 weiden Exp $
* $Id: desktop.c,v 1.12 2004/05/05 22:47:06 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -49,6 +49,19 @@
#define NDEBUG
#include <debug.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
/* GLOBALS *******************************************************************/
/* Currently active desktop */
@ -131,7 +144,44 @@ IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop)
PDESKTOP_OBJECT FASTCALL
IntGetActiveDesktop(VOID)
{
return InputDesktop;
return InputDesktop;
}
/*
* returns or creates a handle to the desktop object
*/
HDESK FASTCALL
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject)
{
NTSTATUS Status;
HDESK Ret;
ASSERT(DesktopObject);
Status = ObFindHandleForObject(PsGetCurrentProcess(),
DesktopObject,
ExDesktopObjectType,
NULL,
(PHANDLE)&Ret);
if(!NT_SUCCESS(Status))
{
Status = ObOpenObjectByPointer(DesktopObject,
0,
NULL,
0,
ExDesktopObjectType,
UserMode,
(PHANDLE)&Ret);
if(!NT_SUCCESS(Status))
{
/* unable to create a handle */
DPRINT1("Unable to create a desktop handle\n");
return NULL;
}
}
return Ret;
}
PUSER_MESSAGE_QUEUE FASTCALL
@ -394,8 +444,6 @@ NtUserCreateDesktop(
0,
NULL,
(HANDLE*)&Desktop);
DesktopObject->Self = (HANDLE)Desktop;
ObDereferenceObject(DesktopObject);
ExFreePool(DesktopName.Buffer);
@ -774,10 +822,11 @@ NtUserResolveDesktopForWOW(DWORD Unknown0)
HDESK STDCALL
NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
{
PDESKTOP_OBJECT Desktop;
NTSTATUS Status;
PETHREAD Thread;
HDESK Ret;
PDESKTOP_OBJECT DesktopObject;
HDESK Ret, hThreadDesktop;
OBJECT_HANDLE_INFORMATION HandleInformation;
if(!dwThreadId)
{
@ -792,27 +841,52 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
return 0;
}
Desktop = Thread->Win32Thread->Desktop;
if(Desktop)
if(Thread->ThreadsProcess == PsGetCurrentProcess())
{
Status = ObReferenceObjectByPointer(Desktop,
0,
ExDesktopObjectType,
UserMode);
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return 0;
}
Ret = (HDESK)Desktop->Self;
ObDereferenceObject(Desktop);
/* just return the handle, we queried the desktop handle of a thread running
in the same context */
Ret = Thread->Win32Thread->hDesktop;
ObDereferenceObject(Thread);
return Ret;
}
return 0;
/* get the desktop handle and the desktop of the thread */
if(!(hThreadDesktop = Thread->Win32Thread->hDesktop) ||
!(DesktopObject = Thread->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;
}
/*
@ -825,6 +899,7 @@ NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1)
BOOL STDCALL
NtUserSetThreadDesktop(HDESK hDesktop)
{
PW32THREAD W32Thread;
PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status;
@ -841,21 +916,24 @@ NtUserSetThreadDesktop(HDESK hDesktop)
return FALSE;
}
W32Thread = PsGetWin32Thread();
/* Check for setting the same desktop as before. */
if (DesktopObject == PsGetWin32Thread()->Desktop)
if (DesktopObject == W32Thread->Desktop)
{
W32Thread->hDesktop = hDesktop;
ObDereferenceObject(DesktopObject);
return TRUE;
}
/* FIXME: Should check here to see if the thread has any windows. */
if (PsGetWin32Thread()->Desktop != NULL)
if (W32Thread->Desktop != NULL)
{
ObDereferenceObject(PsGetWin32Thread()->Desktop);
ObDereferenceObject(W32Thread->Desktop);
}
PsGetWin32Thread()->Desktop = DesktopObject;
W32Thread->Desktop = DesktopObject;
W32Thread->hDesktop = hDesktop;
return TRUE;
}