| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/google/google_update_app_command.h" |
| |
| #include "base/win/scoped_bstr.h" |
| #include "chrome/install_static/install_util.h" |
| |
| void ConfigureProxyBlanket(IUnknown* interface_pointer) { |
| ::CoSetProxyBlanket( |
| interface_pointer, RPC_C_AUTHN_DEFAULT, RPC_C_AUTHZ_DEFAULT, |
| COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, |
| RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DYNAMIC_CLOAKING); |
| } |
| |
| base::expected<Microsoft::WRL::ComPtr<IAppCommandWeb>, HRESULT> |
| GetUpdaterAppCommand(const std::wstring& command_name) { |
| Microsoft::WRL::ComPtr<IUnknown> server; |
| HRESULT hr = ::CoCreateInstance(CLSID_GoogleUpdate3WebSystemClass, nullptr, |
| CLSCTX_ALL, IID_PPV_ARGS(&server)); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| |
| ConfigureProxyBlanket(server.Get()); |
| |
| // Chrome queries for the SxS IIDs first, with a fallback to the legacy IID. |
| // Without this change, marshaling can load the typelib from the wrong hive |
| // (HKCU instead of HKLM, or vice-versa). |
| Microsoft::WRL::ComPtr<IGoogleUpdate3Web> google_update; |
| hr = server.CopyTo(__uuidof(IGoogleUpdate3WebSystem), |
| IID_PPV_ARGS_Helper(&google_update)); |
| if (FAILED(hr)) { |
| hr = server.As(&google_update); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| } |
| |
| Microsoft::WRL::ComPtr<IDispatch> dispatch; |
| hr = google_update->createAppBundleWeb(&dispatch); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| |
| // Chrome queries for the SxS IIDs first, with a fallback to the legacy IID. |
| // Without this change, marshaling can load the typelib from the wrong hive |
| // (HKCU instead of HKLM, or vice-versa). |
| Microsoft::WRL::ComPtr<IAppBundleWeb> app_bundle; |
| hr = dispatch.CopyTo(__uuidof(IAppBundleWebSystem), |
| IID_PPV_ARGS_Helper(&app_bundle)); |
| if (FAILED(hr)) { |
| hr = dispatch.As(&app_bundle); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| } |
| |
| dispatch.Reset(); |
| ConfigureProxyBlanket(app_bundle.Get()); |
| app_bundle->initialize(); |
| const wchar_t* app_guid = install_static::GetAppGuid(); |
| hr = app_bundle->createInstalledApp(base::win::ScopedBstr(app_guid).Get()); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| |
| hr = app_bundle->get_appWeb(0, &dispatch); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| |
| Microsoft::WRL::ComPtr<IAppWeb> app; |
| hr = dispatch.CopyTo(__uuidof(IAppWebSystem), IID_PPV_ARGS_Helper(&app)); |
| if (FAILED(hr)) { |
| hr = dispatch.As(&app); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| } |
| |
| dispatch.Reset(); |
| ConfigureProxyBlanket(app.Get()); |
| |
| hr = app->get_command(base::win::ScopedBstr(command_name).Get(), &dispatch); |
| if (FAILED(hr) || !dispatch) { |
| return base::unexpected(hr); |
| } |
| |
| Microsoft::WRL::ComPtr<IAppCommandWeb> app_command; |
| hr = dispatch.CopyTo(__uuidof(IAppCommandWebSystem), |
| IID_PPV_ARGS_Helper(&app_command)); |
| if (FAILED(hr)) { |
| hr = dispatch.As(&app_command); |
| if (FAILED(hr)) { |
| return base::unexpected(hr); |
| } |
| } |
| |
| ConfigureProxyBlanket(app_command.Get()); |
| return base::ok(app_command); |
| } |