From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/info.c | 46 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/system.c | 20 +++++++++++++++++ dlls/wow64/system.c | 4 ++++ 3 files changed, 70 insertions(+)
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..6a61d6b7a4d 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 */ @@ -627,6 +628,9 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformationEx( UINT *args )
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;