1 //===-- HostInfoWindows.cpp -------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Host/windows/windows.h"
11 
12 #include <objbase.h>
13 
14 #include <mutex> // std::once
15 
16 #include "lldb/Host/windows/HostInfoWindows.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Support/Path.h"
21 
22 using namespace lldb_private;
23 
24 FileSpec HostInfoWindows::m_program_filespec;
25 
26 void
27 HostInfoWindows::Initialize()
28 {
29     ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
30     HostInfoBase::Initialize();
31 }
32 
33 void
34 HostInfoWindows::Terminate()
35 {
36     HostInfoBase::Terminate();
37     ::CoUninitialize();
38 }
39 
40 size_t
41 HostInfoWindows::GetPageSize()
42 {
43     SYSTEM_INFO systemInfo;
44     GetNativeSystemInfo(&systemInfo);
45     return systemInfo.dwPageSize;
46 }
47 
48 bool
49 HostInfoWindows::GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update)
50 {
51     OSVERSIONINFOEX info;
52 
53     ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
54     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
55 #pragma warning(push)
56 #pragma warning(disable : 4996)
57     // Starting with Microsoft SDK for Windows 8.1, this function is deprecated in favor of the
58     // new Windows Version Helper APIs.  Since we don't specify a minimum SDK version, it's easier
59     // to simply disable the warning rather than try to support both APIs.
60     if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
61     {
62         return false;
63     }
64 #pragma warning(pop)
65 
66     major = info.dwMajorVersion;
67     minor = info.dwMinorVersion;
68     update = info.wServicePackMajor;
69 
70     return true;
71 }
72 
73 bool
74 HostInfoWindows::GetOSBuildString(std::string &s)
75 {
76     s.clear();
77     uint32_t major, minor, update;
78     if (!GetOSVersion(major, minor, update))
79         return false;
80 
81     llvm::raw_string_ostream stream(s);
82     stream << "Windows NT " << major << "." << minor << "." << update;
83     return true;
84 }
85 
86 bool
87 HostInfoWindows::GetOSKernelDescription(std::string &s)
88 {
89     return GetOSBuildString(s);
90 }
91 
92 bool
93 HostInfoWindows::GetHostname(std::string &s)
94 {
95     char buffer[MAX_COMPUTERNAME_LENGTH + 1];
96     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
97     if (!::GetComputerName(buffer, &dwSize))
98         return false;
99 
100     s.assign(buffer, buffer + dwSize);
101     return true;
102 }
103 
104 FileSpec
105 HostInfoWindows::GetProgramFileSpec()
106 {
107     static std::once_flag g_once_flag;
108     std::call_once(g_once_flag,  []() {
109         char buffer[PATH_MAX];
110         ::GetModuleFileName(NULL, buffer, sizeof(buffer));
111         m_program_filespec.SetFile(buffer, false);
112     });
113     return m_program_filespec;
114 }
115 
116 FileSpec
117 HostInfoWindows::GetDefaultShell()
118 {
119     return FileSpec(::getenv("ComSpec"), false);
120 }
121 
122 bool
123 HostInfoWindows::ComputePythonDirectory(FileSpec &file_spec)
124 {
125     FileSpec lldb_file_spec;
126     if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, lldb_file_spec))
127         return false;
128     llvm::SmallString<64> path(lldb_file_spec.GetDirectory().AsCString());
129     llvm::sys::path::remove_filename(path);
130     llvm::sys::path::append(path, "lib", "site-packages");
131     std::replace(path.begin(), path.end(), '\\', '/');
132     file_spec.GetDirectory().SetString(path.c_str());
133     return true;
134 }
135