Windows/Path.inc: Move <shlobj.h> after "Windows.h" for some API available.
[oota-llvm.git] / lib / Support / Windows / Process.inc
index 7f7e06c85501d652f9cb51a02a780d0a8346d3db..a0e3bc413a3f2c32d9de0fc28fafeefc5b1337c7 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Allocator.h"
+#include <malloc.h>
 
+// The Windows.h header must be after LLVM and standard headers.
 #include "Windows.h"
+
 #include <direct.h>
 #include <io.h>
-#include <malloc.h>
 #include <psapi.h>
-#include <Shellapi.h>
+#include <shellapi.h>
 
 #ifdef __MINGW32__
  #if (HAVE_LIBPSAPI != 1)
@@ -28,8 +30,8 @@
   #error "libshell32.a should be present"
  #endif
 #else
-#pragma comment(lib, "psapi.lib")
-#pragma comment(lib, "Shell32.lib")
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "shell32.lib")
 #endif
 
 //===----------------------------------------------------------------------===//
@@ -162,7 +164,8 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
   size_t Size = MAX_PATH;
   do {
     Buf.reserve(Size);
-    Size = GetEnvironmentVariableW(&NameUTF16[0], &Buf[0], Buf.capacity());
+    Size =
+        GetEnvironmentVariableW(NameUTF16.data(), Buf.data(), Buf.capacity());
     if (Size == 0)
       return None;
 
@@ -172,9 +175,9 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
 
   // Convert the result from UTF-16 to UTF-8.
   SmallVector<char, MAX_PATH> Res;
-  if (error_code ec = windows::UTF16ToUTF8(&Buf[0], Size, Res))
+  if (error_code ec = windows::UTF16ToUTF8(Buf.data(), Size, Res))
     return None;
-  return std::string(&Res[0]);
+  return std::string(Res.data());
 }
 
 error_code
@@ -357,3 +360,17 @@ const char *Process::ResetColor() {
   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
   return 0;
 }
+
+unsigned Process::GetRandomNumber() {
+  HCRYPTPROV HCPC;
+  if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL,
+                              CRYPT_VERIFYCONTEXT))
+    assert(false && "Could not acquire a cryptographic context");
+
+  ScopedCryptContext CryptoProvider(HCPC);
+  unsigned Ret;
+  if (!::CryptGenRandom(CryptoProvider, sizeof(Ret),
+                        reinterpret_cast<BYTE *>(&Ret)))
+    assert(false && "Could not generate a random number");
+  return Ret;
+}