| Left: | ||
| Right: |
| 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(), MB_OK); | |
|
Wladimir Palant
2013/08/01 09:58:24
Add MB_ICONEXCLAMATION flag?
Felix Dahlke
2013/08/02 10:48:01
Done.
| |
| 142 } | |
| 143 } | |
| 144 } | |
| OLD | NEW |