| author | |
| committer | |
| log | 60e2ea0bfbb8a8ae2df31a8e45ef8c416a9ff77e |
| tree | c221bd13b362fbc0161260bb41fe94c16bdb9bb4 |
| parent | 36044a0e81702954e0ad5d5bd14a8b23929e7db8 |
rather than SystemFunction036 from advapi32. This has the advantage that
the code is loaded preemptively, preventing random numbers from
failing when they are needed for the first time on a system under heavy
load.7 files changed, 6 insertions(+), 36 deletions(-)
lib/std/os/windows.zig+1-27| ... | ... | @@ -22,6 +22,7 @@ test { |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | 24 | pub const advapi32 = @import("windows/advapi32.zig"); |
| 25 | pub const bcryptprimitives = @import("windows/bcryptprimitives.zig"); | |
| 25 | 26 | pub const kernel32 = @import("windows/kernel32.zig"); |
| 26 | 27 | pub const ntdll = @import("windows/ntdll.zig"); |
| 27 | 28 | pub const ws2_32 = @import("windows/ws2_32.zig"); |
| ... | ... | @@ -2644,33 +2645,6 @@ pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInfor |
| 2644 | 2645 | } |
| 2645 | 2646 | } |
| 2646 | 2647 | |
| 2647 | pub const RtlGenRandomError = error{ | |
| 2648 | /// `RtlGenRandom` has been known to fail in situations where the system is under heavy load. | |
| 2649 | /// Unfortunately, it does not call `SetLastError`, so it is not possible to get more specific | |
| 2650 | /// error information; it could actually be due to an out-of-memory condition, for example. | |
| 2651 | SystemResources, | |
| 2652 | }; | |
| 2653 | ||
| 2654 | /// Call RtlGenRandom() instead of CryptGetRandom() on Windows | |
| 2655 | /// https://github.com/rust-lang-nursery/rand/issues/111 | |
| 2656 | /// https://bugzilla.mozilla.org/show_bug.cgi?id=504270 | |
| 2657 | pub fn RtlGenRandom(output: []u8) RtlGenRandomError!void { | |
| 2658 | var total_read: usize = 0; | |
| 2659 | var buff: []u8 = output[0..]; | |
| 2660 | const max_read_size: ULONG = maxInt(ULONG); | |
| 2661 | ||
| 2662 | while (total_read < output.len) { | |
| 2663 | const to_read: ULONG = @min(buff.len, max_read_size); | |
| 2664 | ||
| 2665 | if (advapi32.RtlGenRandom(buff.ptr, to_read) == 0) { | |
| 2666 | return error.SystemResources; | |
| 2667 | } | |
| 2668 | ||
| 2669 | total_read += to_read; | |
| 2670 | buff = buff[to_read..]; | |
| 2671 | } | |
| 2672 | } | |
| 2673 | ||
| 2674 | 2648 | pub const WaitForSingleObjectError = error{ |
| 2675 | 2649 | WaitAbandoned, |
| 2676 | 2650 | WaitTimeOut, |
lib/std/os/windows/advapi32.zig-5| ... | ... | @@ -28,11 +28,6 @@ pub extern "advapi32" fn RegQueryValueExW( |
| 28 | 28 | |
| 29 | 29 | pub extern "advapi32" fn RegCloseKey(hKey: HKEY) callconv(.winapi) LSTATUS; |
| 30 | 30 | |
| 31 | // RtlGenRandom is known as SystemFunction036 under advapi32 | |
| 32 | // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx */ | |
| 33 | pub extern "advapi32" fn SystemFunction036(output: [*]u8, length: ULONG) callconv(.winapi) BOOL; | |
| 34 | pub const RtlGenRandom = SystemFunction036; | |
| 35 | ||
| 36 | 31 | pub const RRF = struct { |
| 37 | 32 | pub const RT_ANY: DWORD = 0x0000ffff; |
| 38 | 33 |
lib/std/os/windows/bcryptprimitives.zig created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | const std = @import("../../std.zig"); | |
| 2 | const windows = std.os.windows; | |
| 3 | ||
| 4 | pub extern "bcryptprimitives" fn ProcessPrng(pbData: [*]u8, cbData: usize) callconv(.winapi) c_int; |
lib/std/posix.zig+1-1| ... | ... | @@ -370,7 +370,7 @@ pub const GetRandomError = OpenError; |
| 370 | 370 | /// library implementation. |
| 371 | 371 | pub fn getrandom(buffer: []u8) GetRandomError!void { |
| 372 | 372 | if (native_os == .windows) { |
| 373 | return windows.RtlGenRandom(buffer); | |
| 373 | return assert(windows.bcryptprimitives.ProcessPrng(buffer.ptr, buffer.len) == 1); | |
| 374 | 374 | } |
| 375 | 375 | if (builtin.link_libc and @TypeOf(system.arc4random_buf) != void) { |
| 376 | 376 | system.arc4random_buf(buffer.ptr, buffer.len); |
test/standalone/issue_5825/build.zig-1| ... | ... | @@ -32,7 +32,6 @@ pub fn build(b: *std.Build) void { |
| 32 | 32 | }), |
| 33 | 33 | }); |
| 34 | 34 | exe.subsystem = .console; |
| 35 | exe.root_module.linkSystemLibrary("advapi32", .{}); // for RtlGenRandom | |
| 36 | 35 | exe.root_module.linkSystemLibrary("kernel32", .{}); |
| 37 | 36 | exe.root_module.linkSystemLibrary("ntdll", .{}); |
| 38 | 37 | exe.root_module.addObject(obj); |
test/standalone/test_obj_link_run/build.zig-1| ... | ... | @@ -12,7 +12,6 @@ pub fn build(b: *std.Build) void { |
| 12 | 12 | test_obj.root_module.linkSystemLibrary("ntdll", .{}); |
| 13 | 13 | test_obj.root_module.linkSystemLibrary("kernel32", .{}); |
| 14 | 14 | test_obj.root_module.linkSystemLibrary("ws2_32", .{}); |
| 15 | test_obj.root_module.linkSystemLibrary("advapi32", .{}); // for RtlGenRandom | |
| 16 | 15 | } |
| 17 | 16 | |
| 18 | 17 | const test_exe_mod = b.createModule(.{ |
test/standalone/windows_argv/build.zig-1| ... | ... | @@ -86,7 +86,6 @@ pub fn build(b: *std.Build) !void { |
| 86 | 86 | .optimize = optimize, |
| 87 | 87 | }), |
| 88 | 88 | }); |
| 89 | lib_msvc.root_module.linkSystemLibrary("advapi32", .{}); // for RtlGenRandom | |
| 90 | 89 | const verify_msvc = b.addExecutable(.{ |
| 91 | 90 | .name = "verify-msvc", |
| 92 | 91 | .root_module = b.createModule(.{ |