LLVM API Documentation

WindowsSupport.h
Go to the documentation of this file.
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.