From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/info.c | 46 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/system.c | 20 +++++++++++++++++ dlls/wow64/system.c | 11 +++++++--- 3 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 8e8abbfb467..ba19b248e43 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -4019,6 +4019,51 @@ static void test_process_id(void) } }
+static void test_processor_idle_cycle_time(void) +{ + unsigned int cpu_count = NtCurrentTeb()->Peb->NumberOfProcessors; + ULONG64 buffer[64]; + NTSTATUS status; + USHORT group_id; + ULONG size; + + size = 0xdeadbeef; + status = pNtQuerySystemInformation( SystemProcessorIdleCycleTimeInformation, NULL, 0, &size ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx.\n", status ); + ok( size == cpu_count * sizeof(*buffer), "got %#lx.\n", size ); + + size = 0xdeadbeef; + status = pNtQuerySystemInformation( SystemProcessorIdleCycleTimeInformation, buffer, 7, &size ); + ok( status == STATUS_BUFFER_TOO_SMALL, "got %#lx.\n", status ); + ok( size == cpu_count * sizeof(*buffer), "got %#lx.\n", size ); + + size = 0xdeadbeef; + status = pNtQuerySystemInformation( SystemProcessorIdleCycleTimeInformation, NULL, sizeof(buffer), &size ); + ok( status == STATUS_ACCESS_VIOLATION, "got %#lx.\n", status ); + ok( size == 0xdeadbeef, "got %#lx.\n", size ); + + size = 0xdeadbeef; + status = pNtQuerySystemInformation( SystemProcessorIdleCycleTimeInformation, buffer, sizeof(buffer), &size ); + ok( !status, "got %#lx.\n", status ); + ok( size == cpu_count * sizeof(*buffer), "got %#lx.\n", size ); + + memset( buffer, 0xcc, sizeof(buffer) ); + size = 0xdeadbeef; + status = pNtQuerySystemInformationEx( SystemProcessorIdleCycleTimeInformation, NULL, 0, buffer, sizeof(buffer), &size ); + ok( status == STATUS_INVALID_PARAMETER, "got %#lx.\n", status ); + ok( size == 0xdeadbeef, "got %#lx.\n", size ); + group_id = 50; + size = 0xdeadbeef; + status = pNtQuerySystemInformationEx( SystemProcessorIdleCycleTimeInformation, &group_id, sizeof(group_id), buffer, sizeof(buffer), &size ); + ok( status == STATUS_INVALID_PARAMETER, "got %#lx.\n", status ); + ok( size == 0xdeadbeef, "got %#lx.\n", size ); + group_id = 0; + size = 0xdeadbeef; + status = pNtQuerySystemInformationEx( SystemProcessorIdleCycleTimeInformation, &group_id, sizeof(group_id), buffer, sizeof(buffer), &size ); + ok( status == STATUS_SUCCESS, "got %#lx.\n", status ); + ok( size == cpu_count * sizeof(*buffer), "got %#lx.\n", size ); +} + START_TEST(info) { char **argv; @@ -4098,4 +4143,5 @@ START_TEST(info) test_system_debug_control(); test_process_token(argc, argv); test_process_id(); + test_processor_idle_cycle_time(); } diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index efb6e7f4579..7eba7ecdbf9 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -3258,6 +3258,13 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, break; }
+ case SystemProcessorIdleCycleTimeInformation: /* 83 */ + { + ULONG group_id = 0; /* FIXME: should probably be current CPU group id. */ + + return NtQuerySystemInformationEx( class, &group_id, sizeof(group_id), info, size, ret_size ); + } + case SystemProcessIdInformation: /* 88 */ { SYSTEM_PROCESS_ID_INFORMATION *id = info; @@ -3407,6 +3414,19 @@ NTSTATUS WINAPI NtQuerySystemInformationEx( SYSTEM_INFORMATION_CLASS class,
switch (class) { + case SystemProcessorIdleCycleTimeInformation: + len = peb->NumberOfProcessors * sizeof(ULONG64); + if (!query || query_len < sizeof(USHORT) || *(USHORT *)query) return STATUS_INVALID_PARAMETER; + if (size < len) + { + ret = STATUS_BUFFER_TOO_SMALL; + break; + } + FIXME( "SystemProcessorIdleCycleTimeInformation stub.\n" ); + memset( info, 0, len ); + ret = STATUS_SUCCESS; + break; + case SystemLogicalProcessorInformationEx: { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *p; diff --git a/dlls/wow64/system.c b/dlls/wow64/system.c index 6e78c462984..5f3056a4179 100644 --- a/dlls/wow64/system.c +++ b/dlls/wow64/system.c @@ -326,6 +326,7 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformation( UINT *args ) case SystemCurrentTimeZoneInformation: /* RTL_TIME_ZONE_INFORMATION */ case SystemRecommendedSharedDataAlignment: /* ULONG */ case SystemFirmwareTableInformation: /* SYSTEM_FIRMWARE_TABLE_INFORMATION */ + case SystemProcessorIdleCycleTimeInformation: /* ULONG64[] */ case SystemDynamicTimeZoneInformation: /* RTL_DYNAMIC_TIME_ZONE_INFORMATION */ case SystemCodeIntegrityInformation: /* SYSTEM_CODEINTEGRITY_INFORMATION */ case SystemKernelDebuggerInformationEx: /* SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX */ @@ -622,17 +623,19 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformationEx( UINT *args ) HANDLE handle; NTSTATUS status;
- if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER; - handle = LongToHandle( *(LONG *)query ); - switch (class) { + case SystemProcessorIdleCycleTimeInformation: + return NtQuerySystemInformationEx( class, query, query_len, ptr, len, retlen ); + case SystemLogicalProcessorInformationEx: /* SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX */ { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX32 *ex32, *info32 = ptr; SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *ex, *info; ULONG size, size32, pos = 0, pos32 = 0;
+ if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER; + handle = LongToHandle( *(LONG *)query ); status = NtQuerySystemInformationEx( class, &handle, sizeof(handle), NULL, 0, &size ); if (status != STATUS_INFO_LENGTH_MISMATCH) return status; info = Wow64AllocateTemp( size ); @@ -676,6 +679,8 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformationEx( UINT *args )
case SystemCpuSetInformation: /* SYSTEM_CPU_SET_INFORMATION */ case SystemSupportedProcessorArchitectures: /* SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION */ + if (!query || query_len < sizeof(LONG)) return STATUS_INVALID_PARAMETER; + handle = LongToHandle( *(LONG *)query ); return NtQuerySystemInformationEx( class, &handle, sizeof(handle), ptr, len, retlen );
default: