https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9c0564063d6d3e4c78520…
commit 9c0564063d6d3e4c78520a7742d463a2710b63d6
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jun 16 19:43:59 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Aug 19 22:18:22 2018 +0200
[USER32] Implement the special case in CreateWindowStationW() that, when no window
station name is provided (either NULL or empty string), does not open any WindowStation
directory handle to be passed to the Win32k function.
Observed via API monitoring.
This corresponds to the case where Win32k creates a window station whose name is based
on the logon session identifier for the calling process.
Add also a note about the fact that we need to use a per-session-based WindowStation
directory name, as done already in Win32k.
CORE-11933 and PR #621.
---
win32ss/user/user32/misc/winsta.c | 53 ++++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/win32ss/user/user32/misc/winsta.c b/win32ss/user/user32/misc/winsta.c
index 24f6d893b2..7308ad1461 100644
--- a/win32ss/user/user32/misc/winsta.c
+++ b/win32ss/user/user32/misc/winsta.c
@@ -60,32 +60,49 @@ CreateWindowStationW(
NTSTATUS Status;
HWINSTA hWinSta;
UNICODE_STRING WindowStationName;
+ // FIXME: We should cache a per-session directory (see
ntuser\winsta.c!UserCreateWinstaDirectory).
UNICODE_STRING WindowStationsDir =
RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;
- /* Open WindowStations directory */
- InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationsDir,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ /*
+ * If provided, the window station name is always relative to the
+ * current user session's WindowStations directory.
+ * Otherwise (the window station name is NULL or an empty string),
+ * pass both an empty string and no WindowStations directory handle
+ * to win32k, so that it will create a window station whose name
+ * is based on the logon session identifier for the calling process.
+ */
+ if (lpwinsta && *lpwinsta)
+ {
+ /* Open WindowStations directory */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &WindowStationsDir,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = NtOpenDirectoryObject(&hWindowStationsDir,
+ DIRECTORY_CREATE_OBJECT,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Failed to open WindowStations directory\n");
+ return NULL;
+ }
- Status = NtOpenDirectoryObject(&hWindowStationsDir,
- DIRECTORY_CREATE_OBJECT,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
+ RtlInitUnicodeString(&WindowStationName, lpwinsta);
+ }
+ else
{
- ERR("Failed to open WindowStations directory\n");
- return NULL;
+ lpwinsta = NULL;
+ hWindowStationsDir = NULL;
}
- RtlInitUnicodeString(&WindowStationName, lpwinsta);
-
/* Create the window station object */
InitializeObjectAttributes(&ObjectAttributes,
- &WindowStationName,
- OBJ_CASE_INSENSITIVE,
+ lpwinsta ? &WindowStationName : NULL,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
hWindowStationsDir,
NULL);
@@ -99,7 +116,8 @@ CreateWindowStationW(
dwDesiredAccess,
0, 0, 0, 0, 0);
- NtClose(hWindowStationsDir);
+ if (hWindowStationsDir)
+ NtClose(hWindowStationsDir);
return hWinSta;
}
@@ -349,6 +367,7 @@ OpenWindowStationW(
NTSTATUS Status;
HWINSTA hWinSta;
UNICODE_STRING WindowStationName;
+ // FIXME: We should cache a per-session directory (see
ntuser\winsta.c!UserCreateWinstaDirectory).
UNICODE_STRING WindowStationsDir =
RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;