blob: e290e558ef8bd37f67c0d034b181c8ae6962b62e [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include <windows.h>
6#include <atlbase.h>
7
8#pragma comment(lib, "wbemuuid.lib")
9
10#include "base/wmi_util.h"
11
12bool WMIUtil::CreateLocalConnection(bool set_blanket,
13 IWbemServices** wmi_services) {
14 CComPtr<IWbemLocator> wmi_locator;
15 HRESULT hr = wmi_locator.CoCreateInstance(CLSID_WbemLocator, NULL,
16 CLSCTX_INPROC_SERVER);
17 if (FAILED(hr))
18 return false;
19
20 CComPtr<IWbemServices> wmi_services_r;
21 hr = wmi_locator->ConnectServer(CComBSTR(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL,
22 0, 0, &wmi_services_r);
23 if (FAILED(hr))
24 return false;
25
26 if (set_blanket) {
27 hr = ::CoSetProxyBlanket(wmi_services_r,
28 RPC_C_AUTHN_WINNT,
29 RPC_C_AUTHZ_NONE,
30 NULL,
31 RPC_C_AUTHN_LEVEL_CALL,
32 RPC_C_IMP_LEVEL_IMPERSONATE,
33 NULL,
34 EOAC_NONE);
35 if (FAILED(hr))
36 return false;
37 }
38
39 *wmi_services = wmi_services_r.Detach();
40 return true;
41}
42
43bool WMIUtil::CreateClassMethodObject(IWbemServices* wmi_services,
44 const std::wstring& class_name,
45 const std::wstring& method_name,
46 IWbemClassObject** class_instance) {
47 // We attempt to instantiate a COM object that represents a WMI object plus
48 // a method rolled into one entity.
49 CComBSTR b_class_name(class_name.c_str());
50 CComBSTR b_method_name(method_name.c_str());
51 CComPtr<IWbemClassObject> class_object = NULL;
52 HRESULT hr;
53 hr = wmi_services->GetObject(b_class_name, 0, NULL, &class_object, NULL);
54 if (FAILED(hr))
55 return false;
56
57 CComPtr<IWbemClassObject> params_def = NULL;
58 hr = class_object->GetMethod(b_method_name, 0, &params_def, NULL);
59 if (FAILED(hr))
60 return false;
61
62 if (NULL == params_def) {
63 // You hit this special case if the WMI class is not a CIM class. MSDN
64 // sometimes tells you this. Welcome to WMI hell.
65 return false;
66 }
67
68 hr = params_def->SpawnInstance(0, class_instance);
69 return(SUCCEEDED(hr));
70}
71
72bool SetParameter(IWbemClassObject* class_method,
73 const std::wstring& parameter_name, VARIANT* parameter) {
74 HRESULT hr = class_method->Put(parameter_name.c_str(), 0, parameter, 0);
75 return SUCCEEDED(hr);
76}
77
78
79// The code in Launch() basically calls the Create Method of the Win32_Process
80// CIM class is documented here:
81// http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx
82
83bool WMIProcessUtil::Launch(const std::wstring& command_line, int* process_id) {
84 CComPtr<IWbemServices> wmi_local;
85 if (!WMIUtil::CreateLocalConnection(true, &wmi_local))
86 return false;
87
88 const wchar_t class_name[] = L"Win32_Process";
89 const wchar_t method_name[] = L"Create";
90 CComPtr<IWbemClassObject> process_create;
91 if (!WMIUtil::CreateClassMethodObject(wmi_local, class_name, method_name,
92 &process_create))
93 return false;
94
95 CComVariant b_command_line(command_line.c_str());
96 if (!SetParameter(process_create, L"CommandLine", &b_command_line))
97 return false;
98
99 CComPtr<IWbemClassObject> out_params;
100 HRESULT hr = wmi_local->ExecMethod(CComBSTR(class_name),
101 CComBSTR(method_name), 0, NULL,
102 process_create, &out_params, NULL);
103 if (FAILED(hr))
104 return false;
105
106 CComVariant ret_value;
107 hr = out_params->Get(L"ReturnValue", 0, &ret_value, NULL, 0);
108 if (FAILED(hr) || (0 != ret_value.uintVal))
109 return false;
110
111 CComVariant pid;
112 hr = out_params->Get(L"ProcessId", 0, &pid, NULL, 0);
113 if (FAILED(hr) || (0 == pid.intVal))
114 return false;
115
116 if (process_id)
117 *process_id = pid.intVal;
118
119 return true;
120}
license.botf003cfe2008-08-24 09:55:55 +0900121