Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/installer/util/wmi.h" | 5 #include "chrome/installer/util/wmi.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/scoped_bstr_win.h" | 10 #include "base/win/scoped_bstr.h" |
| 11 #include "base/scoped_comptr_win.h" | 11 #include "base/win/scoped_comptr.h" |
| 12 | 12 |
| 13 #pragma comment(lib, "wbemuuid.lib") | 13 #pragma comment(lib, "wbemuuid.lib") |
| 14 | 14 |
| 15 namespace installer { | 15 namespace installer { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Simple class to manage the lifetime of a variant. | 19 // Simple class to manage the lifetime of a variant. |
| 20 // TODO(tommi): Replace this for a more useful class. | 20 // TODO(tommi): Replace this for a more useful class. |
| 21 class VariantHelper : public VARIANT { | 21 class VariantHelper : public VARIANT { |
| 22 public: | 22 public: |
| 23 VariantHelper() { | 23 VariantHelper() { |
| 24 vt = VT_EMPTY; | 24 vt = VT_EMPTY; |
| 25 } | 25 } |
| 26 explicit VariantHelper(VARTYPE type) { | 26 explicit VariantHelper(VARTYPE type) { |
| 27 vt = type; | 27 vt = type; |
| 28 } | 28 } |
| 29 ~VariantHelper() { | 29 ~VariantHelper() { |
| 30 ::VariantClear(this); | 30 ::VariantClear(this); |
| 31 } | 31 } |
| 32 private: | 32 private: |
| 33 DISALLOW_COPY_AND_ASSIGN(VariantHelper); | 33 DISALLOW_COPY_AND_ASSIGN(VariantHelper); |
| 34 }; | 34 }; |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 bool WMI::CreateLocalConnection(bool set_blanket, | 38 bool WMI::CreateLocalConnection(bool set_blanket, |
| 39 IWbemServices** wmi_services) { | 39 IWbemServices** wmi_services) { |
| 40 ScopedComPtr<IWbemLocator> wmi_locator; | 40 base::win::ScopedComPtr<IWbemLocator> wmi_locator; |
| 41 HRESULT hr = wmi_locator.CreateInstance(CLSID_WbemLocator, NULL, | 41 HRESULT hr = wmi_locator.CreateInstance(CLSID_WbemLocator, NULL, |
| 42 CLSCTX_INPROC_SERVER); | 42 CLSCTX_INPROC_SERVER); |
| 43 if (FAILED(hr)) | 43 if (FAILED(hr)) |
| 44 return false; | 44 return false; |
| 45 | 45 |
| 46 ScopedComPtr<IWbemServices> wmi_services_r; | 46 base::win::ScopedComPtr<IWbemServices> wmi_services_r; |
| 47 hr = wmi_locator->ConnectServer(StackBstr(L"ROOT\\CIMV2"), NULL, NULL, 0, | 47 hr = wmi_locator->ConnectServer(base::win::ScopedBstr(L"ROOT\\CIMV2"), |
| 48 NULL, 0, 0, wmi_services_r.Receive()); | 48 NULL, NULL, 0, NULL, 0, 0, |
| 49 wmi_services_r.Receive()); | |
| 49 if (FAILED(hr)) | 50 if (FAILED(hr)) |
| 50 return false; | 51 return false; |
| 51 | 52 |
| 52 if (set_blanket) { | 53 if (set_blanket) { |
| 53 hr = ::CoSetProxyBlanket(wmi_services_r, | 54 hr = ::CoSetProxyBlanket(wmi_services_r, |
| 54 RPC_C_AUTHN_WINNT, | 55 RPC_C_AUTHN_WINNT, |
| 55 RPC_C_AUTHZ_NONE, | 56 RPC_C_AUTHZ_NONE, |
| 56 NULL, | 57 NULL, |
| 57 RPC_C_AUTHN_LEVEL_CALL, | 58 RPC_C_AUTHN_LEVEL_CALL, |
| 58 RPC_C_IMP_LEVEL_IMPERSONATE, | 59 RPC_C_IMP_LEVEL_IMPERSONATE, |
| 59 NULL, | 60 NULL, |
| 60 EOAC_NONE); | 61 EOAC_NONE); |
| 61 if (FAILED(hr)) | 62 if (FAILED(hr)) |
| 62 return false; | 63 return false; |
| 63 } | 64 } |
| 64 | 65 |
| 65 *wmi_services = wmi_services_r.Detach(); | 66 *wmi_services = wmi_services_r.Detach(); |
| 66 return true; | 67 return true; |
| 67 } | 68 } |
| 68 | 69 |
| 69 bool WMI::CreateClassMethodObject(IWbemServices* wmi_services, | 70 bool WMI::CreateClassMethodObject(IWbemServices* wmi_services, |
| 70 const std::wstring& class_name, | 71 const std::wstring& class_name, |
| 71 const std::wstring& method_name, | 72 const std::wstring& method_name, |
| 72 IWbemClassObject** class_instance) { | 73 IWbemClassObject** class_instance) { |
| 73 // We attempt to instantiate a COM object that represents a WMI object plus | 74 // We attempt to instantiate a COM object that represents a WMI object plus |
| 74 // a method rolled into one entity. | 75 // a method rolled into one entity. |
| 75 ScopedBstr b_class_name(class_name.c_str()); | 76 base::win::ScopedBstr b_class_name(class_name.c_str()); |
| 76 ScopedBstr b_method_name(method_name.c_str()); | 77 base::win::ScopedBstr b_method_name(method_name.c_str()); |
| 77 ScopedComPtr<IWbemClassObject> class_object; | 78 base::win::ScopedComPtr<IWbemClassObject> class_object; |
| 78 HRESULT hr; | 79 HRESULT hr; |
| 79 hr = wmi_services->GetObject(b_class_name, 0, NULL, | 80 hr = wmi_services->GetObject(b_class_name, 0, NULL, |
| 80 class_object.Receive(), NULL); | 81 class_object.Receive(), NULL); |
| 81 if (FAILED(hr)) | 82 if (FAILED(hr)) |
| 82 return false; | 83 return false; |
| 83 | 84 |
| 84 ScopedComPtr<IWbemClassObject> params_def; | 85 base::win::ScopedComPtr<IWbemClassObject> params_def; |
| 85 hr = class_object->GetMethod(b_method_name, 0, params_def.Receive(), NULL); | 86 hr = class_object->GetMethod(b_method_name, 0, params_def.Receive(), NULL); |
| 86 if (FAILED(hr)) | 87 if (FAILED(hr)) |
| 87 return false; | 88 return false; |
| 88 | 89 |
| 89 if (NULL == params_def) { | 90 if (NULL == params_def) { |
| 90 // You hit this special case if the WMI class is not a CIM class. MSDN | 91 // You hit this special case if the WMI class is not a CIM class. MSDN |
| 91 // sometimes tells you this. Welcome to WMI hell. | 92 // sometimes tells you this. Welcome to WMI hell. |
| 92 return false; | 93 return false; |
| 93 } | 94 } |
| 94 | 95 |
| 95 hr = params_def->SpawnInstance(0, class_instance); | 96 hr = params_def->SpawnInstance(0, class_instance); |
| 96 return(SUCCEEDED(hr)); | 97 return(SUCCEEDED(hr)); |
| 97 } | 98 } |
| 98 | 99 |
| 99 bool SetParameter(IWbemClassObject* class_method, | 100 bool SetParameter(IWbemClassObject* class_method, |
| 100 const std::wstring& parameter_name, VARIANT* parameter) { | 101 const std::wstring& parameter_name, VARIANT* parameter) { |
| 101 HRESULT hr = class_method->Put(parameter_name.c_str(), 0, parameter, 0); | 102 HRESULT hr = class_method->Put(parameter_name.c_str(), 0, parameter, 0); |
| 102 return SUCCEEDED(hr); | 103 return SUCCEEDED(hr); |
| 103 } | 104 } |
| 104 | 105 |
| 105 | 106 |
| 106 // The code in Launch() basically calls the Create Method of the Win32_Process | 107 // The code in Launch() basically calls the Create Method of the Win32_Process |
| 107 // CIM class is documented here: | 108 // CIM class is documented here: |
| 108 // http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx | 109 // http://msdn2.microsoft.com/en-us/library/aa389388(VS.85).aspx |
| 109 | 110 |
| 110 bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) { | 111 bool WMIProcess::Launch(const std::wstring& command_line, int* process_id) { |
| 111 ScopedComPtr<IWbemServices> wmi_local; | 112 base::win::ScopedComPtr<IWbemServices> wmi_local; |
| 112 if (!WMI::CreateLocalConnection(true, wmi_local.Receive())) | 113 if (!WMI::CreateLocalConnection(true, wmi_local.Receive())) |
| 113 return false; | 114 return false; |
| 114 | 115 |
| 115 const wchar_t class_name[] = L"Win32_Process"; | 116 const wchar_t class_name[] = L"Win32_Process"; |
| 116 const wchar_t method_name[] = L"Create"; | 117 const wchar_t method_name[] = L"Create"; |
| 117 ScopedComPtr<IWbemClassObject> process_create; | 118 base::win::ScopedComPtr<IWbemClassObject> process_create; |
|
darin (slow to review)
2010/10/15 05:58:11
the base::win:: is actually a bit obnoxious in win
| |
| 118 if (!WMI::CreateClassMethodObject(wmi_local, class_name, method_name, | 119 if (!WMI::CreateClassMethodObject(wmi_local, class_name, method_name, |
| 119 process_create.Receive())) | 120 process_create.Receive())) |
| 120 return false; | 121 return false; |
| 121 | 122 |
| 122 VariantHelper b_command_line(VT_BSTR); | 123 VariantHelper b_command_line(VT_BSTR); |
| 123 b_command_line.bstrVal = ::SysAllocString(command_line.c_str()); | 124 b_command_line.bstrVal = ::SysAllocString(command_line.c_str()); |
| 124 | 125 |
| 125 if (!SetParameter(process_create, L"CommandLine", &b_command_line)) | 126 if (!SetParameter(process_create, L"CommandLine", &b_command_line)) |
| 126 return false; | 127 return false; |
| 127 | 128 |
| 128 ScopedComPtr<IWbemClassObject> out_params; | 129 base::win::ScopedComPtr<IWbemClassObject> out_params; |
| 129 HRESULT hr = wmi_local->ExecMethod(StackBstr(class_name), | 130 HRESULT hr = wmi_local->ExecMethod(base::win::ScopedBstr(class_name), |
| 130 StackBstr(method_name), 0, NULL, | 131 base::win::ScopedBstr(method_name), |
| 131 process_create, out_params.Receive(), | 132 0, NULL, process_create, |
| 132 NULL); | 133 out_params.Receive(), NULL); |
| 133 if (FAILED(hr)) | 134 if (FAILED(hr)) |
| 134 return false; | 135 return false; |
| 135 | 136 |
| 136 VariantHelper ret_value; | 137 VariantHelper ret_value; |
| 137 hr = out_params->Get(L"ReturnValue", 0, &ret_value, NULL, 0); | 138 hr = out_params->Get(L"ReturnValue", 0, &ret_value, NULL, 0); |
| 138 if (FAILED(hr) || (0 != ret_value.uintVal)) | 139 if (FAILED(hr) || (0 != ret_value.uintVal)) |
| 139 return false; | 140 return false; |
| 140 | 141 |
| 141 VariantHelper pid; | 142 VariantHelper pid; |
| 142 hr = out_params->Get(L"ProcessId", 0, &pid, NULL, 0); | 143 hr = out_params->Get(L"ProcessId", 0, &pid, NULL, 0); |
| 143 if (FAILED(hr) || (0 == pid.intVal)) | 144 if (FAILED(hr) || (0 == pid.intVal)) |
| 144 return false; | 145 return false; |
| 145 | 146 |
| 146 if (process_id) | 147 if (process_id) |
| 147 *process_id = pid.intVal; | 148 *process_id = pid.intVal; |
| 148 | 149 |
| 149 return true; | 150 return true; |
| 150 } | 151 } |
| 151 | 152 |
| 152 } // namespace installer | 153 } // namespace installer |
| OLD | NEW |