From 9daca174737d245e9dc16de024c99fff12c3633a Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sun, 23 Nov 2003 11:39:48 +0000 Subject: [PATCH] - Added test for unimplemented EnumWindowStations and EnumDesktops functions. - Small window station cleanup. svn path=/trunk/; revision=6757 --- reactos/apps/tests/enumws/enumws.c | 35 + reactos/apps/tests/enumws/makefile | 21 + reactos/include/win32k/ntuser.h | 12 +- reactos/ntoskrnl/include/internal/ex.h | 6 +- reactos/subsys/win32k/include/winsta.h | 76 +- reactos/subsys/win32k/main/dllmain.c | 17 +- reactos/subsys/win32k/makefile | 4 +- reactos/subsys/win32k/ntuser/caret.c | 18 +- reactos/subsys/win32k/ntuser/class.c | 14 +- reactos/subsys/win32k/ntuser/menu.c | 6 +- reactos/subsys/win32k/ntuser/metric.c | 10 +- reactos/subsys/win32k/ntuser/misc.c | 34 +- reactos/subsys/win32k/ntuser/msgqueue.c | 3 +- reactos/subsys/win32k/ntuser/stubs.c | 16 +- reactos/subsys/win32k/ntuser/window.c | 128 +- reactos/subsys/win32k/ntuser/winpos.c | 3 +- reactos/subsys/win32k/ntuser/winsta.c | 2157 ++++++++++++-------- reactos/subsys/win32k/objects/cursoricon.c | 30 +- 18 files changed, 1533 insertions(+), 1057 deletions(-) create mode 100644 reactos/apps/tests/enumws/enumws.c create mode 100644 reactos/apps/tests/enumws/makefile diff --git a/reactos/apps/tests/enumws/enumws.c b/reactos/apps/tests/enumws/enumws.c new file mode 100644 index 00000000000..93d5a216bb2 --- /dev/null +++ b/reactos/apps/tests/enumws/enumws.c @@ -0,0 +1,35 @@ +#include +#include + +BOOL CALLBACK +EnumDesktopProc(LPWSTR lpszWindowStation, LPARAM lParam) +{ + printf("\t%S\n", lpszWindowStation); + + return TRUE; +} + +BOOL CALLBACK +EnumWindowStationProc(LPWSTR lpszWindowStation, LPARAM lParam) +{ + HWINSTA hWinSta; + + printf("%S\n", lpszWindowStation); + hWinSta = OpenWindowStationW(lpszWindowStation, FALSE, + WINSTA_ENUMDESKTOPS); + if (hWinSta == NULL) + { + printf("\tCan't open window station.\n"); + return TRUE; + } + EnumDesktopsW(hWinSta, EnumDesktopProc, 0xdede); + + return TRUE; +} + +int main() +{ + EnumWindowStationsW(EnumWindowStationProc, 0xbadbed); + + return 0; +} diff --git a/reactos/apps/tests/enumws/makefile b/reactos/apps/tests/enumws/makefile new file mode 100644 index 00000000000..f1ad683c312 --- /dev/null +++ b/reactos/apps/tests/enumws/makefile @@ -0,0 +1,21 @@ +PATH_TO_TOP = ../../.. + +TARGET_NORC = yes + +TARGET_TYPE = program + +TARGET_APPTYPE = console + +TARGET_NAME = enumws + +TARGET_SDKLIBS = user32.a + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index 75d4f3879f3..6daa0e7d083 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -92,14 +92,12 @@ NtUserBuildMenuItemList( ULONG nBufSize, DWORD Reserved); - -DWORD -STDCALL +NTSTATUS STDCALL NtUserBuildNameList( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3); + HWINSTA hWinSta, + ULONG dwSize, + PVOID lpBuffer, + PULONG pRequiredSize); NTSTATUS STDCALL diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 8d6698b97c0..12852684a11 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -77,7 +77,11 @@ typedef struct _DESKTOP_OBJECT /* Pointer to the active queue. */ PVOID ActiveMessageQueue; /* Rectangle of the work area */ - struct RECT* WorkArea; +#ifdef __WIN32K__ + RECT WorkArea; +#else + LONG WorkArea[4]; +#endif /* Handle of the desktop window. */ HANDLE DesktopWindow; HANDLE PrevActiveWindow; diff --git a/reactos/subsys/win32k/include/winsta.h b/reactos/subsys/win32k/include/winsta.h index a2998d4dc33..8ac905f0782 100644 --- a/reactos/subsys/win32k/include/winsta.h +++ b/reactos/subsys/win32k/include/winsta.h @@ -7,18 +7,16 @@ #include #include "msgqueue.h" - #define PROCESS_WINDOW_STATION() \ ((HWINSTA)(IoGetCurrentProcess()->Win32WindowStation)) #define SET_PROCESS_WINDOW_STATION(WinSta) \ ((IoGetCurrentProcess()->Win32WindowStation) = (PVOID)(WinSta)) -WINSTATION_OBJECT *InputWindowStation; -//FAST_MUTEX InputWindowStationLock; - -extern HDC ScreenDeviceContext; +#define WINSTA_ROOT_NAME L"\\Windows\\WindowStations" +#define WINSTA_ROOT_NAME_LENGTH 23 +extern WINSTATION_OBJECT *InputWindowStation; NTSTATUS FASTCALL InitWindowStationImpl(VOID); @@ -26,41 +24,49 @@ InitWindowStationImpl(VOID); NTSTATUS FASTCALL CleanupWindowStationImpl(VOID); -NTSTATUS STDCALL -ValidateWindowStationHandle(HWINSTA WindowStation, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PWINSTATION_OBJECT *Object); +NTSTATUS FASTCALL +InitDesktopImpl(VOID); -NTSTATUS STDCALL -ValidateDesktopHandle(HDESK Desktop, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PDESKTOP_OBJECT *Object); -LRESULT CALLBACK -IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); -PDESKTOP_OBJECT FASTCALL -IntGetActiveDesktop(VOID); -PDESKTOP_OBJECT FASTCALL -IntGetDesktopObject ( HDESK hDesk ); -PUSER_MESSAGE_QUEUE FASTCALL -IntGetFocusMessageQueue(VOID); -VOID FASTCALL -IntInitializeDesktopGraphics(VOID); -VOID FASTCALL -IntEndDesktopGraphics(VOID); -HDC FASTCALL -IntGetScreenDC(VOID); -VOID STDCALL -IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue); -struct _WINDOW_OBJECT* STDCALL -IntGetCaptureWindow(VOID); -VOID STDCALL -IntSetCaptureWindow(struct _WINDOW_OBJECT* Window); +NTSTATUS FASTCALL +CleanupDesktopImpl(VOID); + +NTSTATUS FASTCALL +IntValidateWindowStationHandle( + HWINSTA WindowStation, + KPROCESSOR_MODE AccessMode, + ACCESS_MASK DesiredAccess, + PWINSTATION_OBJECT *Object); BOOL FASTCALL IntGetWindowStationObject(PWINSTATION_OBJECT Object); +LRESULT CALLBACK +IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +HDC FASTCALL +IntGetScreenDC(VOID); + +VOID FASTCALL +IntInitializeDesktopGraphics(VOID); + +VOID FASTCALL +IntEndDesktopGraphics(VOID); + +struct _WINDOW_OBJECT* FASTCALL +IntGetCaptureWindow(VOID); + +VOID FASTCALL +IntSetCaptureWindow(struct _WINDOW_OBJECT* Window); + +PUSER_MESSAGE_QUEUE FASTCALL +IntGetFocusMessageQueue(VOID); + +VOID FASTCALL +IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue); + +PDESKTOP_OBJECT FASTCALL +IntGetActiveDesktop(VOID); + #endif /* _WIN32K_WINSTA_H */ /* EOF */ diff --git a/reactos/subsys/win32k/main/dllmain.c b/reactos/subsys/win32k/main/dllmain.c index 78e703b5026..f3e41a51fb9 100644 --- a/reactos/subsys/win32k/main/dllmain.c +++ b/reactos/subsys/win32k/main/dllmain.c @@ -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.52 2003/11/19 13:19:40 weiden Exp $ +/* $Id: dllmain.c,v 1.53 2003/11/23 11:39:48 navaraf Exp $ * * Entry Point for win32k.sys */ @@ -77,10 +77,10 @@ Win32kProcessCallback (struct _EPROCESS *Process, if (Process->Win32WindowStation != NULL) { Status = - ValidateWindowStationHandle(Process->Win32WindowStation, - UserMode, - GENERIC_ALL, - &Win32Process->WindowStation); + IntValidateWindowStationHandle(Process->Win32WindowStation, + UserMode, + GENERIC_ALL, + &Win32Process->WindowStation); if (!NT_SUCCESS(Status)) { DbgPrint("Win32K: Failed to reference a window station for " @@ -217,6 +217,13 @@ DllMain ( return STATUS_UNSUCCESSFUL; } + Status = InitDesktopImpl(); + if (!NT_SUCCESS(Status)) + { + DbgPrint("Failed to initialize window station implementation!\n"); + return STATUS_UNSUCCESSFUL; + } + Status = InitWindowImpl(); if (!NT_SUCCESS(Status)) { diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 1cf626d7e2e..9c031ff7519 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.82 2003/11/02 16:33:51 ekohl Exp $ +# $Id: makefile,v 1.83 2003/11/23 11:39:48 navaraf Exp $ PATH_TO_TOP = ../.. @@ -53,7 +53,7 @@ NTUSER_OBJECTS = ntuser/callback.o ntuser/caret.o ntuser/class.o ntuser/guicheck ntuser/menu.o ntuser/message.o ntuser/metric.o ntuser/misc.o \ ntuser/msgqueue.o ntuser/painting.o ntuser/prop.o ntuser/scrollbar.o \ ntuser/stubs.o ntuser/timer.o ntuser/userobj.o ntuser/vis.o \ - ntuser/windc.o ntuser/window.o ntuser/winlock.o ntuser/winpos.o\ + ntuser/windc.o ntuser/window.o ntuser/winlock.o ntuser/winpos.o \ ntuser/winsta.o OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \ diff --git a/reactos/subsys/win32k/ntuser/caret.c b/reactos/subsys/win32k/ntuser/caret.c index bf2b00c8859..56604046c8a 100644 --- a/reactos/subsys/win32k/ntuser/caret.c +++ b/reactos/subsys/win32k/ntuser/caret.c @@ -1,4 +1,4 @@ -/* $Id: caret.c,v 1.7 2003/11/22 11:49:09 weiden Exp $ +/* $Id: caret.c,v 1.8 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -56,10 +56,10 @@ IntSetCaretBlinkTime(UINT uMSeconds) NTSTATUS Status; PWINSTATION_OBJECT WinStaObject; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -155,10 +155,10 @@ IntGetCaretBlinkTime(VOID) PWINSTATION_OBJECT WinStaObject; UINT Ret; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); diff --git a/reactos/subsys/win32k/ntuser/class.c b/reactos/subsys/win32k/ntuser/class.c index 7d2a354bc30..406c2967669 100644 --- a/reactos/subsys/win32k/ntuser/class.c +++ b/reactos/subsys/win32k/ntuser/class.c @@ -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: class.c,v 1.39 2003/11/11 20:28:21 gvg Exp $ +/* $Id: class.c,v 1.40 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -99,10 +99,10 @@ ClassReferenceClassByName(PWNDCLASS_OBJECT *Class, return(STATUS_INVALID_PARAMETER); } - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) { DPRINT("Validation of window station handle (0x%X) failed\n", @@ -218,7 +218,7 @@ IntGetClassName(struct _WINDOW_OBJECT *WindowObject, { DPRINT("About to open window station handle (0x%X)\n", PROCESS_WINDOW_STATION()); - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -399,7 +399,7 @@ NtUserRegisterClassExWOW( RTL_ATOM Atom; DPRINT("About to open window station handle (0x%X)\n", PROCESS_WINDOW_STATION()); - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); diff --git a/reactos/subsys/win32k/ntuser/menu.c b/reactos/subsys/win32k/ntuser/menu.c index c0aee24ba3a..d4ff6ca934e 100644 --- a/reactos/subsys/win32k/ntuser/menu.c +++ b/reactos/subsys/win32k/ntuser/menu.c @@ -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: menu.c,v 1.31 2003/10/04 16:04:01 weiden Exp $ +/* $Id: menu.c,v 1.32 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1108,7 +1108,7 @@ NtUserCheckMenuItem( /* - * @implemented + * @unimplemented */ HMENU STDCALL NtUserCreateMenu(VOID) @@ -1116,7 +1116,7 @@ NtUserCreateMenu(VOID) PWINSTATION_OBJECT WinStaObject; HANDLE Handle; - NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + NTSTATUS Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); diff --git a/reactos/subsys/win32k/ntuser/metric.c b/reactos/subsys/win32k/ntuser/metric.c index 42bd9034e1b..10cbe2a1650 100644 --- a/reactos/subsys/win32k/ntuser/metric.c +++ b/reactos/subsys/win32k/ntuser/metric.c @@ -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: metric.c,v 1.14 2003/09/08 18:50:00 weiden Exp $ +/* $Id: metric.c,v 1.15 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -73,10 +73,10 @@ NtUserGetSystemMetrics(ULONG Index) case SM_CXDOUBLECLK: case SM_CYDOUBLECLK: case SM_SWAPBUTTON: - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) return 0xFFFFFFFF; diff --git a/reactos/subsys/win32k/ntuser/misc.c b/reactos/subsys/win32k/ntuser/misc.c index 5947653128b..36ae0b04b7a 100644 --- a/reactos/subsys/win32k/ntuser/misc.c +++ b/reactos/subsys/win32k/ntuser/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.27 2003/11/22 11:01:28 navaraf Exp $ +/* $Id: misc.c,v 1.28 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -137,10 +137,10 @@ NtUserCallOneParam( return Result; case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON: - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) return (DWORD)FALSE; @@ -216,10 +216,10 @@ NtUserCallTwoParam( case TWOPARAM_ROUTINE_CURSORPOSITION: if(!Param1) return (DWORD)FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) return (DWORD)FALSE; @@ -321,10 +321,10 @@ NtUserSystemParametersInfo( case SPI_SETDOUBLECLKHEIGHT: case SPI_SETDOUBLECLICKTIME: { - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) return (DWORD)FALSE; @@ -441,10 +441,10 @@ NtUserGetDoubleClickTime(VOID) NTSTATUS Status; PWINSTATION_OBJECT WinStaObject; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) return (DWORD)FALSE; diff --git a/reactos/subsys/win32k/ntuser/msgqueue.c b/reactos/subsys/win32k/ntuser/msgqueue.c index a3f63c65bde..6d0dbdd55f0 100644 --- a/reactos/subsys/win32k/ntuser/msgqueue.c +++ b/reactos/subsys/win32k/ntuser/msgqueue.c @@ -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: msgqueue.c,v 1.35 2003/11/22 12:22:07 weiden Exp $ +/* $Id: msgqueue.c,v 1.36 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/subsys/win32k/ntuser/stubs.c b/reactos/subsys/win32k/ntuser/stubs.c index 1076f8b9737..ea1a450db28 100644 --- a/reactos/subsys/win32k/ntuser/stubs.c +++ b/reactos/subsys/win32k/ntuser/stubs.c @@ -1,4 +1,4 @@ -/* $Id: stubs.c,v 1.38 2003/11/22 11:01:28 navaraf Exp $ +/* $Id: stubs.c,v 1.39 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -65,20 +65,6 @@ NtUserBlockInput( } -DWORD -STDCALL -NtUserBuildNameList( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - - DWORD STDCALL NtUserCallHwnd( diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 6953b33854b..72e0cb5394d 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -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: window.c,v 1.142 2003/11/21 21:12:08 navaraf Exp $ +/* $Id: window.c,v 1.143 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -441,64 +441,6 @@ DestroyThreadWindows(struct _ETHREAD *Thread) } -HWND STDCALL -IntCreateDesktopWindow(PWINSTATION_OBJECT WindowStation, - PWNDCLASS_OBJECT DesktopClass, - ULONG Width, ULONG Height) -{ - PWSTR WindowName; - HWND Handle; - PWINDOW_OBJECT WindowObject; - - /* Create the window object. */ - WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable, - &Handle, - otWindow, - sizeof(WINDOW_OBJECT)); - if (!WindowObject) - { - return((HWND)0); - } - - /* - * Fill out the structure describing it. - */ - WindowObject->Class = DesktopClass; - WindowObject->ExStyle = 0; - WindowObject->Style = WS_VISIBLE; - WindowObject->Flags = 0; - WindowObject->Parent = NULL; - WindowObject->Owner = NULL; - WindowObject->IDMenu = 0; - WindowObject->Instance = NULL; - WindowObject->Self = Handle; - WindowObject->MessageQueue = NULL; - WindowObject->ExtraData = NULL; - WindowObject->ExtraDataSize = 0; - WindowObject->WindowRect.left = 0; - WindowObject->WindowRect.top = 0; - WindowObject->WindowRect.right = Width; - WindowObject->WindowRect.bottom = Height; - WindowObject->ClientRect = WindowObject->WindowRect; - WindowObject->UserData = 0; - /*FIXME: figure out what the correct strange value is and what to do with it (and how to set the wndproc values correctly) */ - WindowObject->WndProcA = DesktopClass->lpfnWndProcA; - WindowObject->WndProcW = DesktopClass->lpfnWndProcW; - WindowObject->OwnerThread = PsGetCurrentThread(); - WindowObject->FirstChild = NULL; - WindowObject->LastChild = NULL; - WindowObject->PrevSibling = NULL; - WindowObject->NextSibling = NULL; - - ExInitializeFastMutex(&WindowObject->ChildrenListLock); - - WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP")); - wcscpy(WindowName, L"DESKTOP"); - RtlInitUnicodeString(&WindowObject->WindowName, WindowName); - - return(Handle); -} - HWND FASTCALL IntGetActiveWindow(VOID) @@ -655,6 +597,64 @@ IntGetWindowThreadProcessId(PWINDOW_OBJECT Wnd, PDWORD pid) } +HWND STDCALL +IntCreateDesktopWindow(PWINSTATION_OBJECT WindowStation, + PWNDCLASS_OBJECT DesktopClass, + ULONG Width, ULONG Height) +{ + PWSTR WindowName; + HWND Handle; + PWINDOW_OBJECT WindowObject; + + /* Create the window object. */ + WindowObject = (PWINDOW_OBJECT)ObmCreateObject(WindowStation->HandleTable, + &Handle, + otWindow, + sizeof(WINDOW_OBJECT)); + if (!WindowObject) + { + return((HWND)0); + } + + /* + * Fill out the structure describing it. + */ + WindowObject->Class = DesktopClass; + WindowObject->ExStyle = 0; + WindowObject->Style = WS_VISIBLE; + WindowObject->Flags = 0; + WindowObject->Parent = NULL; + WindowObject->Owner = NULL; + WindowObject->IDMenu = 0; + WindowObject->Instance = NULL; + WindowObject->Self = Handle; + WindowObject->MessageQueue = NULL; + WindowObject->ExtraData = NULL; + WindowObject->ExtraDataSize = 0; + WindowObject->WindowRect.left = 0; + WindowObject->WindowRect.top = 0; + WindowObject->WindowRect.right = Width; + WindowObject->WindowRect.bottom = Height; + WindowObject->ClientRect = WindowObject->WindowRect; + WindowObject->UserData = 0; + /*FIXME: figure out what the correct strange value is and what to do with it (and how to set the wndproc values correctly) */ + WindowObject->WndProcA = DesktopClass->lpfnWndProcA; + WindowObject->WndProcW = DesktopClass->lpfnWndProcW; + WindowObject->OwnerThread = PsGetCurrentThread(); + WindowObject->FirstChild = NULL; + WindowObject->LastChild = NULL; + WindowObject->PrevSibling = NULL; + WindowObject->NextSibling = NULL; + + ExInitializeFastMutex(&WindowObject->ChildrenListLock); + + WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP")); + wcscpy(WindowName, L"DESKTOP"); + RtlInitUnicodeString(&WindowObject->WindowName, WindowName); + + return(Handle); +} + VOID FASTCALL IntInitDesktopWindow(ULONG Width, ULONG Height) { @@ -1236,9 +1236,11 @@ NtUserBuildHwndList( KIRQL OldIrql; PWINDOW_OBJECT Child, WndDesktop; +#if 0 if ( hDesktop ) DesktopObject = IntGetDesktopObject ( hDesktop ); else +#endif DesktopObject = IntGetActiveDesktop(); if (!DesktopObject) { @@ -1387,10 +1389,10 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* Check the window station. */ DPRINT("IoGetCurrentProcess() %X\n", IoGetCurrentProcess()); DPRINT("PROCESS_WINDOW_STATION %X\n", PROCESS_WINDOW_STATION()); - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&WindowName); diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index 4de3af95b8d..11ece69e2bb 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -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: winpos.c,v 1.45 2003/11/21 17:01:16 navaraf Exp $ +/* $Id: winpos.c,v 1.46 2003/11/23 11:39:48 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index 9e6fae95351..30ec5f5ec0f 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -15,898 +15,1293 @@ * 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: winsta.c,v 1.44 2003/11/21 16:36:26 weiden Exp $ * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Window stations and desktops - * FILE: subsys/win32k/ntuser/winsta.c - * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) - * REVISION HISTORY: + * $Id: winsta.c,v 1.45 2003/11/23 11:39:48 navaraf Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Window stations and Desktops + * FILE: subsys/win32k/ntuser/winsta.c + * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * REVISION HISTORY: * 06-06-2001 CSH Created - * NOTES: Exported functions set the Win32 last error value - * on errors. The value can be retrieved with the Win32 - * function GetLastError(). - * TODO: The process window station is created on - * the first USER32/GDI32 call not related - * to window station/desktop handling + * NOTES: Exported functions set the Win32 last error value + * on errors. The value can be retrieved with the Win32 + * function GetLastError(). + * TODO: The process window station is created on + * the first USER32/GDI32 call not related + * to window station/desktop handling */ /* INCLUDES ******************************************************************/ +#define __WIN32K__ #define NTOS_MODE_KERNEL #include #include #include #include #include -#include -#include #include #include -#include -#include -#include #include #include -#include +#include +#include +#include #define NDEBUG #include /* GLOBALS *******************************************************************/ -#define WINSTA_ROOT_NAME L"\\Windows\\WindowStations" +/* Currently active window station */ +PWINSTATION_OBJECT InputWindowStation = NULL; +/* Currently active desktop */ +STATIC PDESKTOP_OBJECT InputDesktop = NULL; +STATIC HDESK InputDesktopHandle = NULL; LRESULT CALLBACK IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); STATIC PWNDCLASS_OBJECT DesktopWindowClass; - -/* Currently active desktop */ -STATIC HDESK InputDesktopHandle = NULL; -STATIC PDESKTOP_OBJECT InputDesktop = NULL; -//STATIC PWINSTATION_OBJECT InputWindowStation = NULL; - HDC ScreenDeviceContext = NULL; -/* FUNCTIONS *****************************************************************/ - - -PDESKTOP_OBJECT FASTCALL -IntGetActiveDesktop(VOID) -{ - return(InputDesktop); -} - -PDESKTOP_OBJECT FASTCALL -IntGetDesktopObject ( HDESK hDesk ) -{ - /* FIXME - this obviously isn't right */ - return IntGetActiveDesktop(); -} - -VOID STDCALL -IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue) -{ - PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); - - pdo->ActiveMessageQueue = NewQueue; -} - -PUSER_MESSAGE_QUEUE FASTCALL -IntGetFocusMessageQueue(VOID) -{ - PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); - - if (!pdo) - { - DPRINT("No active desktop\n"); - return(NULL); - } - - return (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue; -} - -PWINDOW_OBJECT STDCALL -IntGetCaptureWindow(VOID) -{ - PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); - if (!pdo) - { - DPRINT("No active desktop\n"); - return(NULL); - } - return(pdo->CaptureWindow); -} - -VOID STDCALL -IntSetCaptureWindow(PWINDOW_OBJECT Window) -{ - PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); - if (!pdo) - { - DPRINT("No active desktop\n"); - } - pdo->CaptureWindow = Window; -} +/* INITALIZATION FUNCTIONS ****************************************************/ NTSTATUS FASTCALL InitWindowStationImpl(VOID) { - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE WindowStationsDirectory; - UNICODE_STRING UnicodeString; - NTSTATUS Status; - WNDCLASSEXW wcx; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE WindowStationsDirectory; + UNICODE_STRING UnicodeString; + NTSTATUS Status; - InputWindowStation = NULL; - - /* - * Create the '\Windows\WindowStations' directory - */ - RtlRosInitUnicodeStringFromLiteral(&UnicodeString, - WINSTA_ROOT_NAME); + /* + * Create the '\Windows\WindowStations' directory + */ - InitializeObjectAttributes(&ObjectAttributes, - &UnicodeString, - 0, - NULL, - NULL); - - Status = ZwCreateDirectoryObject(&WindowStationsDirectory, - 0, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { + RtlInitUnicodeString(&UnicodeString, WINSTA_ROOT_NAME); + InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, + 0, NULL, NULL); + Status = ZwCreateDirectoryObject(&WindowStationsDirectory, 0, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { DPRINT("Could not create \\Windows\\WindowStations directory " "(Status 0x%X)\n", Status); return Status; - } + } - /* - * Create the desktop window class - */ - wcx.style = 0; - wcx.lpfnWndProc = IntDesktopWindowProc; - wcx.cbClsExtra = wcx.cbWndExtra = 0; - wcx.hInstance = wcx.hIcon = wcx.hCursor = NULL; - wcx.hbrBackground = NULL; - wcx.lpszMenuName = NULL; - wcx.lpszClassName = L"DesktopWindowClass"; - DesktopWindowClass = IntCreateClass(&wcx, TRUE, IntDesktopWindowProc, (RTL_ATOM)32880); - - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } NTSTATUS FASTCALL CleanupWindowStationImpl(VOID) { - return STATUS_SUCCESS; + return STATUS_SUCCESS; } - -NTSTATUS STDCALL -ValidateWindowStationHandle(HWINSTA WindowStation, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PWINSTATION_OBJECT *Object) +NTSTATUS FASTCALL +InitDesktopImpl(VOID) { - NTSTATUS Status; + WNDCLASSEXW wcx; + + /* + * Create the desktop window class + */ + wcx.style = 0; + wcx.lpfnWndProc = IntDesktopWindowProc; + wcx.cbClsExtra = wcx.cbWndExtra = 0; + wcx.hInstance = wcx.hIcon = wcx.hCursor = NULL; + wcx.hbrBackground = NULL; + wcx.lpszMenuName = NULL; + wcx.lpszClassName = L"DesktopWindowClass"; + DesktopWindowClass = IntCreateClass(&wcx, TRUE, IntDesktopWindowProc, + (RTL_ATOM)32880); - Status = ObReferenceObjectByHandle(WindowStation, - DesiredAccess, - ExWindowStationObjectType, - AccessMode, - (PVOID*)Object, - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - } - - return Status; + return STATUS_SUCCESS; } -NTSTATUS STDCALL -ValidateDesktopHandle(HDESK Desktop, - KPROCESSOR_MODE AccessMode, - ACCESS_MASK DesiredAccess, - PDESKTOP_OBJECT *Object) +NTSTATUS FASTCALL +CleanupDesktopImpl(VOID) { - NTSTATUS Status; + /* FIXME: Unregister the desktop window class */ - Status = ObReferenceObjectByHandle(Desktop, - DesiredAccess, - ExDesktopObjectType, - AccessMode, - (PVOID*)Object, - NULL); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - } + return STATUS_SUCCESS; +} + +/* PRIVATE FUNCTIONS **********************************************************/ + +/* + * IntGetFullWindowStationName + * + * Get a full desktop object name from a name specified in + * NtUserCreateWindowStation, NtUserOpenWindowStation, NtUserCreateDesktop + * or NtUserOpenDesktop. + * + * Return Value + * TRUE on success, FALSE on failure. + */ + +BOOL FASTCALL +IntGetFullWindowStationName( + OUT PUNICODE_STRING FullName, + IN PUNICODE_STRING WinStaName, + IN OPTIONAL PUNICODE_STRING DesktopName) +{ + PWCHAR Buffer; + + FullName->Length = (WINSTA_ROOT_NAME_LENGTH + 1) * sizeof(WCHAR) + + WinStaName->Length; + if (DesktopName != NULL) + FullName->Length += DesktopName->Length + sizeof(WCHAR); + FullName->Buffer = ExAllocatePool(NonPagedPool, FullName->Length); + if (FullName->Buffer == NULL) + { + return FALSE; + } + + Buffer = FullName->Buffer; + memcpy(Buffer, WINSTA_ROOT_NAME, WINSTA_ROOT_NAME_LENGTH * sizeof(WCHAR)); + Buffer += WINSTA_ROOT_NAME_LENGTH; + memcpy(Buffer, L"\\", sizeof(WCHAR)); + Buffer ++; + memcpy(Buffer, WinStaName->Buffer, WinStaName->Length); + + if (DesktopName != NULL) + { + Buffer += WinStaName->Length / sizeof(WCHAR); + memcpy(Buffer, L"\\", sizeof(WCHAR)); + Buffer ++; + memcpy(Buffer, DesktopName->Buffer, DesktopName->Length); + } + + return TRUE; +} + +/* + * IntValidateWindowStationHandle + * + * Validates the window station handle. + * + * Remarks + * If the function succeeds, the handle remains referenced. If the + * fucntion fails, last error is set. + */ + +NTSTATUS FASTCALL +IntValidateWindowStationHandle( + HWINSTA WindowStation, + KPROCESSOR_MODE AccessMode, + ACCESS_MASK DesiredAccess, + PWINSTATION_OBJECT *Object) +{ + NTSTATUS Status; - return Status; + Status = ObReferenceObjectByHandle( + WindowStation, + DesiredAccess, + ExWindowStationObjectType, + AccessMode, + (PVOID*)Object, + NULL); + + if (!NT_SUCCESS(Status)) + SetLastNtError(Status); + + return Status; +} + +BOOL FASTCALL +IntGetWindowStationObject(PWINSTATION_OBJECT Object) +{ + NTSTATUS Status; + + Status = ObReferenceObjectByPointer( + Object, + KernelMode, + ExWindowStationObjectType, + 0); + + return NT_SUCCESS(Status); +} + +LRESULT CALLBACK +IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_CREATE: + return 0; + + case WM_NCCREATE: + return 1; + + case WM_ERASEBKGND: + return NtUserPaintDesktop((HDC)wParam); + + default: + return 0; + } } /* - * FUNCTION: - * Closes a window station handle - * ARGUMENTS: - * hWinSta = Handle to the window station - * RETURNS: - * Status - * NOTES: - * The window station handle can be created with - * NtUserCreateWindowStation() or NtUserOpenWindowStation(). - * Attemps to close a handle to the window station assigned - * to the calling process will fail + * IntValidateDesktopHandle + * + * Validates the desktop handle. + * + * Remarks + * If the function succeeds, the handle remains referenced. If the + * fucntion fails, last error is set. */ + +NTSTATUS FASTCALL +IntValidateDesktopHandle( + HDESK Desktop, + KPROCESSOR_MODE AccessMode, + ACCESS_MASK DesiredAccess, + PDESKTOP_OBJECT *Object) +{ + NTSTATUS Status; + + Status = ObReferenceObjectByHandle( + Desktop, + DesiredAccess, + ExDesktopObjectType, + AccessMode, + (PVOID*)Object, + NULL); + + if (!NT_SUCCESS(Status)) + SetLastNtError(Status); + + return Status; +} + +VOID FASTCALL +IntInitializeDesktopGraphics(VOID) +{ + ScreenDeviceContext = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL); + GDIOBJ_MarkObjectGlobal(ScreenDeviceContext); + EnableMouse(ScreenDeviceContext); + /* not the best place to load the cursors but it's good for now */ + IntLoadDefaultCursors(FALSE); + NtUserAcquireOrReleaseInputOwnership(FALSE); +} + +VOID FASTCALL +IntEndDesktopGraphics(VOID) +{ + NtUserAcquireOrReleaseInputOwnership(TRUE); + EnableMouse(FALSE); + if (NULL != ScreenDeviceContext) + { + GDIOBJ_UnmarkObjectGlobal(ScreenDeviceContext); + NtGdiDeleteDC(ScreenDeviceContext); + ScreenDeviceContext = NULL; + } +} + +HDC FASTCALL +IntGetScreenDC(VOID) +{ + return ScreenDeviceContext; +} + +PDESKTOP_OBJECT FASTCALL +IntGetActiveDesktop(VOID) +{ + return InputDesktop; +} + +PWINDOW_OBJECT FASTCALL +IntGetCaptureWindow(VOID) +{ + PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); + if (!pdo) + { + DPRINT("No active desktop\n"); + return NULL; + } + return pdo->CaptureWindow; +} + +VOID FASTCALL +IntSetCaptureWindow(PWINDOW_OBJECT Window) +{ + PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); + if (!pdo) + { + DPRINT("No active desktop\n"); + return; + } + pdo->CaptureWindow = Window; +} + +PUSER_MESSAGE_QUEUE FASTCALL +IntGetFocusMessageQueue(VOID) +{ + PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); + if (!pdo) + { + DPRINT("No active desktop\n"); + return(NULL); + } + return (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue; +} + +VOID FASTCALL +IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue) +{ + PDESKTOP_OBJECT pdo = IntGetActiveDesktop(); + if (!pdo) + { + DPRINT("No active desktop\n"); + return; + } + pdo->ActiveMessageQueue = NewQueue; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * NtUserCreateWindowStation + * + * Creates a new window station. + * + * Parameters + * lpszWindowStationName + * Pointer to a null-terminated string specifying the name of the + * window station to be created. Window station names are + * case-insensitive and cannot contain backslash characters (\). + * Only members of the Administrators group are allowed to specify a + * name. + * + * dwDesiredAccess + * Requested type of access + * + * lpSecurity + * Security descriptor + * + * Unknown3, Unknown4, Unknown5 + * Unused + * + * Return Value + * If the function succeeds, the return value is a handle to the newly + * created window station. If the specified window station already + * exists, the function succeeds and returns a handle to the existing + * window station. If the function fails, the return value is NULL. + * + * Todo + * Correct the prototype to match the Windows one (with 7 parameters + * on Windows XP). + * + * Status + * @implemented + */ + +HWINSTA STDCALL +NtUserCreateWindowStation( + PUNICODE_STRING lpszWindowStationName, + ACCESS_MASK dwDesiredAccess, + LPSECURITY_ATTRIBUTES lpSecurity, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5) +{ + UNICODE_STRING WindowStationName; + PWINSTATION_OBJECT WindowStationObject; + HWINSTA WindowStation; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + + /* + * Generate full window station name + */ + + if (!IntGetFullWindowStationName(&WindowStationName, lpszWindowStationName, + NULL)) + { + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return 0; + } + + /* + * Try to open already existing window station + */ + + DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); + + /* Initialize ObjectAttributes for the window station object */ + InitializeObjectAttributes( + &ObjectAttributes, + &WindowStationName, + 0, + NULL, + NULL); + + Status = ObOpenObjectByName( + &ObjectAttributes, + ExWindowStationObjectType, + NULL, + UserMode, + dwDesiredAccess, + NULL, + &WindowStation); + + if (NT_SUCCESS(Status)) + { + DPRINT("Successfully opened window station (%wZ)\n", WindowStationName); + ExFreePool(WindowStationName.Buffer); + return (HWINSTA)WindowStation; + } + + /* + * No existing window station found, try to create new one + */ + + DPRINT("Creating window station (%wZ)\n", &WindowStationName); + + Status = ObCreateObject( + ExGetPreviousMode(), + ExWindowStationObjectType, + &ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(WINSTATION_OBJECT), + 0, + 0, + (PVOID*)&WindowStationObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); + ExFreePool(WindowStationName.Buffer); + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return 0; + } + + Status = ObInsertObject( + (PVOID)WindowStationObject, + NULL, + STANDARD_RIGHTS_REQUIRED, + 0, + NULL, + &WindowStation); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); + ExFreePool(WindowStationName.Buffer); + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + ObDereferenceObject(WindowStationObject); + return 0; + } + + /* + * Initialize the new window station object + */ + + WindowStationObject->HandleTable = ObmCreateHandleTable(); + if (!WindowStationObject->HandleTable) + { + DPRINT("Failed creating handle table\n"); + ExFreePool(WindowStationName.Buffer); + ObDereferenceObject(WindowStationObject); + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return 0; + } + + InitHotKeys(WindowStationObject); + + ExInitializeFastMutex(&WindowStationObject->SystemCursor.CursorMutex); + WindowStationObject->SystemCursor.Enabled = FALSE; + WindowStationObject->SystemCursor.ButtonsDown = 0; + WindowStationObject->SystemCursor.x = (LONG)0; + WindowStationObject->SystemCursor.y = (LONG)0; + WindowStationObject->SystemCursor.CursorClipInfo.IsClipped = FALSE; + WindowStationObject->SystemCursor.LastBtnDown = 0; + WindowStationObject->SystemCursor.CurrentCursorObject = NULL; + WindowStationObject->SystemCursor.ShowingCursor = 0; + + /* FIXME: Obtain the following information from the registry */ + WindowStationObject->SystemCursor.SwapButtons = FALSE; + WindowStationObject->SystemCursor.SafetySwitch = FALSE; + WindowStationObject->SystemCursor.SafetySwitch2 = TRUE; + WindowStationObject->SystemCursor.DblClickSpeed = 500; + WindowStationObject->SystemCursor.DblClickWidth = 4; + WindowStationObject->SystemCursor.DblClickHeight = 4; + + if (!IntSetupCurIconHandles(WindowStationObject)) + { + DPRINT1("Setting up the Cursor/Icon Handle table failed!\n"); + /* FIXME: Complain more loudly? */ + } + + DPRINT("Window station successfully created (%wZ)\n", &WindowStationName); + ExFreePool(WindowStationName.Buffer); + + return WindowStation; +} + +/* + * NtUserOpenWindowStation + * + * Opens an existing window station. + * + * Parameters + * lpszWindowStationName + * Name of the existing window station. + * + * dwDesiredAccess + * Requested type of access. + * + * Return Value + * If the function succeeds, the return value is the handle to the + * specified window station. If the function fails, the return value + * is NULL. + * + * Remarks + * The returned handle can be closed with NtUserCloseWindowStation. + * + * Status + * @implemented + */ + +HWINSTA STDCALL +NtUserOpenWindowStation( + PUNICODE_STRING lpszWindowStationName, + ACCESS_MASK dwDesiredAccess) +{ + UNICODE_STRING WindowStationName; + HWINSTA WindowStation; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + + /* + * Generate full window station name + */ + + if (!IntGetFullWindowStationName(&WindowStationName, lpszWindowStationName, + NULL)) + { + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + return 0; + } + + DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); + + /* Initialize ObjectAttributes for the window station object */ + InitializeObjectAttributes( + &ObjectAttributes, + &WindowStationName, + 0, + NULL, + NULL); + + Status = ObOpenObjectByName( + &ObjectAttributes, + ExDesktopObjectType, + NULL, + UserMode, + dwDesiredAccess, + NULL, + &WindowStation); + + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + ExFreePool(WindowStationName.Buffer); + return 0; + } + + DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName); + ExFreePool(WindowStationName.Buffer); + + return WindowStation; +} + +/* + * NtUserCloseWindowStation + * + * Closes a window station handle. + * + * Parameters + * hWinSta + * Handle to the window station. + * + * Return Value + * Status + * + * Remarks + * The window station handle can be created with NtUserCreateWindowStation + * or NtUserOpenWindowStation. Attemps to close a handle to the window + * station assigned to the calling process will fail. + * + * Status + * @implemented + */ + BOOL STDCALL NtUserCloseWindowStation( - HWINSTA hWinSta) + HWINSTA hWinSta) { - PWINSTATION_OBJECT Object; - NTSTATUS Status; + PWINSTATION_OBJECT Object; + NTSTATUS Status; - DPRINT("About to close window station handle (0x%X)\n", hWinSta); + DPRINT("About to close window station handle (0x%X)\n", hWinSta); - Status = ValidateWindowStationHandle( - hWinSta, - KernelMode, - 0, - &Object); - if (!NT_SUCCESS(Status)) { - DPRINT("Validation of window station handle (0x%X) failed\n", hWinSta); - return FALSE; - } + Status = IntValidateWindowStationHandle( + hWinSta, + KernelMode, + 0, + &Object); - ObDereferenceObject(Object); + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of window station handle (0x%X) failed\n", hWinSta); + return FALSE; + } - DPRINT("Closing window station handle (0x%X)\n", hWinSta); + ObDereferenceObject(Object); - Status = ZwClose(hWinSta); - if (!NT_SUCCESS(Status)) { - SetLastNtError(Status); - return FALSE; - } else { - return TRUE; - } + DPRINT("Closing window station handle (0x%X)\n", hWinSta); + + Status = ZwClose(hWinSta); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + + return TRUE; } /* - * FUNCTION: - * Creates a new window station - * ARGUMENTS: - * lpszWindowStationName = Name of the new window station - * dwDesiredAccess = Requested type of access - * lpSecurity = Security descriptor - * Unknown3 = Unused - * Unknown4 = Unused - * Unknown5 = Unused - * RETURNS: - * Handle to the new window station that can be closed with - * NtUserCloseWindowStation() - * Zero on failure + * NtUserGetObjectInformation + * + * The NtUserGetObjectInformation function retrieves information about a + * window station or desktop object. + * + * Parameters + * hObj + * Handle to the window station or desktop object for which to + * return information. This can be a handle of type HDESK or HWINSTA + * (for example, a handle returned by NtUserCreateWindowStation, + * NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop). + * + * nIndex + * Specifies the object information to be retrieved. + * + * pvInfo + * Pointer to a buffer to receive the object information. + * + * nLength + * Specifies the size, in bytes, of the buffer pointed to by the + * pvInfo parameter. + * + * lpnLengthNeeded + * Pointer to a variable receiving the number of bytes required to + * store the requested information. If this variable's value is + * greater than the value of the nLength parameter when the function + * returns, the function returns FALSE, and none of the information + * is copied to the pvInfo buffer. If the value of the variable pointed + * to by lpnLengthNeeded is less than or equal to the value of nLength, + * the entire information block is copied. + * + * Return Value + * If the function succeeds, the return value is nonzero. If the function + * fails, the return value is zero. + * + * Status + * @unimplemented */ -HWINSTA STDCALL -NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING WindowStationName; - PWINSTATION_OBJECT WinStaObject; - WCHAR NameBuffer[MAX_PATH]; - NTSTATUS Status; - HWINSTA WinSta; - wcscpy(NameBuffer, WINSTA_ROOT_NAME); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, lpszWindowStationName->Buffer); - RtlInitUnicodeString(&WindowStationName, NameBuffer); - - DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes(&ObjectAttributes, - &WindowStationName, - 0, - NULL, - NULL); - - Status = ObOpenObjectByName(&ObjectAttributes, - ExWindowStationObjectType, - NULL, - UserMode, - dwDesiredAccess, - NULL, - &WinSta); - if (NT_SUCCESS(Status)) - { - DPRINT("Successfully opened window station (%wZ)\n", WindowStationName); - return((HWINSTA)WinSta); - } - - DPRINT("Creating window station (%wZ)\n", &WindowStationName); - - Status = ObCreateObject(ExGetPreviousMode(), - ExWindowStationObjectType, - &ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(WINSTATION_OBJECT), - 0, - 0, - (PVOID*)&WinStaObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return (HWINSTA)0; - } - - Status = ObInsertObject ((PVOID)WinStaObject, - NULL, - STANDARD_RIGHTS_REQUIRED, - 0, - NULL, - &WinSta); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed creating window station (%wZ)\n", &WindowStationName); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - ObDereferenceObject(WinStaObject); - return (HWINSTA)0; - } - - WinStaObject->HandleTable = ObmCreateHandleTable(); - if (!WinStaObject->HandleTable) - { - DPRINT("Failed creating handle table\n"); - ObDereferenceObject(WinStaObject); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return((HWINSTA)0); - } - - InitHotKeys(WinStaObject); - - ExInitializeFastMutex(&WinStaObject->SystemCursor.CursorMutex); - WinStaObject->SystemCursor.Enabled = FALSE; - WinStaObject->SystemCursor.ButtonsDown = 0; - WinStaObject->SystemCursor.x = (LONG)0; - WinStaObject->SystemCursor.y = (LONG)0; - WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE; - WinStaObject->SystemCursor.LastBtnDown = 0; - WinStaObject->SystemCursor.CurrentCursorObject = NULL; - WinStaObject->SystemCursor.ShowingCursor = 0; - - /* FIXME Obtain the following information from the registry */ - WinStaObject->SystemCursor.SwapButtons = FALSE; - WinStaObject->SystemCursor.SafetySwitch = FALSE; - WinStaObject->SystemCursor.SafetySwitch2 = TRUE; - WinStaObject->SystemCursor.DblClickSpeed = 500; - WinStaObject->SystemCursor.DblClickWidth = 4; - WinStaObject->SystemCursor.DblClickHeight = 4; - - if(!IntSetupCurIconHandles(WinStaObject)) - { - DbgPrint("Setting up the Cursor/Icon Handle table failed!\n"); - } - - DPRINT("Window station successfully created (%wZ)\n", &WindowStationName); - - return((HWINSTA)WinSta); -} - -BOOL -STDCALL +BOOL STDCALL NtUserGetObjectInformation( - HANDLE hObject, - DWORD nIndex, - PVOID pvInformation, - DWORD nLength, - PDWORD nLengthNeeded) + HANDLE hObject, + DWORD nIndex, + PVOID pvInformation, + DWORD nLength, + PDWORD nLengthNeeded) { - return FALSE; + SetLastNtError(STATUS_UNSUCCESSFUL); + return FALSE; } /* - * FUNCTION: - * Returns a handle to the current process window station - * ARGUMENTS: - * None - * RETURNS: - * Handle to the window station assigned to the current process - * Zero on failure - * NOTES: - * The handle need not be closed by the caller + * NtUserSetObjectInformation + * + * The NtUserSetObjectInformation function sets information about a + * window station or desktop object. + * + * Parameters + * hObj + * Handle to the window station or desktop object for which to set + * object information. This value can be a handle of type HDESK or + * HWINSTA. + * + * nIndex + * Specifies the object information to be set. + * + * pvInfo + * Pointer to a buffer containing the object information. + * + * nLength + * Specifies the size, in bytes, of the information contained in the + * buffer pointed to by pvInfo. + * + * Return Value + * If the function succeeds, the return value is nonzero. If the function + * fails the return value is zero. + * + * Status + * @unimplemented */ -HWINSTA -STDCALL -NtUserGetProcessWindowStation(VOID) -{ - return PROCESS_WINDOW_STATION(); -} - -BOOL -STDCALL -NtUserLockWindowStation( - HWINSTA hWindowStation) -{ - UNIMPLEMENTED - - return 0; -} - -/* - * FUNCTION: - * Opens an existing window station - * ARGUMENTS: - * lpszWindowStationName = Name of the existing window station - * dwDesiredAccess = Requested type of access - * RETURNS: - * Handle to the window station - * Zero on failure - * NOTES: - * The returned handle can be closed with NtUserCloseWindowStation() - */ -HWINSTA -STDCALL -NtUserOpenWindowStation( - PUNICODE_STRING lpszWindowStationName, - ACCESS_MASK dwDesiredAccess) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING WindowStationName; - //PWINSTATION_OBJECT WinStaObject; - WCHAR NameBuffer[MAX_PATH]; - NTSTATUS Status; - HWINSTA WinSta; - - wcscpy(NameBuffer, WINSTA_ROOT_NAME); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, lpszWindowStationName->Buffer); - RtlInitUnicodeString(&WindowStationName, NameBuffer); - - DPRINT("Trying to open window station (%wZ)\n", &WindowStationName); - - /* Initialize ObjectAttributes for the window station object */ - InitializeObjectAttributes( - &ObjectAttributes, - &WindowStationName, - 0, - NULL, - NULL); - - Status = ObOpenObjectByName( - &ObjectAttributes, - ExDesktopObjectType, - NULL, - UserMode, - dwDesiredAccess, - NULL, - &WinSta); - if (NT_SUCCESS(Status)) - { - DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName); - return (HWINSTA)WinSta; - } - - SetLastNtError(Status); - return (HWINSTA)0; -} BOOL STDCALL NtUserSetObjectInformation( - HANDLE hObject, - DWORD nIndex, - PVOID pvInformation, - DWORD nLength) + HANDLE hObject, + DWORD nIndex, + PVOID pvInformation, + DWORD nLength) { - /* FIXME: ZwQueryObject */ - /* FIXME: ZwSetInformationObject */ - SetLastNtError(STATUS_UNSUCCESSFUL); - return FALSE; + /* FIXME: ZwQueryObject */ + /* FIXME: ZwSetInformationObject */ + SetLastNtError(STATUS_UNSUCCESSFUL); + return FALSE; } /* - * FUNCTION: - * Assigns a window station to the current process - * ARGUMENTS: - * hWinSta = Handle to the window station - * RETURNS: - * Status + * NtUserGetProcessWindowStation + * + * Returns a handle to the current process window station. + * + * Return Value + * If the function succeeds, the return value is handle to the window + * station assigned to the current process. If the function fails, the + * return value is NULL. + * + * Status + * @implemented */ + +HWINSTA STDCALL +NtUserGetProcessWindowStation(VOID) +{ + return PROCESS_WINDOW_STATION(); +} + +/* + * NtUserSetProcessWindowStation + * + * Assigns a window station to the current process. + * + * Parameters + * hWinSta + * Handle to the window station. + * + * Return Value + * Status + * + * Status + * @implemented + */ + BOOL STDCALL NtUserSetProcessWindowStation(HWINSTA hWindowStation) { - PWINSTATION_OBJECT Object; - PW32PROCESS Win32Process; - NTSTATUS Status; + PWINSTATION_OBJECT Object; + PW32PROCESS Win32Process; + NTSTATUS Status; - DPRINT("About to set process window station with handle (0x%X)\n", - hWindowStation); + DPRINT("About to set process window station with handle (0x%X)\n", + hWindowStation); - Status = ValidateWindowStationHandle(hWindowStation, - KernelMode, - 0, - &Object); - if (!NT_SUCCESS(Status)) - { + Status = IntValidateWindowStationHandle( + hWindowStation, + KernelMode, + 0, + &Object); + + if (!NT_SUCCESS(Status)) + { DPRINT("Validation of window station handle (0x%X) failed\n", - hWindowStation); + hWindowStation); return FALSE; - } + } - Win32Process = PsGetWin32Process(); - if (NULL == Win32Process) - { + Win32Process = PsGetWin32Process(); + if (Win32Process == NULL) + { ObDereferenceObject(Object); - } - else - { - if (NULL != Win32Process->WindowStation) - { - ObDereferenceObject(Win32Process->WindowStation); - } + } + else + { + if (Win32Process->WindowStation != NULL) + ObDereferenceObject(Win32Process->WindowStation); Win32Process->WindowStation = Object; - } + } - SET_PROCESS_WINDOW_STATION(hWindowStation); - DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n", - IoGetCurrentProcess()->Win32WindowStation); - - return TRUE; -} - -DWORD -STDCALL -NtUserSetWindowStationUser( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - -BOOL -STDCALL -NtUserUnlockWindowStation( - HWINSTA hWindowStation) -{ - UNIMPLEMENTED - - return FALSE; -} - - -/* - * FUNCTION: - * Closes a desktop handle - * ARGUMENTS: - * hDesktop = Handle to the desktop - * RETURNS: - * Status - * NOTES: - * The desktop handle can be created with NtUserCreateDesktop() or - * NtUserOpenDesktop(). - * The function will fail if any thread in the calling process is using the - * specified desktop handle or if the handle refers to the initial desktop - * of the calling process - */ -BOOL -STDCALL -NtUserCloseDesktop( - HDESK hDesktop) -{ - PDESKTOP_OBJECT Object; - NTSTATUS Status; - - DPRINT("About to close desktop handle (0x%X)\n", hDesktop); - - Status = ValidateDesktopHandle( - hDesktop, - KernelMode, - 0, - &Object); - if (!NT_SUCCESS(Status)) { - DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - return FALSE; - } - - ObDereferenceObject(Object); - - DPRINT("Closing desktop handle (0x%X)\n", hDesktop); - - Status = ZwClose(hDesktop); - if (!NT_SUCCESS(Status)) { - SetLastNtError(Status); - return FALSE; - } else { - return TRUE; - } -} - -/* - * FUNCTION: - * Creates a new desktop - * ARGUMENTS: - * lpszDesktopName = Name of the new desktop - * dwFlags = Interaction flags - * dwDesiredAccess = Requested type of access - * lpSecurity = Security descriptor - * hWindowStation = Handle to window station on which to create the desktop - * RETURNS: - * Handle to the new desktop that can be closed with NtUserCloseDesktop() - * Zero on failure - */ -HDESK STDCALL -NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName, - DWORD dwFlags, - ACCESS_MASK dwDesiredAccess, - LPSECURITY_ATTRIBUTES lpSecurity, - HWINSTA hWindowStation) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - PWINSTATION_OBJECT WinStaObject; - PDESKTOP_OBJECT DesktopObject; - UNICODE_STRING DesktopName; - WCHAR NameBuffer[MAX_PATH]; - NTSTATUS Status; - HDESK Desktop; - PRECT WorkArea; - - Status = ValidateWindowStationHandle(hWindowStation, - KernelMode, - 0, - &WinStaObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed validation of window station handle (0x%X)\n", - hWindowStation); - return((HDESK)0); - } + SET_PROCESS_WINDOW_STATION(hWindowStation); - wcscpy(NameBuffer, WINSTA_ROOT_NAME); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, WinStaObject->Name.Buffer); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, lpszDesktopName->Buffer); - RtlInitUnicodeString(&DesktopName, NameBuffer); + DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n", + IoGetCurrentProcess()->Win32WindowStation); - ObDereferenceObject(WinStaObject); + return TRUE; +} - DPRINT("Trying to open desktop (%wZ)\n", &DesktopName); +/* + * NtUserLockWindowStation + * + * Status + * @unimplemented + */ - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes(&ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); - Status = ObOpenObjectByName(&ObjectAttributes, - ExDesktopObjectType, - NULL, - UserMode, - dwDesiredAccess, - NULL, - &Desktop); - if (NT_SUCCESS(Status)) - { +BOOL STDCALL +NtUserLockWindowStation(HWINSTA hWindowStation) +{ + UNIMPLEMENTED + + return 0; +} + +/* + * NtUserUnlockWindowStation + * + * Status + * @unimplemented + */ + +BOOL STDCALL +NtUserUnlockWindowStation(HWINSTA hWindowStation) +{ + UNIMPLEMENTED + + return FALSE; +} + +/* + * NtUserSetWindowStationUser + * + * Status + * @unimplemented + */ + +DWORD STDCALL +NtUserSetWindowStationUser( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3) +{ + UNIMPLEMENTED + + return 0; +} + +/* + * NtUserCreateDesktop + * + * Creates a new desktop. + * + * Parameters + * lpszDesktopName + * Name of the new desktop. + * + * 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 + * created desktop. If the specified desktop already exists, the function + * succeeds and returns a handle to the existing desktop. When you are + * finished using the handle, call the CloseDesktop function to close it. + * If the function fails, the return value is NULL. + * + * Status + * @implemented + */ + +HDESK STDCALL +NtUserCreateDesktop( + PUNICODE_STRING lpszDesktopName, + DWORD dwFlags, + ACCESS_MASK dwDesiredAccess, + LPSECURITY_ATTRIBUTES lpSecurity, + HWINSTA hWindowStation) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + PWINSTATION_OBJECT WinStaObject; + PDESKTOP_OBJECT DesktopObject; + UNICODE_STRING DesktopName; + NTSTATUS Status; + HDESK Desktop; + + Status = IntValidateWindowStationHandle( + hWindowStation, + KernelMode, + 0, + &WinStaObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed validation of window station handle (0x%X)\n", + hWindowStation); + SetLastNtError(Status); + return 0; + } + + if (!IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, + lpszDesktopName)) + { + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + ObDereferenceObject(WinStaObject); + return 0; + } + + 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, + &Desktop); + + if (NT_SUCCESS(Status)) + { DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName); - return((HDESK)Desktop); - } + ExFreePool(DesktopName.Buffer); + return Desktop; + } - DPRINT("Status for open operation (0x%X)\n", Status); + /* + * No existing desktop found, try to create new one + */ - Status = ObCreateObject(ExGetPreviousMode(), - ExDesktopObjectType, - &ObjectAttributes, - ExGetPreviousMode(), - NULL, - sizeof(DESKTOP_OBJECT) + sizeof(RECT), - 0, - 0, - (PVOID*)&DesktopObject); - if (!NT_SUCCESS(Status)) - { + Status = ObCreateObject( + ExGetPreviousMode(), + ExDesktopObjectType, + &ObjectAttributes, + ExGetPreviousMode(), + NULL, + sizeof(DESKTOP_OBJECT), + 0, + 0, + (PVOID*)&DesktopObject); + + if (!NT_SUCCESS(Status)) + { DPRINT("Failed creating desktop (%wZ)\n", &DesktopName); + ExFreePool(DesktopName.Buffer); SetLastNtError(STATUS_UNSUCCESSFUL); return((HDESK)0); - } + } - WorkArea = (PRECT)((PDESKTOP_OBJECT)(DesktopObject + 1)); - DesktopObject->WorkArea = (struct RECT *)WorkArea; - WorkArea->left = 0; - WorkArea->top = 0; - WorkArea->right = 640; - WorkArea->bottom = 480; + /* FIXME: Set correct dimensions. */ + DesktopObject->WorkArea.left = 0; + DesktopObject->WorkArea.top = 0; + DesktopObject->WorkArea.right = 640; + DesktopObject->WorkArea.bottom = 480; - /* Initialize some local (to win32k) desktop state. */ - DesktopObject->ActiveMessageQueue = NULL; - DesktopObject->DesktopWindow = - IntCreateDesktopWindow(DesktopObject->WindowStation, - DesktopWindowClass, - 640, 480); - DbgPrint( "Created Desktop Window: %08x\n", DesktopObject->DesktopWindow ); + /* Initialize some local (to win32k) desktop state. */ + DesktopObject->ActiveMessageQueue = NULL; + DesktopObject->DesktopWindow = IntCreateDesktopWindow( + DesktopObject->WindowStation, + DesktopWindowClass, + DesktopObject->WorkArea.right, + DesktopObject->WorkArea.bottom); - Status = ObInsertObject ((PVOID)DesktopObject, - NULL, - STANDARD_RIGHTS_REQUIRED, - 0, - NULL, - &Desktop); - ObDereferenceObject(DesktopObject); - if (!NT_SUCCESS(Status)) - { + DPRINT1("Created Desktop Window: %08x\n", DesktopObject->DesktopWindow); + + Status = ObInsertObject( + (PVOID)DesktopObject, + NULL, + STANDARD_RIGHTS_REQUIRED, + 0, + NULL, + &Desktop); + + ObDereferenceObject(DesktopObject); + ExFreePool(DesktopName.Buffer); + + if (!NT_SUCCESS(Status)) + { DPRINT("Failed to create desktop handle\n"); SetLastNtError(STATUS_UNSUCCESSFUL); - return((HDESK)0); - } + return 0; + } - return((HDESK)Desktop); + return Desktop; } +/* + * NtUserOpenDesktop + * + * Opens an existing desktop. + * + * Parameters + * lpszDesktopName + * Name of the existing desktop. + * + * dwFlags + * Interaction flags. + * + * dwDesiredAccess + * Requested type of access. + * + * Return Value + * Handle to the desktop or zero on failure. + * + * Status + * @implemented + */ + HDESK STDCALL -NtUserGetThreadDesktop(DWORD dwThreadId, - DWORD Unknown1) -{ - UNIMPLEMENTED; - return((HDESK)0); -} - -/* - * FUNCTION: - * Opens an existing desktop - * ARGUMENTS: - * lpszDesktopName = Name of the existing desktop - * dwFlags = Interaction flags - * dwDesiredAccess = Requested type of access - * RETURNS: - * Handle to the desktop - * Zero on failure - * NOTES: - * The returned handle can be closed with NtUserCloseDesktop() - */ -HDESK -STDCALL NtUserOpenDesktop( - PUNICODE_STRING lpszDesktopName, - DWORD dwFlags, - ACCESS_MASK dwDesiredAccess) + PUNICODE_STRING lpszDesktopName, + DWORD dwFlags, + ACCESS_MASK dwDesiredAccess) { - OBJECT_ATTRIBUTES ObjectAttributes; - PWINSTATION_OBJECT WinStaObject; - UNICODE_STRING DesktopName; - WCHAR NameBuffer[MAX_PATH]; - NTSTATUS Status; - HDESK Desktop; + OBJECT_ATTRIBUTES ObjectAttributes; + PWINSTATION_OBJECT WinStaObject; + UNICODE_STRING DesktopName; + NTSTATUS Status; + HDESK Desktop; - /* Validate the window station handle and - compose the fully qualified desktop name */ + /* + * Validate the window station handle and compose the fully + * qualified desktop name + */ - Status = ValidateWindowStationHandle( - PROCESS_WINDOW_STATION(), - KernelMode, - 0, - &WinStaObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed validation of window station handle (0x%X)\n", - PROCESS_WINDOW_STATION()); - return (HDESK)0; - } + Status = IntValidateWindowStationHandle( + PROCESS_WINDOW_STATION(), + KernelMode, + 0, + &WinStaObject); - wcscpy(NameBuffer, WINSTA_ROOT_NAME); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, WinStaObject->Name.Buffer); - wcscat(NameBuffer, L"\\"); - wcscat(NameBuffer, lpszDesktopName->Buffer); - RtlInitUnicodeString(&DesktopName, NameBuffer); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed validation of window station handle (0x%X)\n", + PROCESS_WINDOW_STATION()); + SetLastNtError(Status); + return 0; + } - ObDereferenceObject(WinStaObject); + if (!IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name, + lpszDesktopName)) + { + SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); + ObDereferenceObject(WinStaObject); + return 0; + } + + ObDereferenceObject(WinStaObject); + DPRINT("Trying to open desktop station (%wZ)\n", &DesktopName); - DPRINT("Trying to open desktop station (%wZ)\n", &DesktopName); + /* Initialize ObjectAttributes for the desktop object */ + InitializeObjectAttributes( + &ObjectAttributes, + &DesktopName, + 0, + NULL, + NULL); - /* Initialize ObjectAttributes for the desktop object */ - InitializeObjectAttributes( - &ObjectAttributes, - &DesktopName, - 0, - NULL, - NULL); + Status = ObOpenObjectByName( + &ObjectAttributes, + ExDesktopObjectType, + NULL, + UserMode, + dwDesiredAccess, + NULL, + &Desktop); - Status = ObOpenObjectByName( - &ObjectAttributes, - ExDesktopObjectType, - NULL, - UserMode, - dwDesiredAccess, - NULL, - &Desktop); - if (NT_SUCCESS(Status)) - { - DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName); - return (HDESK)Desktop; - } + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + ExFreePool(DesktopName.Buffer); + return 0; + } - SetLastNtError(Status); - return (HDESK)0; + DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName); + ExFreePool(DesktopName.Buffer); + + return Desktop; } /* - * FUNCTION: - * Opens the input (interactive) desktop - * ARGUMENTS: - * dwFlags = Interaction flags - * fInherit = Inheritance option - * dwDesiredAccess = Requested type of access - * RETURNS: - * Handle to the input desktop - * Zero on failure - * NOTES: - * The returned handle can be closed with NtUserCloseDesktop() + * NtUserOpenInputDesktop + * + * Opens the input (interactive) desktop. + * + * Parameters + * dwFlags + * Interaction flags. + * + * fInherit + * Inheritance option. + * + * dwDesiredAccess + * Requested type of access. + * + * Return Value + * Handle to the input desktop or zero on failure. + * + * Status + * @implemented */ -HDESK -STDCALL + +HDESK STDCALL NtUserOpenInputDesktop( - DWORD dwFlags, - BOOL fInherit, - ACCESS_MASK dwDesiredAccess) + DWORD dwFlags, + BOOL fInherit, + ACCESS_MASK dwDesiredAccess) { - PDESKTOP_OBJECT Object; - NTSTATUS Status; - HDESK Desktop; + PDESKTOP_OBJECT Object; + NTSTATUS Status; + HDESK Desktop; - DPRINT("About to open input desktop\n"); + DPRINT("About to open input desktop\n"); - /* Get a pointer to the desktop object */ + /* Get a pointer to the desktop object */ - Status = ValidateDesktopHandle( - InputDesktop, - KernelMode, - 0, - &Object); - if (!NT_SUCCESS(Status)) { - DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop); - return (HDESK)0; - } + Status = IntValidateDesktopHandle( + InputDesktop, + KernelMode, + 0, + &Object); - /* Create a new handle to the object */ + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop); + return (HDESK)0; + } - Status = ObOpenObjectByPointer( - Object, - 0, - NULL, - dwDesiredAccess, - ExDesktopObjectType, - UserMode, - &Desktop); + /* Create a new handle to the object */ - ObDereferenceObject(Object); + Status = ObOpenObjectByPointer( + Object, + 0, + NULL, + dwDesiredAccess, + ExDesktopObjectType, + UserMode, + &Desktop); - if (NT_SUCCESS(Status)) - { - DPRINT("Successfully opened input desktop\n"); - return (HDESK)Desktop; - } + ObDereferenceObject(Object); - SetLastNtError(Status); - return (HDESK)0; + if (NT_SUCCESS(Status)) + { + DPRINT("Successfully opened input desktop\n"); + return (HDESK)Desktop; + } + + SetLastNtError(Status); + return (HDESK)0; } +/* + * NtUserCloseDesktop + * + * Closes a desktop handle. + * + * Parameters + * hDesktop + * Handle to the desktop. + * + * Return Value + * Status + * + * Remarks + * The desktop handle can be created with NtUserCreateDesktop or + * NtUserOpenDesktop. This function will fail if any thread in the calling + * process is using the specified desktop handle or if the handle refers + * to the initial desktop of the calling process. + * + * Status + * @implemented + */ + +BOOL STDCALL +NtUserCloseDesktop(HDESK hDesktop) +{ + PDESKTOP_OBJECT Object; + NTSTATUS Status; + + DPRINT("About to close desktop handle (0x%X)\n", hDesktop); + + Status = IntValidateDesktopHandle( + hDesktop, + KernelMode, + 0, + &Object); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); + return FALSE; + } + + ObDereferenceObject(Object); + + DPRINT("Closing desktop handle (0x%X)\n", hDesktop); + + Status = ZwClose(hDesktop); + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return FALSE; + } + + return TRUE; +} + +/* + * NtUserPaintDesktop + * + * The NtUserPaintDesktop function fills the clipping region in the + * specified device context with the desktop pattern or wallpaper. The + * function is provided primarily for shell desktops. + * + * Parameters + * hdc + * Handle to the device context. + * + * Status + * @implemented + */ + BOOL STDCALL NtUserPaintDesktop(HDC hDC) { @@ -916,6 +1311,7 @@ NtUserPaintDesktop(HDC hDC) * Check for an owning thread, otherwise don't paint anything * (non-desktop mode) */ + if (NtUserGetWindowThreadProcessId(hwnd, NULL)) { RECT Rect; @@ -926,6 +1322,7 @@ NtUserPaintDesktop(HDC hDC) /* * Paint desktop background */ + PreviousBrush = NtGdiSelectObject(hDC, NtGdiGetSysColorBrush(COLOR_BACKGROUND)); NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY); NtGdiSelectObject(hDC, PreviousBrush); @@ -934,149 +1331,169 @@ NtUserPaintDesktop(HDC hDC) return TRUE; } +/* + * NtUserSwitchDesktop + * + * Sets the current input (interactive) desktop. + * + * Parameters + * hDesktop + * Handle to desktop. + * + * Return Value + * Status + * + * Status + * @unimplemented + */ + +BOOL STDCALL +NtUserSwitchDesktop(HDESK hDesktop) +{ + PDESKTOP_OBJECT DesktopObject; + NTSTATUS Status; + + DPRINT("About to switch desktop (0x%X)\n", hDesktop); + + Status = IntValidateDesktopHandle( + hDesktop, + KernelMode, + 0, + &DesktopObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); + 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 */ + /* FIXME: Connect to input device */ + + /* Set the active desktop in the desktop's window station. */ + DesktopObject->WindowStation->ActiveDesktop = DesktopObject; + + /* Set the global state. */ + InputDesktop = DesktopObject; + InputDesktopHandle = hDesktop; + InputWindowStation = DesktopObject->WindowStation; + + ObDereferenceObject(DesktopObject); + + return TRUE; +} + +/* + * NtUserResolveDesktopForWOW + * + * Status + * @unimplemented + */ + DWORD STDCALL NtUserResolveDesktopForWOW(DWORD Unknown0) { - UNIMPLEMENTED - return 0; + UNIMPLEMENTED + return 0; } +/* + * NtUserGetThreadDesktop + * + * Status + * @unimplemented + */ + +HDESK STDCALL +NtUserGetThreadDesktop(DWORD dwThreadId, DWORD Unknown1) +{ + UNIMPLEMENTED + return 0; +} + +/* + * NtUserSetThreadDesktop + * + * Status + * @implemented + */ + BOOL STDCALL NtUserSetThreadDesktop(HDESK hDesktop) { - PDESKTOP_OBJECT DesktopObject; - NTSTATUS Status; + PDESKTOP_OBJECT DesktopObject; + NTSTATUS Status; - /* Validate the new desktop. */ - Status = ValidateDesktopHandle(hDesktop, - KernelMode, - 0, - &DesktopObject); - if (!NT_SUCCESS(Status)) - { + /* Validate the new desktop. */ + Status = IntValidateDesktopHandle( + hDesktop, + KernelMode, + 0, + &DesktopObject); + + if (!NT_SUCCESS(Status)) + { DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - return(FALSE); - } + return FALSE; + } - /* Check for setting the same desktop as before. */ - if (DesktopObject == PsGetWin32Thread()->Desktop) - { + /* Check for setting the same desktop as before. */ + if (DesktopObject == PsGetWin32Thread()->Desktop) + { ObDereferenceObject(DesktopObject); - return(TRUE); - } + return TRUE; + } - /* FIXME: Should check here to see if the thread has any windows. */ + /* FIXME: Should check here to see if the thread has any windows. */ - if (PsGetWin32Thread()->Desktop != NULL) - { + if (PsGetWin32Thread()->Desktop != NULL) + { ObDereferenceObject(PsGetWin32Thread()->Desktop); - } - PsGetWin32Thread()->Desktop = DesktopObject; + } - return(TRUE); + PsGetWin32Thread()->Desktop = DesktopObject; + + return TRUE; } /* - * FUNCTION: - * Sets the current input (interactive) desktop - * ARGUMENTS: - * hDesktop = Handle to desktop - * RETURNS: - * Status + * NtUserBuildNameList + * + * Function used for enumeration of desktops or window stations. + * + * Parameters + * hWinSta + * For enumeration of window stations this parameter must be set to + * zero. Otherwise it's handle for window station. + * + * dwSize + * Size of buffer passed by caller. + * + * lpBuffer + * Buffer passed by caller. If the function succedes, the buffer is + * filled with window station/desktop count (in first DWORD) and + * NULL-terminated window station/desktop names. + * + * pRequiredSize + * If the function suceedes, this is the number of bytes copied. + * Otherwise it's size of buffer needed for function to succeed. + * + * Status + * @unimplemented */ -BOOL STDCALL -NtUserSwitchDesktop(HDESK hDesktop) + +NTSTATUS STDCALL +NtUserBuildNameList( + HWINSTA hWinSta, + ULONG dwSize, + PVOID lpBuffer, + PULONG pRequiredSize) { - PDESKTOP_OBJECT DesktopObject; - NTSTATUS Status; + UNIMPLEMENTED - DPRINT("About to switch desktop (0x%X)\n", hDesktop); - - Status = ValidateDesktopHandle(hDesktop, - KernelMode, - 0, - &DesktopObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop); - 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 */ - /* FIXME: Connect to input device */ - - /* Set the active desktop in the desktop's window station. */ - DesktopObject->WindowStation->ActiveDesktop = DesktopObject; - - /* Set the global state. */ - InputDesktopHandle = hDesktop; - InputDesktop = DesktopObject; - InputWindowStation = DesktopObject->WindowStation; - - ObDereferenceObject(DesktopObject); - - return(TRUE); -} - -VOID FASTCALL -IntInitializeDesktopGraphics(VOID) -{ - ScreenDeviceContext = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL); - GDIOBJ_MarkObjectGlobal(ScreenDeviceContext); - EnableMouse(ScreenDeviceContext); - /* not the best place to load the cursors but it's good for now */ - IntLoadDefaultCursors(FALSE); - NtUserAcquireOrReleaseInputOwnership(FALSE); -} - -VOID FASTCALL -IntEndDesktopGraphics(VOID) -{ - NtUserAcquireOrReleaseInputOwnership(TRUE); - EnableMouse(FALSE); - if (NULL != ScreenDeviceContext) - { - GDIOBJ_UnmarkObjectGlobal(ScreenDeviceContext); - NtGdiDeleteDC(ScreenDeviceContext); - ScreenDeviceContext = NULL; - } -} - -HDC FASTCALL -IntGetScreenDC(VOID) -{ - return(ScreenDeviceContext); -} - -LRESULT CALLBACK -IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_CREATE: - return(0); - - case WM_NCCREATE: - return(1); - - default: - return(0); - } -} - -BOOL FASTCALL -IntGetWindowStationObject(PWINSTATION_OBJECT Object) -{ - NTSTATUS Status; - - Status = ObReferenceObjectByPointer(Object, - KernelMode, - ExWindowStationObjectType, - 0); - - return NT_SUCCESS(Status); + return STATUS_UNSUCCESSFUL; } /* EOF */ diff --git a/reactos/subsys/win32k/objects/cursoricon.c b/reactos/subsys/win32k/objects/cursoricon.c index a9c156ba482..bdf61822681 100644 --- a/reactos/subsys/win32k/objects/cursoricon.c +++ b/reactos/subsys/win32k/objects/cursoricon.c @@ -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: cursoricon.c,v 1.24 2003/11/21 22:46:27 weiden Exp $ */ +/* $Id: cursoricon.c,v 1.25 2003/11/23 11:39:48 navaraf Exp $ */ #undef WIN32_LEAN_AND_MEAN @@ -105,14 +105,14 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo goto done; /* FIXME use the desktop's HDC instead of using ScreenDeviceContext */ - dc = DC_LockDc(ScreenDeviceContext); + dc = DC_LockDc(IntGetScreenDC()); if(!dc) goto done; SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface); SurfGDI = (PSURFGDI)AccessInternalObject((ULONG) dc->Surface); DevInfo = dc->DevInfo; - DC_UnlockDc(ScreenDeviceContext); + DC_UnlockDc(IntGetScreenDC()); if(!NewCursor && (CurInfo->CurrentCursorObject || ForceChange)) { @@ -459,7 +459,7 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect) NTSTATUS Status; HICON Ret; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -535,7 +535,7 @@ NtUserGetIconInfo( NTSTATUS Status; BOOL Ret = FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -596,7 +596,7 @@ NtUserGetIconSize( NTSTATUS Status; BOOL Ret = FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -686,7 +686,7 @@ NtUserGetCursorInfo( return FALSE; } - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -733,7 +733,7 @@ NtUserClipCursor( RECT Rect; PWINDOW_OBJECT DesktopWindow = NULL; - NTSTATUS Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + NTSTATUS Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -789,7 +789,7 @@ NtUserDestroyCursor( PWINSTATION_OBJECT WinStaObject; NTSTATUS Status; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -826,7 +826,7 @@ NtUserFindExistingCursorIcon( NTSTATUS Status; HICON Ret = (HICON)0; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -870,7 +870,7 @@ NtUserGetClipCursor( if(!lpRect) return FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -924,7 +924,7 @@ NtUserSetCursor( PWINSTATION_OBJECT WinStaObject; NTSTATUS Status; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -963,7 +963,7 @@ NtUserSetCursorIconContents( NTSTATUS Status; BOOL Ret = FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -1037,7 +1037,7 @@ NtUserSetCursorIconData( POINT SafeHotspot; BOOL Ret = FALSE; - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject); @@ -1155,7 +1155,7 @@ NtUserDrawIconEx( INT nStretchMode; #endif - Status = ValidateWindowStationHandle(PROCESS_WINDOW_STATION(), + Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(), KernelMode, 0, &WinStaObject);