https://git.reactos.org/?p=reactos.git;a=commitdiff;h=dae57caa3605c6a7898e5…
commit dae57caa3605c6a7898e5db4094f4e06c3968195
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jun 16 19:45:20 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Aug 19 22:18:32 2018 +0200
[WIN32K:NTUSER] Detect when the NtUserCreateWindowStation() caller has provided an
empty window station name, and if so, generate a name in the format:
"Service-0x<luidhigh>-<luidlow>$" .
CORE-11933 and PR #621.
---
win32ss/user/ntuser/winsta.c | 74 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 70 insertions(+), 4 deletions(-)
diff --git a/win32ss/user/ntuser/winsta.c b/win32ss/user/ntuser/winsta.c
index eb3ca30e74..f373b1cedf 100644
--- a/win32ss/user/ntuser/winsta.c
+++ b/win32ss/user/ntuser/winsta.c
@@ -512,6 +512,7 @@ NtUserCreateWindowStation(
HWINSTA hWinSta;
OBJECT_ATTRIBUTES LocalObjectAttributes;
UNICODE_STRING WindowStationName;
+ KPROCESSOR_MODE AccessMode = UserMode;
TRACE("NtUserCreateWindowStation called\n");
@@ -520,9 +521,21 @@ NtUserCreateWindowStation(
{
ProbeForRead(ObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(ULONG));
LocalObjectAttributes = *ObjectAttributes;
- Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName,
-
LocalObjectAttributes.ObjectName);
- LocalObjectAttributes.ObjectName = &WindowStationName;
+ if (LocalObjectAttributes.ObjectName ||
+ LocalObjectAttributes.RootDirectory
+ /* &&
+ LocalObjectAttributes.ObjectName->Buffer &&
+ LocalObjectAttributes.ObjectName->Length > 0 */)
+ {
+ Status = IntSafeCopyUnicodeStringTerminateNULL(&WindowStationName,
+
LocalObjectAttributes.ObjectName);
+ LocalObjectAttributes.ObjectName = &WindowStationName;
+ }
+ else
+ {
+ LocalObjectAttributes.ObjectName = NULL;
+ Status = STATUS_SUCCESS;
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -537,11 +550,64 @@ NtUserCreateWindowStation(
return NULL;
}
+ /*
+ * If the caller did not provide a window station name, build a new one
+ * based on the logon session identifier for the calling process.
+ */
+ if (!LocalObjectAttributes.ObjectName)
+ {
+ LUID CallerLuid;
+ WCHAR ServiceWinStaName[MAX_PATH];
+
+ /* Retrieve the LUID of the current process */
+ Status = GetProcessLuid(NULL, NULL, &CallerLuid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Failed to retrieve the caller LUID, Status 0x%08lx\n",
Status);
+ SetLastNtError(Status);
+ return NULL;
+ }
+
+ /* Build a valid window station name from the LUID */
+ Status = RtlStringCbPrintfW(ServiceWinStaName,
+ sizeof(ServiceWinStaName),
+ L"%wZ\\Service-0x%x-%x$",
+ &gustrWindowStationsDir,
+ CallerLuid.HighPart,
+ CallerLuid.LowPart);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Impossible to build a valid window station name, Status
0x%08lx\n", Status);
+ SetLastNtError(Status);
+ return NULL;
+ }
+
+ WindowStationName.Length = wcslen(ServiceWinStaName) * sizeof(WCHAR);
+ WindowStationName.MaximumLength =
+ WindowStationName.Length + sizeof(UNICODE_NULL);
+ WindowStationName.Buffer =
+ ExAllocatePoolWithTag(PagedPool,
+ WindowStationName.MaximumLength,
+ TAG_STRING);
+ if (!WindowStationName.Buffer)
+ {
+ Status = STATUS_NO_MEMORY;
+ ERR("Impossible to build a valid window station name, Status
0x%08lx\n", Status);
+ SetLastNtError(Status);
+ return NULL;
+ }
+ RtlStringCbCopyW(WindowStationName.Buffer,
+ WindowStationName.MaximumLength,
+ ServiceWinStaName);
+ LocalObjectAttributes.ObjectName = &WindowStationName;
+ AccessMode = KernelMode;
+ }
+
// TODO: Capture and use the SecurityQualityOfService!
Status = IntCreateWindowStation(&hWinSta,
&LocalObjectAttributes,
- UserMode,
+ AccessMode,
dwDesiredAccess,
Unknown2,
Unknown3,