123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines things specific to Windows implementations. In addition to
- // providing some helpers for working with win32 APIs, this header wraps
- // <windows.h> with some portability macros. Always include WindowsSupport.h
- // instead of including <windows.h> directly.
- //
- //===----------------------------------------------------------------------===//
- //===----------------------------------------------------------------------===//
- //=== WARNING: Implementation here must contain only generic Win32 code that
- //=== is guaranteed to work on *all* Win32 variants.
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
- #define LLVM_SUPPORT_WINDOWSSUPPORT_H
- // mingw-w64 tends to define it as 0x0502 in its headers.
- #undef _WIN32_WINNT
- #undef _WIN32_IE
- // Require at least Windows 7 API.
- #define _WIN32_WINNT 0x0601
- #define _WIN32_IE 0x0800 // MinGW at it again. FIXME: verify if still needed.
- #define WIN32_LEAN_AND_MEAN
- #ifndef NOMINMAX
- #define NOMINMAX
- #endif
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/ADT/StringExtras.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/ADT/Twine.h"
- #include "llvm/Config/llvm-config.h" // Get build system configuration settings
- #include "llvm/Support/Allocator.h"
- #include "llvm/Support/Chrono.h"
- #include "llvm/Support/Compiler.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/VersionTuple.h"
- #include <cassert>
- #include <string>
- #include <system_error>
- #include <windows.h>
- // Must be included after windows.h
- #include <wincrypt.h>
- namespace llvm {
- /// Determines if the program is running on Windows 8 or newer. This
- /// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
- /// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
- /// yet have VersionHelpers.h, so we have our own helper.
- bool RunningWindows8OrGreater();
- /// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
- /// RtlGetVersion or GetVersionEx under the hood depending on what is available.
- /// GetVersionEx is deprecated, but this API exposes the build number which can
- /// be useful for working around certain kernel bugs.
- llvm::VersionTuple GetWindowsOSVersion();
- bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
- // Include GetLastError() in a fatal error message.
- [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) {
- std::string ErrMsg;
- MakeErrMsg(&ErrMsg, Msg);
- llvm::report_fatal_error(Twine(ErrMsg));
- }
- 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:
- ScopedHandle()
- : Handle(HandleTraits::GetInvalid()) {}
- explicit ScopedHandle(handle_type h)
- : Handle(h) {}
- ~ScopedHandle() {
- if (HandleTraits::IsValid(Handle))
- HandleTraits::Close(Handle);
- }
- handle_type take() {
- handle_type t = Handle;
- Handle = HandleTraits::GetInvalid();
- return t;
- }
- ScopedHandle &operator=(handle_type h) {
- if (HandleTraits::IsValid(Handle))
- HandleTraits::Close(Handle);
- Handle = h;
- return *this;
- }
- // True if Handle is valid.
- explicit operator bool() const {
- return HandleTraits::IsValid(Handle) ? true : false;
- }
- operator handle_type() const {
- return Handle;
- }
- };
- struct CommonHandleTraits {
- typedef HANDLE handle_type;
- static handle_type GetInvalid() {
- return INVALID_HANDLE_VALUE;
- }
- static void Close(handle_type h) {
- ::CloseHandle(h);
- }
- static bool IsValid(handle_type h) {
- return h != GetInvalid();
- }
- };
- struct JobHandleTraits : CommonHandleTraits {
- static handle_type GetInvalid() {
- return NULL;
- }
- };
- struct CryptContextTraits : CommonHandleTraits {
- typedef HCRYPTPROV handle_type;
- static handle_type GetInvalid() {
- return 0;
- }
- static void Close(handle_type h) {
- ::CryptReleaseContext(h, 0);
- }
- static bool IsValid(handle_type h) {
- return h != GetInvalid();
- }
- };
- struct RegTraits : CommonHandleTraits {
- typedef HKEY handle_type;
- static handle_type GetInvalid() {
- return NULL;
- }
- static void Close(handle_type h) {
- ::RegCloseKey(h);
- }
- static bool IsValid(handle_type h) {
- return h != GetInvalid();
- }
- };
- struct FindHandleTraits : CommonHandleTraits {
- static void Close(handle_type h) {
- ::FindClose(h);
- }
- };
- struct FileHandleTraits : CommonHandleTraits {};
- typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
- typedef ScopedHandle<FileHandleTraits> ScopedFileHandle;
- typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
- typedef ScopedHandle<RegTraits> ScopedRegHandle;
- typedef ScopedHandle<FindHandleTraits> ScopedFindHandle;
- typedef ScopedHandle<JobHandleTraits> ScopedJobHandle;
- template <class T>
- class SmallVectorImpl;
- template <class T>
- typename SmallVectorImpl<T>::const_pointer
- c_str(SmallVectorImpl<T> &str) {
- str.push_back(0);
- str.pop_back();
- return str.data();
- }
- namespace sys {
- inline std::chrono::nanoseconds toDuration(FILETIME Time) {
- ULARGE_INTEGER TimeInteger;
- TimeInteger.LowPart = Time.dwLowDateTime;
- TimeInteger.HighPart = Time.dwHighDateTime;
- // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
- return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
- }
- inline TimePoint<> toTimePoint(FILETIME Time) {
- ULARGE_INTEGER TimeInteger;
- TimeInteger.LowPart = Time.dwLowDateTime;
- TimeInteger.HighPart = Time.dwHighDateTime;
- // Adjust for different epoch
- TimeInteger.QuadPart -= 11644473600ll * 10000000;
- // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
- return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
- }
- inline FILETIME toFILETIME(TimePoint<> TP) {
- ULARGE_INTEGER TimeInteger;
- TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
- TimeInteger.QuadPart += 11644473600ll * 10000000;
- FILETIME Time;
- Time.dwLowDateTime = TimeInteger.LowPart;
- Time.dwHighDateTime = TimeInteger.HighPart;
- return Time;
- }
- namespace windows {
- // Returns command line arguments. Unlike arguments given to main(),
- // this function guarantees that the returned arguments are encoded in
- // UTF-8 regardless of the current code page setting.
- std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
- BumpPtrAllocator &Alloc);
- /// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
- /// File API.
- std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
- size_t MaxPathLen = MAX_PATH);
- } // end namespace windows
- } // end namespace sys
- } // end namespace llvm.
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|