//=== is guaranteed to work on *all* Win32 variants.
//===----------------------------------------------------------------------===//
-// Require at least Windows 2000 API.
-#define _WIN32_WINNT 0x0500
-#define _WIN32_IE 0x0500 // MinGW at it again.
+// mingw-w64 tends to define it as 0x0502 in its headers.
+#undef _WIN32_WINNT
+#undef _WIN32_IE
+
+// Require at least Windows XP(5.1) API.
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0600 // MinGW at it again.
#define WIN32_LEAN_AND_MEAN
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h" // Get build system configuration settings
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/system_error.h"
#include <windows.h>
-#include <shlobj.h>
+#include <wincrypt.h>
#include <cassert>
#include <string>
+#include <vector>
inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) {
if (!ErrMsg)
return true;
char *buffer = NULL;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
- NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
- *ErrMsg = prefix + buffer;
+ DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL);
+ if (R)
+ *ErrMsg = prefix + buffer;
+ else
+ *ErrMsg = prefix + "Unknown error";
+
LocalFree(buffer);
- return true;
+ return R != 0;
}
-class AutoHandle {
- HANDLE handle;
+template <typename HandleTraits>
+class ScopedHandle {
+ typedef typename HandleTraits::handle_type handle_type;
+ handle_type Handle;
+ ScopedHandle(const ScopedHandle &other); // = delete;
+ void operator=(const ScopedHandle &other); // = delete;
public:
- AutoHandle(HANDLE h) : handle(h) {}
+ ScopedHandle()
+ : Handle(HandleTraits::GetInvalid()) {}
- ~AutoHandle() {
- if (handle)
- CloseHandle(handle);
+ explicit ScopedHandle(handle_type h)
+ : Handle(h) {}
+
+ ~ScopedHandle() {
+ if (HandleTraits::IsValid(Handle))
+ HandleTraits::Close(Handle);
}
- operator HANDLE() {
- return handle;
+ handle_type take() {
+ handle_type t = Handle;
+ Handle = HandleTraits::GetInvalid();
+ return t;
}
- AutoHandle &operator=(HANDLE h) {
- handle = h;
+ ScopedHandle &operator=(handle_type h) {
+ if (HandleTraits::IsValid(Handle))
+ HandleTraits::Close(Handle);
+ Handle = h;
return *this;
}
+
+ // True if Handle is valid.
+ LLVM_EXPLICIT operator bool() const {
+ return HandleTraits::IsValid(Handle) ? true : false;
+ }
+
+ operator handle_type() const {
+ return Handle;
+ }
};
-template <class HandleType, uintptr_t InvalidHandle,
- class DeleterType, DeleterType D>
-class ScopedHandle {
- HandleType Handle;
+struct CommonHandleTraits {
+ typedef HANDLE handle_type;
-public:
- ScopedHandle() : Handle(InvalidHandle) {}
- ScopedHandle(HandleType handle) : Handle(handle) {}
+ static handle_type GetInvalid() {
+ return INVALID_HANDLE_VALUE;
+ }
- ~ScopedHandle() {
- if (Handle != HandleType(InvalidHandle))
- D(Handle);
+ static void Close(handle_type h) {
+ ::CloseHandle(h);
}
- HandleType take() {
- HandleType temp = Handle;
- Handle = HandleType(InvalidHandle);
- return temp;
+ static bool IsValid(handle_type h) {
+ return h != GetInvalid();
}
+};
- operator HandleType() const { return Handle; }
+struct JobHandleTraits : CommonHandleTraits {
+ static handle_type GetInvalid() {
+ return NULL;
+ }
+};
- ScopedHandle &operator=(HandleType handle) {
- Handle = handle;
- return *this;
+struct CryptContextTraits : CommonHandleTraits {
+ typedef HCRYPTPROV handle_type;
+
+ static handle_type GetInvalid() {
+ return 0;
}
- typedef void (*unspecified_bool_type)();
- static void unspecified_bool_true() {}
+ static void Close(handle_type h) {
+ ::CryptReleaseContext(h, 0);
+ }
- // True if Handle is valid.
- operator unspecified_bool_type() const {
- return Handle == HandleType(InvalidHandle) ? 0 : unspecified_bool_true;
+ static bool IsValid(handle_type h) {
+ return h != GetInvalid();
}
+};
- bool operator!() const {
- return Handle == HandleType(InvalidHandle);
+struct FindHandleTraits : CommonHandleTraits {
+ static void Close(handle_type h) {
+ ::FindClose(h);
}
};
-typedef ScopedHandle<HANDLE, uintptr_t(-1),
- BOOL (WINAPI*)(HANDLE), ::FindClose>
- ScopedFindHandle;
+struct FileHandleTraits : CommonHandleTraits {};
+
+typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
+typedef ScopedHandle<FileHandleTraits> ScopedFileHandle;
+typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
+typedef ScopedHandle<FindHandleTraits> ScopedFindHandle;
+typedef ScopedHandle<JobHandleTraits> ScopedJobHandle;
namespace llvm {
template <class T>
str.pop_back();
return str.data();
}
+
+namespace sys {
+namespace windows {
+error_code UTF8ToUTF16(StringRef utf8,
+ SmallVectorImpl<wchar_t> &utf16);
+error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
+ SmallVectorImpl<char> &utf8);
+} // end namespace windows
+} // end namespace sys
} // end namespace llvm.