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 |