diff --git a/configure b/configure index 5da5e9e7130..8d68b2e4cfa 100755 --- a/configure +++ b/configure @@ -7486,6 +7486,7 @@ for ac_header in \ sys/protosw.h \ sys/ptrace.h \ sys/queue.h \ + sys/random.h \ sys/resource.h \ sys/scsiio.h \ sys/shm.h \ @@ -17877,6 +17878,7 @@ for ac_func in \ getauxval \ getifaddrs \ getopt_long_only \ + getrandom \ kqueue \ lstat \ mach_continuous_time \ diff --git a/configure.ac b/configure.ac index 08d0af0ec19..123dea0f5f1 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 \ @@ -2181,6 +2182,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 #include #include +#include #ifdef HAVE_SYS_TIME_H # include #endif @@ -42,6 +43,9 @@ #ifdef HAVE_MACHINE_CPU_H # include #endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif #ifdef HAVE_IOKIT_IOKITLIB_H # include # include @@ -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; } diff --git a/include/config.h.in b/include/config.h.in index 5a21875f66c..4309920ffac 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -252,6 +252,9 @@ /* Define to 1 if you have the `getopt_long_only' function. */ #undef HAVE_GETOPT_LONG_ONLY +/* Define to 1 if you have the `getrandom' function. */ +#undef HAVE_GETRANDOM + /* Define to 1 if you have the `getservbyport' function. */ #undef HAVE_GETSERVBYPORT @@ -1061,6 +1064,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_QUEUE_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RANDOM_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H