* LICENSE: GPL - See COPYING in the top level directory
* PURPOSE: Test for NtQuery/SetSystemInformation
* PROGRAMMERS: Timo Kreuzer
+ * Thomas Faber <thomas.faber@reactos.org>
*/
-#define WIN32_NO_STATUS
-#include <stdio.h>
-#include <wine/test.h>
-#include <ndk/ntndk.h>
+#include <apitest.h>
-#define ok_long(x, y) \
- ok(x == y, "got %ld, expected %ld\n", (long)x, (long)y);
+#define WIN32_NO_STATUS
+#include <ndk/exfuncs.h>
+#include <ndk/rtlfuncs.h>
+#include <ndk/setypes.h>
-#define ok_ntstatus(status, expected) \
- ok(status == expected, "got 0x%lx, expected 0x%lx\n", status, expected);
-// ok(status == expected, "expected: " ##expected## ", got 0x%lx\n", status)
+#define ntv6(x) (LOBYTE(LOWORD(GetVersion())) >= 6 ? (x) : 0)
+static
void
-GetPrivilege()
+Test_Flags(void)
{
- HANDLE hToken;
- TOKEN_PRIVILEGES tkp;
+ NTSTATUS Status;
+ ULONG ReturnLength;
+ ULONG Flags;
+ ULONG Buffer[2];
+ ULONG Buffer2[2];
+ PSYSTEM_FLAGS_INFORMATION FlagsInfo = (PVOID)Buffer;
+ BOOLEAN PrivilegeEnabled;
- OpenProcessToken(GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
- &hToken);
+ /* Query */
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(SystemFlagsInformation, NULL, 0, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
- LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid);
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(SystemFlagsInformation, NULL, sizeof(SYSTEM_FLAGS_INFORMATION) - 1, &ReturnLength);
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0x55555555, "ReturnLength = %lu\n", ReturnLength);
- tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(SystemFlagsInformation, (PVOID)2, 0, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
- AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
-}
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(SystemFlagsInformation, (PVOID)4, 0, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, (PUCHAR)FlagsInfo + 2, sizeof(SYSTEM_FLAGS_INFORMATION), &ReturnLength);
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0x55555555, "ReturnLength = %lu\n", ReturnLength);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, (PUCHAR)FlagsInfo + 2, sizeof(SYSTEM_FLAGS_INFORMATION) - 1, &ReturnLength);
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0x55555555, "ReturnLength = %lu\n", ReturnLength);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION) - 1, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), &ReturnLength);
+ ok(Status == STATUS_SUCCESS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION), "ReturnLength = %lu\n", ReturnLength);
+ ok(FlagsInfo->Flags != 0x55555555, "Flags = %lx\n", FlagsInfo->Flags);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+ Flags = FlagsInfo->Flags;
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION) + 1, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_FLAGS_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), NULL);
+ ok(Status == STATUS_SUCCESS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(FlagsInfo->Flags == Flags, "Flags = %lx, expected %lx\n", FlagsInfo->Flags, Flags);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), (PVOID)4);
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), (PVOID)2);
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), (PVOID)1);
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ RtlFillMemory(Buffer2, sizeof(Buffer2), 0x55);
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION), (PULONG)((PUCHAR)Buffer2 + 1));
+ ok(Status == STATUS_SUCCESS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(FlagsInfo->Flags == Flags, "Flags = %lx, expected %lx\n", FlagsInfo->Flags, Flags);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+ ok(Buffer2[0] == 0x00000455, "Buffer2[0] = %lx\n", Buffer2[0]);
+ ok(Buffer2[1] == 0x55555500, "Buffer2[1] = %lx\n", Buffer2[1]);
+
+ /* Set */
+ Status = NtSetSystemInformation(SystemFlagsInformation, NULL, 0);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, NULL, sizeof(SYSTEM_FLAGS_INFORMATION) - 1);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, NULL, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_ACCESS_DENIED, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, (PVOID)2, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &PrivilegeEnabled);
+ if (!NT_SUCCESS(Status))
+ {
+ skip("Cannot acquire SeDebugPrivilege\n");
+ return;
+ }
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, NULL, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, (PVOID)2, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, (PVOID)4, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_ACCESS_VIOLATION, "NtSetSystemInformation returned %lx\n", Status);
+
+ FlagsInfo->Flags = Flags;
+ Status = NtSetSystemInformation(SystemFlagsInformation, (PUCHAR)FlagsInfo + 2, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, (PUCHAR)FlagsInfo + 2, sizeof(SYSTEM_FLAGS_INFORMATION) - 1);
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT, "NtSetSystemInformation returned %lx\n", Status);
+
+ Status = NtSetSystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION) - 1);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtSetSystemInformation returned %lx\n", Status);
+ Status = NtSetSystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION) + 1);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtSetSystemInformation returned %lx\n", Status);
+ Status = NtSetSystemInformation(SystemFlagsInformation, FlagsInfo, sizeof(SYSTEM_FLAGS_INFORMATION));
+ ok(Status == STATUS_SUCCESS, "NtSetSystemInformation returned %lx\n", Status);
+
+ ok(FlagsInfo->Flags == Flags, "Flags = %lx, expected %lu\n", FlagsInfo->Flags, Flags);
+
+ Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, PrivilegeEnabled, FALSE, &PrivilegeEnabled);
+ ok(Status == STATUS_SUCCESS, "RtlAdjustPrivilege returned %lx\n", Status);
+}
+
+static
void
Test_TimeAdjustment(void)
{
SYSTEM_SET_TIME_ADJUST_INFORMATION SetTimeInfo;
NTSTATUS Status;
ULONG ReturnLength;
-
- GetPrivilege();
+ BOOLEAN PrivilegeEnabled;
SetTimeInfo.TimeAdjustment = 0;
SetTimeInfo.Enable = 0;
ok_ntstatus(Status, STATUS_PRIVILEGE_NOT_HELD);
/* Get the required privilege */
- GetPrivilege();
+ Status = RtlAdjustPrivilege(SE_SYSTEMTIME_PRIVILEGE, TRUE, FALSE, &PrivilegeEnabled);
+ if (!NT_SUCCESS(Status))
+ {
+ skip("Cannot acquire SeSystemTimePrivilege\n");
+ return;
+ }
/* Test wrong length */
Status = NtSetSystemInformation(SystemTimeAdjustmentInformation,
sizeof(SetTimeInfo));
ok_ntstatus(Status, STATUS_SUCCESS);
+ Status = RtlAdjustPrivilege(SE_SYSTEMTIME_PRIVILEGE, PrivilegeEnabled, FALSE, &PrivilegeEnabled);
+ ok(Status == STATUS_SUCCESS, "RtlAdjustPrivilege returned %lx\n", Status);
+}
+
+static
+void
+Test_KernelDebugger(void)
+{
+ NTSTATUS Status;
+ ULONG ReturnLength;
+ ULONG Buffer[2];
+ PSYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo = (PVOID)Buffer;
+
+ /* Query */
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, NULL, 0, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, DebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION) - 1, &ReturnLength);
+ ok(Status == STATUS_INFO_LENGTH_MISMATCH, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION)), "ReturnLength = %lu\n", ReturnLength);
+ ok(Buffer[0] == 0x55555555, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, (PUCHAR)DebuggerInfo + 1, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), &ReturnLength);
+ ok(Status == STATUS_SUCCESS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), "ReturnLength = %lu\n", ReturnLength);
+ ok((Buffer[0] & 0x55fefe55) == 0x55000055, "Buffer[0] = %lx\n", Buffer[0]);
+ ok(Buffer[1] == 0x55555555, "Buffer[1] = %lx\n", Buffer[1]);
+
+ ReturnLength = 0x55555555;
+ RtlFillMemory(Buffer, sizeof(Buffer), 0x55);
+ Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, DebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), &ReturnLength);
+ ok(Status == STATUS_SUCCESS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION), "ReturnLength = %lu\n", ReturnLength);
+ ok(DebuggerInfo->KernelDebuggerEnabled == FALSE ||
+ DebuggerInfo->KernelDebuggerEnabled == TRUE, "KernelDebuggerEnabled = %u\n", DebuggerInfo->KernelDebuggerEnabled);
+ ok(DebuggerInfo->KernelDebuggerNotPresent == FALSE ||
+ DebuggerInfo->KernelDebuggerNotPresent == TRUE, "KernelDebuggerNotPresent = %u\n", DebuggerInfo->KernelDebuggerNotPresent);
+
+ /* Set - not supported */
+ DebuggerInfo->KernelDebuggerEnabled = FALSE;
+ DebuggerInfo->KernelDebuggerNotPresent = TRUE;
+ Status = NtSetSystemInformation(SystemKernelDebuggerInformation, DebuggerInfo, sizeof(SYSTEM_KERNEL_DEBUGGER_INFORMATION));
+ ok(Status == STATUS_INVALID_INFO_CLASS, "NtSetSystemInformation returned %lx\n", Status);
}
START_TEST(NtSystemInformation)
{
+ NTSTATUS Status;
+ ULONG ReturnLength;
+
+ Status = NtQuerySystemInformation(9999, NULL, 0, NULL);
+ ok(Status == STATUS_INVALID_INFO_CLASS, "NtQuerySystemInformation returned %lx\n", Status);
+
+ Status = NtQuerySystemInformation(9999, NULL, 0, (PVOID)1);
+ ok(Status == STATUS_ACCESS_VIOLATION ||
+ ntv6(Status == STATUS_INVALID_INFO_CLASS), "NtQuerySystemInformation returned %lx\n", Status);
+
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(9999, NULL, 0, &ReturnLength);
+ ok(Status == STATUS_INVALID_INFO_CLASS, "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0 ||
+ ntv6(ReturnLength == 0x55555555), "ReturnLength = %lu\n", ReturnLength);
+
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(9999, NULL, 1, &ReturnLength);
+ ok(Status == STATUS_ACCESS_VIOLATION ||
+ ntv6(Status == STATUS_INVALID_INFO_CLASS), "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0x55555555, "ReturnLength = %lu\n", ReturnLength);
+
+ ReturnLength = 0x55555555;
+ Status = NtQuerySystemInformation(9999, (PVOID)1, 1, &ReturnLength);
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT ||
+ ntv6(Status == STATUS_INVALID_INFO_CLASS), "NtQuerySystemInformation returned %lx\n", Status);
+ ok(ReturnLength == 0x55555555, "ReturnLength = %lu\n", ReturnLength);
+
+ Status = NtQuerySystemInformation(9999, NULL, 1, (PVOID)1);
+ ok(Status == STATUS_ACCESS_VIOLATION ||
+ ntv6(Status == STATUS_INVALID_INFO_CLASS), "NtQuerySystemInformation returned %lx\n", Status);
+
+ Status = NtQuerySystemInformation(9999, (PVOID)1, 1, (PVOID)1);
+ ok(Status == STATUS_DATATYPE_MISALIGNMENT ||
+ ntv6(Status == STATUS_INVALID_INFO_CLASS), "NtQuerySystemInformation returned %lx\n", Status);
+
+ Test_Flags();
Test_TimeAdjustment();
+ Test_KernelDebugger();
}