LLVM API Documentation
00001 //===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines things specific to Windows implementations. In addition to 00011 // providing some helpers for working with win32 APIs, this header wraps 00012 // <windows.h> with some portability macros. Always include WindowsSupport.h 00013 // instead of including <windows.h> directly. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 //===----------------------------------------------------------------------===// 00018 //=== WARNING: Implementation here must contain only generic Win32 code that 00019 //=== is guaranteed to work on *all* Win32 variants. 00020 //===----------------------------------------------------------------------===// 00021 00022 // mingw-w64 tends to define it as 0x0502 in its headers. 00023 #undef _WIN32_WINNT 00024 #undef _WIN32_IE 00025 00026 // Require at least Windows XP(5.1) API. 00027 #define _WIN32_WINNT 0x0501 00028 #define _WIN32_IE 0x0600 // MinGW at it again. 00029 #define WIN32_LEAN_AND_MEAN 00030 00031 #include "llvm/ADT/SmallVector.h" 00032 #include "llvm/ADT/StringRef.h" 00033 #include "llvm/Config/config.h" // Get build system configuration settings 00034 #include "llvm/Support/Compiler.h" 00035 #include <system_error> 00036 #include <windows.h> 00037 #include <wincrypt.h> 00038 #include <cassert> 00039 #include <string> 00040 #include <vector> 00041 00042 inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { 00043 if (!ErrMsg) 00044 return true; 00045 char *buffer = NULL; 00046 DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 00047 FORMAT_MESSAGE_FROM_SYSTEM, 00048 NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL); 00049 if (R) 00050 *ErrMsg = prefix + buffer; 00051 else 00052 *ErrMsg = prefix + "Unknown error"; 00053 00054 LocalFree(buffer); 00055 return R != 0; 00056 } 00057 00058 template <typename HandleTraits> 00059 class ScopedHandle { 00060 typedef typename HandleTraits::handle_type handle_type; 00061 handle_type Handle; 00062 00063 ScopedHandle(const ScopedHandle &other); // = delete; 00064 void operator=(const ScopedHandle &other); // = delete; 00065 public: 00066 ScopedHandle() 00067 : Handle(HandleTraits::GetInvalid()) {} 00068 00069 explicit ScopedHandle(handle_type h) 00070 : Handle(h) {} 00071 00072 ~ScopedHandle() { 00073 if (HandleTraits::IsValid(Handle)) 00074 HandleTraits::Close(Handle); 00075 } 00076 00077 handle_type take() { 00078 handle_type t = Handle; 00079 Handle = HandleTraits::GetInvalid(); 00080 return t; 00081 } 00082 00083 ScopedHandle &operator=(handle_type h) { 00084 if (HandleTraits::IsValid(Handle)) 00085 HandleTraits::Close(Handle); 00086 Handle = h; 00087 return *this; 00088 } 00089 00090 // True if Handle is valid. 00091 LLVM_EXPLICIT operator bool() const { 00092 return HandleTraits::IsValid(Handle) ? true : false; 00093 } 00094 00095 operator handle_type() const { 00096 return Handle; 00097 } 00098 }; 00099 00100 struct CommonHandleTraits { 00101 typedef HANDLE handle_type; 00102 00103 static handle_type GetInvalid() { 00104 return INVALID_HANDLE_VALUE; 00105 } 00106 00107 static void Close(handle_type h) { 00108 ::CloseHandle(h); 00109 } 00110 00111 static bool IsValid(handle_type h) { 00112 return h != GetInvalid(); 00113 } 00114 }; 00115 00116 struct JobHandleTraits : CommonHandleTraits { 00117 static handle_type GetInvalid() { 00118 return NULL; 00119 } 00120 }; 00121 00122 struct CryptContextTraits : CommonHandleTraits { 00123 typedef HCRYPTPROV handle_type; 00124 00125 static handle_type GetInvalid() { 00126 return 0; 00127 } 00128 00129 static void Close(handle_type h) { 00130 ::CryptReleaseContext(h, 0); 00131 } 00132 00133 static bool IsValid(handle_type h) { 00134 return h != GetInvalid(); 00135 } 00136 }; 00137 00138 struct FindHandleTraits : CommonHandleTraits { 00139 static void Close(handle_type h) { 00140 ::FindClose(h); 00141 } 00142 }; 00143 00144 struct FileHandleTraits : CommonHandleTraits {}; 00145 00146 typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle; 00147 typedef ScopedHandle<FileHandleTraits> ScopedFileHandle; 00148 typedef ScopedHandle<CryptContextTraits> ScopedCryptContext; 00149 typedef ScopedHandle<FindHandleTraits> ScopedFindHandle; 00150 typedef ScopedHandle<JobHandleTraits> ScopedJobHandle; 00151 00152 namespace llvm { 00153 template <class T> 00154 class SmallVectorImpl; 00155 00156 template <class T> 00157 typename SmallVectorImpl<T>::const_pointer 00158 c_str(SmallVectorImpl<T> &str) { 00159 str.push_back(0); 00160 str.pop_back(); 00161 return str.data(); 00162 } 00163 00164 namespace sys { 00165 namespace windows { 00166 std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16); 00167 std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, 00168 SmallVectorImpl<char> &utf8); 00169 /// Convert from UTF16 to the current code page used in the system 00170 std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len, 00171 SmallVectorImpl<char> &utf8); 00172 } // end namespace windows 00173 } // end namespace sys 00174 } // end namespace llvm.