mirror of
https://github.com/reactos/reactos.git
synced 2025-05-24 03:24:45 +00:00
[WIN32K:NTUSER] Split NtUserCreateWindowStation() into the part that captures the user-mode data and the internal worker IntCreateWindowStation() function, which will also be used later.
Add a FIXME note about how we currently handle the window station name.
This commit is contained in:
parent
f47afc3b61
commit
ba018294d3
2 changed files with 135 additions and 50 deletions
|
@ -386,108 +386,96 @@ CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HWINSTA APIENTRY
|
NTSTATUS
|
||||||
NtUserCreateWindowStation(
|
FASTCALL
|
||||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
IntCreateWindowStation(
|
||||||
ACCESS_MASK dwDesiredAccess,
|
OUT HWINSTA* phWinSta,
|
||||||
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
IN ACCESS_MASK dwDesiredAccess,
|
||||||
DWORD Unknown2,
|
DWORD Unknown2,
|
||||||
DWORD Unknown3,
|
DWORD Unknown3,
|
||||||
DWORD Unknown4,
|
DWORD Unknown4,
|
||||||
DWORD Unknown5,
|
DWORD Unknown5,
|
||||||
DWORD Unknown6)
|
DWORD Unknown6)
|
||||||
{
|
{
|
||||||
UNICODE_STRING WindowStationName;
|
|
||||||
PWINSTATION_OBJECT WindowStationObject;
|
|
||||||
HWINSTA WindowStation;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
HWINSTA WindowStation;
|
||||||
|
PWINSTATION_OBJECT WindowStationObject;
|
||||||
|
|
||||||
TRACE("NtUserCreateWindowStation called\n");
|
TRACE("IntCreateWindowStation called\n");
|
||||||
|
|
||||||
|
ASSERT(phWinSta);
|
||||||
|
*phWinSta = NULL;
|
||||||
|
|
||||||
Status = ObOpenObjectByName(ObjectAttributes,
|
Status = ObOpenObjectByName(ObjectAttributes,
|
||||||
ExWindowStationObjectType,
|
ExWindowStationObjectType,
|
||||||
UserMode,
|
AccessMode,
|
||||||
NULL,
|
NULL,
|
||||||
dwDesiredAccess,
|
dwDesiredAccess,
|
||||||
NULL,
|
NULL,
|
||||||
(PVOID*)&WindowStation);
|
(PVOID*)&WindowStation);
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
TRACE("NtUserCreateWindowStation opened window station %wZ\n", ObjectAttributes->ObjectName);
|
TRACE("IntCreateWindowStation opened window station %wZ\n",
|
||||||
return (HWINSTA)WindowStation;
|
ObjectAttributes->ObjectName);
|
||||||
|
*phWinSta = WindowStation;
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No existing window station found, try to create new one
|
* No existing window station found, try to create new one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Capture window station name */
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
ProbeForRead( ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), 1);
|
|
||||||
Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName, ObjectAttributes->ObjectName);
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
{
|
|
||||||
Status =_SEH2_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH2_END
|
|
||||||
|
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ERR("Failed reading capturing window station name\n");
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the window station object */
|
/* Create the window station object */
|
||||||
Status = ObCreateObject(UserMode,
|
Status = ObCreateObject(KernelMode,
|
||||||
ExWindowStationObjectType,
|
ExWindowStationObjectType,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
UserMode,
|
AccessMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(WINSTATION_OBJECT),
|
sizeof(WINSTATION_OBJECT),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&WindowStationObject);
|
(PVOID*)&WindowStationObject);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("ObCreateObject failed with %lx for window station %wZ\n", Status, &WindowStationName);
|
ERR("ObCreateObject failed with %lx for window station %wZ\n",
|
||||||
ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING);
|
Status, ObjectAttributes->ObjectName);
|
||||||
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
SetLastNtError(Status);
|
||||||
return 0;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the window station */
|
/* Initialize the window station */
|
||||||
RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));
|
RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));
|
||||||
|
|
||||||
InitializeListHead(&WindowStationObject->DesktopListHead);
|
InitializeListHead(&WindowStationObject->DesktopListHead);
|
||||||
WindowStationObject->Name = WindowStationName;
|
WindowStationObject->Name = *ObjectAttributes->ObjectName;
|
||||||
|
ObjectAttributes->ObjectName = NULL; // FIXME! (see NtUserCreateWindowStation())
|
||||||
WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId;
|
WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId;
|
||||||
Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable);
|
Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("RtlCreateAtomTable failed with %lx for window station %wZ\n", Status, &WindowStationName);
|
ERR("RtlCreateAtomTable failed with %lx for window station %wZ\n", Status, ObjectAttributes->ObjectName);
|
||||||
ObDereferenceObject(WindowStationObject);
|
ObDereferenceObject(WindowStationObject);
|
||||||
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
SetLastNtError(Status);
|
||||||
return 0;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObInsertObject((PVOID)WindowStationObject,
|
Status = ObInsertObject(WindowStationObject,
|
||||||
NULL,
|
NULL,
|
||||||
dwDesiredAccess,
|
dwDesiredAccess,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
(PVOID*)&WindowStation);
|
(PVOID*)&WindowStation);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("ObInsertObject failed with %lx for window station\n", Status);
|
ERR("ObInsertObject failed with %lx for window station\n", Status);
|
||||||
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
|
SetLastNtError(Status);
|
||||||
return 0;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME! TODO: Add this new window station to a linked list
|
||||||
|
|
||||||
if (InputWindowStation == NULL)
|
if (InputWindowStation == NULL)
|
||||||
{
|
{
|
||||||
ERR("Initializing input window station\n");
|
ERR("Initializing input window station\n");
|
||||||
|
@ -502,9 +490,84 @@ NtUserCreateWindowStation(
|
||||||
WindowStationObject->Flags |= WSS_NOIO;
|
WindowStationObject->Flags |= WSS_NOIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("NtUserCreateWindowStation created object %p with name %wZ handle %p\n",
|
TRACE("IntCreateWindowStation created object 0x%p with name %wZ handle 0x%p\n",
|
||||||
WindowStation, &WindowStationObject->Name, WindowStation);
|
WindowStationObject, &WindowStationObject->Name, WindowStation);
|
||||||
return WindowStation;
|
|
||||||
|
*phWinSta = WindowStation;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWINSTA
|
||||||
|
APIENTRY
|
||||||
|
NtUserCreateWindowStation(
|
||||||
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
IN ACCESS_MASK dwDesiredAccess,
|
||||||
|
DWORD Unknown2,
|
||||||
|
DWORD Unknown3,
|
||||||
|
DWORD Unknown4,
|
||||||
|
DWORD Unknown5,
|
||||||
|
DWORD Unknown6)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HWINSTA hWinSta;
|
||||||
|
OBJECT_ATTRIBUTES LocalObjectAttributes;
|
||||||
|
UNICODE_STRING WindowStationName;
|
||||||
|
|
||||||
|
TRACE("NtUserCreateWindowStation called\n");
|
||||||
|
|
||||||
|
/* Capture window station name */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
|
||||||
|
LocalObjectAttributes = *ObjectAttributes;
|
||||||
|
Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName,
|
||||||
|
LocalObjectAttributes.ObjectName);
|
||||||
|
LocalObjectAttributes.ObjectName = &WindowStationName;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status =_SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ERR("Failed reading or capturing window station name, Status 0x%08lx\n", Status);
|
||||||
|
SetLastNtError(Status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Capture and use the SecurityQualityOfService!
|
||||||
|
|
||||||
|
Status = IntCreateWindowStation(&hWinSta,
|
||||||
|
&LocalObjectAttributes,
|
||||||
|
UserMode,
|
||||||
|
dwDesiredAccess,
|
||||||
|
Unknown2,
|
||||||
|
Unknown3,
|
||||||
|
Unknown4,
|
||||||
|
Unknown5,
|
||||||
|
Unknown6);
|
||||||
|
|
||||||
|
// FIXME! Because in some situations we store the allocated window station name
|
||||||
|
// inside the window station, we must not free it now! We know this fact when
|
||||||
|
// IntCreateWindowStation() sets LocalObjectAttributes.ObjectName to NULL.
|
||||||
|
// This hack must be removed once we just use the stored Ob name instead
|
||||||
|
// (in which case we will always free the allocated name here).
|
||||||
|
if (LocalObjectAttributes.ObjectName)
|
||||||
|
ExFreePoolWithTag(LocalObjectAttributes.ObjectName->Buffer, TAG_STRING);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
TRACE("NtUserCreateWindowStation created a window station with handle 0x%p\n", hWinSta);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(hWinSta == NULL);
|
||||||
|
TRACE("NtUserCreateWindowStation failed to create a window station!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return hWinSta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -764,6 +827,7 @@ NtUserGetObjectInformation(
|
||||||
|
|
||||||
case UOI_NAME:
|
case UOI_NAME:
|
||||||
{
|
{
|
||||||
|
// FIXME: Use either ObQueryNameString() or read directly that name inside the Object section!
|
||||||
if (WinStaObject != NULL)
|
if (WinStaObject != NULL)
|
||||||
{
|
{
|
||||||
pvData = WinStaObject->Name.Buffer;
|
pvData = WinStaObject->Name.Buffer;
|
||||||
|
@ -1136,6 +1200,14 @@ BuildWindowStationNameList(
|
||||||
POBJECT_DIRECTORY_INFORMATION DirEntry;
|
POBJECT_DIRECTORY_INFORMATION DirEntry;
|
||||||
WCHAR NullWchar;
|
WCHAR NullWchar;
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: Fully wrong! Since, by calling NtUserCreateWindowStation
|
||||||
|
// with judicious parameters one can create window stations elsewhere
|
||||||
|
// than in Windows\WindowStations directory, Win32k definitely MUST
|
||||||
|
// maintain a list of window stations it has created, and not rely
|
||||||
|
// on the enumeration of Windows\WindowStations !!!
|
||||||
|
//
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to open the directory.
|
* Try to open the directory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -107,6 +107,19 @@ IntValidateWindowStationHandle(
|
||||||
PWINSTATION_OBJECT *Object,
|
PWINSTATION_OBJECT *Object,
|
||||||
POBJECT_HANDLE_INFORMATION pObjectHandleInfo);
|
POBJECT_HANDLE_INFORMATION pObjectHandleInfo);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
FASTCALL
|
||||||
|
IntCreateWindowStation(
|
||||||
|
OUT HWINSTA* phWinSta,
|
||||||
|
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||||
|
IN KPROCESSOR_MODE AccessMode,
|
||||||
|
IN ACCESS_MASK dwDesiredAccess,
|
||||||
|
DWORD Unknown2,
|
||||||
|
DWORD Unknown3,
|
||||||
|
DWORD Unknown4,
|
||||||
|
DWORD Unknown5,
|
||||||
|
DWORD Unknown6);
|
||||||
|
|
||||||
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation);
|
BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation);
|
||||||
|
|
||||||
BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID);
|
BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID);
|
||||||
|
|
Loading…
Reference in a new issue