1//===-- HostInfoWindows.cpp -----------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "lldb/Host/windows/windows.h" 10 11#include <objbase.h> 12 13#include <mutex> 14#include <optional> 15 16#include "lldb/Host/windows/HostInfoWindows.h" 17#include "lldb/Host/windows/PosixApi.h" 18#include "lldb/Utility/UserIDResolver.h" 19#include "llvm/ADT/SmallString.h" 20#include "llvm/Support/ConvertUTF.h" 21#include "llvm/Support/FileSystem.h" 22#include "llvm/Support/ManagedStatic.h" 23#include "llvm/Support/Path.h" 24#include "llvm/Support/Threading.h" 25#include "llvm/Support/raw_ostream.h" 26 27using namespace lldb_private; 28 29namespace { 30class WindowsUserIDResolver : public UserIDResolver { 31protected: 32 std::optional<std::string> DoGetUserName(id_t uid) override { 33 return std::nullopt; 34 } 35 std::optional<std::string> DoGetGroupName(id_t gid) override { 36 return std::nullopt; 37 } 38}; 39} // namespace 40 41FileSpec HostInfoWindows::m_program_filespec; 42 43void HostInfoWindows::Initialize(SharedLibraryDirectoryHelper *helper) { 44 ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); 45 HostInfoBase::Initialize(helper); 46} 47 48void HostInfoWindows::Terminate() { 49 HostInfoBase::Terminate(); 50 ::CoUninitialize(); 51} 52 53size_t HostInfoWindows::GetPageSize() { 54 SYSTEM_INFO systemInfo; 55 GetNativeSystemInfo(&systemInfo); 56 return systemInfo.dwPageSize; 57} 58 59llvm::VersionTuple HostInfoWindows::GetOSVersion() { 60 OSVERSIONINFOEX info; 61 62 ZeroMemory(&info, sizeof(OSVERSIONINFOEX)); 63 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 64#pragma warning(push) 65#pragma warning(disable : 4996) 66 // Starting with Microsoft SDK for Windows 8.1, this function is deprecated 67 // in favor of the new Windows Version Helper APIs. Since we don't specify a 68 // minimum SDK version, it's easier to simply disable the warning rather than 69 // try to support both APIs. 70 if (GetVersionEx((LPOSVERSIONINFO)&info) == 0) 71 return llvm::VersionTuple(); 72#pragma warning(pop) 73 74 return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion, 75 info.wServicePackMajor); 76} 77 78std::optional<std::string> HostInfoWindows::GetOSBuildString() { 79 llvm::VersionTuple version = GetOSVersion(); 80 if (version.empty()) 81 return std::nullopt; 82 83 return "Windows NT " + version.getAsString(); 84} 85 86std::optional<std::string> HostInfoWindows::GetOSKernelDescription() { 87 return GetOSBuildString(); 88} 89 90bool HostInfoWindows::GetHostname(std::string &s) { 91 wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1]; 92 DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; 93 if (!::GetComputerNameW(buffer, &dwSize)) 94 return false; 95 96 // The conversion requires an empty string. 97 s.clear(); 98 return llvm::convertWideToUTF8(buffer, s); 99} 100 101FileSpec HostInfoWindows::GetProgramFileSpec() { 102 static llvm::once_flag g_once_flag; 103 llvm::call_once(g_once_flag, []() { 104 std::vector<wchar_t> buffer(PATH_MAX); 105 ::GetModuleFileNameW(NULL, buffer.data(), buffer.size()); 106 std::string path; 107 llvm::convertWideToUTF8(buffer.data(), path); 108 m_program_filespec.SetFile(path, FileSpec::Style::native); 109 }); 110 return m_program_filespec; 111} 112 113FileSpec HostInfoWindows::GetDefaultShell() { 114 // Try to retrieve ComSpec from the environment. On the rare occasion 115 // that it fails, try a well-known path for ComSpec instead. 116 117 std::string shell; 118 if (GetEnvironmentVar("ComSpec", shell)) 119 return FileSpec(shell); 120 121 return FileSpec("C:\\Windows\\system32\\cmd.exe"); 122} 123 124bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name, 125 std::string &var) { 126 std::wstring wvar_name; 127 if (!llvm::ConvertUTF8toWide(var_name, wvar_name)) 128 return false; 129 130 if (const wchar_t *wvar = _wgetenv(wvar_name.c_str())) 131 return llvm::convertWideToUTF8(wvar, var); 132 return false; 133} 134 135static llvm::ManagedStatic<WindowsUserIDResolver> g_user_id_resolver; 136 137UserIDResolver &HostInfoWindows::GetUserIDResolver() { 138 return *g_user_id_resolver; 139} 140