1 // Copyright 2010 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // WMI (Windows Management and Instrumentation) is a big, complex, COM-based 6 // API that can be used to perform all sorts of things. Sometimes is the best 7 // way to accomplish something under windows but its lack of an approachable 8 // C++ interface prevents its use. This collection of functions is a step in 9 // that direction. 10 // There are two classes; WMIUtil and WMIProcessUtil. The first 11 // one contains generic helpers and the second one contains the only 12 // functionality that is needed right now which is to use WMI to launch a 13 // process. 14 // To use any function on this header you must call CoInitialize or 15 // CoInitializeEx beforehand. 16 // 17 // For more information about WMI programming: 18 // https://docs.microsoft.com/en-us/windows/win32/wmisdk 19 20 #ifndef BASE_WIN_WMI_H_ 21 #define BASE_WIN_WMI_H_ 22 23 #include <wbemidl.h> 24 #include <wrl/client.h> 25 26 #include <optional> 27 #include <string> 28 #include <string_view> 29 30 #include "base/base_export.h" 31 32 namespace base { 33 namespace win { 34 35 // Enumeration of errors that can arise when connecting to a WMI server and 36 // running a query. 37 // Do not change ordering. This enum is captured as `WmiQueryError` in 38 // enums.xml. 39 enum class WmiError { 40 kFailedToCreateInstance = 0, 41 kFailedToConnectToWMI = 1, 42 kFailedToSetSecurityBlanket = 2, 43 kFailedToExecWMIQuery = 3, 44 kMaxValue = kFailedToExecWMIQuery 45 }; 46 47 // String used to connect to the CIMV2 WMI server. 48 BASE_EXPORT extern const wchar_t kCimV2ServerName[]; 49 50 // String used to connect to the SecurityCenter2 WMI server. 51 BASE_EXPORT extern const wchar_t kSecurityCenter2ServerName[]; 52 53 // Connects to a server named `server_name` on the local computer through COM 54 // and run the given WQL `query`. Sets `enumerator` with the values returned by 55 // that `query`. Will return a WmiError value if an error occurs, else returns 56 // std::nullopt. 57 BASE_EXPORT std::optional<WmiError> RunWmiQuery( 58 const std::wstring& server_name, 59 const std::wstring& query, 60 Microsoft::WRL::ComPtr<IEnumWbemClassObject>* enumerator); 61 62 // Creates an instance of the WMI service connected to the local computer and 63 // returns its COM interface. If |set_blanket| is set to true, the basic COM 64 // security blanket is applied to the returned interface. This is almost 65 // always desirable unless you set the parameter to false and apply a custom 66 // COM security blanket. 67 // Returns true if succeeded and |wmi_services|: the pointer to the service. 68 BASE_EXPORT bool CreateLocalWmiConnection( 69 bool set_blanket, 70 Microsoft::WRL::ComPtr<IWbemServices>* wmi_services); 71 72 // Creates an instance of the WMI service connected to the resource and 73 // returns its COM interface. If |set_blanket| is set to true, the basic COM 74 // security blanket is applied to the returned interface. This is almost 75 // always desirable unless you set the parameter to false and apply a custom 76 // COM security blanket. 77 // Returns a valid ComPtr<IWbemServices> on success, nullptr on failure. 78 BASE_EXPORT Microsoft::WRL::ComPtr<IWbemServices> CreateWmiConnection( 79 bool set_blanket, 80 const std::wstring& resource); 81 82 // Creates a WMI method using from a WMI class named |class_name| that 83 // contains a method named |method_name|. Only WMI classes that are CIM 84 // classes can be created using this function. 85 // Returns true if succeeded and |class_instance| returns a pointer to the 86 // WMI method that you can fill with parameter values using SetParameter. 87 BASE_EXPORT bool CreateWmiClassMethodObject( 88 IWbemServices* wmi_services, 89 std::wstring_view class_name, 90 std::wstring_view method_name, 91 Microsoft::WRL::ComPtr<IWbemClassObject>* class_instance); 92 93 // Creates a new process from |command_line|. The advantage over CreateProcess 94 // is that it allows you to always break out from a Job object that the caller 95 // is attached to even if the Job object flags prevent that. 96 // Returns true and the process id in process_id if the process is launched 97 // successful. False otherwise. 98 // Note that a fully qualified path must be specified in most cases unless 99 // the program is not in the search path of winmgmt.exe. 100 // Processes created this way are children of wmiprvse.exe and run with the 101 // caller credentials. 102 // More info: http://msdn2.microsoft.com/en-us/library/aa394372(VS.85).aspx 103 BASE_EXPORT bool WmiLaunchProcess(const std::wstring& command_line, 104 int* process_id); 105 106 // An encapsulation of information retrieved from the 'Win32_ComputerSystem' and 107 // 'Win32_Bios' WMI classes; see : 108 // https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-computersystem 109 // https://docs.microsoft.com/en-us/windows/desktop/CIMWin32Prov/win32-systembios 110 // Note that while model and manufacturer can be obtained through WMI, it is 111 // more efficient to obtain them via SysInfo::GetHardwareInfo() which uses the 112 // registry. 113 class BASE_EXPORT WmiComputerSystemInfo { 114 public: 115 static WmiComputerSystemInfo Get(); 116 serial_number()117 const std::wstring& serial_number() const { return serial_number_; } 118 119 private: 120 void PopulateSerialNumber( 121 const Microsoft::WRL::ComPtr<IEnumWbemClassObject>& enumerator_bios); 122 123 std::wstring serial_number_; 124 }; 125 126 } // namespace win 127 } // namespace base 128 129 #endif // BASE_WIN_WMI_H_ 130