about summary refs log tree commit diff
path: root/src/libstd/sys/windows
diff options
context:
space:
mode:
authorSean McArthur <sean.monstar@gmail.com>2016-02-17 13:56:16 -0800
committerSean McArthur <sean.monstar@gmail.com>2016-02-17 16:21:32 -0800
commit34dfc3991db26a363657f0bd56db1669032468b3 (patch)
treea954d70137f6c2527a0ef4e5ce6bfb60d70451c5 /src/libstd/sys/windows
parentb54770c24578311ad6cc782fcf1d0dc8cb41e997 (diff)
downloadrust-34dfc3991db26a363657f0bd56db1669032468b3.tar.gz
rust-34dfc3991db26a363657f0bd56db1669032468b3.zip
std: restructure rand os code into sys modules
Diffstat (limited to 'src/libstd/sys/windows')
-rw-r--r--src/libstd/sys/windows/mod.rs1
-rw-r--r--src/libstd/sys/windows/rand.rs72
2 files changed, 73 insertions, 0 deletions
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 9ecef5ee92c..765e6e09427 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -33,6 +33,7 @@ pub mod os;
 pub mod os_str;
 pub mod pipe;
 pub mod process;
+pub mod rand;
 pub mod rwlock;
 pub mod stack_overflow;
 pub mod thread;
diff --git a/src/libstd/sys/windows/rand.rs b/src/libstd/sys/windows/rand.rs
new file mode 100644
index 00000000000..fdd260b6e28
--- /dev/null
+++ b/src/libstd/sys/windows/rand.rs
@@ -0,0 +1,72 @@
+// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+use io;
+use mem;
+use rand::Rng;
+use sys::c;
+
+pub struct OsRng {
+    hcryptprov: c::HCRYPTPROV
+}
+
+impl OsRng {
+    /// Create a new `OsRng`.
+    pub fn new() -> io::Result<OsRng> {
+        let mut hcp = 0;
+        let ret = unsafe {
+            c::CryptAcquireContextA(&mut hcp, 0 as c::LPCSTR, 0 as c::LPCSTR,
+                                    c::PROV_RSA_FULL,
+                                    c::CRYPT_VERIFYCONTEXT | c::CRYPT_SILENT)
+        };
+
+        if ret == 0 {
+            Err(io::Error::last_os_error())
+        } else {
+            Ok(OsRng { hcryptprov: hcp })
+        }
+    }
+}
+
+impl Rng for OsRng {
+    fn next_u32(&mut self) -> u32 {
+        let mut v = [0; 4];
+        self.fill_bytes(&mut v);
+        unsafe { mem::transmute(v) }
+    }
+    fn next_u64(&mut self) -> u64 {
+        let mut v = [0; 8];
+        self.fill_bytes(&mut v);
+        unsafe { mem::transmute(v) }
+    }
+    fn fill_bytes(&mut self, v: &mut [u8]) {
+        let ret = unsafe {
+            c::CryptGenRandom(self.hcryptprov, v.len() as c::DWORD,
+                              v.as_mut_ptr())
+        };
+        if ret == 0 {
+            panic!("couldn't generate random bytes: {}",
+                   io::Error::last_os_error());
+        }
+    }
+}
+
+impl Drop for OsRng {
+    fn drop(&mut self) {
+        let ret = unsafe {
+            c::CryptReleaseContext(self.hcryptprov, 0)
+        };
+        if ret == 0 {
+            panic!("couldn't release context: {}",
+                   io::Error::last_os_error());
+        }
+    }
+}