https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ba018294d3a3bca3b18c12...
commit ba018294d3a3bca3b18c12ccb4b6a332aea2e703 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sat Jun 16 19:45:07 2018 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Aug 19 22:18:31 2018 +0200
[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. --- win32ss/user/ntuser/winsta.c | 172 ++++++++++++++++++++++++++++++------------- win32ss/user/ntuser/winsta.h | 13 ++++ 2 files changed, 135 insertions(+), 50 deletions(-)
diff --git a/win32ss/user/ntuser/winsta.c b/win32ss/user/ntuser/winsta.c index 901897857b..eb3ca30e74 100644 --- a/win32ss/user/ntuser/winsta.c +++ b/win32ss/user/ntuser/winsta.c @@ -386,108 +386,96 @@ CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess) * @implemented */
-HWINSTA APIENTRY -NtUserCreateWindowStation( - POBJECT_ATTRIBUTES ObjectAttributes, - ACCESS_MASK dwDesiredAccess, +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) { - UNICODE_STRING WindowStationName; - PWINSTATION_OBJECT WindowStationObject; - HWINSTA WindowStation; NTSTATUS Status; + HWINSTA WindowStation; + PWINSTATION_OBJECT WindowStationObject;
- TRACE("NtUserCreateWindowStation called\n"); + TRACE("IntCreateWindowStation called\n"); + + ASSERT(phWinSta); + *phWinSta = NULL;
Status = ObOpenObjectByName(ObjectAttributes, ExWindowStationObjectType, - UserMode, + AccessMode, NULL, dwDesiredAccess, NULL, (PVOID*)&WindowStation); - if (NT_SUCCESS(Status)) { - TRACE("NtUserCreateWindowStation opened window station %wZ\n", ObjectAttributes->ObjectName); - return (HWINSTA)WindowStation; + TRACE("IntCreateWindowStation opened window station %wZ\n", + 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 */ - Status = ObCreateObject(UserMode, + Status = ObCreateObject(KernelMode, ExWindowStationObjectType, ObjectAttributes, - UserMode, + AccessMode, NULL, sizeof(WINSTATION_OBJECT), 0, 0, (PVOID*)&WindowStationObject); - if (!NT_SUCCESS(Status)) { - ERR("ObCreateObject failed with %lx for window station %wZ\n", Status, &WindowStationName); - ExFreePoolWithTag(WindowStationName.Buffer, TAG_STRING); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; + ERR("ObCreateObject failed with %lx for window station %wZ\n", + Status, ObjectAttributes->ObjectName); + SetLastNtError(Status); + return Status; }
/* Initialize the window station */ RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));
InitializeListHead(&WindowStationObject->DesktopListHead); - WindowStationObject->Name = WindowStationName; + WindowStationObject->Name = *ObjectAttributes->ObjectName; + ObjectAttributes->ObjectName = NULL; // FIXME! (see NtUserCreateWindowStation()) WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId; Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); 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); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; + SetLastNtError(Status); + return Status; }
- Status = ObInsertObject((PVOID)WindowStationObject, + Status = ObInsertObject(WindowStationObject, NULL, dwDesiredAccess, 0, NULL, (PVOID*)&WindowStation); - if (!NT_SUCCESS(Status)) { ERR("ObInsertObject failed with %lx for window station\n", Status); - SetLastNtError(STATUS_INSUFFICIENT_RESOURCES); - return 0; + SetLastNtError(Status); + return Status; }
+ // FIXME! TODO: Add this new window station to a linked list + if (InputWindowStation == NULL) { ERR("Initializing input window station\n"); @@ -502,9 +490,84 @@ NtUserCreateWindowStation( WindowStationObject->Flags |= WSS_NOIO; }
- TRACE("NtUserCreateWindowStation created object %p with name %wZ handle %p\n", - WindowStation, &WindowStationObject->Name, WindowStation); - return WindowStation; + TRACE("IntCreateWindowStation created object 0x%p with name %wZ handle 0x%p\n", + WindowStationObject, &WindowStationObject->Name, 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: { + // FIXME: Use either ObQueryNameString() or read directly that name inside the Object section! if (WinStaObject != NULL) { pvData = WinStaObject->Name.Buffer; @@ -1136,6 +1200,14 @@ BuildWindowStationNameList( POBJECT_DIRECTORY_INFORMATION DirEntry; 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. */ diff --git a/win32ss/user/ntuser/winsta.h b/win32ss/user/ntuser/winsta.h index b41834e7c1..085f3bcb26 100644 --- a/win32ss/user/ntuser/winsta.h +++ b/win32ss/user/ntuser/winsta.h @@ -107,6 +107,19 @@ IntValidateWindowStationHandle( PWINSTATION_OBJECT *Object, 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 co_IntInitializeDesktopGraphics(VOID);