1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/common/win/install_utils.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <windows.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/file_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/file_version_info_win.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/path_service.h" 14bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/launch.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/win/registry.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace cloud_print { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Google Update related constants. 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kClientsKey[] = L"SOFTWARE\\Google\\Update\\Clients\\"; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kClientStateKey[] = L"SOFTWARE\\Google\\Update\\ClientState\\"; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t* kUsageKey = L"dr"; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kVersionKey[] = L"pv"; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kNameKey[] = L"name"; 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const DWORD kInstallerResultFailedCustomError = 1; 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kRegValueInstallerResult[] = L"InstallerResult"; 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kRegValueInstallerResultUIString[] = L"InstallerResultUIString"; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Uninstall related constants. 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kUninstallKey[] = 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kInstallLocation[] = L"InstallLocation"; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kUninstallString[] = L"UninstallString"; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kDisplayVersion[] = L"DisplayVersion"; 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kDisplayIcon[] = L"DisplayIcon"; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kDisplayName[] = L"DisplayName"; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kPublisher[] = L"Publisher"; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kNoModify[] = L"NoModify"; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const wchar_t kNoRepair[] = L"NoRepair"; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SetGoogleUpdateKeys(const base::string16& product_id, 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& product_name) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::win::RegKey key; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.Create(HKEY_LOCAL_MACHINE, 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kClientsKey + product_id).c_str(), 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KEY_SET_VALUE) != ERROR_SUCCESS) { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to open key"; 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the version from the resource file. 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 version_string; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<FileVersionInfo> version_info( 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (version_info.get()) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileVersionInfoWin* version_info_win = 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<FileVersionInfoWin*>(version_info.get()); 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) version_string = version_info_win->product_version(); 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to get version string"; 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use a random version string so that Google Update has something to go by. 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) version_string = L"0.0.0.99"; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.WriteValue(kVersionKey, version_string.c_str()) != ERROR_SUCCESS || 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kNameKey, product_name.c_str()) != ERROR_SUCCESS) { 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to set registry keys"; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SetGoogleUpdateError(const base::string16& product_id, 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& message) { 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << message; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::win::RegKey key; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.Create(HKEY_LOCAL_MACHINE, 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kClientStateKey + product_id).c_str(), 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KEY_SET_VALUE) != ERROR_SUCCESS) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to open key"; 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.WriteValue(kRegValueInstallerResult, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kInstallerResultFailedCustomError) != ERROR_SUCCESS || 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kRegValueInstallerResultUIString, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message.c_str()) != ERROR_SUCCESS) { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to set registry keys"; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DeleteGoogleUpdateKeys(const base::string16& product_id) { 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::win::RegKey key; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.Open(HKEY_LOCAL_MACHINE, 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kClientsKey + product_id).c_str(), 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DELETE) != ERROR_SUCCESS) { 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to open key to delete"; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.DeleteKey(L"") != ERROR_SUCCESS) { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to delete key"; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void CreateUninstallKey(const base::string16& uninstall_id, 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const base::string16& product_name, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& uninstall_switch) { 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Now write the Windows Uninstall entries 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Minimal error checking here since the install can continue 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // if this fails. 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::win::RegKey key; 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.Create(HKEY_LOCAL_MACHINE, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kUninstallKey + uninstall_id).c_str(), 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KEY_SET_VALUE) != ERROR_SUCCESS) { 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to open key"; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath unstall_binary; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK(PathService::Get(base::FILE_EXE, &unstall_binary)); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CommandLine uninstall_command(unstall_binary); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uninstall_command.AppendSwitch(uninstall_switch); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kUninstallString, 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uninstall_command.GetCommandLineString().c_str()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kInstallLocation, 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unstall_binary.DirName().value().c_str()); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the version resource. 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<FileVersionInfo> version_info( 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (version_info.get()) { 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileVersionInfoWin* version_info_win = 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<FileVersionInfoWin*>(version_info.get()); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kDisplayVersion, 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) version_info_win->file_version().c_str()); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kPublisher, version_info_win->company_name().c_str()); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to get version string"; 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kDisplayName, product_name.c_str()); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kDisplayIcon, unstall_binary.value().c_str()); 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kNoModify, 1); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.WriteValue(kNoRepair, 1); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DeleteUninstallKey(const base::string16& uninstall_id) { 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ::RegDeleteKey(HKEY_LOCAL_MACHINE, 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kUninstallKey + uninstall_id).c_str()); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::FilePath GetInstallLocation(const base::string16& uninstall_id) { 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::win::RegKey key; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (key.Open(HKEY_LOCAL_MACHINE, 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (cloud_print::kUninstallKey + uninstall_id).c_str(), 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KEY_QUERY_VALUE) != ERROR_SUCCESS) { 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Not installed. 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::FilePath(); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 install_path_value; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) key.ReadValue(kInstallLocation, &install_path_value); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base::FilePath(install_path_value); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DeleteProgramDir(const std::string& delete_switch) { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath installer_source; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!PathService::Get(base::FILE_EXE, &installer_source)) 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deletes only subdirs of program files. 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!IsProgramsFilesParent(installer_source)) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath temp_path; 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!base::CreateTemporaryFile(&temp_path)) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::CopyFile(installer_source, temp_path); 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFileAfterReboot(temp_path); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CommandLine command_line(temp_path); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) command_line.AppendSwitchPath(delete_switch, installer_source.DirName()); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::LaunchOptions options; 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ProcessHandle process_handle; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!base::LaunchProcess(command_line, options, &process_handle)) { 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Unable to launch child uninstall."; 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsProgramsFilesParent(const base::FilePath& path) { 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath program_files; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!PathService::Get(base::DIR_PROGRAM_FILESX86, &program_files)) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return program_files.IsParent(path); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace cloud_print 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 198