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