https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b003d68ca58ce94766141…
commit b003d68ca58ce94766141c779332e4c42b7fc430
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jul 8 20:39:19 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Jul 22 19:26:53 2018 +0200
[WIN32SS:NTUSER] Update SetWindowStationUser() and NtUserSetWindowStationUser()
prototypes.
Also, improve NtUserSetWindowStationUser() capture order, make psid optional as it
should (and avoid a user-mode triggered BSOD), and initialize luidUser only when
everything succeeded.
---
win32ss/include/ntuser.h | 8 ++--
win32ss/user/ntuser/winsta.c | 80 ++++++++++++++++++++++++++-------------
win32ss/user/user32/misc/winsta.c | 6 +--
3 files changed, 61 insertions(+), 33 deletions(-)
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 724e3e612c..9e4b70938b 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -3289,10 +3289,10 @@ NtUserSetWindowsHookEx(
BOOL
NTAPI
NtUserSetWindowStationUser(
- HWINSTA hWindowStation,
- PLUID pluid,
- PSID psid,
- DWORD size);
+ IN HWINSTA hWindowStation,
+ IN PLUID pluid,
+ IN PSID psid OPTIONAL,
+ IN DWORD size);
WORD
NTAPI
diff --git a/win32ss/user/ntuser/winsta.c b/win32ss/user/ntuser/winsta.c
index e999ba8a2c..44a8f40505 100644
--- a/win32ss/user/ntuser/winsta.c
+++ b/win32ss/user/ntuser/winsta.c
@@ -1482,16 +1482,18 @@ NtUserLockWorkStation(VOID)
return ret;
}
-BOOL APIENTRY
+BOOL
+NTAPI
NtUserSetWindowStationUser(
- HWINSTA hWindowStation,
- PLUID pluid,
- PSID psid,
- DWORD size)
+ IN HWINSTA hWindowStation,
+ IN PLUID pluid,
+ IN PSID psid OPTIONAL,
+ IN DWORD size)
{
+ BOOL Ret = FALSE;
NTSTATUS Status;
PWINSTATION_OBJECT WindowStation = NULL;
- BOOL Ret = FALSE;
+ LUID luidUser;
UserEnterExclusive();
@@ -1501,53 +1503,79 @@ NtUserSetWindowStationUser(
goto Leave;
}
+ /* Validate the window station */
Status = IntValidateWindowStationHandle(hWindowStation,
UserMode,
0,
&WindowStation,
- 0);
+ NULL);
if (!NT_SUCCESS(Status))
{
goto Leave;
}
- if (WindowStation->psidUser)
- {
- ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
- }
-
- WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size,
USERTAG_SECURITY);
- if (WindowStation->psidUser == NULL)
- {
- EngSetLastError(ERROR_OUTOFMEMORY);
- goto Leave;
- }
-
+ /* Capture the user LUID */
_SEH2_TRY
{
- ProbeForRead(psid, size, 1);
ProbeForRead(pluid, sizeof(LUID), 1);
-
- RtlCopyMemory(WindowStation->psidUser, psid, size);
- WindowStation->luidUser = *pluid;
+ luidUser = *pluid;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
+ _SEH2_YIELD(goto Leave);
}
_SEH2_END;
- if (!NT_SUCCESS(Status))
+ /* Reset the window station user LUID */
+ RtlZeroMemory(&WindowStation->luidUser, sizeof(LUID));
+
+ /* Reset the window station user SID */
+ if (WindowStation->psidUser)
{
ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
WindowStation->psidUser = NULL;
- goto Leave;
}
+ /* Copy the new user SID if one has been provided */
+ if (psid)
+ {
+ WindowStation->psidUser = ExAllocatePoolWithTag(PagedPool, size,
USERTAG_SECURITY);
+ if (WindowStation->psidUser == NULL)
+ {
+ EngSetLastError(ERROR_OUTOFMEMORY);
+ goto Leave;
+ }
+
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ ProbeForRead(psid, size, 1);
+ RtlCopyMemory(WindowStation->psidUser, psid, size);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(WindowStation->psidUser, USERTAG_SECURITY);
+ WindowStation->psidUser = NULL;
+ goto Leave;
+ }
+ }
+
+ /* Copy the new user LUID */
+ WindowStation->luidUser = luidUser;
+
Ret = TRUE;
Leave:
- if (WindowStation) ObDereferenceObject(WindowStation);
+ if (WindowStation)
+ ObDereferenceObject(WindowStation);
+
UserLeave();
return Ret;
}
diff --git a/win32ss/user/user32/misc/winsta.c b/win32ss/user/user32/misc/winsta.c
index 11d4bb5a00..24f6d893b2 100644
--- a/win32ss/user/user32/misc/winsta.c
+++ b/win32ss/user/user32/misc/winsta.c
@@ -399,8 +399,8 @@ BOOL
WINAPI
SetWindowStationUser(
IN HWINSTA hWindowStation,
- IN PLUID pluid OPTIONAL,
- IN PSID psid,
+ IN PLUID pluid,
+ IN PSID psid OPTIONAL,
IN DWORD size)
{
BOOL Success;
@@ -410,7 +410,7 @@ SetWindowStationUser(
{
/* Signal log-on/off to WINSRV */
- /* User is logging on if pluid != LuidNone, otherwise it is a log-off */
+ /* User is logging on if *pluid != LuidNone, otherwise it is a log-off */
LUID LuidNone = {0, 0};
BOOL IsLogon = (pluid && !RtlEqualLuid(pluid, &LuidNone));