Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:27

0001 //===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines things specific to Windows implementations.  In addition to
0010 // providing some helpers for working with win32 APIs, this header wraps
0011 // <windows.h> with some portability macros.  Always include WindowsSupport.h
0012 // instead of including <windows.h> directly.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 //===----------------------------------------------------------------------===//
0017 //=== WARNING: Implementation here must contain only generic Win32 code that
0018 //===          is guaranteed to work on *all* Win32 variants.
0019 //===----------------------------------------------------------------------===//
0020 
0021 #ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
0022 #define LLVM_SUPPORT_WINDOWSSUPPORT_H
0023 
0024 // mingw-w64 tends to define it as 0x0502 in its headers.
0025 #undef _WIN32_WINNT
0026 
0027 // Require at least Windows 7 API.
0028 #define _WIN32_WINNT 0x0601
0029 #define WIN32_LEAN_AND_MEAN
0030 #ifndef NOMINMAX
0031 #define NOMINMAX
0032 #endif
0033 
0034 #include "llvm/ADT/SmallVector.h"
0035 #include "llvm/ADT/StringExtras.h"
0036 #include "llvm/ADT/StringRef.h"
0037 #include "llvm/ADT/Twine.h"
0038 #include "llvm/Config/llvm-config.h" // Get build system configuration settings
0039 #include "llvm/Support/Allocator.h"
0040 #include "llvm/Support/Chrono.h"
0041 #include "llvm/Support/Compiler.h"
0042 #include "llvm/Support/ErrorHandling.h"
0043 #include "llvm/Support/VersionTuple.h"
0044 #include <cassert>
0045 #include <string>
0046 #include <system_error>
0047 #include <windows.h>
0048 
0049 // Must be included after windows.h
0050 #include <wincrypt.h>
0051 
0052 namespace llvm {
0053 
0054 /// Determines if the program is running on Windows 8 or newer. This
0055 /// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
0056 /// to supercede raw calls to GetVersionEx. Old SDKs, Cygwin, and MinGW don't
0057 /// yet have VersionHelpers.h, so we have our own helper.
0058 bool RunningWindows8OrGreater();
0059 
0060 /// Determines if the program is running on Windows 11 or Windows Server 2022.
0061 bool RunningWindows11OrGreater();
0062 
0063 /// Returns the Windows version as Major.Minor.0.BuildNumber. Uses
0064 /// RtlGetVersion or GetVersionEx under the hood depending on what is available.
0065 /// GetVersionEx is deprecated, but this API exposes the build number which can
0066 /// be useful for working around certain kernel bugs.
0067 llvm::VersionTuple GetWindowsOSVersion();
0068 
0069 bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix);
0070 
0071 // Include GetLastError() in a fatal error message.
0072 [[noreturn]] inline void ReportLastErrorFatal(const char *Msg) {
0073   std::string ErrMsg;
0074   MakeErrMsg(&ErrMsg, Msg);
0075   llvm::report_fatal_error(Twine(ErrMsg));
0076 }
0077 
0078 template <typename HandleTraits>
0079 class ScopedHandle {
0080   typedef typename HandleTraits::handle_type handle_type;
0081   handle_type Handle;
0082 
0083   ScopedHandle(const ScopedHandle &other) = delete;
0084   void operator=(const ScopedHandle &other) = delete;
0085 public:
0086   ScopedHandle()
0087     : Handle(HandleTraits::GetInvalid()) {}
0088 
0089   explicit ScopedHandle(handle_type h)
0090     : Handle(h) {}
0091 
0092   ~ScopedHandle() {
0093     if (HandleTraits::IsValid(Handle))
0094       HandleTraits::Close(Handle);
0095   }
0096 
0097   handle_type take() {
0098     handle_type t = Handle;
0099     Handle = HandleTraits::GetInvalid();
0100     return t;
0101   }
0102 
0103   ScopedHandle &operator=(handle_type h) {
0104     if (HandleTraits::IsValid(Handle))
0105       HandleTraits::Close(Handle);
0106     Handle = h;
0107     return *this;
0108   }
0109 
0110   // True if Handle is valid.
0111   explicit operator bool() const {
0112     return HandleTraits::IsValid(Handle) ? true : false;
0113   }
0114 
0115   operator handle_type() const {
0116     return Handle;
0117   }
0118 };
0119 
0120 struct CommonHandleTraits {
0121   typedef HANDLE handle_type;
0122 
0123   static handle_type GetInvalid() {
0124     return INVALID_HANDLE_VALUE;
0125   }
0126 
0127   static void Close(handle_type h) {
0128     ::CloseHandle(h);
0129   }
0130 
0131   static bool IsValid(handle_type h) {
0132     return h != GetInvalid();
0133   }
0134 };
0135 
0136 struct JobHandleTraits : CommonHandleTraits {
0137   static handle_type GetInvalid() {
0138     return NULL;
0139   }
0140 };
0141 
0142 struct CryptContextTraits : CommonHandleTraits {
0143   typedef HCRYPTPROV handle_type;
0144 
0145   static handle_type GetInvalid() {
0146     return 0;
0147   }
0148 
0149   static void Close(handle_type h) {
0150     ::CryptReleaseContext(h, 0);
0151   }
0152 
0153   static bool IsValid(handle_type h) {
0154     return h != GetInvalid();
0155   }
0156 };
0157 
0158 struct RegTraits : CommonHandleTraits {
0159   typedef HKEY handle_type;
0160 
0161   static handle_type GetInvalid() {
0162     return NULL;
0163   }
0164 
0165   static void Close(handle_type h) {
0166     ::RegCloseKey(h);
0167   }
0168 
0169   static bool IsValid(handle_type h) {
0170     return h != GetInvalid();
0171   }
0172 };
0173 
0174 struct FindHandleTraits : CommonHandleTraits {
0175   static void Close(handle_type h) {
0176     ::FindClose(h);
0177   }
0178 };
0179 
0180 struct FileHandleTraits : CommonHandleTraits {};
0181 
0182 typedef ScopedHandle<CommonHandleTraits> ScopedCommonHandle;
0183 typedef ScopedHandle<FileHandleTraits>   ScopedFileHandle;
0184 typedef ScopedHandle<CryptContextTraits> ScopedCryptContext;
0185 typedef ScopedHandle<RegTraits>          ScopedRegHandle;
0186 typedef ScopedHandle<FindHandleTraits>   ScopedFindHandle;
0187 typedef ScopedHandle<JobHandleTraits>    ScopedJobHandle;
0188 
0189 template <class T>
0190 class SmallVectorImpl;
0191 
0192 template <class T>
0193 typename SmallVectorImpl<T>::const_pointer
0194 c_str(SmallVectorImpl<T> &str) {
0195   str.push_back(0);
0196   str.pop_back();
0197   return str.data();
0198 }
0199 
0200 namespace sys {
0201 
0202 inline std::chrono::nanoseconds toDuration(FILETIME Time) {
0203   ULARGE_INTEGER TimeInteger;
0204   TimeInteger.LowPart = Time.dwLowDateTime;
0205   TimeInteger.HighPart = Time.dwHighDateTime;
0206 
0207   // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
0208   return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
0209 }
0210 
0211 inline TimePoint<> toTimePoint(FILETIME Time) {
0212   ULARGE_INTEGER TimeInteger;
0213   TimeInteger.LowPart = Time.dwLowDateTime;
0214   TimeInteger.HighPart = Time.dwHighDateTime;
0215 
0216   // Adjust for different epoch
0217   TimeInteger.QuadPart -= 11644473600ll * 10000000;
0218 
0219   // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
0220   return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
0221 }
0222 
0223 inline FILETIME toFILETIME(TimePoint<> TP) {
0224   ULARGE_INTEGER TimeInteger;
0225   TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
0226   TimeInteger.QuadPart += 11644473600ll * 10000000;
0227 
0228   FILETIME Time;
0229   Time.dwLowDateTime = TimeInteger.LowPart;
0230   Time.dwHighDateTime = TimeInteger.HighPart;
0231   return Time;
0232 }
0233 
0234 namespace windows {
0235 // Returns command line arguments. Unlike arguments given to main(),
0236 // this function guarantees that the returned arguments are encoded in
0237 // UTF-8 regardless of the current code page setting.
0238 std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
0239                                         BumpPtrAllocator &Alloc);
0240 
0241 /// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
0242 /// File API.
0243 std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
0244                           size_t MaxPathLen = MAX_PATH);
0245 
0246 } // end namespace windows
0247 } // end namespace sys
0248 } // end namespace llvm.
0249 
0250 #endif