Upgrade rust/crates/getrandom to 0.2.3

Test: make
Change-Id: I9d01567c5723cd80e2675c1e5c8edbae2b6b65d1
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 64fafa1..d80d39e 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "d79de0c95c01860268e071bcb6b0d019e18cd608"
+    "sha1": "de51e2961d05c7af3f19c0c78f9a414cdcb83b67"
   }
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3ca728..0ae351a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,16 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.2.3] - 2021-04-10
+### Changed
+- Replace build.rs with link attributes. [#205]
+- Add support for getrandom syscall on DragonFly BSD. [#210]
+- Improve Node.js detection. [#215]
+
+[#205]: https://github.com/rust-random/getrandom/pull/205
+[#210]: https://github.com/rust-random/getrandom/pull/210
+[#215]: https://github.com/rust-random/getrandom/pull/215
+
 ## [0.2.2] - 2021-01-19
 ### Changed
 - Forward `rustc-dep-of-std` to dependencies. [#198]
diff --git a/Cargo.toml b/Cargo.toml
index 2c0c056..8c0d4f4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 [package]
 edition = "2018"
 name = "getrandom"
-version = "0.2.2"
+version = "0.2.3"
 authors = ["The Rand Project Developers"]
 exclude = [".*"]
 description = "A small cross-platform library for retrieving random data from system source"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index dabf016..4ab9ad6 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "getrandom"
-version = "0.2.2" # Also update html_root_url in lib.rs when bumping this
+version = "0.2.3" # Also update html_root_url in lib.rs when bumping this
 edition = "2018"
 authors = ["The Rand Project Developers"]
 license = "MIT OR Apache-2.0"
diff --git a/METADATA b/METADATA
index 60dca65..aaa5815 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/getrandom/getrandom-0.2.2.crate"
+    value: "https://static.crates.io/crates/getrandom/getrandom-0.2.3.crate"
   }
-  version: "0.2.2"
+  version: "0.2.3"
   license_type: NOTICE
   last_upgrade_date {
     year: 2021
-    month: 3
-    day: 3
+    month: 6
+    day: 21
   }
 }
diff --git a/TEST_MAPPING b/TEST_MAPPING
index efa80d7..0aed480 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,28 +2,250 @@
 {
   "presubmit": [
     {
-      "name": "keystore2_test"
+      "name": "crossbeam-epoch_device_test_src_lib"
+    },
+    {
+      "name": "crossbeam-epoch_device_test_tests_loom"
+    },
+    {
+      "name": "crossbeam-utils_device_test_src_lib"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_atomic_cell"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_cache_padded"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_parker"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_sharded_lock"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_thread"
+    },
+    {
+      "name": "crossbeam-utils_device_test_tests_wait_group"
+    },
+    {
+      "name": "getrandom_device_test_src_lib"
     },
     {
       "name": "getrandom_device_test_tests_custom"
     },
     {
-      "name": "rand_xorshift_device_test_tests_mod"
-    },
-    {
       "name": "getrandom_device_test_tests_normal"
     },
     {
-      "name": "rand_xorshift_device_test_src_lib"
-    },
-    {
       "name": "getrandom_device_test_tests_rdrand"
     },
     {
+      "name": "keystore2_test"
+    },
+    {
       "name": "rand_core_device_test_src_lib"
     },
     {
-      "name": "getrandom_device_test_src_lib"
+      "name": "rand_xorshift_device_test_src_lib"
+    },
+    {
+      "name": "rand_xorshift_device_test_tests_mod"
+    },
+    {
+      "name": "tokio_device_test_tests__require_full"
+    },
+    {
+      "name": "tokio_device_test_tests_buffered"
+    },
+    {
+      "name": "tokio_device_test_tests_io_async_fd"
+    },
+    {
+      "name": "tokio_device_test_tests_io_async_read"
+    },
+    {
+      "name": "tokio_device_test_tests_io_chain"
+    },
+    {
+      "name": "tokio_device_test_tests_io_copy"
+    },
+    {
+      "name": "tokio_device_test_tests_io_copy_bidirectional"
+    },
+    {
+      "name": "tokio_device_test_tests_io_driver"
+    },
+    {
+      "name": "tokio_device_test_tests_io_driver_drop"
+    },
+    {
+      "name": "tokio_device_test_tests_io_lines"
+    },
+    {
+      "name": "tokio_device_test_tests_io_mem_stream"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_buf"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_exact"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_line"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_to_end"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_to_string"
+    },
+    {
+      "name": "tokio_device_test_tests_io_read_until"
+    },
+    {
+      "name": "tokio_device_test_tests_io_split"
+    },
+    {
+      "name": "tokio_device_test_tests_io_take"
+    },
+    {
+      "name": "tokio_device_test_tests_io_write"
+    },
+    {
+      "name": "tokio_device_test_tests_io_write_all"
+    },
+    {
+      "name": "tokio_device_test_tests_io_write_buf"
+    },
+    {
+      "name": "tokio_device_test_tests_io_write_int"
+    },
+    {
+      "name": "tokio_device_test_tests_macros_join"
+    },
+    {
+      "name": "tokio_device_test_tests_macros_pin"
+    },
+    {
+      "name": "tokio_device_test_tests_macros_select"
+    },
+    {
+      "name": "tokio_device_test_tests_macros_test"
+    },
+    {
+      "name": "tokio_device_test_tests_macros_try_join"
+    },
+    {
+      "name": "tokio_device_test_tests_net_bind_resource"
+    },
+    {
+      "name": "tokio_device_test_tests_net_lookup_host"
+    },
+    {
+      "name": "tokio_device_test_tests_no_rt"
+    },
+    {
+      "name": "tokio_device_test_tests_process_kill_on_drop"
+    },
+    {
+      "name": "tokio_device_test_tests_rt_basic"
+    },
+    {
+      "name": "tokio_device_test_tests_rt_common"
+    },
+    {
+      "name": "tokio_device_test_tests_rt_threaded"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_barrier"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_broadcast"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_errors"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_mpsc"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_mutex"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_mutex_owned"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_notify"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_oneshot"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_rwlock"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_semaphore"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_semaphore_owned"
+    },
+    {
+      "name": "tokio_device_test_tests_sync_watch"
+    },
+    {
+      "name": "tokio_device_test_tests_task_abort"
+    },
+    {
+      "name": "tokio_device_test_tests_task_blocking"
+    },
+    {
+      "name": "tokio_device_test_tests_task_local"
+    },
+    {
+      "name": "tokio_device_test_tests_task_local_set"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_accept"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_connect"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_echo"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_into_split"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_into_std"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_peek"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_shutdown"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_socket"
+    },
+    {
+      "name": "tokio_device_test_tests_tcp_split"
+    },
+    {
+      "name": "tokio_device_test_tests_time_rt"
+    },
+    {
+      "name": "tokio_device_test_tests_udp"
+    },
+    {
+      "name": "tokio_device_test_tests_uds_cred"
+    },
+    {
+      "name": "tokio_device_test_tests_uds_split"
     },
     {
       "name": "vpnprofilestore_test"
diff --git a/build.rs b/build.rs
deleted file mode 100644
index 95f4b90..0000000
--- a/build.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![deny(warnings)]
-
-use std::env;
-
-fn main() {
-    let target = env::var("TARGET").expect("TARGET was not set");
-    if target.contains("windows") {
-        // for BCryptGenRandom
-        println!("cargo:rustc-link-lib=bcrypt");
-    } else if target.contains("apple-ios") {
-        // for SecRandomCopyBytes and kSecRandomDefault
-        println!("cargo:rustc-link-lib=framework=Security");
-    }
-}
diff --git a/src/dragonfly.rs b/src/dragonfly.rs
new file mode 100644
index 0000000..f27e906
--- /dev/null
+++ b/src/dragonfly.rs
@@ -0,0 +1,26 @@
+// Copyright 2021 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 DragonFly BSD
+use crate::{
+    use_file,
+    util_libc::{sys_fill_exact, Weak},
+    Error,
+};
+
+pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
+    static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
+    type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
+
+    if let Some(fptr) = GETRANDOM.ptr() {
+        let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
+        return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
+    } else {
+        use_file::getrandom_inner(dest)
+    }
+}
diff --git a/src/error.rs b/src/error.rs
index 48abdc1..0f52186 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -162,7 +162,7 @@
         Error::WINDOWS_RTL_GEN_RANDOM => Some("RtlGenRandom: Windows system function failure"),
         Error::FAILED_RDRAND => Some("RDRAND: failed multiple times: CPU issue likely"),
         Error::NO_RDRAND => Some("RDRAND: instruction not supported"),
-        Error::WEB_CRYPTO => Some("Web API self.crypto is unavailable"),
+        Error::WEB_CRYPTO => Some("Web Crypto API is unavailable"),
         Error::WEB_GET_RANDOM_VALUES => Some("Web API crypto.getRandomValues is unavailable"),
         Error::VXWORKS_RAND_SECURE => Some("randSecure: VxWorks RNG module is not initialized"),
         Error::NODE_CRYPTO => Some("Node.js crypto module is unavailable"),
diff --git a/src/js.rs b/src/js.rs
index d48c7d3..657d2ac 100644
--- a/src/js.rs
+++ b/src/js.rs
@@ -11,7 +11,7 @@
 use std::thread_local;
 
 use js_sys::Uint8Array;
-use wasm_bindgen::prelude::*;
+use wasm_bindgen::{prelude::*, JsCast};
 
 // Maximum is 65536 bytes see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
 const BROWSER_CRYPTO_BUFFER_SIZE: usize = 256;
@@ -57,50 +57,65 @@
 }
 
 fn getrandom_init() -> Result<RngSource, Error> {
-    if let Ok(self_) = Global::get_self() {
-        // If `self` is defined then we're in a browser somehow (main window
-        // or web worker). We get `self.crypto` (called `msCrypto` on IE), so we
-        // can call `crypto.getRandomValues`. If `crypto` isn't defined, we
-        // assume we're in an older web browser and the OS RNG isn't available.
-
-        let crypto: BrowserCrypto = match (self_.crypto(), self_.ms_crypto()) {
-            (crypto, _) if !crypto.is_undefined() => crypto,
-            (_, crypto) if !crypto.is_undefined() => crypto,
-            _ => return Err(Error::WEB_CRYPTO),
-        };
-
-        let buf = Uint8Array::new_with_length(BROWSER_CRYPTO_BUFFER_SIZE as u32);
-        return Ok(RngSource::Browser(crypto, buf));
+    let global: Global = js_sys::global().unchecked_into();
+    if is_node(&global) {
+        let crypto = require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
+        return Ok(RngSource::Node(crypto));
     }
 
-    let crypto = MODULE.require("crypto").map_err(|_| Error::NODE_CRYPTO)?;
-    Ok(RngSource::Node(crypto))
+    // Assume we are in some Web environment (browser or web worker). We get
+    // `self.crypto` (called `msCrypto` on IE), so we can call
+    // `crypto.getRandomValues`. If `crypto` isn't defined, we assume that
+    // we are in an older web browser and the OS RNG isn't available.
+    let crypto = match (global.crypto(), global.ms_crypto()) {
+        (c, _) if c.is_object() => c,
+        (_, c) if c.is_object() => c,
+        _ => return Err(Error::WEB_CRYPTO),
+    };
+
+    let buf = Uint8Array::new_with_length(BROWSER_CRYPTO_BUFFER_SIZE as u32);
+    Ok(RngSource::Browser(crypto, buf))
+}
+
+// Taken from https://www.npmjs.com/package/browser-or-node
+fn is_node(global: &Global) -> bool {
+    let process = global.process();
+    if process.is_object() {
+        let versions = process.versions();
+        if versions.is_object() {
+            return versions.node().is_string();
+        }
+    }
+    false
 }
 
 #[wasm_bindgen]
 extern "C" {
-    type Global;
-    #[wasm_bindgen(getter, catch, static_method_of = Global, js_class = self, js_name = self)]
-    fn get_self() -> Result<Self_, JsValue>;
+    type Global; // Return type of js_sys::global()
 
-    type Self_;
+    // Web Crypto API (https://www.w3.org/TR/WebCryptoAPI/)
     #[wasm_bindgen(method, getter, js_name = "msCrypto")]
-    fn ms_crypto(me: &Self_) -> BrowserCrypto;
+    fn ms_crypto(this: &Global) -> BrowserCrypto;
     #[wasm_bindgen(method, getter)]
-    fn crypto(me: &Self_) -> BrowserCrypto;
-
+    fn crypto(this: &Global) -> BrowserCrypto;
     type BrowserCrypto;
     #[wasm_bindgen(method, js_name = getRandomValues, catch)]
-    fn get_random_values(me: &BrowserCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
+    fn get_random_values(this: &BrowserCrypto, buf: &Uint8Array) -> Result<(), JsValue>;
 
-    #[wasm_bindgen(js_name = module)]
-    static MODULE: NodeModule;
-
-    type NodeModule;
-    #[wasm_bindgen(method, catch)]
-    fn require(this: &NodeModule, s: &str) -> Result<NodeCrypto, JsValue>;
-
+    // Node JS crypto module (https://nodejs.org/api/crypto.html)
+    #[wasm_bindgen(catch, js_name = "module.require")]
+    fn require(s: &str) -> Result<NodeCrypto, JsValue>;
     type NodeCrypto;
     #[wasm_bindgen(method, js_name = randomFillSync, catch)]
-    fn random_fill_sync(crypto: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;
+    fn random_fill_sync(this: &NodeCrypto, buf: &mut [u8]) -> Result<(), JsValue>;
+
+    // Node JS process Object (https://nodejs.org/api/process.html)
+    #[wasm_bindgen(method, getter)]
+    fn process(this: &Global) -> Process;
+    type Process;
+    #[wasm_bindgen(method, getter)]
+    fn versions(this: &Process) -> Versions;
+    type Versions;
+    #[wasm_bindgen(method, getter)]
+    fn node(this: &Versions) -> JsValue;
 }
diff --git a/src/lib.rs b/src/lib.rs
index b1a5b10..107b2d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,7 +19,7 @@
 //! | FreeBSD           | `*‑freebsd`        | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
 //! | OpenBSD           | `*‑openbsd`        | [`getentropy`][6]
 //! | NetBSD            | `*‑netbsd`         | [`kern.arandom`][7]
-//! | Dragonfly BSD     | `*‑dragonfly`      | [`/dev/random`][8]
+//! | Dragonfly BSD     | `*‑dragonfly`      | [`getrandom()`][22] if available, otherwise [`/dev/random`][8]
 //! | Solaris, illumos  | `*‑solaris`, `*‑illumos` | [`getrandom()`][9] if available, otherwise [`/dev/random`][10]
 //! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`][11]
 //! | Redox             | `*‑redox`          | [`rand:`][12]
@@ -27,7 +27,7 @@
 //! | SGX               | `x86_64‑*‑sgx`     | [RDRAND][18]
 //! | VxWorks           | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`
 //! | Emscripten        | `*‑emscripten`     | `/dev/random` (identical to `/dev/urandom`)
-//! | WASI              | `wasm32‑wasi`      | [`__wasi_random_get`][17]
+//! | WASI              | `wasm32‑wasi`      | [`random_get`][17]
 //! | Web Browser       | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16]
 //! | Node.js           | `wasm32‑*‑unknown` | [`crypto.randomBytes`][15], see [WebAssembly support][16]
 //!
@@ -59,7 +59,8 @@
 //! This crate fully supports the
 //! [`wasm32-wasi`](https://github.com/CraneStation/wasi) and
 //! [`wasm32-unknown-emscripten`](https://www.hellorust.com/setup/emscripten/)
-//! targets. However, the `wasm32-unknown-unknown` target is not automatically
+//! targets. However, the `wasm32-unknown-unknown` target (i.e. the target used
+//! by `wasm-pack`) is not automatically
 //! supported since, from the target name alone, we cannot deduce which
 //! JavaScript interface is in use (or if JavaScript is available at all).
 //!
@@ -124,7 +125,7 @@
 //! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
 //! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
 //! [6]: https://man.openbsd.org/getentropy.2
-//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
+//! [7]: https://man.netbsd.org/sysctl.7
 //! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
 //! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
 //! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
@@ -133,16 +134,17 @@
 //! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
 //! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
 //! [16]: #webassembly-support
-//! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
+//! [17]: https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-random_getbuf-pointeru8-buf_len-size---errno
 //! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
 //! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
 //! [20]: https://www.unix.com/man-page/mojave/4/random/
 //! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable
+//! [22]: https://leaf.dragonflybsd.org/cgi/web-man?command=getrandom
 
 #![doc(
     html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
     html_favicon_url = "https://www.rust-lang.org/favicon.ico",
-    html_root_url = "https://docs.rs/getrandom/0.2.2"
+    html_root_url = "https://docs.rs/getrandom/0.2.3"
 )]
 #![no_std]
 #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
@@ -166,8 +168,8 @@
 //
 // These should all provide getrandom_inner with the same signature as getrandom.
 cfg_if! {
-    if #[cfg(any(target_os = "dragonfly", target_os = "emscripten",
-                 target_os = "haiku",     target_os = "redox"))] {
+    if #[cfg(any(target_os = "emscripten", target_os = "haiku",
+                 target_os = "redox"))] {
         mod util_libc;
         #[path = "use_file.rs"] mod imp;
     } else if #[cfg(any(target_os = "android", target_os = "linux"))] {
@@ -181,6 +183,10 @@
     } else if #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] {
         mod util_libc;
         #[path = "bsd_arandom.rs"] mod imp;
+    } else if #[cfg(target_os = "dragonfly")] {
+        mod util_libc;
+        mod use_file;
+        #[path = "dragonfly.rs"] mod imp;
     } else if #[cfg(target_os = "fuchsia")] {
         #[path = "fuchsia.rs"] mod imp;
     } else if #[cfg(target_os = "ios")] {
@@ -209,6 +215,11 @@
         #[path = "js.rs"] mod imp;
     } else if #[cfg(feature = "custom")] {
         use custom as imp;
+    } else if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
+        compile_error!("the wasm32-unknown-unknown target is not supported by \
+                        default, you may need to enable the \"js\" feature. \
+                        For more information see: \
+                        https://docs.rs/getrandom/#webassembly-support");
     } else {
         compile_error!("target is not supported, for more information see: \
                         https://docs.rs/getrandom/#unsupported-targets");
diff --git a/src/windows.rs b/src/windows.rs
index 56b3d07..643badd 100644
--- a/src/windows.rs
+++ b/src/windows.rs
@@ -11,6 +11,7 @@
 
 const BCRYPT_USE_SYSTEM_PREFERRED_RNG: u32 = 0x00000002;
 
+#[link(name = "bcrypt")]
 extern "system" {
     fn BCryptGenRandom(
         hAlgorithm: *mut c_void,