Implement Random.cpp for MSVC
authorOrvid King <blah38621@gmail.com>
Mon, 17 Aug 2015 17:32:51 +0000 (10:32 -0700)
committerfacebook-github-bot-1 <folly-bot@fb.com>
Mon, 17 Aug 2015 18:20:20 +0000 (11:20 -0700)
Summary: This uses `<random>` to implement it, because there is no `/dev/urandom` on Windows.
Closes #250

Reviewed By: @yfeldblum

Differential Revision: D2282887

Pulled By: @sgolemon

folly/Random.cpp

index 87da68b6b5216469591efd17ad68466fd1c00068..62eb8f9fbc23ac5f450f6d8de8ccf4ca3f30c250 100644 (file)
@@ -19,6 +19,7 @@
 #include <atomic>
 #include <unistd.h>
 #include <sys/time.h>
+#include <mutex>
 #include <random>
 #include <array>
 
 #include <folly/File.h>
 #include <folly/FileUtil.h>
 
+#ifdef _MSC_VER
+# include <wincrypt.h>
+#endif
+
 namespace folly {
 
 namespace {
 
 void readRandomDevice(void* data, size_t size) {
+#ifdef _MSC_VER
+  static std::once_flag flag;
+  static HCRYPTPROV cryptoProv;
+  std::call_once(flag, [&] {
+    PCHECK(CryptAcquireContext(&cryptoProv, nullptr, nullptr,
+                               PROV_RSA_FULL, 0));
+  });
+  CHECK(size <= std::numeric_limits<DWORD>::max());
+  PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data));
+#else
   // Keep the random device open for the duration of the program.
   static int randomFd = ::open("/dev/urandom", O_RDONLY);
   PCHECK(randomFd >= 0);
   auto bytesRead = readFull(randomFd, data, size);
   PCHECK(bytesRead >= 0 && size_t(bytesRead) == size);
+#endif
 }
 
 class BufferedRandomDevice {