xref: /openbsd-src/gnu/llvm/lldb/source/Host/windows/HostInfoWindows.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- HostInfoWindows.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Host/windows/windows.h"
10061da546Spatrick 
11061da546Spatrick #include <objbase.h>
12061da546Spatrick 
13061da546Spatrick #include <mutex>
14*f6aab3d8Srobert #include <optional>
15061da546Spatrick 
16061da546Spatrick #include "lldb/Host/windows/HostInfoWindows.h"
17061da546Spatrick #include "lldb/Host/windows/PosixApi.h"
18061da546Spatrick #include "lldb/Utility/UserIDResolver.h"
19061da546Spatrick #include "llvm/ADT/SmallString.h"
20061da546Spatrick #include "llvm/Support/ConvertUTF.h"
21061da546Spatrick #include "llvm/Support/FileSystem.h"
22061da546Spatrick #include "llvm/Support/ManagedStatic.h"
23061da546Spatrick #include "llvm/Support/Path.h"
24061da546Spatrick #include "llvm/Support/Threading.h"
25061da546Spatrick #include "llvm/Support/raw_ostream.h"
26061da546Spatrick 
27061da546Spatrick using namespace lldb_private;
28061da546Spatrick 
29061da546Spatrick namespace {
30061da546Spatrick class WindowsUserIDResolver : public UserIDResolver {
31061da546Spatrick protected:
DoGetUserName(id_t uid)32*f6aab3d8Srobert   std::optional<std::string> DoGetUserName(id_t uid) override {
33*f6aab3d8Srobert     return std::nullopt;
34061da546Spatrick   }
DoGetGroupName(id_t gid)35*f6aab3d8Srobert   std::optional<std::string> DoGetGroupName(id_t gid) override {
36*f6aab3d8Srobert     return std::nullopt;
37061da546Spatrick   }
38061da546Spatrick };
39061da546Spatrick } // namespace
40061da546Spatrick 
41061da546Spatrick FileSpec HostInfoWindows::m_program_filespec;
42061da546Spatrick 
Initialize(SharedLibraryDirectoryHelper * helper)43be691f3bSpatrick void HostInfoWindows::Initialize(SharedLibraryDirectoryHelper *helper) {
44061da546Spatrick   ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
45be691f3bSpatrick   HostInfoBase::Initialize(helper);
46061da546Spatrick }
47061da546Spatrick 
Terminate()48061da546Spatrick void HostInfoWindows::Terminate() {
49061da546Spatrick   HostInfoBase::Terminate();
50061da546Spatrick   ::CoUninitialize();
51061da546Spatrick }
52061da546Spatrick 
GetPageSize()53061da546Spatrick size_t HostInfoWindows::GetPageSize() {
54061da546Spatrick   SYSTEM_INFO systemInfo;
55061da546Spatrick   GetNativeSystemInfo(&systemInfo);
56061da546Spatrick   return systemInfo.dwPageSize;
57061da546Spatrick }
58061da546Spatrick 
GetOSVersion()59061da546Spatrick llvm::VersionTuple HostInfoWindows::GetOSVersion() {
60061da546Spatrick   OSVERSIONINFOEX info;
61061da546Spatrick 
62061da546Spatrick   ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
63061da546Spatrick   info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
64061da546Spatrick #pragma warning(push)
65061da546Spatrick #pragma warning(disable : 4996)
66061da546Spatrick   // Starting with Microsoft SDK for Windows 8.1, this function is deprecated
67061da546Spatrick   // in favor of the new Windows Version Helper APIs.  Since we don't specify a
68061da546Spatrick   // minimum SDK version, it's easier to simply disable the warning rather than
69061da546Spatrick   // try to support both APIs.
70061da546Spatrick   if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
71061da546Spatrick     return llvm::VersionTuple();
72061da546Spatrick #pragma warning(pop)
73061da546Spatrick 
74061da546Spatrick   return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion,
75061da546Spatrick                             info.wServicePackMajor);
76061da546Spatrick }
77061da546Spatrick 
GetOSBuildString()78*f6aab3d8Srobert std::optional<std::string> HostInfoWindows::GetOSBuildString() {
79061da546Spatrick   llvm::VersionTuple version = GetOSVersion();
80061da546Spatrick   if (version.empty())
81*f6aab3d8Srobert     return std::nullopt;
82061da546Spatrick 
83*f6aab3d8Srobert   return "Windows NT " + version.getAsString();
84061da546Spatrick }
85061da546Spatrick 
GetOSKernelDescription()86*f6aab3d8Srobert std::optional<std::string> HostInfoWindows::GetOSKernelDescription() {
87*f6aab3d8Srobert   return GetOSBuildString();
88061da546Spatrick }
89061da546Spatrick 
GetHostname(std::string & s)90061da546Spatrick bool HostInfoWindows::GetHostname(std::string &s) {
91061da546Spatrick   wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
92061da546Spatrick   DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
93061da546Spatrick   if (!::GetComputerNameW(buffer, &dwSize))
94061da546Spatrick     return false;
95061da546Spatrick 
96061da546Spatrick   // The conversion requires an empty string.
97061da546Spatrick   s.clear();
98061da546Spatrick   return llvm::convertWideToUTF8(buffer, s);
99061da546Spatrick }
100061da546Spatrick 
GetProgramFileSpec()101061da546Spatrick FileSpec HostInfoWindows::GetProgramFileSpec() {
102061da546Spatrick   static llvm::once_flag g_once_flag;
103061da546Spatrick   llvm::call_once(g_once_flag, []() {
104061da546Spatrick     std::vector<wchar_t> buffer(PATH_MAX);
105061da546Spatrick     ::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
106061da546Spatrick     std::string path;
107061da546Spatrick     llvm::convertWideToUTF8(buffer.data(), path);
108061da546Spatrick     m_program_filespec.SetFile(path, FileSpec::Style::native);
109061da546Spatrick   });
110061da546Spatrick   return m_program_filespec;
111061da546Spatrick }
112061da546Spatrick 
GetDefaultShell()113061da546Spatrick FileSpec HostInfoWindows::GetDefaultShell() {
114061da546Spatrick   // Try to retrieve ComSpec from the environment. On the rare occasion
115061da546Spatrick   // that it fails, try a well-known path for ComSpec instead.
116061da546Spatrick 
117061da546Spatrick   std::string shell;
118061da546Spatrick   if (GetEnvironmentVar("ComSpec", shell))
119061da546Spatrick     return FileSpec(shell);
120061da546Spatrick 
121061da546Spatrick   return FileSpec("C:\\Windows\\system32\\cmd.exe");
122061da546Spatrick }
123061da546Spatrick 
GetEnvironmentVar(const std::string & var_name,std::string & var)124061da546Spatrick bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name,
125061da546Spatrick                                         std::string &var) {
126061da546Spatrick   std::wstring wvar_name;
127061da546Spatrick   if (!llvm::ConvertUTF8toWide(var_name, wvar_name))
128061da546Spatrick     return false;
129061da546Spatrick 
130061da546Spatrick   if (const wchar_t *wvar = _wgetenv(wvar_name.c_str()))
131061da546Spatrick     return llvm::convertWideToUTF8(wvar, var);
132061da546Spatrick   return false;
133061da546Spatrick }
134061da546Spatrick 
135061da546Spatrick static llvm::ManagedStatic<WindowsUserIDResolver> g_user_id_resolver;
136061da546Spatrick 
GetUserIDResolver()137061da546Spatrick UserIDResolver &HostInfoWindows::GetUserIDResolver() {
138061da546Spatrick   return *g_user_id_resolver;
139061da546Spatrick }
140