Windows/Path.inc: Move <shlobj.h> after "Windows.h" for some API available.
[oota-llvm.git] / lib / Support / Windows / Path.inc
index 0b39198e6b35c67b71848a1b06b473bff41bfbeb..8329d271b39ff1d149fe33bd1585f98566028462 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/STLExtras.h"
-#include "Windows.h"
 #include <fcntl.h>
 #include <io.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
+// These two headers must be included last, and make sure shlobj is required
+// after Windows.h to make sure it picks up our definition of _WIN32_WINNT
+#include "Windows.h"
+#include <shlobj.h>
+
 #undef max
 
 // MinGW doesn't define this.
@@ -109,25 +113,13 @@ static error_code createUniqueEntity(const Twine &model, int &result_fd,
   // needed if the randomly chosen path already exists.
   SmallVector<wchar_t, 128> random_path_utf16;
 
-  // Get a Crypto Provider for CryptGenRandom.
-  HCRYPTPROV HCPC;
-  if (!::CryptAcquireContextW(&HCPC,
-                              NULL,
-                              NULL,
-                              PROV_RSA_FULL,
-                              CRYPT_VERIFYCONTEXT))
-    return windows_error(::GetLastError());
-  ScopedCryptContext CryptoProvider(HCPC);
-
 retry_random_path:
   random_path_utf16.set_size(0);
   for (SmallVectorImpl<wchar_t>::const_iterator i = model_utf16.begin(),
                                                 e = model_utf16.end();
                                                 i != e; ++i) {
     if (*i == L'%') {
-      BYTE val = 0;
-      if (!::CryptGenRandom(CryptoProvider, 1, &val))
-          return windows_error(::GetLastError());
+      unsigned val = sys::Process::GetRandomNumber();
       random_path_utf16.push_back(L"0123456789abcdef"[val & 15]);
     }
     else
@@ -859,7 +851,7 @@ uint64_t mapped_file_region::size() const {
 }
 
 char *mapped_file_region::data() const {
-  assert(Mode != readonly && "Cannot get non const data for readonly mapping!");
+  assert(Mode != readonly && "Cannot get non-const data for readonly mapping!");
   assert(Mapping && "Mapping failed but used anyway!");
   return reinterpret_cast<char*>(Mapping);
 }
@@ -1061,6 +1053,22 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD,
 }
 } // end namespace fs
 
+namespace path {
+
+bool home_directory(SmallVectorImpl<char> &result) {
+  wchar_t Path[MAX_PATH];
+  if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0,
+                         /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK)
+    return false;
+
+  if (UTF16ToUTF8(Path, ::wcslen(Path), result))
+    return false;
+
+  return true;
+}
+
+} // end namespace path
+
 namespace windows {
 llvm::error_code UTF8ToUTF16(llvm::StringRef utf8,
                              llvm::SmallVectorImpl<wchar_t> &utf16) {