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