Based on a patch by Sebastian Lackner.
Signed-off-by: Hans Leidekker hans@codeweavers.com --- configure.ac | 2 ++ dlls/ntdll/tests/info.c | 3 ++- dlls/ntdll/unix/system.c | 34 +++++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac index 006087e05ec..c017d204aab 100644 --- a/configure.ac +++ b/configure.ac @@ -514,6 +514,7 @@ AC_CHECK_HEADERS(\ sys/protosw.h \ sys/ptrace.h \ sys/queue.h \ + sys/random.h \ sys/resource.h \ sys/scsiio.h \ sys/shm.h \ @@ -2203,6 +2204,7 @@ AC_CHECK_FUNCS(\ getauxval \ getifaddrs \ getopt_long_only \ + getrandom \ kqueue \ lstat \ mach_continuous_time \ diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 057b855914a..b09c57b97a7 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -643,7 +643,8 @@ static void test_query_interrupt(void) sii = HeapAlloc(GetProcessHeap(), 0, NeededLength);
status = pNtQuerySystemInformation(SystemInterruptInformation, sii, 0, &ReturnLength); - ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + ok(ReturnLength == NeededLength, "got %u\n", ReturnLength);
/* Try it for all processors */ status = pNtQuerySystemInformation(SystemInterruptInformation, sii, NeededLength, &ReturnLength); diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index c2412643afa..ccbc68b972d 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -29,6 +29,7 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <errno.h> #ifdef HAVE_SYS_TIME_H # include <sys/time.h> #endif @@ -42,6 +43,9 @@ #ifdef HAVE_MACHINE_CPU_H # include <machine/cpu.h> #endif +#ifdef HAVE_SYS_RANDOM_H +# include <sys/random.h> +#endif #ifdef HAVE_IOKIT_IOKITLIB_H # include <CoreFoundation/CoreFoundation.h> # include <IOKit/IOKitLib.h> @@ -2422,16 +2426,36 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
case SystemInterruptInformation: { - SYSTEM_INTERRUPT_INFORMATION sii = {{ 0 }}; - - len = sizeof(sii); + len = NtCurrentTeb()->Peb->NumberOfProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION); if (size >= len) { if (!info) ret = STATUS_ACCESS_VIOLATION; - else memcpy( info, &sii, len); + else + { +#ifdef HAVE_GETRANDOM + int ret; + do + { + ret = getrandom( info, len, 0 ); + } + while (ret == -1 && errno == EINTR); +#else + int fd = open( "/dev/urandom", O_RDONLY ); + if (fd != -1) + { + int ret; + do + { + ret = read( fd, info, len ); + } + while (ret == -1 && errno == EINTR); + close( fd ); + } + else WARN( "can't open /dev/urandom\n" ); +#endif + } } else ret = STATUS_INFO_LENGTH_MISMATCH; - FIXME("info_class SYSTEM_INTERRUPT_INFORMATION\n"); break; }