Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #include <stdio.h> |
michael@0 | 8 | #include <windows.h> |
michael@0 | 9 | #include <commctrl.h> |
michael@0 | 10 | #include <process.h> |
michael@0 | 11 | #include <io.h> |
michael@0 | 12 | |
michael@0 | 13 | #include "resource.h" |
michael@0 | 14 | #include "progressui.h" |
michael@0 | 15 | #include "readstrings.h" |
michael@0 | 16 | #include "errors.h" |
michael@0 | 17 | |
michael@0 | 18 | #define TIMER_ID 1 |
michael@0 | 19 | #define TIMER_INTERVAL 100 |
michael@0 | 20 | |
michael@0 | 21 | #define RESIZE_WINDOW(hwnd, extrax, extray) \ |
michael@0 | 22 | { \ |
michael@0 | 23 | RECT windowSize; \ |
michael@0 | 24 | GetWindowRect(hwnd, &windowSize); \ |
michael@0 | 25 | SetWindowPos(hwnd, 0, 0, 0, windowSize.right - windowSize.left + extrax, \ |
michael@0 | 26 | windowSize.bottom - windowSize.top + extray, \ |
michael@0 | 27 | SWP_NOMOVE | SWP_NOZORDER); \ |
michael@0 | 28 | } |
michael@0 | 29 | |
michael@0 | 30 | #define MOVE_WINDOW(hwnd, dx, dy) \ |
michael@0 | 31 | { \ |
michael@0 | 32 | RECT rc; \ |
michael@0 | 33 | POINT pt; \ |
michael@0 | 34 | GetWindowRect(hwnd, &rc); \ |
michael@0 | 35 | pt.x = rc.left; \ |
michael@0 | 36 | pt.y = rc.top; \ |
michael@0 | 37 | ScreenToClient(GetParent(hwnd), &pt); \ |
michael@0 | 38 | SetWindowPos(hwnd, 0, pt.x + dx, pt.y + dy, 0, 0, \ |
michael@0 | 39 | SWP_NOSIZE | SWP_NOZORDER); \ |
michael@0 | 40 | } |
michael@0 | 41 | |
michael@0 | 42 | static float sProgress; // between 0 and 100 |
michael@0 | 43 | static BOOL sQuit = FALSE; |
michael@0 | 44 | static BOOL sIndeterminate = FALSE; |
michael@0 | 45 | static StringTable sUIStrings; |
michael@0 | 46 | |
michael@0 | 47 | static BOOL |
michael@0 | 48 | GetStringsFile(WCHAR filename[MAX_PATH]) |
michael@0 | 49 | { |
michael@0 | 50 | if (!GetModuleFileNameW(nullptr, filename, MAX_PATH)) |
michael@0 | 51 | return FALSE; |
michael@0 | 52 | |
michael@0 | 53 | WCHAR *dot = wcsrchr(filename, '.'); |
michael@0 | 54 | if (!dot || wcsicmp(dot + 1, L"exe")) |
michael@0 | 55 | return FALSE; |
michael@0 | 56 | |
michael@0 | 57 | wcscpy(dot + 1, L"ini"); |
michael@0 | 58 | return TRUE; |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | static void |
michael@0 | 62 | UpdateDialog(HWND hDlg) |
michael@0 | 63 | { |
michael@0 | 64 | int pos = int(sProgress + 0.5f); |
michael@0 | 65 | HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS); |
michael@0 | 66 | SendMessage(hWndPro, PBM_SETPOS, pos, 0L); |
michael@0 | 67 | } |
michael@0 | 68 | |
michael@0 | 69 | // The code in this function is from MSDN: |
michael@0 | 70 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/usingdialogboxes.asp |
michael@0 | 71 | static void |
michael@0 | 72 | CenterDialog(HWND hDlg) |
michael@0 | 73 | { |
michael@0 | 74 | RECT rc, rcOwner, rcDlg; |
michael@0 | 75 | |
michael@0 | 76 | // Get the owner window and dialog box rectangles. |
michael@0 | 77 | HWND desktop = GetDesktopWindow(); |
michael@0 | 78 | |
michael@0 | 79 | GetWindowRect(desktop, &rcOwner); |
michael@0 | 80 | GetWindowRect(hDlg, &rcDlg); |
michael@0 | 81 | CopyRect(&rc, &rcOwner); |
michael@0 | 82 | |
michael@0 | 83 | // Offset the owner and dialog box rectangles so that |
michael@0 | 84 | // right and bottom values represent the width and |
michael@0 | 85 | // height, and then offset the owner again to discard |
michael@0 | 86 | // space taken up by the dialog box. |
michael@0 | 87 | |
michael@0 | 88 | OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); |
michael@0 | 89 | OffsetRect(&rc, -rc.left, -rc.top); |
michael@0 | 90 | OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); |
michael@0 | 91 | |
michael@0 | 92 | // The new position is the sum of half the remaining |
michael@0 | 93 | // space and the owner's original position. |
michael@0 | 94 | |
michael@0 | 95 | SetWindowPos(hDlg, |
michael@0 | 96 | HWND_TOP, |
michael@0 | 97 | rcOwner.left + (rc.right / 2), |
michael@0 | 98 | rcOwner.top + (rc.bottom / 2), |
michael@0 | 99 | 0, 0, // ignores size arguments |
michael@0 | 100 | SWP_NOSIZE); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | static void |
michael@0 | 104 | InitDialog(HWND hDlg) |
michael@0 | 105 | { |
michael@0 | 106 | WCHAR szwTitle[MAX_TEXT_LEN]; |
michael@0 | 107 | WCHAR szwInfo[MAX_TEXT_LEN]; |
michael@0 | 108 | |
michael@0 | 109 | MultiByteToWideChar(CP_UTF8, 0, sUIStrings.title, -1, szwTitle, |
michael@0 | 110 | sizeof(szwTitle)/sizeof(szwTitle[0])); |
michael@0 | 111 | MultiByteToWideChar(CP_UTF8, 0, sUIStrings.info, -1, szwInfo, |
michael@0 | 112 | sizeof(szwInfo)/sizeof(szwInfo[0])); |
michael@0 | 113 | |
michael@0 | 114 | SetWindowTextW(hDlg, szwTitle); |
michael@0 | 115 | SetWindowTextW(GetDlgItem(hDlg, IDC_INFO), szwInfo); |
michael@0 | 116 | |
michael@0 | 117 | // Set dialog icon |
michael@0 | 118 | HICON hIcon = LoadIcon(GetModuleHandle(nullptr), |
michael@0 | 119 | MAKEINTRESOURCE(IDI_DIALOG)); |
michael@0 | 120 | if (hIcon) |
michael@0 | 121 | SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon); |
michael@0 | 122 | |
michael@0 | 123 | HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS); |
michael@0 | 124 | SendMessage(hWndPro, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); |
michael@0 | 125 | if (sIndeterminate) { |
michael@0 | 126 | LONG_PTR val = GetWindowLongPtr(hWndPro, GWL_STYLE); |
michael@0 | 127 | SetWindowLongPtr(hWndPro, GWL_STYLE, val|PBS_MARQUEE); |
michael@0 | 128 | SendMessage(hWndPro,(UINT) PBM_SETMARQUEE,(WPARAM) TRUE,(LPARAM)50 ); |
michael@0 | 129 | } |
michael@0 | 130 | |
michael@0 | 131 | // Resize the dialog to fit all of the text if necessary. |
michael@0 | 132 | RECT infoSize, textSize; |
michael@0 | 133 | HWND hWndInfo = GetDlgItem(hDlg, IDC_INFO); |
michael@0 | 134 | |
michael@0 | 135 | // Get the control's font for calculating the new size for the control |
michael@0 | 136 | HDC hDCInfo = GetDC(hWndInfo); |
michael@0 | 137 | HFONT hInfoFont, hOldFont; |
michael@0 | 138 | hInfoFont = (HFONT)SendMessage(hWndInfo, WM_GETFONT, 0, 0); |
michael@0 | 139 | |
michael@0 | 140 | if (hInfoFont) |
michael@0 | 141 | hOldFont = (HFONT)SelectObject(hDCInfo, hInfoFont); |
michael@0 | 142 | |
michael@0 | 143 | // Measure the space needed for the text on a single line. DT_CALCRECT means |
michael@0 | 144 | // nothing is drawn. |
michael@0 | 145 | if (DrawText(hDCInfo, szwInfo, -1, &textSize, |
michael@0 | 146 | DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE)) { |
michael@0 | 147 | GetClientRect(hWndInfo, &infoSize); |
michael@0 | 148 | SIZE extra; |
michael@0 | 149 | // Calculate the additional space needed for the text by subtracting from |
michael@0 | 150 | // the rectangle returned by DrawText the existing client rectangle's width |
michael@0 | 151 | // and height. |
michael@0 | 152 | extra.cx = (textSize.right - textSize.left) - \ |
michael@0 | 153 | (infoSize.right - infoSize.left); |
michael@0 | 154 | extra.cy = (textSize.bottom - textSize.top) - \ |
michael@0 | 155 | (infoSize.bottom - infoSize.top); |
michael@0 | 156 | if (extra.cx < 0) |
michael@0 | 157 | extra.cx = 0; |
michael@0 | 158 | if (extra.cy < 0) |
michael@0 | 159 | extra.cy = 0; |
michael@0 | 160 | if ((extra.cx > 0) || (extra.cy > 0)) { |
michael@0 | 161 | RESIZE_WINDOW(hDlg, extra.cx, extra.cy); |
michael@0 | 162 | RESIZE_WINDOW(hWndInfo, extra.cx, extra.cy); |
michael@0 | 163 | RESIZE_WINDOW(hWndPro, extra.cx, 0); |
michael@0 | 164 | MOVE_WINDOW(hWndPro, 0, extra.cy); |
michael@0 | 165 | } |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | if (hOldFont) |
michael@0 | 169 | SelectObject(hDCInfo, hOldFont); |
michael@0 | 170 | |
michael@0 | 171 | ReleaseDC(hWndInfo, hDCInfo); |
michael@0 | 172 | |
michael@0 | 173 | CenterDialog(hDlg); // make dialog appear in the center of the screen |
michael@0 | 174 | |
michael@0 | 175 | SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, nullptr); |
michael@0 | 176 | } |
michael@0 | 177 | |
michael@0 | 178 | // Message handler for update dialog. |
michael@0 | 179 | static LRESULT CALLBACK |
michael@0 | 180 | DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) |
michael@0 | 181 | { |
michael@0 | 182 | switch (message) |
michael@0 | 183 | { |
michael@0 | 184 | case WM_INITDIALOG: |
michael@0 | 185 | InitDialog(hDlg); |
michael@0 | 186 | return TRUE; |
michael@0 | 187 | |
michael@0 | 188 | case WM_TIMER: |
michael@0 | 189 | if (sQuit) { |
michael@0 | 190 | EndDialog(hDlg, 0); |
michael@0 | 191 | } else { |
michael@0 | 192 | UpdateDialog(hDlg); |
michael@0 | 193 | } |
michael@0 | 194 | return TRUE; |
michael@0 | 195 | |
michael@0 | 196 | case WM_COMMAND: |
michael@0 | 197 | return TRUE; |
michael@0 | 198 | } |
michael@0 | 199 | return FALSE; |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | int |
michael@0 | 203 | InitProgressUI(int *argc, NS_tchar ***argv) |
michael@0 | 204 | { |
michael@0 | 205 | return 0; |
michael@0 | 206 | } |
michael@0 | 207 | |
michael@0 | 208 | /** |
michael@0 | 209 | * Initializes the progress UI strings |
michael@0 | 210 | * |
michael@0 | 211 | * @return 0 on success, -1 on error |
michael@0 | 212 | */ |
michael@0 | 213 | int |
michael@0 | 214 | InitProgressUIStrings() { |
michael@0 | 215 | // If we do not have updater.ini, then we should not bother showing UI. |
michael@0 | 216 | WCHAR filename[MAX_PATH]; |
michael@0 | 217 | if (!GetStringsFile(filename)) { |
michael@0 | 218 | return -1; |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | if (_waccess(filename, 04)) { |
michael@0 | 222 | return -1; |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | // If the updater.ini doesn't have the required strings, then we should not |
michael@0 | 226 | // bother showing UI. |
michael@0 | 227 | if (ReadStrings(filename, &sUIStrings) != OK) { |
michael@0 | 228 | return -1; |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | return 0; |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | int |
michael@0 | 235 | ShowProgressUI(bool indeterminate, bool initUIStrings) |
michael@0 | 236 | { |
michael@0 | 237 | sIndeterminate = indeterminate; |
michael@0 | 238 | if (!indeterminate) { |
michael@0 | 239 | // Only show the Progress UI if the process is taking a significant amount of |
michael@0 | 240 | // time where a significant amount of time is defined as .5 seconds after |
michael@0 | 241 | // ShowProgressUI is called sProgress is less than 70. |
michael@0 | 242 | Sleep(500); |
michael@0 | 243 | |
michael@0 | 244 | if (sQuit || sProgress > 70.0f) |
michael@0 | 245 | return 0; |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | if (initUIStrings && InitProgressUIStrings() == -1) { |
michael@0 | 249 | return -1; |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | INITCOMMONCONTROLSEX icc = { |
michael@0 | 253 | sizeof(INITCOMMONCONTROLSEX), |
michael@0 | 254 | ICC_PROGRESS_CLASS |
michael@0 | 255 | }; |
michael@0 | 256 | InitCommonControlsEx(&icc); |
michael@0 | 257 | |
michael@0 | 258 | DialogBox(GetModuleHandle(nullptr), |
michael@0 | 259 | MAKEINTRESOURCE(IDD_DIALOG), nullptr, |
michael@0 | 260 | (DLGPROC) DialogProc); |
michael@0 | 261 | |
michael@0 | 262 | return 0; |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | void |
michael@0 | 266 | QuitProgressUI() |
michael@0 | 267 | { |
michael@0 | 268 | sQuit = TRUE; |
michael@0 | 269 | } |
michael@0 | 270 | |
michael@0 | 271 | void |
michael@0 | 272 | UpdateProgressUI(float progress) |
michael@0 | 273 | { |
michael@0 | 274 | sProgress = progress; // 32-bit writes are atomic |
michael@0 | 275 | } |