//===----------------------------------------------------------------------===//
#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.
/*__in*/ LPCWSTR lpTargetFileName,
/*__in*/ DWORD dwFlags);
- PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW(
- ::GetProcAddress(::GetModuleHandleA("kernel32.dll"),
- "CreateSymbolicLinkW"));
+ PtrCreateSymbolicLinkW create_symbolic_link_api =
+ PtrCreateSymbolicLinkW(::GetProcAddress(
+ ::GetModuleHandleW(L"Kernel32.dll"), "CreateSymbolicLinkW"));
error_code TempDir(SmallVectorImpl<wchar_t> &result) {
retry_temp_dir:
// 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
namespace fs {
std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
- char pathname[MAX_PATH];
- DWORD ret = ::GetModuleFileNameA(NULL, pathname, MAX_PATH);
- return ret != MAX_PATH ? pathname : "";
+ SmallVector<wchar_t, MAX_PATH> PathName;
+ DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.capacity());
+
+ // A zero return value indicates a failure other than insufficient space.
+ if (Size == 0)
+ return "";
+
+ // Insufficient space is determined by a return value equal to the size of
+ // the buffer passed in.
+ if (Size == PathName.capacity())
+ return "";
+
+ // On success, GetModuleFileNameW returns the number of characters written to
+ // the buffer not including the NULL terminator.
+ PathName.set_size(Size);
+
+ // Convert the result from UTF-16 to UTF-8.
+ SmallVector<char, MAX_PATH> PathNameUTF8;
+ if (UTF16ToUTF8(PathName.data(), PathName.size(), PathNameUTF8))
+ return "";
+
+ return std::string(PathNameUTF8.data());
}
UniqueID file_status::getUniqueID() const {
case priv: flprotect = PAGE_WRITECOPY; break;
}
- FileMappingHandle = ::CreateFileMapping(FileHandle,
- 0,
- flprotect,
- (Offset + Size) >> 32,
- (Offset + Size) & 0xffffffff,
- 0);
+ FileMappingHandle =
+ ::CreateFileMappingW(FileHandle, 0, flprotect,
+ (Offset + Size) >> 32,
+ (Offset + Size) & 0xffffffff,
+ 0);
if (FileMappingHandle == NULL) {
error_code ec = windows_error(GetLastError());
if (FileDescriptor) {
}
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);
}
}
} // 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) {