OLD | NEW |
1 #include <functional> | 1 #include <functional> |
2 #include <memory> | 2 #include <memory> |
3 #include <sstream> | 3 #include <sstream> |
4 | 4 |
5 #include <Windows.h> | 5 #include <Windows.h> |
6 | 6 |
7 #include <AdblockPlus/FileSystem.h> | 7 #include <AdblockPlus/FileSystem.h> |
8 #include <AdblockPlus/WebRequest.h> | 8 #include <AdblockPlus/WebRequest.h> |
9 | 9 |
10 #include "../shared/AutoHandle.h" | 10 #include "../shared/AutoHandle.h" |
11 #include "../shared/Dictionary.h" | 11 #include "../shared/Dictionary.h" |
12 #include "../shared/Utils.h" | 12 #include "../shared/Utils.h" |
13 #include "Debug.h" | 13 #include "Debug.h" |
14 #include "Resource.h" | 14 #include "Resource.h" |
| 15 #include "UpdateInstallDialog.h" |
15 #include "Updater.h" | 16 #include "Updater.h" |
16 | 17 |
17 namespace | 18 namespace |
18 { | 19 { |
19 typedef std::function<void()> ThreadCallbackType; | 20 typedef std::function<void()> ThreadCallbackType; |
20 typedef std::function<void(HWND)> DialogCallbackType; | |
21 | 21 |
22 const int DOWNLOAD_FAILED = 101; | 22 const int DOWNLOAD_FAILED = 101; |
23 | 23 |
24 LRESULT CALLBACK UpdateDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
am) | |
25 { | |
26 switch (msg) | |
27 { | |
28 case WM_INITDIALOG: | |
29 { | |
30 Dictionary* dict = Dictionary::GetInstance(); | |
31 SetWindowTextW(hWnd, dict->Lookup("updater", "update-title").c_str()); | |
32 SetDlgItemTextW(hWnd, IDC_UPDATETEXT, dict->Lookup("updater", "update-te
xt").c_str()); | |
33 SetDlgItemTextW(hWnd, IDC_DOYOU, dict->Lookup("updater", "update-questio
n").c_str()); | |
34 SetDlgItemTextW(hWnd, IDOK, dict->Lookup("general", "button-yes").c_str(
)); | |
35 SetDlgItemTextW(hWnd, IDCANCEL, dict->Lookup("general", "button-no").c_s
tr()); | |
36 return TRUE; | |
37 } | |
38 case WM_COMMAND: | |
39 { | |
40 if (wParam == IDOK || wParam == IDCANCEL) | |
41 { | |
42 EndDialog(hWnd, wParam); | |
43 return TRUE; | |
44 } | |
45 break; | |
46 } | |
47 } | |
48 | |
49 return FALSE; | |
50 } | |
51 | |
52 LRESULT CALLBACK DownloadDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
aram) | |
53 { | |
54 // TODO: Indicate progress | |
55 | |
56 switch (msg) | |
57 { | |
58 case WM_INITDIALOG: | |
59 { | |
60 Dictionary* dict = Dictionary::GetInstance(); | |
61 SetWindowTextW(hWnd, dict->Lookup("updater", "download-title").c_str()); | |
62 SetDlgItemTextW(hWnd, IDC_INSTALLMSG, dict->Lookup("updater", "download-
progress-text").c_str()); | |
63 SetDlgItemTextW(hWnd, IDCANCEL, dict->Lookup("general", "button-cancel")
.c_str()); | |
64 | |
65 std::auto_ptr<DialogCallbackType> callback(reinterpret_cast<DialogCallba
ckType*>(lParam)); | |
66 (*callback)(hWnd); | |
67 return TRUE; | |
68 } | |
69 case WM_COMMAND: | |
70 { | |
71 if (wParam == IDCANCEL) | |
72 { | |
73 EndDialog(hWnd, wParam); | |
74 return TRUE; | |
75 } | |
76 break; | |
77 } | |
78 } | |
79 return FALSE; | |
80 } | |
81 | |
82 DWORD RunThread(LPVOID param) | 24 DWORD RunThread(LPVOID param) |
83 { | 25 { |
84 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy
pe*>(param)); | 26 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy
pe*>(param)); |
85 (*callback)(); | 27 (*callback)(); |
86 return 0; | 28 return 0; |
87 } | 29 } |
88 | 30 |
89 std::wstring EscapeCommandLineArg(const std::wstring& arg) | 31 std::wstring EscapeCommandLineArg(const std::wstring& arg) |
90 { | 32 { |
91 // This does the inverse of CommandLineToArgvW(). See | 33 // This does the inverse of CommandLineToArgvW(). See |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 } | 76 } |
135 } | 77 } |
136 | 78 |
137 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url) | 79 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url) |
138 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.msi") | 80 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.msi") |
139 { | 81 { |
140 } | 82 } |
141 | 83 |
142 void Updater::Update() | 84 void Updater::Update() |
143 { | 85 { |
144 Debug("Update available: " + url); | 86 Debug("Downloading update: " + url); |
145 | 87 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::Down
load, this)); |
146 if (DialogBox(NULL, MAKEINTRESOURCE(IDD_UPDATEDIALOG), GetDesktopWindow(), | 88 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread),
callback, 0, NULL); |
147 reinterpret_cast<DLGPROC>(&UpdateDlgProc)) == IDOK) | |
148 { | |
149 Debug("User accepted update"); | |
150 | |
151 DialogCallbackType* callback = new DialogCallbackType(std::bind(&Updater::St
artDownload, | |
152 this, std::placeholders::_1)); | |
153 int result = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DOWNLOADDIALOG), GetDe
sktopWindow(), | |
154 reinterpret_cast<DLGPROC>(&DownloadDlgProc), | |
155 reinterpret_cast<LPARAM>(callback)); | |
156 if (result == DOWNLOAD_FAILED) | |
157 { | |
158 Dictionary* dict = Dictionary::GetInstance(); | |
159 MessageBoxW(NULL, | |
160 dict->Lookup("updater", "download-error-neterror").c_str(), | |
161 dict->Lookup("updater", "download-error-title").c_str(), | |
162 0); | |
163 } | |
164 if (result != IDOK) | |
165 return; | |
166 | |
167 if (!InstallUpdate(tempFile)) | |
168 { | |
169 DebugLastError("Running updater failed"); | |
170 | |
171 Dictionary* dict = Dictionary::GetInstance(); | |
172 MessageBoxW(NULL, | |
173 dict->Lookup("updater", "download-error-runerror").c_str(), | |
174 dict->Lookup("updater", "download-error-title").c_str(), | |
175 0); | |
176 } | |
177 } | |
178 } | 89 } |
179 | 90 |
180 void Updater::StartDownload(HWND dialog) | 91 void Updater::Download() |
181 { | |
182 this->dialog = dialog; | |
183 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::RunD
ownload, this)); | |
184 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread), | |
185 callback, 0, NULL); | |
186 } | |
187 | |
188 void Updater::RunDownload() | |
189 { | 92 { |
190 AdblockPlus::ServerResponse response = jsEngine->GetWebRequest()->GET(url, Adb
lockPlus::HeaderList()); | 93 AdblockPlus::ServerResponse response = jsEngine->GetWebRequest()->GET(url, Adb
lockPlus::HeaderList()); |
191 if (response.status != AdblockPlus::WebRequest::NS_OK || | 94 if (response.status != AdblockPlus::WebRequest::NS_OK || |
192 response.responseStatus != 200) | 95 response.responseStatus != 200) |
193 { | 96 { |
194 std::stringstream ss; | 97 std::stringstream ss; |
195 ss << "Update download failed (status: " << response.status << ", "; | 98 ss << "Update download failed (status: " << response.status << ", "; |
196 ss << "response: " << response.responseStatus << ")"; | 99 ss << "response: " << response.responseStatus << ")"; |
197 Debug(ss.str()); | 100 Debug(ss.str()); |
198 | |
199 EndDialog(dialog, DOWNLOAD_FAILED); | |
200 return; | 101 return; |
201 } | 102 } |
202 | 103 |
203 AdblockPlus::FileSystemPtr fileSystem = jsEngine->GetFileSystem(); | 104 AdblockPlus::FileSystemPtr fileSystem = jsEngine->GetFileSystem(); |
204 std::string utfTempFile = ToUtf8String(tempFile); | 105 std::string utfTempFile = ToUtf8String(tempFile); |
205 try | 106 try |
206 { | 107 { |
207 // Remove left-overs from previous update attempts | 108 // Remove left-overs from previous update attempts |
208 fileSystem->Remove(utfTempFile); | 109 fileSystem->Remove(utfTempFile); |
209 } | 110 } |
210 catch (const std::exception&) | 111 catch (const std::exception&) |
211 { | 112 { |
212 } | 113 } |
213 | 114 |
214 try | 115 try |
215 { | 116 { |
216 std::tr1::shared_ptr<std::istream> fileData(new std::istringstream(response.
responseText)); | 117 std::tr1::shared_ptr<std::istream> fileData(new std::istringstream(response.
responseText)); |
217 fileSystem->Write(utfTempFile, fileData); | 118 fileSystem->Write(utfTempFile, fileData); |
218 } | 119 } |
219 catch (const std::exception& e) | 120 catch (const std::exception& e) |
220 { | 121 { |
221 DebugException(e); | 122 DebugException(e); |
222 EndDialog(dialog, DOWNLOAD_FAILED); | |
223 return; | 123 return; |
224 } | 124 } |
225 | 125 |
226 EndDialog(dialog, IDOK); | 126 OnDownloadSuccess(); |
227 } | 127 } |
| 128 |
| 129 void Updater::OnDownloadSuccess() |
| 130 { |
| 131 UpdateInstallDialog dialog; |
| 132 bool shouldInstall = dialog.Show(); |
| 133 if (shouldInstall) |
| 134 { |
| 135 if (!InstallUpdate(tempFile)) |
| 136 { |
| 137 DebugLastError("Failed to install update"); |
| 138 Dictionary* dictionary = Dictionary::GetInstance(); |
| 139 MessageBoxW( |
| 140 0, dictionary->Lookup("updater", "install-error-text").c_str(), |
| 141 dictionary->Lookup("updater", "install-error-title").c_str(), |
| 142 MB_OK | MB_ICONEXCLAMATION); |
| 143 } |
| 144 } |
| 145 } |
OLD | NEW |