Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / installer / util / wmi.cc
blob20c1050600f8c6c5f9f64ed862a755d89e47a06d
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/installer/util/wmi.h"
7 #include <windows.h>
9 #include "base/basictypes.h"
10 #include "base/win/scoped_bstr.h"
11 #include "base/win/scoped_comptr.h"
12 #include "base/win/scoped_variant.h"
14 #pragma comment(lib, "wbemuuid.lib")
16 using base::win::ScopedVariant;
18 namespace installer {
20 bool WMI::CreateLocalConnection(bool set_blanket,
21 IWbemServices** wmi_services) {
22 base::win::ScopedComPtr<IWbemLocator> wmi_locator;
23 HRESULT hr = wmi_locator.CreateInstance(CLSID_WbemLocator, NULL,
24 CLSCTX_INPROC_SERVER);
25 if (FAILED(hr))
26 return false;
28 base::win::ScopedComPtr<IWbemServices> wmi_services_r;
29 hr = wmi_locator->ConnectServer(base::win::ScopedBstr(L"ROOT\\CIMV2"),
30 NULL, NULL, 0, NULL, 0, 0,
31 wmi_services_r.Receive());
32 if (FAILED(hr))
33 return false;
35 if (set_blanket) {
36 hr = ::CoSetProxyBlanket(wmi_services_r,
37 RPC_C_AUTHN_WINNT,
38 RPC_C_AUTHZ_NONE,
39 NULL,
40 RPC_C_AUTHN_LEVEL_CALL,
41 RPC_C_IMP_LEVEL_IMPERSONATE,
42 NULL,
43 EOAC_NONE);
44 if (FAILED(hr))
45 return false;
48 *wmi_services = wmi_services_r.Detach();
49 return true;
52 bool WMI::CreateClassMethodObject(IWbemServices* wmi_services,
53 const std::wstring& class_name,
54 const std::wstring& method_name,
55 IWbemClassObject** class_instance) {
56 // We attempt to instantiate a COM object that represents a WMI object plus
57 // a method rolled into one entity.
58 base::win::ScopedBstr b_class_name(class_name.c_str());
59 base::win::ScopedBstr b_method_name(method_name.c_str());
60 base::win::ScopedComPtr<IWbemClassObject> class_object;
61 HRESULT hr;
62 hr = wmi_services->GetObject(b_class_name, 0, NULL,
63 class_object.Receive(), NULL);
64 if (FAILED(hr))
65 return false;
67 base::win::ScopedComPtr<IWbemClassObject> params_def;
68 hr = class_object->GetMethod(b_method_name, 0, params_def.Receive(), NULL);
69 if (FAILED(hr))
70 return false;
72 if (NULL == params_def) {
73 // You hit this special case if the WMI class is not a CIM class. MSDN
74 // sometimes tells you this. Welcome to WMI hell.
75 return false;
78 hr = params_def->SpawnInstance(0, class_instance);
79 return(SUCCEEDED(hr));
82 bool SetParameter(IWbemClassObject* class_method,
83 const std::wstring& parameter_name, VARIANT* parameter) {
84 HRESULT hr = class_method->Put(parameter_name.c_str(), 0, parameter, 0);
85 return SUCCEEDED(hr);
89 // The code in Launch() basically calls the Create Method of the Win32_Process
90 // CIM class is documented here:
91 // http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx
92 // NOTE: The documentation for the Create method suggests that the ProcessId
93 // parameter and return value are of type uint32, but when we call the method
94 // the values in the returned out_params, are VT_I4, which is int32.
96 bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) {
97 base::win::ScopedComPtr<IWbemServices> wmi_local;
98 if (!WMI::CreateLocalConnection(true, wmi_local.Receive()))
99 return false;
101 const wchar_t class_name[] = L"Win32_Process";
102 const wchar_t method_name[] = L"Create";
103 base::win::ScopedComPtr<IWbemClassObject> process_create;
104 if (!WMI::CreateClassMethodObject(wmi_local, class_name, method_name,
105 process_create.Receive()))
106 return false;
108 ScopedVariant b_command_line(command_line.c_str());
110 if (!SetParameter(process_create, L"CommandLine", b_command_line.AsInput()))
111 return false;
113 base::win::ScopedComPtr<IWbemClassObject> out_params;
114 HRESULT hr = wmi_local->ExecMethod(base::win::ScopedBstr(class_name),
115 base::win::ScopedBstr(method_name),
116 0, NULL, process_create,
117 out_params.Receive(), NULL);
118 if (FAILED(hr))
119 return false;
121 // We're only expecting int32 or uint32 values, so no need for ScopedVariant.
122 VARIANT ret_value = {VT_EMPTY};
123 hr = out_params->Get(L"ReturnValue", 0, &ret_value, NULL, 0);
124 if (FAILED(hr) || 0 != V_I4(&ret_value))
125 return false;
127 VARIANT pid = {VT_EMPTY};
128 hr = out_params->Get(L"ProcessId", 0, &pid, NULL, 0);
129 if (FAILED(hr) || 0 == V_I4(&pid))
130 return false;
132 if (process_id)
133 *process_id = V_I4(&pid);
135 return true;
138 base::string16 WMIComputerSystem::GetModel() {
139 base::win::ScopedComPtr<IWbemServices> services;
140 if (!WMI::CreateLocalConnection(true, services.Receive()))
141 return base::string16();
143 base::win::ScopedBstr query_language(L"WQL");
144 base::win::ScopedBstr query(L"SELECT * FROM Win32_ComputerSystem");
145 base::win::ScopedComPtr<IEnumWbemClassObject> enumerator;
146 HRESULT hr = services->ExecQuery(
147 query_language, query,
148 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL,
149 enumerator.Receive());
150 if (FAILED(hr) || !enumerator)
151 return base::string16();
153 base::win::ScopedComPtr<IWbemClassObject> class_object;
154 ULONG items_returned = 0;
155 hr = enumerator->Next(WBEM_INFINITE, 1, class_object.Receive(),
156 &items_returned);
157 if (!items_returned)
158 return base::string16();
160 base::win::ScopedVariant manufacturer;
161 class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), 0, 0);
162 base::win::ScopedVariant model;
163 class_object->Get(L"Model", 0, model.Receive(), 0, 0);
165 base::string16 model_string;
166 if (manufacturer.type() == VT_BSTR) {
167 model_string = V_BSTR(&manufacturer);
168 if (model.type() == VT_BSTR)
169 model_string += L" ";
171 if (model.type() == VT_BSTR)
172 model_string += V_BSTR(&model);
174 return model_string;
177 } // namespace installer