| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // InstallerWrapper supports installing one app at a time. Installs from | |
| 17 // multiple instances are serialized by a mutex. | |
| 18 | |
| 19 #ifndef OMAHA_GOOPDATE_INSTALLER_WRAPPER_H_ | |
| 20 #define OMAHA_GOOPDATE_INSTALLER_WRAPPER_H_ | |
| 21 | |
| 22 #include <windows.h> | |
| 23 #include <atlstr.h> | |
| 24 #include <queue> | |
| 25 #include <utility> | |
| 26 #include "base/basictypes.h" | |
| 27 #include "base/scoped_ptr.h" | |
| 28 #include "omaha/base/synchronized.h" | |
| 29 #include "omaha/goopdate/installer_result_info.h" | |
| 30 | |
| 31 // TODO(omaha): consider removing this dependency on the model. | |
| 32 #include "omaha/goopdate/model.h" | |
| 33 | |
| 34 namespace omaha { | |
| 35 | |
| 36 class AppVersion; | |
| 37 class Process; | |
| 38 | |
| 39 | |
| 40 class InstallerWrapper { | |
| 41 public: | |
| 42 explicit InstallerWrapper(bool is_machine); | |
| 43 ~InstallerWrapper(); | |
| 44 HRESULT Initialize(); | |
| 45 | |
| 46 // Installs the specified app. | |
| 47 // This is a blocking call. All errors are reported through the return | |
| 48 // value. Depending on the return value, messages may be obtained as follows: | |
| 49 // * SUCCEEDED(hr): result_info may contain a custom success message. | |
| 50 // * GOOPDATEINSTALL_E_INSTALLER_FAILED: output parameters contain | |
| 51 // information and a message for the installer error. | |
| 52 // * Other error values: Callers may use GetMessageForError() to convert the | |
| 53 // error value to an error message. | |
| 54 HRESULT InstallApp(HANDLE user_token, | |
| 55 const GUID& app_guid, | |
| 56 const CString& installer_path, | |
| 57 const CString& arguments, | |
| 58 const CString& installer_data, | |
| 59 const CString& language, | |
| 60 InstallerResultInfo* result_info); | |
| 61 | |
| 62 // Validate that the installer wrote the client key and the product version. | |
| 63 HRESULT CheckApplicationRegistration(const GUID& app_guid, | |
| 64 const CString& registered_version, | |
| 65 const CString& expected_version, | |
| 66 const CString& previous_version, | |
| 67 bool is_update) const; | |
| 68 | |
| 69 // Obtains the localized text for Omaha errors that may occur during install. | |
| 70 static CString GetMessageForError(HRESULT error_code, | |
| 71 const CString& installer_filename, | |
| 72 const CString& language); | |
| 73 | |
| 74 void set_num_tries_when_msi_busy(int num_tries_when_msi_busy); | |
| 75 | |
| 76 private: | |
| 77 // Types of installers that Omaha supports. | |
| 78 enum InstallerType { | |
| 79 UNKNOWN_INSTALLER = 0, | |
| 80 CUSTOM_INSTALLER, | |
| 81 MSI_INSTALLER, | |
| 82 MAX_INSTALLER // Last Installer Type value. | |
| 83 }; | |
| 84 | |
| 85 // Determines the executable, command line, and installer type for | |
| 86 // the installation based on the filename. | |
| 87 static HRESULT BuildCommandLineFromFilename(const CString& filename, | |
| 88 const CString& arguments, | |
| 89 const CString& installer_data, | |
| 90 CString* executable_name, | |
| 91 CString* command_line, | |
| 92 InstallerType* installer_type); | |
| 93 | |
| 94 // Executes the installer and waits for it to complete. Retries if necessary. | |
| 95 HRESULT ExecuteAndWaitForInstaller(HANDLE user_token, | |
| 96 const GUID& app_guid, | |
| 97 const CString& executable_name, | |
| 98 const CString& command_line, | |
| 99 InstallerType installer_type, | |
| 100 const CString& language, | |
| 101 InstallerResultInfo* result_info); | |
| 102 | |
| 103 // Executes the installer for ExecuteAndWaitForInstaller. | |
| 104 HRESULT DoExecuteAndWaitForInstaller(HANDLE user_token, | |
| 105 const GUID& app_guid, | |
| 106 const CString& executable_name, | |
| 107 const CString& command_line, | |
| 108 InstallerType installer_type, | |
| 109 const CString& language, | |
| 110 InstallerResultInfo* result_info); | |
| 111 | |
| 112 // Determines whether the installer succeeded and returns completion info. | |
| 113 HRESULT GetInstallerResult(const GUID& app_guid, | |
| 114 InstallerType installer_type, | |
| 115 const Process& p, | |
| 116 const CString& language, | |
| 117 InstallerResultInfo* result_info); | |
| 118 | |
| 119 // Does most of the work for GetInstallerResult. | |
| 120 void GetInstallerResultHelper(const GUID& app_guid, | |
| 121 InstallerType installer_type, | |
| 122 uint32 exit_code, | |
| 123 const CString& language, | |
| 124 InstallerResultInfo* result_info); | |
| 125 | |
| 126 // Cleans up the registry from an installer that set custom result values. | |
| 127 void ClearInstallerResultApiValues(const CString& app_guid); | |
| 128 | |
| 129 // Installs the specified application and reports the results. | |
| 130 HRESULT DoInstallApp(HANDLE user_token, | |
| 131 const GUID& app_guid, | |
| 132 const CString& installer_path, | |
| 133 const CString& arguments, | |
| 134 const CString& installer_data, | |
| 135 const CString& language, | |
| 136 InstallerResultInfo* result_info); | |
| 137 | |
| 138 // Whether this object is running in a machine Goopdate instance. | |
| 139 const bool is_machine_; | |
| 140 | |
| 141 // The number of times to try installing an MSI when an MSI install is | |
| 142 // already running. There is an exponential backoff starting from | |
| 143 // kMsiAlreadyRunningRetryDelayBaseMs. | |
| 144 int num_tries_when_msi_busy_; | |
| 145 | |
| 146 // This is the base retry delay between retries when msiexec returns | |
| 147 // ERROR_INSTALL_ALREADY_RUNNING. We exponentially backoff from this value. | |
| 148 // Note that there is an additional delay for the MSI call, so the tries may | |
| 149 // be a few seconds further apart. | |
| 150 static const int kMsiAlreadyRunningRetryDelayBaseMs = 5000; | |
| 151 | |
| 152 // Interval to wait for installer completion. | |
| 153 static const int kInstallerCompleteIntervalMs = 15 * 60 * 1000; | |
| 154 | |
| 155 // Ensures that a single installer is run by us at a time. | |
| 156 // Not sure if we can run installers in different sessions without | |
| 157 // interference. In that case we can use a local lock instead of a | |
| 158 // global lock. | |
| 159 GLock installer_lock_; | |
| 160 | |
| 161 friend class InstallerWrapperTest; | |
| 162 | |
| 163 DISALLOW_COPY_AND_ASSIGN(InstallerWrapper); | |
| 164 }; | |
| 165 | |
| 166 } // namespace omaha | |
| 167 | |
| 168 #endif // OMAHA_GOOPDATE_INSTALLER_WRAPPER_H_ | |
| 169 | |
| OLD | NEW |