https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cb22d5f697187d013ce85…
commit cb22d5f697187d013ce85f3126ef723809aef56a
Author:     Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun Feb 11 11:26:51 2018 +0100
Commit:     Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sun Sep 20 23:08:17 2020 +0200
    [NTOS:PS] On x64 don't fail in NtSetInformationProcess with ProcessUserModeIOPL
information class, instead just don't do anything.
    For NT6+ appcompat setting return STATUS_NOT_IMPLEMENTED
---
 ntoskrnl/include/internal/rtl.h |  5 +++++
 ntoskrnl/ps/query.c             |  9 +++++++++
 sdk/lib/rtl/process.c           | 17 +++++++++++++++++
 3 files changed, 31 insertions(+)
diff --git a/ntoskrnl/include/internal/rtl.h b/ntoskrnl/include/internal/rtl.h
index c38886c7cab..80e363c7acd 100644
--- a/ntoskrnl/include/internal/rtl.h
+++ b/ntoskrnl/include/internal/rtl.h
@@ -34,4 +34,9 @@ RtlFindCharInUnicodeString(
     _Out_ PUSHORT Position
 );
+_IRQL_requires_max_(APC_LEVEL)
+ULONG
+NTAPI
+RtlRosGetAppcompatVersion(VOID);
+
 /* EOF */
diff --git a/ntoskrnl/ps/query.c b/ntoskrnl/ps/query.c
index 31275a5247f..5e340c7ccdf 100644
--- a/ntoskrnl/ps/query.c
+++ b/ntoskrnl/ps/query.c
@@ -1902,6 +1902,15 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
             /* Only supported on x86 */
 #if defined (_X86_)
             Ke386SetIOPL();
+#elif defined(_M_AMD64)
+            /* On x64 this function isn't implemented.
+               On Windows 2003 it returns success.
+               On Vista+ it returns STATUS_NOT_IMPLEMENTED. */
+            if ((ExGetPreviousMode() != KernelMode) &&
+                (RtlRosGetAppcompatVersion() > _WIN32_WINNT_WS03))
+            {
+                Status = STATUS_NOT_IMPLEMENTED;
+            }
 #else
             Status = STATUS_NOT_IMPLEMENTED;
 #endif
diff --git a/sdk/lib/rtl/process.c b/sdk/lib/rtl/process.c
index 444c6cc2018..637046ba8a9 100644
--- a/sdk/lib/rtl/process.c
+++ b/sdk/lib/rtl/process.c
@@ -493,3 +493,20 @@ RtlGetCurrentProcessorNumber(VOID)
     /* Forward to kernel */
     return NtGetCurrentProcessorNumber();
 }
+
+_IRQL_requires_max_(APC_LEVEL)
+ULONG
+NTAPI
+RtlRosGetAppcompatVersion(VOID)
+{
+    /* Get the current PEB */
+    PPEB Peb = RtlGetCurrentPeb();
+    if (Peb == NULL)
+    {
+        /* Default to Server 2003 */
+        return _WIN32_WINNT_WS03;
+    }
+
+    /* Calculate OS version from PEB fields */
+    return (Peb->OSMajorVersion << 8) | Peb->OSMinorVersion;
+}