https://git.reactos.org/?p=reactos.git;a=commitdiff;h=94cb4d6c0c6d8146e57cd…
commit 94cb4d6c0c6d8146e57cda1689473a63f2b73f33
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Wed Sep 4 23:03:49 2024 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Jan 28 15:53:58 2025 +0100
[KMTESTS] Add tests for KdSystemDebugControl and NtSystemDebugControl (#7424)
Tested on Windows 2003 SP1.
Partially tested (but not completely) on higher versions.
---
modules/rostests/kmtests/CMakeLists.txt | 2 +
modules/rostests/kmtests/kmtest/testlist.c | 2 +
modules/rostests/kmtests/kmtest_drv/testlist.c | 2 +
.../kmtests/ntos_kd/KdSystemDebugControl.c | 151 +++++++++++
.../kmtests/ntos_kd/NtSystemDebugControl.c | 293 +++++++++++++++++++++
5 files changed, 450 insertions(+)
diff --git a/modules/rostests/kmtests/CMakeLists.txt
b/modules/rostests/kmtests/CMakeLists.txt
index 40c710f0a46..373ffb887c3 100644
--- a/modules/rostests/kmtests/CMakeLists.txt
+++ b/modules/rostests/kmtests/CMakeLists.txt
@@ -80,6 +80,7 @@ list(APPEND KMTEST_DRV_SOURCE
ntos_io/IoIrp.c
ntos_io/IoMdl.c
ntos_io/IoVolume.c
+ ntos_kd/KdSystemDebugControl.c
ntos_ke/KeApc.c
ntos_ke/KeDevQueue.c
ntos_ke/KeDpc.c
@@ -164,6 +165,7 @@ list(APPEND KMTEST_SOURCE
ntos_io/IoCreateFile_user.c
ntos_io/IoDeviceObject_user.c
ntos_io/IoReadWrite_user.c
+ ntos_kd/NtSystemDebugControl.c
ntos_mm/MmMapLockedPagesSpecifyCache_user.c
ntos_mm/NtCreateSection_user.c
ntos_po/PoIrp_user.c
diff --git a/modules/rostests/kmtests/kmtest/testlist.c
b/modules/rostests/kmtests/kmtest/testlist.c
index 60ab4bb4534..34e387c43f4 100644
--- a/modules/rostests/kmtests/kmtest/testlist.c
+++ b/modules/rostests/kmtests/kmtest/testlist.c
@@ -23,6 +23,7 @@ KMT_TESTFUNC Test_IoDeviceObject;
KMT_TESTFUNC Test_IoReadWrite;
KMT_TESTFUNC Test_MmMapLockedPagesSpecifyCache;
KMT_TESTFUNC Test_NtCreateSection;
+KMT_TESTFUNC Test_NtSystemDebugControl;
KMT_TESTFUNC Test_PoIrp;
KMT_TESTFUNC Test_RtlAvlTree;
KMT_TESTFUNC Test_RtlCaptureContext;
@@ -58,6 +59,7 @@ const KMT_TEST TestList[] =
{ "IoReadWrite", Test_IoReadWrite },
{ "MmMapLockedPagesSpecifyCache", Test_MmMapLockedPagesSpecifyCache },
{ "NtCreateSection", Test_NtCreateSection },
+ { "NtSystemDebugControl", Test_NtSystemDebugControl },
{ "PoIrp", Test_PoIrp },
{ "RtlAvlTree", Test_RtlAvlTree },
{ "RtlException", Test_RtlException },
diff --git a/modules/rostests/kmtests/kmtest_drv/testlist.c
b/modules/rostests/kmtests/kmtest_drv/testlist.c
index 9ef992257ee..b863bcf7b04 100644
--- a/modules/rostests/kmtests/kmtest_drv/testlist.c
+++ b/modules/rostests/kmtests/kmtest_drv/testlist.c
@@ -35,6 +35,7 @@ KMT_TESTFUNC Test_IoInterrupt;
KMT_TESTFUNC Test_IoIrp;
KMT_TESTFUNC Test_IoMdl;
KMT_TESTFUNC Test_IoVolume;
+KMT_TESTFUNC Test_KdSystemDebugControl;
KMT_TESTFUNC Test_KeApc;
KMT_TESTFUNC Test_KeDeviceQueue;
KMT_TESTFUNC Test_KeDpc;
@@ -118,6 +119,7 @@ const KMT_TEST TestList[] =
{ "IoIrp", Test_IoIrp },
{ "IoMdl", Test_IoMdl },
{ "IoVolume", Test_IoVolume },
+ { "KdSystemDebugControl", Test_KdSystemDebugControl },
{ "KeApc", Test_KeApc },
{ "KeDeviceQueue", Test_KeDeviceQueue },
{ "KeDpc", Test_KeDpc },
diff --git a/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c
b/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c
new file mode 100644
index 00000000000..a4da12f2224
--- /dev/null
+++ b/modules/rostests/kmtests/ntos_kd/KdSystemDebugControl.c
@@ -0,0 +1,151 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Kernel-Mode Test Suite for KdSystemDebugControl (kernel-mode)
+ * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto
<hermes.belusca-maito(a)reactos.org>
+ */
+
+#include <kmt_test.h>
+#include <ndk/kdfuncs.h>
+
+#define ok_eq_print_test(testid, value, expected, spec) \
+ ok((value) == (expected), "In test %lu: " #value " = " spec
", expected " spec "\n", testid, value, expected)
+
+#define ok_eq_hex_test(testid, value, expected) \
+ ok_eq_print_test(testid, value, expected, "0x%08lx")
+
+#define ok_neq_print_test(testid, value, expected, spec) \
+ ok((value) != (expected), "In test %lu: " #value " = " spec
", expected != " spec "\n", testid, value, expected)
+
+#define ok_neq_hex_test(testid, value, expected) \
+ ok_neq_print_test(testid, value, expected, "0x%08lx")
+
+
+BOOLEAN
+(NTAPI *pKdRefreshDebuggerNotPresent)(VOID);
+
+NTSTATUS
+(NTAPI *pKdSystemDebugControl)(
+ _In_ SYSDBG_COMMAND Command,
+ _In_ PVOID InputBuffer,
+ _In_ ULONG InputBufferLength,
+ _Out_ PVOID OutputBuffer,
+ _In_ ULONG OutputBufferLength,
+ _Inout_ PULONG ReturnLength,
+ _In_ KPROCESSOR_MODE PreviousMode);
+
+
+static
+NTSTATUS
+TestSystemDebugControl(
+ _In_ SYSDBG_COMMAND Command)
+{
+ return pKdSystemDebugControl(Command,
+ NULL, // _In_ PVOID InputBuffer,
+ 0, // _In_ ULONG InputBufferLength,
+ NULL, // _Out_ PVOID OutputBuffer,
+ 0, // _In_ ULONG OutputBufferLength,
+ NULL,
+ KernelMode);
+}
+
+START_TEST(KdSystemDebugControl)
+{
+ NTSTATUS Status;
+ ULONG Command;
+ RTL_OSVERSIONINFOEXW verInfo;
+ UNICODE_STRING fnName;
+ BOOLEAN IsNT52SP1OrHigher;
+ BOOLEAN IsVistaOrHigher;
+ BOOLEAN IsDebuggerActive;
+
+ /* Test for OS version: KdSystemDebugControl()
+ * exists only on NT 5.2 SP1 and higher */
+ verInfo.dwOSVersionInfoSize = sizeof(verInfo);
+ Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo);
+ if (skip(NT_SUCCESS(Status), "RtlGetVersion() returned 0x%08lx\n",
Status))
+ return;
+
+ // IsWindowsVersionOrGreater(5, 2, 1);
+ IsNT52SP1OrHigher =
+ (verInfo.dwMajorVersion > 5) ||
+ (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion > 2) ||
+ (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion == 2 &&
verInfo.wServicePackMajor >= 1);
+
+ if (skip(IsNT52SP1OrHigher, "KdSystemDebugControl() only exists on NT 5.2 SP1
and higher\n"))
+ return;
+
+ // IsWindowsVersionOrGreater(6, 0, 0);
+ IsVistaOrHigher = (verInfo.dwMajorVersion >= 6);
+
+
+ /* Load the Kd routines at runtime */
+
+ /* Note: KdRefreshDebuggerNotPresent() is NT 5.2+ */
+ RtlInitUnicodeString(&fnName, L"KdRefreshDebuggerNotPresent");
+ pKdRefreshDebuggerNotPresent = MmGetSystemRoutineAddress(&fnName);
+ ok(!!pKdRefreshDebuggerNotPresent,
+ "KdRefreshDebuggerNotPresent() unavailable but OS is NT 5.2 SP1 or
higher?\n");
+
+ RtlInitUnicodeString(&fnName, L"KdSystemDebugControl");
+ pKdSystemDebugControl = MmGetSystemRoutineAddress(&fnName);
+ if (skip(!!pKdSystemDebugControl, "KdSystemDebugControl() unavailable but OS is
NT 5.2 SP1 or higher?\n"))
+ return;
+
+
+ /* Check whether the kernel debugger is present or not */
+ IsDebuggerActive = (pKdRefreshDebuggerNotPresent
+ ? !pKdRefreshDebuggerNotPresent()
+ : (/*KD_DEBUGGER_ENABLED &&*/ !KD_DEBUGGER_NOT_PRESENT));
+
+ trace("Debugger is %s\n", IsDebuggerActive ? "active" :
"inactive");
+
+ /* Unsupported commands */
+ for (Command = 0; Command <= 6; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /*
+ * Supported commands:
+ *
+ * SysDbgQueryVersion = 7,
+ * SysDbgReadVirtual = 8,
+ * SysDbgWriteVirtual = 9,
+ * SysDbgReadPhysical = 10,
+ * SysDbgWritePhysical = 11,
+ * SysDbgReadControlSpace = 12,
+ * SysDbgWriteControlSpace = 13,
+ * SysDbgReadIoSpace = 14,
+ * SysDbgWriteIoSpace = 15,
+ * SysDbgReadMsr = 16,
+ * SysDbgWriteMsr = 17,
+ * SysDbgReadBusData = 18,
+ * SysDbgWriteBusData = 19,
+ * SysDbgCheckLowMemory = 20
+ */
+ for (Command = 7; Command <= 20; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS); // Status must
be != STATUS_INVALID_INFO_CLASS
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* Unsupported commands */
+ for (Command = 21; Command <= 40; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+}
+
+/* EOF */
diff --git a/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c
b/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c
new file mode 100644
index 00000000000..021fc6b0fcf
--- /dev/null
+++ b/modules/rostests/kmtests/ntos_kd/NtSystemDebugControl.c
@@ -0,0 +1,293 @@
+/*
+ * PROJECT: ReactOS kernel-mode tests
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Kernel-Mode Test Suite for NtSystemDebugControl (user-mode)
+ * COPYRIGHT: Copyright 2024 Hermès Bélusca-Maïto
<hermes.belusca-maito(a)reactos.org>
+ */
+
+#include <kmt_test.h>
+#include <ndk/exfuncs.h>
+#include <ndk/kdfuncs.h>
+#include <ndk/setypes.h>
+
+#define ok_eq_print_test(testid, value, expected, spec) \
+ ok((value) == (expected), "In test %lu: " #value " = " spec
", expected " spec "\n", testid, value, expected)
+
+#define ok_eq_hex_test(testid, value, expected) \
+ ok_eq_print_test(testid, value, expected, "0x%08lx")
+
+#define ok_neq_print_test(testid, value, expected, spec) \
+ ok((value) != (expected), "In test %lu: " #value " = " spec
", expected != " spec "\n", testid, value, expected)
+
+#define ok_neq_hex_test(testid, value, expected) \
+ ok_neq_print_test(testid, value, expected, "0x%08lx")
+
+ULONG
+GetNtDdiVersion(VOID)
+{
+ RTL_OSVERSIONINFOEXW verInfo;
+ NTSTATUS Status;
+ ULONG Version;
+
+ verInfo.dwOSVersionInfoSize = sizeof(verInfo);
+ Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&verInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ trace("RtlGetVersion() returned 0x%08lx\n", Status);
+ return 0;
+ }
+
+ Version = ((((verInfo.dwMajorVersion & 0xFF) << 8) |
+ (verInfo.dwMinorVersion & 0xFF)) << 16) |
+ (((verInfo.wServicePackMajor & 0xFF) << 8) |
+ (verInfo.wServicePackMinor & 0xFF));
+
+ return Version;
+}
+
+static
+NTSTATUS
+TestSystemDebugControl(
+ _In_ SYSDBG_COMMAND Command)
+{
+ return NtSystemDebugControl(Command,
+ NULL, // _In_ PVOID InputBuffer,
+ 0, // _In_ ULONG InputBufferLength,
+ NULL, // _Out_ PVOID OutputBuffer,
+ 0, // _In_ ULONG OutputBufferLength,
+ NULL);
+}
+
+START_TEST(NtSystemDebugControl)
+{
+ NTSTATUS Status;
+ ULONG Command;
+ ULONG Version;
+ SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo = {0};
+ BOOLEAN IsNT52SP1OrHigher;
+ BOOLEAN IsVistaOrHigher;
+ BOOLEAN IsDebuggerActive;
+ BOOLEAN PrivilegeSet[2] = {FALSE};
+ BOOLEAN WasDebuggerEnabled;
+
+ /* Test for OS version: KdSystemDebugControl()
+ * exists only on NT 5.2 SP1 and higher */
+ Version = GetNtDdiVersion();
+ if (skip(Version != 0, "GetNtDdiVersion() returned 0\n"))
+ return;
+
+ // IsWindowsVersionOrGreater(5, 2, 1);
+ IsNT52SP1OrHigher = (Version >= NTDDI_WS03SP1);
+
+ // IsWindowsVersionOrGreater(6, 0, 0);
+ IsVistaOrHigher = (Version >= NTDDI_WIN6);
+
+
+ /* Check whether the kernel debugger is present or not */
+ Status = NtQuerySystemInformation(SystemKernelDebuggerInformation,
+ &DebuggerInfo,
+ sizeof(DebuggerInfo),
+ NULL);
+
+ IsDebuggerActive = NT_SUCCESS(Status) &&
!DebuggerInfo.KernelDebuggerNotPresent;
+ // DebuggerInfo.KernelDebuggerEnabled; // SharedUserData->KdDebuggerEnabled;
+
+ trace("Debugger is %s\n", IsDebuggerActive ? "active" :
"inactive");
+
+ /*
+ * Explicitly disable the debug privilege so that we can test
+ * that NtSystemDebugControl() fails when the privilege is absent.
+ * Note that SysDbgGetTriageDump (29) is used for testing here,
+ * because it doesn't require a debugger to be active in order
+ * to proceed further (privilege check and actual functionality).
+ */
+ Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, FALSE, FALSE,
&PrivilegeSet[0]);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+ Status = TestSystemDebugControl(SysDbgGetTriageDump /* 29 */);
+ ok_eq_hex(Status, STATUS_ACCESS_DENIED);
+
+ /* Now, enable the debug privilege for the rest of the tests */
+ Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
+ ok_eq_hex(Status, STATUS_SUCCESS);
+
+ /* Supported commands */
+ for (Command = 0; Command <= 5; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* Test SysDbgBreakPoint (6) only when the debugger is inactive
+ * or disabled; otherwise this call would trigger a breakpoint */
+ if (!skip((IsVistaOrHigher && !IsDebuggerActive) ||
!SharedUserData->KdDebuggerEnabled,
+ "NtSystemDebugControl(SysDbgBreakPoint) skipped because the debugger is
active\n"))
+ {
+ Status = TestSystemDebugControl(SysDbgBreakPoint /* 6 */);
+ if (!SharedUserData->KdDebuggerEnabled /*&& (!IsVistaOrHigher ||
IsDebuggerActive)*/)
+ {
+ ok_eq_hex_test(Command, Status, STATUS_UNSUCCESSFUL);
+ }
+ else
+ {
+ // ASSERT(IsVistaOrHigher && !IsDebuggerActive);
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+ }
+
+ /*
+ * Commands handled by kernel-mode KdSystemDebugControl(),
+ * and unsupported in user-mode:
+ *
+ * SysDbgQueryVersion = 7,
+ * SysDbgReadVirtual = 8,
+ * SysDbgWriteVirtual = 9,
+ * SysDbgReadPhysical = 10,
+ * SysDbgWritePhysical = 11,
+ * SysDbgReadControlSpace = 12,
+ * SysDbgWriteControlSpace = 13,
+ * SysDbgReadIoSpace = 14,
+ * SysDbgWriteIoSpace = 15,
+ * SysDbgReadMsr = 16,
+ * SysDbgWriteMsr = 17,
+ * SysDbgReadBusData = 18,
+ * SysDbgWriteBusData = 19,
+ * SysDbgCheckLowMemory = 20
+ */
+ // TODO: Handle this differently if !IsNT52SP1OrHigher ?
+ DBG_UNREFERENCED_PARAMETER(IsNT52SP1OrHigher);
+ for (Command = 7; Command <= 20; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_eq_hex_test(Command, Status, STATUS_NOT_IMPLEMENTED);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+
+ /*
+ * Separately test commands SysDbgEnableKernelDebugger (21)
+ * and SysDbgDisableKernelDebugger (22), as they influence
+ * the internal state of the debugger. The order of testing
+ * matters, depending on whether the debugger was originally
+ * enabled or disabled.
+ */
+
+ /* Save whether the debugger is currently enabled;
+ * the next tests are going to change its state */
+ WasDebuggerEnabled = SharedUserData->KdDebuggerEnabled;
+
+ /* Try to disable or enable the debugger, depending on its original state */
+ if (WasDebuggerEnabled)
+ Command = SysDbgDisableKernelDebugger; // 22
+ else
+ Command = SysDbgEnableKernelDebugger; // 21
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ {
+ /*
+ * KdEnableDebugger() (with lock enabled) wants a KdDisableDebugger()
+ * first (i.e. that the debugger was previously explicitly disabled)
+ * in order to return success; otherwise it'll return
STATUS_INVALID_PARAMETER.
+ */
+ if (Command == SysDbgEnableKernelDebugger)
+ {
+ ok(Status == STATUS_SUCCESS || Status == STATUS_INVALID_PARAMETER,
+ "In test %lu: Status = 0x%08lx, expected 0x%08lx or
0x%08lx\n",
+ Command, Status, STATUS_SUCCESS, STATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ ok_eq_hex_test(Command, Status, STATUS_SUCCESS);
+ }
+ }
+ else
+ {
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* Re-enable or disable the debugger, depending on its original state */
+ if (WasDebuggerEnabled)
+ Command = SysDbgEnableKernelDebugger; // 21
+ else
+ Command = SysDbgDisableKernelDebugger; // 22
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_eq_hex_test(Command, Status, STATUS_SUCCESS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+
+
+ /* Supported commands */
+ for (Command = 23; Command <= 31; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* These are Vista+ and depend on the OS version */
+ for (Command = 32; Command <= 36; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ {
+ if (Version >= NTDDI_WIN6) // IsVistaOrHigher
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ }
+ else
+ {
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+ }
+
+ Command = 37; // SysDbgGetLiveKernelDump
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ {
+ if (Version >= NTDDI_WINBLUE)
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ }
+ else
+ {
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ Command = 38; // SysDbgKdPullRemoteFile
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ {
+ if (Version >= NTDDI_WIN10_VB)
+ ok_neq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ }
+ else
+ {
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* Unsupported commands */
+ for (Command = 39; Command <= 40; ++Command)
+ {
+ Status = TestSystemDebugControl((SYSDBG_COMMAND)Command);
+ if (!IsVistaOrHigher || IsDebuggerActive)
+ ok_eq_hex_test(Command, Status, STATUS_INVALID_INFO_CLASS);
+ else
+ ok_eq_hex_test(Command, Status, STATUS_DEBUGGER_INACTIVE);
+ }
+
+ /* Finally restore the original debug privilege state */
+ RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, PrivilegeSet[0], FALSE,
&PrivilegeSet[0]);
+}
+
+/* EOF */