Add Windows UWP support (#69)
This commit is contained in:
@@ -137,6 +137,7 @@ matrix:
|
||||
- cargo xbuild --target=x86_64-unknown-uefi
|
||||
- cargo xbuild --target=x86_64-unknown-hermit
|
||||
- cargo xbuild --target=x86_64-unknown-l4re-uclibc
|
||||
- cargo xbuild --target=x86_64-uwp-windows-gnu
|
||||
|
||||
# Trust cross-built/emulated targets. We must repeat all non-default values.
|
||||
- rust: stable
|
||||
|
||||
+12
-1
@@ -21,10 +21,21 @@ environment:
|
||||
|
||||
matrix:
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: 1.32.0
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: stable
|
||||
- TARGET: x86_64-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
- TARGET: i686-pc-windows-msvc
|
||||
CHANNEL: nightly
|
||||
- TARGET: x86_64-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
- TARGET: i686-pc-windows-gnu
|
||||
CHANNEL: nightly
|
||||
|
||||
install:
|
||||
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||
- rustup-init.exe -y --default-host %TARGET%
|
||||
- rustup-init.exe -y --default-host %TARGET% --default-toolchain %CHANNEL%
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
if target.contains("-uwp-windows-") {
|
||||
// for BCryptGenRandom
|
||||
println!("cargo:rustc-link-lib=bcrypt");
|
||||
// to work around unavailability of `target_vendor` on Rust 1.33
|
||||
println!("cargo:rustc-cfg=getrandom_uwp");
|
||||
} else if target.contains("windows") {
|
||||
// for RtlGenRandom (aka SystemFunction036)
|
||||
println!("cargo:rustc-link-lib=advapi32");
|
||||
} else if target.contains("apple-ios") {
|
||||
// for SecRandomCopyBytes and kSecRandomDefault
|
||||
println!("cargo:rustc-link-lib=framework=Security");
|
||||
}
|
||||
}
|
||||
+10
@@ -126,6 +126,14 @@ cfg_if! {
|
||||
macro_rules! error {
|
||||
($($x:tt)*) => {};
|
||||
}
|
||||
#[allow(unused)]
|
||||
macro_rules! warn {
|
||||
($($x:tt)*) => {};
|
||||
}
|
||||
#[allow(unused)]
|
||||
macro_rules! info {
|
||||
($($x:tt)*) => {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +210,8 @@ cfg_if! {
|
||||
#[path = "solaris_illumos.rs"] mod imp;
|
||||
} else if #[cfg(target_os = "wasi")] {
|
||||
#[path = "wasi.rs"] mod imp;
|
||||
} else if #[cfg(all(windows, getrandom_uwp))] {
|
||||
#[path = "windows_uwp.rs"] mod imp;
|
||||
} else if #[cfg(windows)] {
|
||||
#[path = "windows.rs"] mod imp;
|
||||
} else if #[cfg(all(target_arch = "x86_64", any(
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2018 Developers of the Rand project.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation for Windows UWP targets. After deprecation of Windows XP
|
||||
//! and Vista, this can superseed the `RtlGenRandom`-based implementation.
|
||||
use crate::Error;
|
||||
use core::{ffi::c_void, num::NonZeroU32, ptr};
|
||||
|
||||
const BCRYPT_USE_SYSTEM_PREFERRED_RNG: u32 = 0x00000002;
|
||||
|
||||
extern "system" {
|
||||
fn BCryptGenRandom(
|
||||
hAlgorithm: *mut c_void,
|
||||
pBuffer: *mut u8,
|
||||
cbBuffer: u32,
|
||||
dwFlags: u32,
|
||||
) -> u32;
|
||||
}
|
||||
|
||||
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
|
||||
// Prevent overflow of u32
|
||||
for chunk in dest.chunks_mut(u32::max_value() as usize) {
|
||||
let ret = unsafe {
|
||||
BCryptGenRandom(
|
||||
ptr::null_mut(),
|
||||
chunk.as_mut_ptr(),
|
||||
chunk.len() as u32,
|
||||
BCRYPT_USE_SYSTEM_PREFERRED_RNG,
|
||||
)
|
||||
};
|
||||
// NTSTATUS codes use two highest bits for severity status
|
||||
match ret >> 30 {
|
||||
0b01 => {
|
||||
info!("BCryptGenRandom: information code 0x{:08X}", ret);
|
||||
}
|
||||
0b10 => {
|
||||
warn!("BCryptGenRandom: warning code 0x{:08X}", ret);
|
||||
}
|
||||
0b11 => {
|
||||
error!("BCryptGenRandom: failed with 0x{:08X}", ret);
|
||||
// We zeroize the highest bit, so the error code will reside
|
||||
// inside the range of designated for OS codes.
|
||||
let code = ret ^ (1 << 31);
|
||||
// SAFETY: the second highest bit is always equal to one,
|
||||
// so it's impossible to get zero. Unfortunately compiler
|
||||
// is not smart enough to figure out it yet.
|
||||
let code = unsafe { NonZeroU32::new_unchecked(code) };
|
||||
return Err(Error::from(code));
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user