146684Skris//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===// 216Salm// 316Salm// The LLVM Compiler Infrastructure 41057Salm// 516Salm// This file is distributed under the University of Illinois Open Source 616Salm// License. See LICENSE.TXT for details. 716Salm// 816Salm//===----------------------------------------------------------------------===// 916Salm// 1016Salm// This file defines things specific to Win32 implementations. 1116Salm// 1216Salm//===----------------------------------------------------------------------===// 1316Salm 1416Salm//===----------------------------------------------------------------------===// 1516Salm//=== WARNING: Implementation here must contain only generic Win32 code that 161057Salm//=== is guaranteed to work on *all* Win32 variants. 1716Salm//===----------------------------------------------------------------------===// 1816Salm 191057Salm// mingw-w64 tends to define it as 0x0502 in its headers. 2016Salm#undef _WIN32_WINNT 2116Salm 2216Salm// Require at least Windows XP(5.1) API. 2316Salm#define _WIN32_WINNT 0x0501 2416Salm#define _WIN32_IE 0x0600 // MinGW at it again. 2516Salm#define WIN32_LEAN_AND_MEAN 2616Salm 2716Salm#include "llvm/ADT/SmallVector.h" 2827963Ssteve#include "llvm/ADT/StringRef.h" 2999109Sobrien#include "llvm/Config/config.h" // Get build system configuration settings 3099109Sobrien#include "llvm/Support/Compiler.h" 3116Salm#include "llvm/Support/system_error.h" 3216Salm#include <windows.h> 331297Salm#include <wincrypt.h> 3416Salm#include <cassert> 3516Salm#include <string> 3616Salm#include <vector> 3716Salm 38241720Sedinline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { 39241720Sed if (!ErrMsg) 40241720Sed return true; 41241720Sed char *buffer = NULL; 4216Salm DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 431057Salm FORMAT_MESSAGE_FROM_SYSTEM, 4416Salm NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL); 4516Salm if (R) 4690109Simp *ErrMsg = prefix + buffer; 4716Salm else 481057Salm *ErrMsg = prefix + "Unknown error"; 491057Salm 501057Salm LocalFree(buffer); 5116Salm return R != 0; 5216Salm} 531057Salm 5416Salmtemplate <typename HandleTraits> 5516Salmclass ScopedHandle { 5616Salm typedef typename HandleTraits::handle_type handle_type; 5716Salm handle_type Handle; 5816Salm 5982771Sache ScopedHandle(const ScopedHandle &other); // = delete; 6016Salm void operator=(const ScopedHandle &other); // = delete; 6181220Smikepublic: 6216Salm ScopedHandle() 6316Salm : Handle(HandleTraits::GetInvalid()) {} 6416Salm 651057Salm explicit ScopedHandle(handle_type h) 661057Salm : Handle(h) {} 6716Salm 6816Salm ~ScopedHandle() { 6981220Smike if (HandleTraits::IsValid(Handle)) 7016Salm HandleTraits::Close(Handle); 7116Salm } 7216Salm 7316Salm handle_type take() { 7416Salm handle_type t = Handle; 7516Salm Handle = HandleTraits::GetInvalid(); 7616Salm return t; 7716Salm } 781057Salm 7916Salm ScopedHandle &operator=(handle_type h) { 8081220Smike if (HandleTraits::IsValid(Handle)) 8190109Simp HandleTraits::Close(Handle); 8216Salm Handle = h; 8316Salm return *this; 8416Salm } 8581220Smike 8616Salm // True if Handle is valid. 8716Salm LLVM_EXPLICIT operator bool() const { 8816Salm return HandleTraits::IsValid(Handle) ? true : false; 8981220Smike } 9016Salm 9116Salm operator handle_type() const { 9216Salm return Handle; 9316Salm } 9416Salm}; 9516Salm 9681220Smikestruct CommonHandleTraits { 97225215Sbrueffer typedef HANDLE handle_type; 9816Salm 9916Salm static handle_type GetInvalid() { 1001057Salm return INVALID_HANDLE_VALUE; 10116Salm } 10216Salm 10382771Sache static void Close(handle_type h) { 10416Salm ::CloseHandle(h); 10581220Smike } 106225215Sbrueffer 10716Salm static bool IsValid(handle_type h) { 10816Salm return h != GetInvalid(); 10982771Sache } 11016Salm}; 11116Salm 1121057Salmstruct JobHandleTraits : CommonHandleTraits { 11316Salm static handle_type GetInvalid() { 11416Salm return NULL; 11516Salm } 11681220Smike}; 117225215Sbrueffer 11816Salmstruct CryptContextTraits : CommonHandleTraits { 11916Salm typedef HCRYPTPROV handle_type; 12016Salm 12116Salm static handle_type GetInvalid() { 1221057Salm return 0; 12316Salm } 12416Salm 12516Salm static void Close(handle_type h) { 12616Salm ::CryptReleaseContext(h, 0); 12716Salm } 1281057Salm 12916Salm static bool IsValid(handle_type h) { 13090109Simp return h != GetInvalid(); 13116Salm } 13216Salm}; 13316Salm 1341057Salmstruct FindHandleTraits : CommonHandleTraits { 1351297Salm static void Close(handle_type h) { 1361057Salm ::FindClose(h); 1371057Salm } 13816Salm}; 13916Salm 14016Salmstruct FileHandleTraits : CommonHandleTraits {}; 1411057Salm 14216Salmtypedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle; 14390109Simptypedef ScopedHandle<FileHandleTraits> ScopedFileHandle; 14416Salmtypedef ScopedHandle<CryptContextTraits> ScopedCryptContext; 1451057Salmtypedef ScopedHandle<FindHandleTraits> ScopedFindHandle; 14616Salmtypedef ScopedHandle<JobHandleTraits> ScopedJobHandle; 14716Salm 1481057Salmnamespace llvm { 14916Salmtemplate <class T> 1501057Salmclass SmallVectorImpl; 15181220Smike 15249Salmtemplate <class T> 15349Salmtypename SmallVectorImpl<T>::const_pointer 15449Salmc_str(SmallVectorImpl<T> &str) { 15516Salm str.push_back(0); 15616Salm str.pop_back(); 15716Salm return str.data(); 1581057Salm} 15916Salm 16090109Simpnamespace sys { 16116Salmnamespace windows { 1621057Salmerror_code UTF8ToUTF16(StringRef utf8, 16316Salm SmallVectorImpl<wchar_t> &utf16); 16416Salmerror_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, 1651057Salm SmallVectorImpl<char> &utf8); 16616Salm} // end namespace windows 1671057Salm} // end namespace sys 16816Salm} // end namespace llvm. 1691057Salm