2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2003-11-11 20:28:21 +00:00
|
|
|
/* $Id: winsta.c,v 1.41 2003/11/11 20:28:21 gvg Exp $
|
2001-06-12 17:51:51 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2003-06-07 Casper S. Hornstrup <chorns@users.sourceforge.net>
Changes for compiling with w32api
* include/ddk/obfuncs.h (ObCreateObject): Remove.
* include/ntos/zwtypes.h (ObRosCreateObject): Add.
* ntoskrnl/ntoskrnl.def, ntoskrnl/ntoskrnl.edf: Export ObCreateObject@36
and ObRosCreateObject@20.
* ntoskrnl/cm/ntfunc.c, ntoskrnl/cm/registry.c, ntoskrnl/cm/regobj.c,
ntoskrnl/io/create.c, ntoskrnl/io/device.c, ntoskrnl/io/iocomp.c,
ntoskrnl/lpc/connect.c, ntoskrnl/lpc/create.c, ntoskrnl/mm/section.c,
ntoskrnl/nt/evtpair.c, ntoskrnl/nt/mutant.c, ntoskrnl/nt/ntevent.c,
ntoskrnl/nt/ntsem.c, ntoskrnl/nt/nttimer.c, ntoskrnl/nt/profile.c,
ntoskrnl/ob/dirobj.c, ntoskrnl/ob/namespc.c, ntoskrnl/ob/symlink.c,
ntoskrnl/ps/create.c, ntoskrnl/ps/process.c, ntoskrnl/se/token.c,
subsys/win32k/ntuser/winsta.c: Use ObRosCreateObject, not ObCreateObject.
* ntoskrnl/ob/object.c (ObRosCreateObject): Rename from ObCreateObject.
(ObCreateObject): Add stub.
svn path=/trunk/; revision=4867
2003-06-07 12:23:14 +00:00
|
|
|
#define NTOS_MODE_KERNEL
|
|
|
|
#include <ntos.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <ddk/ntddmou.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <win32k/win32k.h>
|
|
|
|
#include <include/winsta.h>
|
|
|
|
#include <include/object.h>
|
2002-09-08 10:23:54 +00:00
|
|
|
#include <napi/win32.h>
|
2002-07-17 21:04:57 +00:00
|
|
|
#include <include/class.h>
|
|
|
|
#include <include/window.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <include/error.h>
|
|
|
|
#include <include/mouse.h>
|
2003-08-29 08:46:20 +00:00
|
|
|
#include <include/callback.h>
|
2003-10-19 19:51:48 +00:00
|
|
|
#include <include/color.h>
|
2003-11-10 17:44:50 +00:00
|
|
|
#include <include/cursoricon.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-08-16 01:39:17 +00:00
|
|
|
#define NDEBUG
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
#define WINSTA_ROOT_NAME L"\\Windows\\WindowStations"
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
LRESULT CALLBACK
|
2003-08-19 11:48:50 +00:00
|
|
|
IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
STATIC PWNDCLASS_OBJECT DesktopWindowClass;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
/* Currently active desktop */
|
|
|
|
STATIC HDESK InputDesktopHandle = NULL;
|
|
|
|
STATIC PDESKTOP_OBJECT InputDesktop = NULL;
|
2003-08-24 01:12:16 +00:00
|
|
|
//STATIC PWINSTATION_OBJECT InputWindowStation = NULL;
|
2002-07-17 21:04:57 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
HDC ScreenDeviceContext = NULL;
|
2002-09-17 23:43:29 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2003-08-02 16:32:18 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
PDESKTOP_OBJECT FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntGetActiveDesktop(VOID)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
|
|
|
return(InputDesktop);
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-07-25 23:02:21 +00:00
|
|
|
PDESKTOP_OBJECT FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntGetDesktopObject ( HDESK hDesk )
|
2003-07-25 23:02:21 +00:00
|
|
|
{
|
|
|
|
/* FIXME - this obviously isn't right */
|
2003-08-19 11:48:50 +00:00
|
|
|
return IntGetActiveDesktop();
|
2003-07-25 23:02:21 +00:00
|
|
|
}
|
|
|
|
|
2003-07-27 11:54:42 +00:00
|
|
|
VOID STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntSetFocusMessageQueue(PUSER_MESSAGE_QUEUE NewQueue)
|
2003-07-27 11:54:42 +00:00
|
|
|
{
|
2003-08-19 11:48:50 +00:00
|
|
|
PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
|
2003-07-27 11:54:42 +00:00
|
|
|
|
|
|
|
pdo->ActiveMessageQueue = NewQueue;
|
|
|
|
}
|
|
|
|
|
2003-07-05 16:04:01 +00:00
|
|
|
PUSER_MESSAGE_QUEUE FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntGetFocusMessageQueue(VOID)
|
2003-07-05 16:04:01 +00:00
|
|
|
{
|
2003-08-19 11:48:50 +00:00
|
|
|
PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
|
2003-07-05 16:04:01 +00:00
|
|
|
|
|
|
|
if (!pdo)
|
|
|
|
{
|
|
|
|
DPRINT("No active desktop\n");
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
|
|
|
|
}
|
|
|
|
|
2003-07-27 11:54:42 +00:00
|
|
|
PWINDOW_OBJECT STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntGetCaptureWindow(VOID)
|
2003-07-27 11:54:42 +00:00
|
|
|
{
|
2003-08-19 11:48:50 +00:00
|
|
|
PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
|
2003-07-27 11:54:42 +00:00
|
|
|
if (!pdo)
|
|
|
|
{
|
|
|
|
DPRINT("No active desktop\n");
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
return(pdo->CaptureWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntSetCaptureWindow(PWINDOW_OBJECT Window)
|
2003-07-27 11:54:42 +00:00
|
|
|
{
|
2003-08-19 11:48:50 +00:00
|
|
|
PDESKTOP_OBJECT pdo = IntGetActiveDesktop();
|
2003-07-27 11:54:42 +00:00
|
|
|
if (!pdo)
|
|
|
|
{
|
|
|
|
DPRINT("No active desktop\n");
|
|
|
|
}
|
|
|
|
pdo->CaptureWindow = Window;
|
|
|
|
}
|
2003-07-05 16:04:01 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
InitWindowStationImpl(VOID)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE WindowStationsDirectory;
|
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
NTSTATUS Status;
|
2003-06-16 13:10:01 +00:00
|
|
|
WNDCLASSEXW wcx;
|
2003-08-24 01:12:16 +00:00
|
|
|
|
|
|
|
InputWindowStation = NULL;
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/*
|
2002-06-11 22:09:03 +00:00
|
|
|
* Create the '\Windows\WindowStations' directory
|
|
|
|
*/
|
2002-08-20 20:37:19 +00:00
|
|
|
RtlInitUnicodeStringFromLiteral(&UnicodeString,
|
2002-06-11 22:09:03 +00:00
|
|
|
WINSTA_ROOT_NAME);
|
|
|
|
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&UnicodeString,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
Status = ZwCreateDirectoryObject(&WindowStationsDirectory,
|
|
|
|
0,
|
|
|
|
&ObjectAttributes);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-06-11 22:09:03 +00:00
|
|
|
{
|
|
|
|
DPRINT("Could not create \\Windows\\WindowStations directory "
|
|
|
|
"(Status 0x%X)\n", Status);
|
|
|
|
return Status;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
/*
|
|
|
|
* Create the desktop window class
|
|
|
|
*/
|
|
|
|
wcx.style = 0;
|
2003-08-19 11:48:50 +00:00
|
|
|
wcx.lpfnWndProc = IntDesktopWindowProc;
|
2002-07-17 21:04:57 +00:00
|
|
|
wcx.cbClsExtra = wcx.cbWndExtra = 0;
|
|
|
|
wcx.hInstance = wcx.hIcon = wcx.hCursor = NULL;
|
|
|
|
wcx.hbrBackground = NULL;
|
|
|
|
wcx.lpszMenuName = NULL;
|
|
|
|
wcx.lpszClassName = L"DesktopWindowClass";
|
2003-11-11 20:28:21 +00:00
|
|
|
DesktopWindowClass = IntCreateClass(&wcx, TRUE, IntDesktopWindowProc, (RTL_ATOM)32880);
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS FASTCALL
|
2001-06-12 17:51:51 +00:00
|
|
|
CleanupWindowStationImpl(VOID)
|
|
|
|
{
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS STDCALL
|
2002-06-11 22:09:03 +00:00
|
|
|
ValidateWindowStationHandle(HWINSTA WindowStation,
|
|
|
|
KPROCESSOR_MODE AccessMode,
|
|
|
|
ACCESS_MASK DesiredAccess,
|
|
|
|
PWINSTATION_OBJECT *Object)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
2002-06-11 22:09:03 +00:00
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle(WindowStation,
|
|
|
|
DesiredAccess,
|
|
|
|
ExWindowStationObjectType,
|
|
|
|
AccessMode,
|
|
|
|
(PVOID*)Object,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
NTSTATUS STDCALL
|
2002-06-11 22:09:03 +00:00
|
|
|
ValidateDesktopHandle(HDESK Desktop,
|
|
|
|
KPROCESSOR_MODE AccessMode,
|
|
|
|
ACCESS_MASK DesiredAccess,
|
|
|
|
PDESKTOP_OBJECT *Object)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2002-06-11 22:09:03 +00:00
|
|
|
Status = ObReferenceObjectByHandle(Desktop,
|
|
|
|
DesiredAccess,
|
|
|
|
ExDesktopObjectType,
|
|
|
|
AccessMode,
|
|
|
|
(PVOID*)Object,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserCloseWindowStation(
|
|
|
|
HWINSTA hWinSta)
|
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT Object;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObDereferenceObject(Object);
|
|
|
|
|
|
|
|
DPRINT("Closing window station handle (0x%X)\n", hWinSta);
|
|
|
|
|
|
|
|
Status = ZwClose(hWinSta);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
} else {
|
|
|
|
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
|
|
|
|
*/
|
2002-07-04 19:56:38 +00:00
|
|
|
HWINSTA STDCALL
|
|
|
|
NtUserCreateWindowStation(PUNICODE_STRING lpszWindowStationName,
|
|
|
|
ACCESS_MASK dwDesiredAccess,
|
|
|
|
LPSECURITY_ATTRIBUTES lpSecurity,
|
|
|
|
DWORD Unknown3,
|
|
|
|
DWORD Unknown4,
|
|
|
|
DWORD Unknown5)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
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 */
|
2002-07-04 19:56:38 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&WindowStationName,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
Status = ObOpenObjectByName(&ObjectAttributes,
|
|
|
|
ExWindowStationObjectType,
|
|
|
|
NULL,
|
|
|
|
UserMode,
|
|
|
|
dwDesiredAccess,
|
|
|
|
NULL,
|
|
|
|
&WinSta);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
2002-07-04 19:56:38 +00:00
|
|
|
{
|
|
|
|
DPRINT("Successfully opened window station (%wZ)\n", WindowStationName);
|
|
|
|
return((HWINSTA)WinSta);
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
DPRINT("Creating window station (%wZ)\n", &WindowStationName);
|
|
|
|
|
2003-09-25 20:09:56 +00:00
|
|
|
Status = ObCreateObject(ExGetPreviousMode(),
|
2002-07-04 19:56:38 +00:00
|
|
|
ExWindowStationObjectType,
|
2003-09-25 20:09:56 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
ExGetPreviousMode(),
|
|
|
|
NULL,
|
|
|
|
sizeof(WINSTATION_OBJECT),
|
|
|
|
0,
|
|
|
|
0,
|
2002-07-04 19:56:38 +00:00
|
|
|
(PVOID*)&WinStaObject);
|
2001-06-16 14:11:31 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-07-04 19:56:38 +00:00
|
|
|
{
|
|
|
|
DPRINT("Failed creating window station (%wZ)\n", &WindowStationName);
|
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
return (HWINSTA)0;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-09-25 20:09:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
WinStaObject->HandleTable = ObmCreateHandleTable();
|
|
|
|
if (!WinStaObject->HandleTable)
|
2002-07-04 19:56:38 +00:00
|
|
|
{
|
|
|
|
DPRINT("Failed creating handle table\n");
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
return((HWINSTA)0);
|
|
|
|
}
|
2003-08-24 01:12:16 +00:00
|
|
|
|
2003-08-25 00:28:23 +00:00
|
|
|
ExInitializeFastMutex(&WinStaObject->SystemCursor.CursorMutex);
|
2003-08-24 23:52:29 +00:00
|
|
|
WinStaObject->SystemCursor.Enabled = FALSE;
|
2003-09-24 18:39:34 +00:00
|
|
|
WinStaObject->SystemCursor.ButtonsDown = 0;
|
2003-08-24 23:52:29 +00:00
|
|
|
WinStaObject->SystemCursor.x = (LONG)0;
|
|
|
|
WinStaObject->SystemCursor.y = (LONG)0;
|
2003-08-28 16:33:22 +00:00
|
|
|
WinStaObject->SystemCursor.CursorClipInfo.IsClipped = FALSE;
|
|
|
|
WinStaObject->SystemCursor.LastBtnDown = 0;
|
2003-11-10 17:44:50 +00:00
|
|
|
WinStaObject->SystemCursor.CurrentCursorObject = NULL;
|
|
|
|
WinStaObject->SystemCursor.ShowingCursor = 0;
|
2003-08-28 16:33:22 +00:00
|
|
|
|
|
|
|
/* FIXME Obtain the following information from the registry */
|
|
|
|
WinStaObject->SystemCursor.SwapButtons = FALSE;
|
2003-08-24 18:52:18 +00:00
|
|
|
WinStaObject->SystemCursor.SafetySwitch = FALSE;
|
2003-08-24 23:52:29 +00:00
|
|
|
WinStaObject->SystemCursor.SafetySwitch2 = TRUE;
|
2003-08-28 16:33:22 +00:00
|
|
|
WinStaObject->SystemCursor.DblClickSpeed = 500;
|
|
|
|
WinStaObject->SystemCursor.DblClickWidth = 4;
|
|
|
|
WinStaObject->SystemCursor.DblClickHeight = 4;
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2003-11-10 17:44:50 +00:00
|
|
|
if(!IntSetupCurIconHandles(WinStaObject))
|
|
|
|
{
|
|
|
|
DbgPrint("Setting up the Cursor/Icon Handle table failed!\n");
|
|
|
|
}
|
2003-08-24 18:52:18 +00:00
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
DPRINT("Window station successfully created (%wZ)\n", &WindowStationName);
|
2002-07-04 19:56:38 +00:00
|
|
|
|
|
|
|
return((HWINSTA)WinSta);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtUserGetObjectInformation(
|
|
|
|
HANDLE hObject,
|
|
|
|
DWORD nIndex,
|
|
|
|
PVOID pvInformation,
|
|
|
|
DWORD nLength,
|
|
|
|
PDWORD nLengthNeeded)
|
|
|
|
{
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
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;
|
2003-05-18 17:16:18 +00:00
|
|
|
//PWINSTATION_OBJECT WinStaObject;
|
2001-06-12 17:51:51 +00:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
/* 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
|
|
|
|
*/
|
2002-06-11 22:09:03 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserSetProcessWindowStation(HWINSTA hWindowStation)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
PWINSTATION_OBJECT Object;
|
2003-10-12 09:46:51 +00:00
|
|
|
PW32PROCESS Win32Process;
|
2001-06-12 17:51:51 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2002-06-11 22:09:03 +00:00
|
|
|
DPRINT("About to set process window station with handle (0x%X)\n",
|
|
|
|
hWindowStation);
|
|
|
|
|
|
|
|
Status = ValidateWindowStationHandle(hWindowStation,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&Object);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
|
|
|
hWindowStation);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-10-12 09:46:51 +00:00
|
|
|
|
|
|
|
Win32Process = PsGetWin32Process();
|
|
|
|
if (NULL == Win32Process)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Object);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (NULL != Win32Process->WindowStation)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Win32Process->WindowStation);
|
|
|
|
}
|
|
|
|
Win32Process->WindowStation = Object;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
SET_PROCESS_WINDOW_STATION(hWindowStation);
|
2002-06-11 22:09:03 +00:00
|
|
|
DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n",
|
|
|
|
IoGetCurrentProcess()->Win32WindowStation);
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2002-07-17 21:04:57 +00:00
|
|
|
HDESK STDCALL
|
|
|
|
NtUserCreateDesktop(PUNICODE_STRING lpszDesktopName,
|
|
|
|
DWORD dwFlags,
|
|
|
|
ACCESS_MASK dwDesiredAccess,
|
|
|
|
LPSECURITY_ATTRIBUTES lpSecurity,
|
|
|
|
HWINSTA hWindowStation)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
PDESKTOP_OBJECT DesktopObject;
|
|
|
|
UNICODE_STRING DesktopName;
|
|
|
|
WCHAR NameBuffer[MAX_PATH];
|
|
|
|
NTSTATUS Status;
|
|
|
|
HDESK Desktop;
|
2003-11-10 17:44:50 +00:00
|
|
|
PRECT WorkArea;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
Status = ValidateWindowStationHandle(hWindowStation,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&WinStaObject);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
|
|
|
DPRINT("Failed validation of window station handle (0x%X)\n",
|
|
|
|
hWindowStation);
|
|
|
|
return((HDESK)0);
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
wcscpy(NameBuffer, WINSTA_ROOT_NAME);
|
|
|
|
wcscat(NameBuffer, L"\\");
|
|
|
|
wcscat(NameBuffer, WinStaObject->Name.Buffer);
|
|
|
|
wcscat(NameBuffer, L"\\");
|
|
|
|
wcscat(NameBuffer, lpszDesktopName->Buffer);
|
|
|
|
RtlInitUnicodeString(&DesktopName, NameBuffer);
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
|
|
|
|
DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
|
|
|
|
|
|
|
|
/* Initialize ObjectAttributes for the desktop object */
|
2002-07-17 21:04:57 +00:00
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&DesktopName,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
Status = ObOpenObjectByName(&ObjectAttributes,
|
|
|
|
ExDesktopObjectType,
|
|
|
|
NULL,
|
|
|
|
UserMode,
|
|
|
|
dwDesiredAccess,
|
|
|
|
NULL,
|
|
|
|
&Desktop);
|
2001-06-12 17:51:51 +00:00
|
|
|
if (NT_SUCCESS(Status))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
|
|
|
DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
|
|
|
|
return((HDESK)Desktop);
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
DPRINT("Status for open operation (0x%X)\n", Status);
|
|
|
|
|
2003-09-25 20:09:56 +00:00
|
|
|
Status = ObCreateObject(ExGetPreviousMode(),
|
2002-07-17 21:04:57 +00:00
|
|
|
ExDesktopObjectType,
|
2003-09-25 20:09:56 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
ExGetPreviousMode(),
|
|
|
|
NULL,
|
2003-11-10 17:44:50 +00:00
|
|
|
sizeof(DESKTOP_OBJECT) + sizeof(RECT),
|
2003-09-25 20:09:56 +00:00
|
|
|
0,
|
|
|
|
0,
|
2002-07-17 21:04:57 +00:00
|
|
|
(PVOID*)&DesktopObject);
|
2001-06-16 14:11:31 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
|
|
|
DPRINT("Failed creating desktop (%wZ)\n", &DesktopName);
|
|
|
|
SetLastNtError(STATUS_UNSUCCESSFUL);
|
|
|
|
return((HDESK)0);
|
|
|
|
}
|
2003-11-10 17:44:50 +00:00
|
|
|
|
|
|
|
WorkArea = (PRECT)((PDESKTOP_OBJECT)(DesktopObject + 1));
|
|
|
|
DesktopObject->WorkArea = (struct RECT *)WorkArea;
|
|
|
|
WorkArea->left = 0;
|
|
|
|
WorkArea->top = 0;
|
|
|
|
WorkArea->right = 640;
|
|
|
|
WorkArea->bottom = 480;
|
2003-09-25 20:09:56 +00:00
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
/* Initialize some local (to win32k) desktop state. */
|
|
|
|
DesktopObject->ActiveMessageQueue = NULL;
|
|
|
|
DesktopObject->DesktopWindow =
|
2003-08-19 11:48:50 +00:00
|
|
|
IntCreateDesktopWindow(DesktopObject->WindowStation,
|
2002-07-17 21:04:57 +00:00
|
|
|
DesktopWindowClass,
|
|
|
|
640, 480);
|
2003-10-09 06:13:05 +00:00
|
|
|
DbgPrint( "Created Desktop Window: %08x\n", DesktopObject->DesktopWindow );
|
2002-07-17 21:04:57 +00:00
|
|
|
|
2003-09-25 20:09:56 +00:00
|
|
|
Status = ObInsertObject ((PVOID)DesktopObject,
|
|
|
|
NULL,
|
|
|
|
STANDARD_RIGHTS_REQUIRED,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
&Desktop);
|
|
|
|
ObDereferenceObject(DesktopObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Failed to create desktop handle\n");
|
|
|
|
SetLastNtError(STATUS_UNSUCCESSFUL);
|
|
|
|
return((HDESK)0);
|
|
|
|
}
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
return((HDESK)Desktop);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-07-04 19:56:38 +00:00
|
|
|
HDESK STDCALL
|
|
|
|
NtUserGetThreadDesktop(DWORD dwThreadId,
|
|
|
|
DWORD Unknown1)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2002-07-04 19:56:38 +00:00
|
|
|
UNIMPLEMENTED;
|
|
|
|
return((HDESK)0);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
PWINSTATION_OBJECT WinStaObject;
|
|
|
|
UNICODE_STRING DesktopName;
|
|
|
|
WCHAR NameBuffer[MAX_PATH];
|
|
|
|
NTSTATUS Status;
|
|
|
|
HDESK Desktop;
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcscpy(NameBuffer, WINSTA_ROOT_NAME);
|
|
|
|
wcscat(NameBuffer, L"\\");
|
|
|
|
wcscat(NameBuffer, WinStaObject->Name.Buffer);
|
|
|
|
wcscat(NameBuffer, L"\\");
|
|
|
|
wcscat(NameBuffer, lpszDesktopName->Buffer);
|
|
|
|
RtlInitUnicodeString(&DesktopName, NameBuffer);
|
|
|
|
|
|
|
|
ObDereferenceObject(WinStaObject);
|
|
|
|
|
|
|
|
|
|
|
|
DPRINT("Trying to open desktop station (%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;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return (HDESK)0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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()
|
|
|
|
*/
|
|
|
|
HDESK
|
|
|
|
STDCALL
|
|
|
|
NtUserOpenInputDesktop(
|
|
|
|
DWORD dwFlags,
|
|
|
|
BOOL fInherit,
|
|
|
|
ACCESS_MASK dwDesiredAccess)
|
|
|
|
{
|
|
|
|
PDESKTOP_OBJECT Object;
|
|
|
|
NTSTATUS Status;
|
|
|
|
HDESK Desktop;
|
|
|
|
|
|
|
|
DPRINT("About to open input desktop\n");
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a new handle to the object */
|
|
|
|
|
|
|
|
Status = ObOpenObjectByPointer(
|
|
|
|
Object,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
dwDesiredAccess,
|
|
|
|
ExDesktopObjectType,
|
|
|
|
UserMode,
|
|
|
|
&Desktop);
|
|
|
|
|
|
|
|
ObDereferenceObject(Object);
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Successfully opened input desktop\n");
|
|
|
|
return (HDESK)Desktop;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return (HDESK)0;
|
|
|
|
}
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserPaintDesktop(HDC hDC)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-10-19 19:51:48 +00:00
|
|
|
HWND hwnd = IntGetDesktopWindow();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check for an owning thread, otherwise don't paint anything
|
|
|
|
* (non-desktop mode)
|
|
|
|
*/
|
|
|
|
if (NtUserGetWindowThreadProcessId(hwnd, NULL))
|
|
|
|
{
|
|
|
|
RECT Rect;
|
|
|
|
HBRUSH PreviousBrush;
|
|
|
|
|
|
|
|
NtUserGetClientRect(hwnd, &Rect);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Paint desktop background
|
|
|
|
*/
|
|
|
|
PreviousBrush = NtGdiSelectObject(hDC, NtGdiGetSysColorBrush(COLOR_BACKGROUND));
|
|
|
|
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
|
|
|
|
NtGdiSelectObject(hDC, PreviousBrush);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
NtUserResolveDesktopForWOW(DWORD Unknown0)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
|
|
|
UNIMPLEMENTED
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-04 19:56:38 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserSetThreadDesktop(HDESK hDesktop)
|
2003-06-20 16:26:53 +00:00
|
|
|
{
|
2002-07-17 21:04:57 +00:00
|
|
|
PDESKTOP_OBJECT DesktopObject;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Validate the new desktop. */
|
|
|
|
Status = ValidateDesktopHandle(hDesktop,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&DesktopObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for setting the same desktop as before. */
|
|
|
|
if (DesktopObject == PsGetWin32Thread()->Desktop)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(DesktopObject);
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Should check here to see if the thread has any windows. */
|
|
|
|
|
2003-06-20 16:26:53 +00:00
|
|
|
if (PsGetWin32Thread()->Desktop != NULL)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(PsGetWin32Thread()->Desktop);
|
|
|
|
}
|
2002-07-17 21:04:57 +00:00
|
|
|
PsGetWin32Thread()->Desktop = DesktopObject;
|
|
|
|
|
|
|
|
return(TRUE);
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* FUNCTION:
|
|
|
|
* Sets the current input (interactive) desktop
|
|
|
|
* ARGUMENTS:
|
|
|
|
* hDesktop = Handle to desktop
|
|
|
|
* RETURNS:
|
|
|
|
* Status
|
|
|
|
*/
|
2002-07-17 21:04:57 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserSwitchDesktop(HDESK hDesktop)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2002-07-17 21:04:57 +00:00
|
|
|
PDESKTOP_OBJECT DesktopObject;
|
2001-06-12 17:51:51 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("About to switch desktop (0x%X)\n", hDesktop);
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
Status = ValidateDesktopHandle(hDesktop,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&DesktopObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
|
|
|
|
return(FALSE);
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
|
|
|
/* 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 */
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntInitializeDesktopGraphics(VOID)
|
2002-09-17 23:43:29 +00:00
|
|
|
{
|
2003-08-19 11:48:50 +00:00
|
|
|
ScreenDeviceContext = NtGdiCreateDC(L"DISPLAY", NULL, NULL, NULL);
|
2002-09-17 23:43:29 +00:00
|
|
|
GDIOBJ_MarkObjectGlobal(ScreenDeviceContext);
|
2003-11-10 17:44:50 +00:00
|
|
|
EnableMouse(ScreenDeviceContext);
|
2003-08-29 08:46:20 +00:00
|
|
|
/* not the best place to load the cursors but it's good for now */
|
|
|
|
IntLoadDefaultCursors();
|
2002-10-31 00:03:31 +00:00
|
|
|
NtUserAcquireOrReleaseInputOwnership(FALSE);
|
2002-09-17 23:43:29 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
VOID FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntEndDesktopGraphics(VOID)
|
2003-03-06 23:57:03 +00:00
|
|
|
{
|
|
|
|
NtUserAcquireOrReleaseInputOwnership(TRUE);
|
|
|
|
EnableMouse(FALSE);
|
|
|
|
if (NULL != ScreenDeviceContext)
|
|
|
|
{
|
2003-09-09 10:57:03 +00:00
|
|
|
GDIOBJ_UnmarkObjectGlobal(ScreenDeviceContext);
|
2003-08-19 11:48:50 +00:00
|
|
|
NtGdiDeleteDC(ScreenDeviceContext);
|
2003-03-06 23:57:03 +00:00
|
|
|
ScreenDeviceContext = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
HDC FASTCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
IntGetScreenDC(VOID)
|
2002-09-17 23:43:29 +00:00
|
|
|
{
|
|
|
|
return(ScreenDeviceContext);
|
|
|
|
}
|
|
|
|
|
2002-07-17 21:04:57 +00:00
|
|
|
LRESULT CALLBACK
|
2003-08-19 11:48:50 +00:00
|
|
|
IntDesktopWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
|
|
|
switch (msg)
|
|
|
|
{
|
|
|
|
case WM_CREATE:
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
case WM_NCCREATE:
|
|
|
|
return(1);
|
|
|
|
|
|
|
|
default:
|
|
|
|
return(0);
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-08-24 01:12:16 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
IntGetWindowStationObject(PWINSTATION_OBJECT Object)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByPointer(Object,
|
|
|
|
KernelMode,
|
|
|
|
ExWindowStationObjectType,
|
|
|
|
0);
|
|
|
|
|
|
|
|
return NT_SUCCESS(Status);
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/* EOF */
|