+ 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;