Commit 73a94302 authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

Move WMI utilities from chrome/installer/util to base/win

This makes these utilities easier to use from other projects, which we
plan to do in the upcoming Hardware Platform Extension API
(see crbug.com/854636).

This CL also refactors the function to get the computer manufacturer
and model so that they are available as separate strings, and adds
a number of style/lint fixes.

Bug: 874408
Change-Id: I408151cc478ccf37a0515d17d1381115b12d9122
Reviewed-on: https://chromium-review.googlesource.com/1175781Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585853}
parent ff29b230
......@@ -1149,6 +1149,8 @@ jumbo_component("base") {
"win/windows_version.h",
"win/winrt_storage_util.cc",
"win/winrt_storage_util.h",
"win/wmi.cc",
"win/wmi.h",
"win/wrapped_window_proc.cc",
"win/wrapped_window_proc.h",
]
......@@ -1648,6 +1650,7 @@ jumbo_component("base") {
"propsys.lib",
"setupapi.lib",
"userenv.lib",
"wbemuuid.lib",
"winmm.lib",
]
all_dependent_configs += [
......@@ -2555,6 +2558,7 @@ test("base_unittests") {
"win/win_util_unittest.cc",
"win/windows_version_unittest.cc",
"win/winrt_storage_util_unittest.cc",
"win/wmi_unittest.cc",
"win/wrapped_window_proc_unittest.cc",
]
......
......@@ -2,127 +2,131 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/installer/util/wmi.h"
#include "base/win/wmi.h"
#include <windows.h>
#include <objbase.h>
#include <stdint.h>
#include <wrl/client.h>
#include <utility>
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_variant.h"
using base::win::ScopedVariant;
using Microsoft::WRL::ComPtr;
namespace installer {
namespace base {
namespace win {
bool WMI::CreateLocalConnection(bool set_blanket,
IWbemServices** wmi_services) {
Microsoft::WRL::ComPtr<IWbemLocator> wmi_locator;
HRESULT hr = ::CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&wmi_locator));
bool CreateLocalWmiConnection(bool set_blanket,
ComPtr<IWbemServices>* wmi_services) {
ComPtr<IWbemLocator> wmi_locator;
HRESULT hr =
::CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&wmi_locator));
if (FAILED(hr))
return false;
Microsoft::WRL::ComPtr<IWbemServices> wmi_services_r;
hr = wmi_locator->ConnectServer(base::win::ScopedBstr(L"ROOT\\CIMV2"), NULL,
NULL, 0, NULL, 0, 0,
ComPtr<IWbemServices> wmi_services_r;
hr = wmi_locator->ConnectServer(ScopedBstr(L"ROOT\\CIMV2"), nullptr, nullptr,
nullptr, 0, nullptr, nullptr,
wmi_services_r.GetAddressOf());
if (FAILED(hr))
return false;
if (set_blanket) {
hr = ::CoSetProxyBlanket(wmi_services_r.Get(), RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
if (FAILED(hr))
return false;
}
*wmi_services = wmi_services_r.Detach();
*wmi_services = std::move(wmi_services_r);
return true;
}
bool WMI::CreateClassMethodObject(IWbemServices* wmi_services,
const std::wstring& class_name,
const std::wstring& method_name,
IWbemClassObject** class_instance) {
bool CreateWmiClassMethodObject(IWbemServices* wmi_services,
const StringPiece16& class_name,
const StringPiece16& method_name,
ComPtr<IWbemClassObject>* class_instance) {
// We attempt to instantiate a COM object that represents a WMI object plus
// a method rolled into one entity.
base::win::ScopedBstr b_class_name(class_name.c_str());
base::win::ScopedBstr b_method_name(method_name.c_str());
Microsoft::WRL::ComPtr<IWbemClassObject> class_object;
ScopedBstr b_class_name(class_name.data());
ScopedBstr b_method_name(method_name.data());
ComPtr<IWbemClassObject> class_object;
HRESULT hr;
hr = wmi_services->GetObject(b_class_name, 0, NULL,
class_object.GetAddressOf(), NULL);
hr = wmi_services->GetObject(b_class_name, 0, nullptr,
class_object.GetAddressOf(), nullptr);
if (FAILED(hr))
return false;
Microsoft::WRL::ComPtr<IWbemClassObject> params_def;
ComPtr<IWbemClassObject> params_def;
hr = class_object->GetMethod(b_method_name, 0, params_def.GetAddressOf(),
NULL);
nullptr);
if (FAILED(hr))
return false;
if (NULL == params_def.Get()) {
if (!params_def.Get()) {
// You hit this special case if the WMI class is not a CIM class. MSDN
// sometimes tells you this. Welcome to WMI hell.
return false;
}
hr = params_def->SpawnInstance(0, class_instance);
return(SUCCEEDED(hr));
hr = params_def->SpawnInstance(0, class_instance->GetAddressOf());
return SUCCEEDED(hr);
}
bool SetParameter(IWbemClassObject* class_method,
const std::wstring& parameter_name, VARIANT* parameter) {
HRESULT hr = class_method->Put(parameter_name.c_str(), 0, parameter, 0);
bool SetWmiClassMethodParameter(IWbemClassObject* class_method,
const StringPiece16& parameter_name,
VARIANT* parameter) {
HRESULT hr = class_method->Put(parameter_name.data(), 0, parameter, 0);
return SUCCEEDED(hr);
}
// The code in Launch() basically calls the Create Method of the Win32_Process
// CIM class is documented here:
// http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx
// NOTE: The documentation for the Create method suggests that the ProcessId
// parameter and return value are of type uint32_t, but when we call the method
// the values in the returned out_params, are VT_I4, which is int32_t.
bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) {
Microsoft::WRL::ComPtr<IWbemServices> wmi_local;
if (!WMI::CreateLocalConnection(true, wmi_local.GetAddressOf()))
bool WmiLaunchProcess(const string16& command_line, int* process_id) {
ComPtr<IWbemServices> wmi_local;
if (!CreateLocalWmiConnection(true, &wmi_local))
return false;
const wchar_t class_name[] = L"Win32_Process";
const wchar_t method_name[] = L"Create";
Microsoft::WRL::ComPtr<IWbemClassObject> process_create;
if (!WMI::CreateClassMethodObject(wmi_local.Get(), class_name, method_name,
process_create.GetAddressOf()))
static constexpr wchar_t class_name[] = L"Win32_Process";
static constexpr wchar_t method_name[] = L"Create";
ComPtr<IWbemClassObject> process_create;
if (!CreateWmiClassMethodObject(wmi_local.Get(), class_name, method_name,
&process_create)) {
return false;
}
ScopedVariant b_command_line(command_line.c_str());
if (!SetParameter(process_create.Get(), L"CommandLine",
b_command_line.AsInput()))
if (!SetWmiClassMethodParameter(process_create.Get(), L"CommandLine",
b_command_line.AsInput())) {
return false;
}
Microsoft::WRL::ComPtr<IWbemClassObject> out_params;
ComPtr<IWbemClassObject> out_params;
HRESULT hr = wmi_local->ExecMethod(
base::win::ScopedBstr(class_name), base::win::ScopedBstr(method_name), 0,
NULL, process_create.Get(), out_params.GetAddressOf(), NULL);
ScopedBstr(class_name), ScopedBstr(method_name), 0, nullptr,
process_create.Get(), out_params.GetAddressOf(), nullptr);
if (FAILED(hr))
return false;
// We're only expecting int32_t or uint32_t values, so no need for
// ScopedVariant.
VARIANT ret_value = {{{VT_EMPTY}}};
hr = out_params->Get(L"ReturnValue", 0, &ret_value, NULL, 0);
if (FAILED(hr) || 0 != V_I4(&ret_value))
hr = out_params->Get(L"ReturnValue", 0, &ret_value, nullptr, 0);
if (FAILED(hr) || V_I4(&ret_value) != 0)
return false;
VARIANT pid = {{{VT_EMPTY}}};
hr = out_params->Get(L"ProcessId", 0, &pid, NULL, 0);
if (FAILED(hr) || 0 == V_I4(&pid))
hr = out_params->Get(L"ProcessId", 0, &pid, nullptr, 0);
if (FAILED(hr) || V_I4(&pid) == 0)
return false;
if (process_id)
......@@ -131,43 +135,42 @@ bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) {
return true;
}
base::string16 WMIComputerSystem::GetModel() {
Microsoft::WRL::ComPtr<IWbemServices> services;
if (!WMI::CreateLocalConnection(true, services.GetAddressOf()))
return base::string16();
WmiComputerSystemInfo WmiComputerSystemInfo::Get() {
ComPtr<IWbemServices> services;
if (!CreateLocalWmiConnection(true, &services))
return WmiComputerSystemInfo();
base::win::ScopedBstr query_language(L"WQL");
base::win::ScopedBstr query(L"SELECT * FROM Win32_ComputerSystem");
Microsoft::WRL::ComPtr<IEnumWbemClassObject> enumerator;
ScopedBstr query_language(L"WQL");
ScopedBstr query(L"SELECT * FROM Win32_ComputerSystem");
ComPtr<IEnumWbemClassObject> enumerator;
HRESULT hr =
services->ExecQuery(query_language, query,
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL, enumerator.GetAddressOf());
nullptr, enumerator.GetAddressOf());
if (FAILED(hr) || !enumerator.Get())
return base::string16();
return WmiComputerSystemInfo();
Microsoft::WRL::ComPtr<IWbemClassObject> class_object;
ComPtr<IWbemClassObject> class_object;
ULONG items_returned = 0;
hr = enumerator->Next(WBEM_INFINITE, 1, class_object.GetAddressOf(),
&items_returned);
if (!items_returned)
return base::string16();
return WmiComputerSystemInfo();
base::win::ScopedVariant manufacturer;
ScopedVariant manufacturer;
class_object->Get(L"Manufacturer", 0, manufacturer.Receive(), 0, 0);
base::win::ScopedVariant model;
ScopedVariant model;
class_object->Get(L"Model", 0, model.Receive(), 0, 0);
base::string16 model_string;
if (manufacturer.type() == VT_BSTR) {
model_string = V_BSTR(manufacturer.ptr());
if (model.type() == VT_BSTR)
model_string += L" ";
}
WmiComputerSystemInfo info;
if (manufacturer.type() == VT_BSTR)
info.manufacturer_ = V_BSTR(manufacturer.ptr());
if (model.type() == VT_BSTR)
model_string += V_BSTR(model.ptr());
info.model_ = V_BSTR(model.ptr());
return model_string;
return info;
}
} // namespace installer
} // namespace win
} // namespace base
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// WMI (Windows Management and Instrumentation) is a big, complex, COM-based
// API that can be used to perform all sorts of things. Sometimes is the best
// way to accomplish something under windows but its lack of an approachable
// C++ interface prevents its use. This collection of functions is a step in
// that direction.
// There are two classes; WMIUtil and WMIProcessUtil. The first
// one contains generic helpers and the second one contains the only
// functionality that is needed right now which is to use WMI to launch a
// process.
// To use any function on this header you must call CoInitialize or
// CoInitializeEx beforehand.
//
// For more information about WMI programming:
// http://msdn2.microsoft.com/en-us/library/aa384642(VS.85).aspx
#ifndef BASE_WIN_WMI_H_
#define BASE_WIN_WMI_H_
#include <wbemidl.h>
#include <wrl/client.h>
#include "base/base_export.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
namespace base {
namespace win {
// Creates an instance of the WMI service connected to the local computer and
// returns its COM interface. If |set_blanket| is set to true, the basic COM
// security blanket is applied to the returned interface. This is almost
// always desirable unless you set the parameter to false and apply a custom
// COM security blanket.
// Returns true if succeeded and |wmi_services|: the pointer to the service.
BASE_EXPORT bool CreateLocalWmiConnection(
bool set_blanket,
Microsoft::WRL::ComPtr<IWbemServices>* wmi_services);
// Creates a WMI method using from a WMI class named |class_name| that
// contains a method named |method_name|. Only WMI classes that are CIM
// classes can be created using this function.
// Returns true if succeeded and |class_instance| returns a pointer to the
// WMI method that you can fill with parameter values using SetParameter.
BASE_EXPORT bool CreateWmiClassMethodObject(
IWbemServices* wmi_services,
const StringPiece16& class_name,
const StringPiece16& method_name,
Microsoft::WRL::ComPtr<IWbemClassObject>* class_instance);
// Fills a single parameter given an instanced |class_method|. Returns true
// if the operation succeeded. When all the parameters are set the method can
// be executed using IWbemServices::ExecMethod().
BASE_EXPORT bool SetWmiClassMethodParameter(IWbemClassObject* class_method,
const StringPiece16& parameter_name,
VARIANT* parameter);
// Creates a new process from |command_line|. The advantage over CreateProcess
// is that it allows you to always break out from a Job object that the caller
// is attached to even if the Job object flags prevent that.
// Returns true and the process id in process_id if the process is launched
// successful. False otherwise.
// Note that a fully qualified path must be specified in most cases unless
// the program is not in the search path of winmgmt.exe.
// Processes created this way are children of wmiprvse.exe and run with the
// caller credentials.
// More info: http://msdn2.microsoft.com/en-us/library/aa394372(VS.85).aspx
BASE_EXPORT bool WmiLaunchProcess(const string16& command_line,
int* process_id);
// This class contains functionality of the WMI class 'Win32_ComputerSystem'.
// More info: http://msdn.microsoft.com/en-us/library/aa394102(VS.85).aspx
class BASE_EXPORT WmiComputerSystemInfo {
public:
static WmiComputerSystemInfo Get();
const string16& manufacturer() const { return manufacturer_; }
const string16& model() const { return model_; }
private:
string16 manufacturer_;
string16 model_;
};
} // namespace win
} // namespace base
#endif // BASE_WIN_WMI_H_
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/win/wmi.h"
#include <windows.h>
#include "base/win/scoped_com_initializer.h"
#include "testing/gtest/include/gtest/gtest.h"
using Microsoft::WRL::ComPtr;
namespace base {
namespace win {
class WMITest : public ::testing::Test {
private:
ScopedCOMInitializer com_initializer;
};
TEST_F(WMITest, TestLocalConnectionSecurityBlanket) {
ComPtr<IWbemServices> wmi_services = nullptr;
EXPECT_TRUE(CreateLocalWmiConnection(true, &wmi_services));
ASSERT_NE(wmi_services.Get(), nullptr);
ULONG refs = wmi_services->Release();
EXPECT_EQ(0u, refs);
}
TEST_F(WMITest, TestLocalConnectionNoSecurityBlanket) {
ComPtr<IWbemServices> wmi_services = nullptr;
EXPECT_TRUE(CreateLocalWmiConnection(false, &wmi_services));
ASSERT_NE(wmi_services.Get(), nullptr);
ULONG refs = wmi_services->Release();
EXPECT_EQ(0u, refs);
}
TEST_F(WMITest, TestCreateClassMethod) {
ComPtr<IWbemServices> wmi_services = nullptr;
EXPECT_TRUE(CreateLocalWmiConnection(true, &wmi_services));
ASSERT_NE(wmi_services.Get(), nullptr);
ComPtr<IWbemClassObject> class_method = nullptr;
EXPECT_TRUE(CreateWmiClassMethodObject(
wmi_services.Get(), L"Win32_ShortcutFile", L"Rename", &class_method));
ASSERT_NE(class_method.Get(), nullptr);
ULONG refs = class_method->Release();
EXPECT_EQ(0u, refs);
refs = wmi_services->Release();
EXPECT_EQ(0u, refs);
}
// Creates an instance of cmd which executes 'echo' and exits immediately.
TEST_F(WMITest, TestLaunchProcess) {
int pid = 0;
bool result = WmiLaunchProcess(L"cmd.exe /c echo excelent!", &pid);
EXPECT_TRUE(result);
EXPECT_GT(pid, 0);
}
TEST_F(WMITest, TestComputerSystemInfo) {
WmiComputerSystemInfo info = WmiComputerSystemInfo::Get();
EXPECT_FALSE(info.manufacturer().empty());
EXPECT_FALSE(info.model().empty());
}
} // namespace win
} // namespace base
......@@ -48,6 +48,7 @@ if (is_win) {
"netapi32.lib",
"ndfapi.lib", # Used by browser/net/net_error_diagnostics_dialog_win.h
"pdh.lib", # Used by browser/private_working_set_snapshot.h
"wbemuuid.lib", # Used by browser/metrics/antivirus_metrics_provider_win.cc
]
ldflags = [
"/DELAYLOAD:ndfapi.dll",
......
......@@ -24,6 +24,7 @@
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "base/win/wmi.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/simple_message_box.h"
#include "chrome/browser/win/chrome_process_finder.h"
......@@ -32,7 +33,6 @@
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/installer/util/wmi.h"
#include "content/public/common/result_codes.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -236,7 +236,7 @@ bool ProcessSingleton::EscapeVirtualization(
if (::GetModuleHandle(L"sftldr_wow64.dll") ||
::GetModuleHandle(L"sftldr.dll")) {
int process_id;
if (!installer::WMIProcess::Launch(::GetCommandLineW(), &process_id))
if (!base::win::WmiLaunchProcess(::GetCommandLineW(), &process_id))
return false;
is_virtualized_ = true;
// The new window was spawned from WMI, and won't be in the foreground.
......
......@@ -6,7 +6,6 @@ include_rules = [
# Take care not to allow any dependence on BrowserDistribution.
"+chrome/installer/util/google_update_constants.h",
"+chrome/installer/util/util_constants.h",
"+chrome/installer/util/wmi.h",
]
specific_include_rules = {
".*_test\.cc": [
......
......@@ -38,13 +38,13 @@
#include "base/win/registry.h"
#include "base/win/scoped_com_initializer.h"
#include "base/win/scoped_handle.h"
#include "base/win/wmi.h"
#include "chrome/installer/gcapi/gcapi_omaha_experiment.h"
#include "chrome/installer/gcapi/gcapi_reactivation.h"
#include "chrome/installer/gcapi/google_update_util.h"
#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/util_constants.h"
#include "chrome/installer/util/wmi.h"
#include "google_update/google_update_idl.h"
using Microsoft::WRL::ComPtr;
......@@ -522,8 +522,8 @@ BOOL __stdcall LaunchGoogleChromeWithDimensions(int x,
base::CommandLine chrome_command(chrome_exe_path);
ScopedCOMInitializer com_initializer;
if (!installer::WMIProcess::Launch(chrome_command.GetCommandLineString(),
NULL)) {
if (!base::win::WmiLaunchProcess(chrome_command.GetCommandLineString(),
NULL)) {
// For some reason WMI failed. Try and launch the old fashioned way,
// knowing that visual glitches will occur when the window pops up.
if (!LaunchGoogleChrome())
......
......@@ -115,7 +115,6 @@ static_library("with_no_strings") {
libs = [
"urlmon.lib",
"wbemuuid.lib",
"wtsapi32.lib",
]
......@@ -196,8 +195,6 @@ static_library("with_no_strings") {
"updating_app_registration_data.h",
"util_constants.cc",
"util_constants.h",
"wmi.cc",
"wmi.h",
"work_item.cc",
"work_item.h",
"work_item_list.cc",
......@@ -323,7 +320,6 @@ if (is_win) {
"test_app_registration_data.cc",
"test_app_registration_data.h",
"uninstall_metrics_unittest.cc",
"wmi_unittest.cc",
"work_item_list_unittest.cc",
"work_item_mocks.cc",
"work_item_mocks.h",
......
......@@ -21,6 +21,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#include "base/win/wmi.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/install_static/install_util.h"
#include "chrome/installer/util/app_registration_data.h"
......@@ -31,7 +32,6 @@
#include "chrome/installer/util/l10n_string_util.h"
#include "chrome/installer/util/uninstall_metrics.h"
#include "chrome/installer/util/updating_app_registration_data.h"
#include "chrome/installer/util/wmi.h"
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
#include "third_party/crashpad/crashpad/client/settings.h"
......@@ -81,7 +81,7 @@ void NavigateToUrlWithIExplore(const base::string16& url) {
// process runs inside a Job object controlled by the shell. As long as there
// are processes running, the shell will not close the uninstall applet. WMI
// allows us to escape from the Job object so the applet will close.
installer::WMIProcess::Launch(command, &pid);
base::win::WmiLaunchProcess(command, &pid);
}
} // namespace
......
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// WMI (Windows Management and Instrumentation) is a big, complex, COM-based
// API that can be used to perform all sorts of things. Sometimes is the best
// way to accomplish something under windows but its lack of an approachable
// C++ interface prevents its use. This collection of fucntions is a step in
// that direction.
// There are two classes; WMIUtil and WMIProcessUtil. The first
// one contain generic helpers and the second one contains the only
// functionality that is needed right now which is to use WMI to launch a
// process.
// To use any function on this header you must call CoInitialize or
// CoInitializeEx beforehand.
//
// For more information about WMI programming:
// http://msdn2.microsoft.com/en-us/library/aa384642(VS.85).aspx
#ifndef CHROME_INSTALLER_UTIL_WMI_H_
#define CHROME_INSTALLER_UTIL_WMI_H_
#include <string>
#include <wbemidl.h>
#include "base/strings/string16.h"
namespace installer {
class WMI {
public:
// Creates an instance of the WMI service connected to the local computer and
// returns its COM interface. If 'set-blanket' is set to true, the basic COM
// security blanket is applied to the returned interface. This is almost
// always desirable unless you set the parameter to false and apply a custom
// COM security blanket.
// Returns true if succeeded and 'wmi_services': the pointer to the service.
// When done with the interface you must call Release();
static bool CreateLocalConnection(bool set_blanket,
IWbemServices** wmi_services);
// Creates a WMI method using from a WMI class named 'class_name' that
// contains a method named 'method_name'. Only WMI classes that are CIM
// classes can be created using this function.
// Returns true if succeeded and 'class_instance' returns a pointer to the
// WMI method that you can fill with parameter values using SetParameter.
// When done with the interface you must call Release();
static bool CreateClassMethodObject(IWbemServices* wmi_services,
const std::wstring& class_name,
const std::wstring& method_name,
IWbemClassObject** class_instance);
// Fills a single parameter given an instanced 'class_method'. Returns true
// if operation succeeded. When all the parameters are set the method can
// be executed using IWbemServices::ExecMethod().
static bool SetParameter(IWbemClassObject* class_method,
const std::wstring& parameter_name,
VARIANT* parameter);
};
// This class contains functionality of the WMI class 'Win32_Process'
// more info: http://msdn2.microsoft.com/en-us/library/aa394372(VS.85).aspx
class WMIProcess {
public:
// Creates a new process from 'command_line'. The advantage over CreateProcess
// is that it allows you to always break out from a Job object that the caller
// is attached to even if the Job object flags prevent that.
// Returns true and the process id in process_id if the process is launched
// successful. False otherwise.
// Note that a fully qualified path must be specified in most cases unless
// the program is not in the search path of winmgmt.exe.
// Processes created this way are children of wmiprvse.exe and run with the
// caller credentials.
static bool Launch(const std::wstring& command_line, int* process_id);
};
// This class contains functionality of the WMI class 'Win32_ComputerSystem'
// more info: http://msdn.microsoft.com/en-us/library/aa394102(VS.85).aspx
class WMIComputerSystem {
public:
// Returns a human readable string for the model/make of this computer.
static base::string16 GetModel();
};
} // namespace installer
#endif // CHROME_INSTALLER_UTIL_WMI_H_
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include "chrome/installer/util/wmi.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace installer {
TEST(WMITest, TestLocalConnectionSecurityBlanket) {
IWbemServices* services = NULL;
EXPECT_TRUE(WMI::CreateLocalConnection(true, &services));
ASSERT_TRUE(NULL != services);
ULONG refs = services->Release();
EXPECT_EQ(0u, refs);
}
TEST(WMITest, TestLocalConnectionNoSecurityBlanket) {
IWbemServices* services = NULL;
EXPECT_TRUE(WMI::CreateLocalConnection(false, &services));
ASSERT_TRUE(NULL != services);
ULONG refs = services->Release();
EXPECT_EQ(0u, refs);
}
TEST(WMITest, TestCreateClassMethod) {
IWbemServices* wmi_services = NULL;
EXPECT_TRUE(WMI::CreateLocalConnection(true, &wmi_services));
ASSERT_TRUE(NULL != wmi_services);
IWbemClassObject* class_method = NULL;
EXPECT_TRUE(WMI::CreateClassMethodObject(wmi_services,
L"Win32_ShortcutFile",
L"Rename", &class_method));
ASSERT_TRUE(NULL != class_method);
ULONG refs = class_method->Release();
EXPECT_EQ(0u, refs);
refs = wmi_services->Release();
EXPECT_EQ(0u, refs);
}
// Creates an instance of cmd which executes 'echo' and exits immediately.
TEST(WMITest, TestLaunchProcess) {
int pid = 0;
bool result = WMIProcess::Launch(L"cmd.exe /c echo excelent!", &pid);
EXPECT_TRUE(result);
EXPECT_GT(pid, 0);
}
} // namespace installer
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment