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-23 11:39:48 +00:00
|
|
|
*
|
2004-05-01 17:06:55 +00:00
|
|
|
* $Id: winsta.c,v 1.58 2004/05/01 17:06:55 weiden Exp $
|
2003-11-23 11:39:48 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
2003-12-07 19:29:33 +00:00
|
|
|
* PURPOSE: Window stations
|
2003-11-23 11:39:48 +00:00
|
|
|
* FILE: subsys/win32k/ntuser/winsta.c
|
|
|
|
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* REVISION HISTORY:
|
2001-06-12 17:51:51 +00:00
|
|
|
* 06-06-2001 CSH Created
|
2003-11-23 11:39:48 +00:00
|
|
|
* 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
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
2002-07-17 21:04:57 +00:00
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
#define __WIN32K__
|
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>
|
2003-12-07 19:29:33 +00:00
|
|
|
#include <include/desktop.h>
|
2001-06-12 17:51:51 +00:00
|
|
|
#include <include/object.h>
|
2002-07-17 21:04:57 +00:00
|
|
|
#include <include/window.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <include/error.h>
|
2003-11-10 17:44:50 +00:00
|
|
|
#include <include/cursoricon.h>
|
2003-11-11 22:17:18 +00:00
|
|
|
#include <include/hotkey.h>
|
2003-11-23 11:39:48 +00:00
|
|
|
#include <include/color.h>
|
|
|
|
#include <include/mouse.h>
|
|
|
|
#include <include/callback.h>
|
2003-11-25 22:06:31 +00:00
|
|
|
#include <include/guicheck.h>
|
2003-12-13 15:49:32 +00:00
|
|
|
#include <include/intgdi.h>
|
2004-02-19 21:12:11 +00:00
|
|
|
#include <include/tags.h>
|
2003-12-13 11:34:53 +00:00
|
|
|
/* Needed for DIRECTORY_OBJECT */
|
|
|
|
#include <internal/ob.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 *******************************************************************/
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/* Currently active window station */
|
|
|
|
PWINSTATION_OBJECT InputWindowStation = NULL;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/* INITALIZATION FUNCTIONS ****************************************************/
|
2002-07-17 21:04:57 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
InitWindowStationImpl(VOID)
|
|
|
|
{
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
HANDLE WindowStationsDirectory;
|
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create the '\Windows\WindowStations' directory
|
|
|
|
*/
|
2002-09-17 23:43:29 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
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;
|
|
|
|
}
|
2002-07-17 21:04:57 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2003-08-02 16:32:18 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
CleanupWindowStationImpl(VOID)
|
2002-07-17 21:04:57 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-07-17 21:04:57 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/* 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)
|
2003-07-05 16:04:01 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
PWCHAR Buffer;
|
|
|
|
|
2003-12-13 11:34:53 +00:00
|
|
|
FullName->Length = WINSTA_ROOT_NAME_LENGTH * sizeof(WCHAR);
|
|
|
|
if (WinStaName != NULL)
|
|
|
|
FullName->Length += WinStaName->Length + sizeof(WCHAR);
|
2003-11-23 11:39:48 +00:00
|
|
|
if (DesktopName != NULL)
|
|
|
|
FullName->Length += DesktopName->Length + sizeof(WCHAR);
|
2004-02-19 21:12:11 +00:00
|
|
|
FullName->Buffer = ExAllocatePoolWithTag(NonPagedPool, FullName->Length, TAG_STRING);
|
2003-11-23 11:39:48 +00:00
|
|
|
if (FullName->Buffer == NULL)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-07-05 16:04:01 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Buffer = FullName->Buffer;
|
|
|
|
memcpy(Buffer, WINSTA_ROOT_NAME, WINSTA_ROOT_NAME_LENGTH * sizeof(WCHAR));
|
|
|
|
Buffer += WINSTA_ROOT_NAME_LENGTH;
|
2003-12-13 11:34:53 +00:00
|
|
|
if (WinStaName != NULL)
|
2003-11-23 11:39:48 +00:00
|
|
|
{
|
|
|
|
memcpy(Buffer, L"\\", sizeof(WCHAR));
|
|
|
|
Buffer ++;
|
2003-12-13 11:34:53 +00:00
|
|
|
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);
|
|
|
|
}
|
2003-11-23 11:39:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle(
|
|
|
|
WindowStation,
|
|
|
|
DesiredAccess,
|
|
|
|
ExWindowStationObjectType,
|
|
|
|
AccessMode,
|
|
|
|
(PVOID*)Object,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
SetLastNtError(Status);
|
|
|
|
|
|
|
|
return Status;
|
2003-07-05 16:04:01 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
IntGetWindowStationObject(PWINSTATION_OBJECT Object)
|
2003-07-27 11:54:42 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByPointer(
|
|
|
|
Object,
|
|
|
|
KernelMode,
|
|
|
|
ExWindowStationObjectType,
|
|
|
|
0);
|
|
|
|
|
|
|
|
return NT_SUCCESS(Status);
|
2003-07-27 11:54:42 +00:00
|
|
|
}
|
|
|
|
|
2003-11-25 22:06:31 +00:00
|
|
|
BOOL FASTCALL
|
2003-11-23 11:39:48 +00:00
|
|
|
IntInitializeDesktopGraphics(VOID)
|
|
|
|
{
|
2003-12-13 15:49:32 +00:00
|
|
|
UNICODE_STRING DriverName;
|
2003-11-25 22:06:31 +00:00
|
|
|
if (! IntCreatePrimarySurface())
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-12-13 15:49:32 +00:00
|
|
|
RtlInitUnicodeString(&DriverName, L"DISPLAY");
|
|
|
|
ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL);
|
2003-11-25 22:06:31 +00:00
|
|
|
if (NULL == ScreenDeviceContext)
|
|
|
|
{
|
|
|
|
IntDestroyPrimarySurface();
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-11-26 21:48:35 +00:00
|
|
|
DC_SetOwnership(ScreenDeviceContext, NULL);
|
2003-12-13 22:38:29 +00:00
|
|
|
|
2003-11-25 22:06:31 +00:00
|
|
|
EnableMouse(ScreenDeviceContext);
|
2003-12-13 22:38:29 +00:00
|
|
|
|
2003-11-25 22:06:31 +00:00
|
|
|
/* not the best place to load the cursors but it's good for now */
|
|
|
|
IntLoadDefaultCursors(FALSE);
|
|
|
|
NtUserAcquireOrReleaseInputOwnership(FALSE);
|
|
|
|
|
|
|
|
return TRUE;
|
2003-11-23 11:39:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID FASTCALL
|
|
|
|
IntEndDesktopGraphics(VOID)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-25 22:06:31 +00:00
|
|
|
NtUserAcquireOrReleaseInputOwnership(TRUE);
|
|
|
|
EnableMouse(FALSE);
|
|
|
|
if (NULL != ScreenDeviceContext)
|
|
|
|
{
|
2003-11-26 21:48:35 +00:00
|
|
|
DC_SetOwnership(ScreenDeviceContext, PsGetCurrentProcess());
|
2003-11-23 11:39:48 +00:00
|
|
|
NtGdiDeleteDC(ScreenDeviceContext);
|
|
|
|
ScreenDeviceContext = NULL;
|
2003-11-25 22:06:31 +00:00
|
|
|
}
|
2003-12-07 23:02:57 +00:00
|
|
|
IntHideDesktop(IntGetActiveDesktop());
|
2003-11-25 22:06:31 +00:00
|
|
|
IntDestroyPrimarySurface();
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
HDC FASTCALL
|
|
|
|
IntGetScreenDC(VOID)
|
|
|
|
{
|
|
|
|
return ScreenDeviceContext;
|
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/*
|
2003-11-23 11:39:48 +00:00
|
|
|
* 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
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
2003-11-23 11:39:48 +00:00
|
|
|
|
2002-07-04 19:56:38 +00:00
|
|
|
HWINSTA STDCALL
|
2003-11-23 11:39:48 +00:00
|
|
|
NtUserCreateWindowStation(
|
|
|
|
PUNICODE_STRING lpszWindowStationName,
|
|
|
|
ACCESS_MASK dwDesiredAccess,
|
|
|
|
LPSECURITY_ATTRIBUTES lpSecurity,
|
|
|
|
DWORD Unknown3,
|
|
|
|
DWORD Unknown4,
|
|
|
|
DWORD Unknown5)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
UNICODE_STRING WindowStationName;
|
|
|
|
PWINSTATION_OBJECT WindowStationObject;
|
|
|
|
HWINSTA WindowStation;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
NTSTATUS Status;
|
2003-12-07 23:02:57 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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,
|
2004-04-09 20:03:21 +00:00
|
|
|
(PVOID*)&WindowStation);
|
2003-11-23 11:39:48 +00:00
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
2002-07-04 19:56:38 +00:00
|
|
|
DPRINT("Successfully opened window station (%wZ)\n", WindowStationName);
|
2003-11-23 11:39:48 +00:00
|
|
|
ExFreePool(WindowStationName.Buffer);
|
|
|
|
return (HWINSTA)WindowStation;
|
|
|
|
}
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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))
|
|
|
|
{
|
2002-07-04 19:56:38 +00:00
|
|
|
DPRINT("Failed creating window station (%wZ)\n", &WindowStationName);
|
2003-11-23 11:39:48 +00:00
|
|
|
ExFreePool(WindowStationName.Buffer);
|
2002-07-04 19:56:38 +00:00
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
2003-11-23 11:39:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = ObInsertObject(
|
|
|
|
(PVOID)WindowStationObject,
|
|
|
|
NULL,
|
|
|
|
STANDARD_RIGHTS_REQUIRED,
|
|
|
|
0,
|
|
|
|
NULL,
|
2004-04-09 20:03:21 +00:00
|
|
|
(PVOID*)&WindowStation);
|
2003-11-23 11:39:48 +00:00
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-09-25 20:09:56 +00:00
|
|
|
DPRINT("Failed creating window station (%wZ)\n", &WindowStationName);
|
2003-11-23 11:39:48 +00:00
|
|
|
ExFreePool(WindowStationName.Buffer);
|
2003-09-25 20:09:56 +00:00
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
2003-11-23 11:39:48 +00:00
|
|
|
ObDereferenceObject(WindowStationObject);
|
|
|
|
return 0;
|
|
|
|
}
|
2003-09-25 20:09:56 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* Initialize the new window station object
|
|
|
|
*/
|
|
|
|
|
|
|
|
WindowStationObject->HandleTable = ObmCreateHandleTable();
|
|
|
|
if (!WindowStationObject->HandleTable)
|
|
|
|
{
|
2002-07-04 19:56:38 +00:00
|
|
|
DPRINT("Failed creating handle table\n");
|
2003-11-23 11:39:48 +00:00
|
|
|
ExFreePool(WindowStationName.Buffer);
|
|
|
|
ObDereferenceObject(WindowStationObject);
|
2002-07-04 19:56:38 +00:00
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
2003-11-23 11:39:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2003-11-11 22:17:18 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
InitHotKeys(WindowStationObject);
|
2003-11-11 22:17:18 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
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;
|
2003-08-28 16:33:22 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/* FIXME: Obtain the following information from the registry */
|
|
|
|
WindowStationObject->SystemCursor.SwapButtons = FALSE;
|
|
|
|
WindowStationObject->SystemCursor.SafetySwitch = FALSE;
|
2004-01-15 16:29:10 +00:00
|
|
|
WindowStationObject->SystemCursor.SafetyRemoveCount = 0;
|
2003-11-23 11:39:48 +00:00
|
|
|
WindowStationObject->SystemCursor.DblClickSpeed = 500;
|
|
|
|
WindowStationObject->SystemCursor.DblClickWidth = 4;
|
|
|
|
WindowStationObject->SystemCursor.DblClickHeight = 4;
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
if (!IntSetupCurIconHandles(WindowStationObject))
|
|
|
|
{
|
|
|
|
DPRINT1("Setting up the Cursor/Icon Handle table failed!\n");
|
|
|
|
/* FIXME: Complain more loudly? */
|
|
|
|
}
|
2003-08-24 18:52:18 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
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;
|
2002-07-04 19:56:38 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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,
|
2004-04-09 20:03:21 +00:00
|
|
|
(PVOID*)&WindowStation);
|
2003-11-23 11:39:48 +00:00
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
ExFreePool(WindowStationName.Buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName);
|
|
|
|
ExFreePool(WindowStationName.Buffer);
|
|
|
|
|
|
|
|
return WindowStation;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-11-23 11:39:48 +00:00
|
|
|
NtUserCloseWindowStation(
|
|
|
|
HWINSTA hWinSta)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
PWINSTATION_OBJECT Object;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("About to close window station handle (0x%X)\n", hWinSta);
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-11-23 11:39:48 +00:00
|
|
|
* 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
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
2003-11-23 11:39:48 +00:00
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtUserGetObjectInformation(
|
|
|
|
HANDLE hObject,
|
|
|
|
DWORD nIndex,
|
|
|
|
PVOID pvInformation,
|
|
|
|
DWORD nLength,
|
|
|
|
PDWORD nLengthNeeded)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
SetLastNtError(STATUS_UNSUCCESSFUL);
|
|
|
|
return FALSE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-11-23 11:39:48 +00:00
|
|
|
NtUserSetObjectInformation(
|
|
|
|
HANDLE hObject,
|
|
|
|
DWORD nIndex,
|
|
|
|
PVOID pvInformation,
|
|
|
|
DWORD nLength)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
/* FIXME: ZwQueryObject */
|
|
|
|
/* FIXME: ZwSetInformationObject */
|
|
|
|
SetLastNtError(STATUS_UNSUCCESSFUL);
|
|
|
|
return FALSE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-11-23 11:39:48 +00:00
|
|
|
* 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
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
HWINSTA STDCALL
|
|
|
|
NtUserGetProcessWindowStation(VOID)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
return PROCESS_WINDOW_STATION();
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-11-23 11:39:48 +00:00
|
|
|
* NtUserSetProcessWindowStation
|
|
|
|
*
|
|
|
|
* Assigns a window station to the current process.
|
|
|
|
*
|
|
|
|
* Parameters
|
|
|
|
* hWinSta
|
|
|
|
* Handle to the window station.
|
|
|
|
*
|
|
|
|
* Return Value
|
|
|
|
* Status
|
|
|
|
*
|
|
|
|
* Status
|
|
|
|
* @implemented
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
2003-11-23 11:39:48 +00:00
|
|
|
|
2002-06-11 22:09:03 +00:00
|
|
|
BOOL STDCALL
|
|
|
|
NtUserSetProcessWindowStation(HWINSTA hWindowStation)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
PWINSTATION_OBJECT Object;
|
|
|
|
PW32PROCESS Win32Process;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("About to set process window station with handle (0x%X)\n",
|
|
|
|
hWindowStation);
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(
|
|
|
|
hWindowStation,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&Object);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2002-06-11 22:09:03 +00:00
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
2003-11-23 11:39:48 +00:00
|
|
|
hWindowStation);
|
2002-06-11 22:09:03 +00:00
|
|
|
return FALSE;
|
2003-11-23 11:39:48 +00:00
|
|
|
}
|
2003-10-12 09:46:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Win32Process = PsGetWin32Process();
|
|
|
|
if (Win32Process == NULL)
|
|
|
|
{
|
2003-10-12 09:46:51 +00:00
|
|
|
ObDereferenceObject(Object);
|
2003-11-23 11:39:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (Win32Process->WindowStation != NULL)
|
|
|
|
ObDereferenceObject(Win32Process->WindowStation);
|
2003-10-12 09:46:51 +00:00
|
|
|
Win32Process->WindowStation = Object;
|
2003-11-23 11:39:48 +00:00
|
|
|
}
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
SET_PROCESS_WINDOW_STATION(hWindowStation);
|
|
|
|
|
|
|
|
DPRINT("IoGetCurrentProcess()->Win32WindowStation 0x%X\n",
|
|
|
|
IoGetCurrentProcess()->Win32WindowStation);
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* NtUserLockWindowStation
|
|
|
|
*
|
2004-05-01 17:06:55 +00:00
|
|
|
* Locks switching desktops. Only the logon application is allowed to call this function.
|
|
|
|
*
|
2003-11-23 11:39:48 +00:00
|
|
|
* Status
|
2004-05-01 17:06:55 +00:00
|
|
|
* @implemented
|
2003-11-23 11:39:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtUserLockWindowStation(HWINSTA hWindowStation)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2004-05-01 17:06:55 +00:00
|
|
|
PWINSTATION_OBJECT Object;
|
|
|
|
NTSTATUS Status;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2004-05-01 17:06:55 +00:00
|
|
|
DPRINT("About to set process window station with handle (0x%X)\n",
|
|
|
|
hWindowStation);
|
|
|
|
|
|
|
|
if(PsGetWin32Process() != LogonProcess)
|
|
|
|
{
|
|
|
|
DPRINT1("Unauthorized process attempted to lock the window station!\n");
|
|
|
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(
|
|
|
|
hWindowStation,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&Object);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
|
|
|
hWindowStation);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Object->Flags |= WSS_LOCKED;
|
|
|
|
|
|
|
|
ObDereferenceObject(Object);
|
|
|
|
return TRUE;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* NtUserUnlockWindowStation
|
|
|
|
*
|
2004-05-01 17:06:55 +00:00
|
|
|
* Unlocks switching desktops. Only the logon application is allowed to call this function.
|
|
|
|
*
|
2003-11-23 11:39:48 +00:00
|
|
|
* Status
|
2004-05-01 17:06:55 +00:00
|
|
|
* @implemented
|
2003-11-23 11:39:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtUserUnlockWindowStation(HWINSTA hWindowStation)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2004-05-01 17:06:55 +00:00
|
|
|
PWINSTATION_OBJECT Object;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret;
|
2001-06-12 17:51:51 +00:00
|
|
|
|
2004-05-01 17:06:55 +00:00
|
|
|
DPRINT("About to set process window station with handle (0x%X)\n",
|
|
|
|
hWindowStation);
|
|
|
|
|
|
|
|
if(PsGetWin32Process() != LogonProcess)
|
|
|
|
{
|
|
|
|
DPRINT1("Unauthorized process attempted to unlock the window station!\n");
|
|
|
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = IntValidateWindowStationHandle(
|
|
|
|
hWindowStation,
|
|
|
|
KernelMode,
|
|
|
|
0,
|
|
|
|
&Object);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT("Validation of window station handle (0x%X) failed\n",
|
|
|
|
hWindowStation);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ret = (Object->Flags & WSS_LOCKED) == WSS_LOCKED;
|
|
|
|
Object->Flags &= ~WSS_LOCKED;
|
|
|
|
|
|
|
|
ObDereferenceObject(Object);
|
|
|
|
return Ret;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2003-11-23 11:39:48 +00:00
|
|
|
* NtUserSetWindowStationUser
|
|
|
|
*
|
|
|
|
* Status
|
|
|
|
* @unimplemented
|
2001-06-12 17:51:51 +00:00
|
|
|
*/
|
2003-11-23 11:39:48 +00:00
|
|
|
|
|
|
|
DWORD STDCALL
|
|
|
|
NtUserSetWindowStationUser(
|
|
|
|
DWORD Unknown0,
|
|
|
|
DWORD Unknown1,
|
|
|
|
DWORD Unknown2,
|
|
|
|
DWORD Unknown3)
|
2001-06-12 17:51:51 +00:00
|
|
|
{
|
2003-11-23 11:39:48 +00:00
|
|
|
UNIMPLEMENTED
|
|
|
|
|
|
|
|
return 0;
|
2001-06-12 17:51:51 +00:00
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
|
|
NtUserBuildNameList(
|
|
|
|
HWINSTA hWinSta,
|
|
|
|
ULONG dwSize,
|
|
|
|
PVOID lpBuffer,
|
|
|
|
PULONG pRequiredSize)
|
2003-08-24 01:12:16 +00:00
|
|
|
{
|
2003-12-13 11:34:53 +00:00
|
|
|
#if 0
|
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE DirectoryHandle;
|
|
|
|
ULONG EntryCount = 0;
|
|
|
|
UNICODE_STRING DirectoryNameW;
|
|
|
|
PWCHAR BufferChar;
|
|
|
|
PDIRECTORY_OBJECT DirObj = NULL;
|
|
|
|
PLIST_ENTRY CurrentEntry = NULL;
|
|
|
|
POBJECT_HEADER CurrentObject = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Generate full window station name
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* FIXME: Correct this for desktop */
|
|
|
|
if (!IntGetFullWindowStationName(&DirectoryNameW, NULL, NULL))
|
|
|
|
{
|
|
|
|
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to open the directory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByName(&DirectoryNameW, 0, NULL, DIRECTORY_QUERY,
|
|
|
|
ObDirectoryType, UserMode, (PVOID*)&DirObj, NULL);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
ExFreePool(DirectoryNameW.Buffer);
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Count the required size of buffer.
|
|
|
|
*/
|
|
|
|
|
|
|
|
*pRequiredSize = sizeof(DWORD);
|
|
|
|
for (CurrentEntry = DirObj->head.Flink; CurrentEntry != &DirObj->head;
|
|
|
|
CurrentEntry = CurrentEntry->Flink)
|
|
|
|
{
|
|
|
|
CurrentObject = CONTAINING_RECORD(CurrentEntry, OBJECT_HEADER, Entry);
|
|
|
|
*pRequiredSize += CurrentObject->Name.Length + sizeof(UNICODE_NULL);
|
|
|
|
++EntryCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT1("Required size: %d Entry count: %d\n", *pRequiredSize, EntryCount);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if the supplied buffer is large enought.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (*pRequiredSize > dwSize)
|
|
|
|
{
|
|
|
|
ExFreePool(DirectoryNameW.Buffer);
|
|
|
|
ObDereferenceObject(DirectoryHandle);
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Generate the resulting buffer contents.
|
|
|
|
*/
|
|
|
|
|
|
|
|
*((DWORD *)lpBuffer) = EntryCount;
|
|
|
|
BufferChar = (PWCHAR)((INT_PTR)lpBuffer + 4);
|
|
|
|
for (CurrentEntry = DirObj->head.Flink; CurrentEntry != &DirObj->head;
|
|
|
|
CurrentEntry = CurrentEntry->Flink)
|
|
|
|
{
|
|
|
|
CurrentObject = CONTAINING_RECORD(CurrentEntry, OBJECT_HEADER, Entry);
|
|
|
|
wcscpy(BufferChar, CurrentObject->Name.Buffer);
|
|
|
|
DPRINT1("Name: %s\n", BufferChar);
|
|
|
|
BufferChar += (CurrentObject->Name.Length / sizeof(WCHAR)) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free any resource.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ExFreePool(DirectoryNameW.Buffer);
|
|
|
|
ObDereferenceObject(DirectoryHandle);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
#else
|
2003-11-23 11:39:48 +00:00
|
|
|
UNIMPLEMENTED
|
2003-08-24 01:12:16 +00:00
|
|
|
|
2003-12-13 11:34:53 +00:00
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
#endif
|
2003-08-24 01:12:16 +00:00
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
/* EOF */
|