| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/verify_config_window_win.h" | 5 #include "remoting/host/verify_config_window_win.h" |
| 6 | 6 |
| 7 #include <atlbase.h> | 7 #include <atlbase.h> |
| 8 #include <atlwin.h> |
| 8 #include <windows.h> | 9 #include <windows.h> |
| 9 | 10 |
| 10 #include "base/base64.h" | 11 #include "base/base64.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 14 #include "remoting/host/elevated_controller_resource.h" | 15 #include "remoting/host/elevated_controller_resource.h" |
| 15 #include "remoting/host/pin_hash.h" | 16 #include "remoting/host/pin_hash.h" |
| 16 #include "remoting/protocol/authentication_method.h" | 17 #include "remoting/protocol/authentication_method.h" |
| 17 | 18 |
| 18 namespace remoting { | 19 namespace remoting { |
| 19 | 20 |
| 20 VerifyConfigWindowWin::VerifyConfigWindowWin(const std::string& email, | 21 VerifyConfigWindowWin::VerifyConfigWindowWin(const std::string& email, |
| 21 const std::string& host_id, const std::string& host_secret_hash) | 22 const std::string& host_id, const std::string& host_secret_hash) |
| 22 : hwnd_(NULL), | 23 : email_(email), |
| 23 email_(email), | |
| 24 host_id_(host_id), | 24 host_id_(host_id), |
| 25 host_secret_hash_(host_secret_hash) { | 25 host_secret_hash_(host_secret_hash) { |
| 26 } | 26 } |
| 27 | 27 |
| 28 VerifyConfigWindowWin::~VerifyConfigWindowWin() { | 28 void VerifyConfigWindowWin::OnCancel(UINT code, int id, HWND control) { |
| 29 EndDialog(); | 29 EndDialog(IDCANCEL); |
| 30 } | 30 } |
| 31 | 31 |
| 32 bool VerifyConfigWindowWin::Run() { | 32 void VerifyConfigWindowWin::OnClose() { |
| 33 // TODO(simonmorris): Provide a handle of a parent window for this dialog. | 33 EndDialog(IDCANCEL); |
| 34 return (DialogBoxParam(ATL::_AtlBaseModule.GetModuleInstance(), | |
| 35 MAKEINTRESOURCE(IDD_VERIFY_CONFIG_DIALOG), | |
| 36 NULL, | |
| 37 (DLGPROC)DialogProc, | |
| 38 (LPARAM)this) != 0); | |
| 39 } | 34 } |
| 40 | 35 |
| 41 BOOL CALLBACK VerifyConfigWindowWin::DialogProc(HWND hwnd, UINT msg, | 36 LRESULT VerifyConfigWindowWin::OnInitDialog(HWND wparam, LPARAM lparam) { |
| 42 WPARAM wParam, LPARAM lParam) { | 37 CenterWindow(); |
| 43 VerifyConfigWindowWin* win = NULL; | 38 |
| 44 if (msg == WM_INITDIALOG) { | 39 // TODO(simonmorris): l10n. |
| 45 win = reinterpret_cast<VerifyConfigWindowWin*>(lParam); | 40 SetWindowText(L"Chrome Remote Desktop"); |
| 46 CHECK(win); | 41 |
| 47 SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)win); | 42 CWindow email_label(GetDlgItem(IDC_EMAIL_LABEL)); |
| 48 } else { | 43 email_label.SetWindowText(L"Account:"); |
| 49 LONG_PTR lp = GetWindowLongPtr(hwnd, DWLP_USER); | 44 |
| 50 win = reinterpret_cast<VerifyConfigWindowWin*>(lp); | 45 CWindow pin_label(GetDlgItem(IDC_PIN_LABEL)); |
| 51 } | 46 pin_label.SetWindowText(L"PIN:"); |
| 52 if (win == NULL) | 47 |
| 53 return FALSE; | 48 CWindow ok_button(GetDlgItem(IDOK)); |
| 54 return win->OnDialogMessage(hwnd, msg, wParam, lParam); | 49 ok_button.SetWindowText(L"Confirm"); |
| 50 |
| 51 CWindow cancel_button(GetDlgItem(IDCANCEL)); |
| 52 cancel_button.SetWindowText(L"Cancel"); |
| 53 |
| 54 CWindow message_text(GetDlgItem(IDC_MESSAGE)); |
| 55 message_text.SetWindowText(L"Please confirm your account and PIN below to " |
| 56 L"allow access by Chrome Remote Desktop."); |
| 57 |
| 58 CWindow email_text(GetDlgItem(IDC_EMAIL)); |
| 59 email_text.SetWindowText(UTF8ToUTF16(email_).c_str()); |
| 60 return TRUE; |
| 55 } | 61 } |
| 56 | 62 |
| 57 BOOL VerifyConfigWindowWin::OnDialogMessage(HWND hwnd, UINT msg, | 63 void VerifyConfigWindowWin::OnOk(UINT code, int id, HWND control) { |
| 58 WPARAM wParam, LPARAM lParam) { | 64 if (VerifyHostSecretHash()) { |
| 59 switch (msg) { | 65 EndDialog(IDOK); |
| 60 case WM_INITDIALOG: | 66 } else { |
| 61 hwnd_ = hwnd; | 67 EndDialog(IDCANCEL); |
| 62 InitDialog(); | |
| 63 return TRUE; | |
| 64 case WM_DESTROY: | |
| 65 ::EndDialog(hwnd, 0); | |
| 66 case WM_COMMAND: | |
| 67 switch (LOWORD(wParam)) { | |
| 68 case IDOK: | |
| 69 ::EndDialog(hwnd, VerifyHostSecretHash()); | |
| 70 hwnd_ = NULL; | |
| 71 return TRUE; | |
| 72 case IDCANCEL: | |
| 73 ::EndDialog(hwnd, 0); | |
| 74 hwnd_ = NULL; | |
| 75 return TRUE; | |
| 76 } | |
| 77 } | |
| 78 return FALSE; | |
| 79 } | |
| 80 | |
| 81 void VerifyConfigWindowWin::InitDialog() { | |
| 82 // TODO(simonmorris): l10n. | |
| 83 SetWindowText(hwnd_, L"Chrome Remote Desktop"); | |
| 84 | |
| 85 HWND hwndOk = GetDlgItem(hwnd_, IDOK); | |
| 86 CHECK(hwndOk); | |
| 87 SetWindowText(hwndOk, L"OK"); | |
| 88 | |
| 89 HWND hwndCancel = GetDlgItem(hwnd_, IDCANCEL); | |
| 90 CHECK(hwndCancel); | |
| 91 SetWindowText(hwndCancel, L"Cancel"); | |
| 92 | |
| 93 HWND hwndMessage = GetDlgItem(hwnd_, IDC_MESSAGE); | |
| 94 CHECK(hwndMessage); | |
| 95 SetWindowText(hwndMessage, L"To confirm that your Chrome Remote Desktop " | |
| 96 L"should be accessible by this account, please enter your PIN below."); | |
| 97 | |
| 98 HWND hwndEmail = GetDlgItem(hwnd_, IDC_EMAIL); | |
| 99 CHECK(hwndEmail); | |
| 100 SetWindowText(hwndEmail, UTF8ToUTF16(email_).c_str()); | |
| 101 | |
| 102 HWND hwndPin = GetDlgItem(hwnd_, IDC_PIN); | |
| 103 CHECK(hwndPin); | |
| 104 SetFocus(hwndPin); | |
| 105 } | |
| 106 | |
| 107 void VerifyConfigWindowWin::EndDialog() { | |
| 108 if (hwnd_) { | |
| 109 ::EndDialog(hwnd_, 0); | |
| 110 hwnd_ = NULL; | |
| 111 } | 68 } |
| 112 } | 69 } |
| 113 | 70 |
| 71 void VerifyConfigWindowWin::CenterWindow() { |
| 72 // Get the window dimensions. |
| 73 RECT rect; |
| 74 if (!GetWindowRect(&rect)) { |
| 75 return; |
| 76 } |
| 77 |
| 78 // Center against the owner window unless it is minimized or invisible. |
| 79 HWND owner = ::GetWindow(m_hWnd, GW_OWNER); |
| 80 if (owner != NULL) { |
| 81 DWORD style = ::GetWindowLong(owner, GWL_STYLE); |
| 82 if ((style & WS_MINIMIZE) != 0 || (style & WS_VISIBLE) == 0) { |
| 83 owner = NULL; |
| 84 } |
| 85 } |
| 86 |
| 87 // Make sure that the window will not end up split by a monitor's boundary. |
| 88 RECT area_rect; |
| 89 if (!::SystemParametersInfo(SPI_GETWORKAREA, NULL, &area_rect, NULL)) { |
| 90 return; |
| 91 } |
| 92 |
| 93 // On a multi-monitor system use the monitor where the owner window is shown. |
| 94 RECT owner_rect = area_rect; |
| 95 if (owner != NULL && ::GetWindowRect(owner, &owner_rect)) { |
| 96 HMONITOR monitor = ::MonitorFromRect(&owner_rect, MONITOR_DEFAULTTONEAREST); |
| 97 if (monitor != NULL) { |
| 98 MONITORINFO monitor_info = {0}; |
| 99 monitor_info.cbSize = sizeof(monitor_info); |
| 100 if (::GetMonitorInfo(monitor, &monitor_info)) { |
| 101 area_rect = monitor_info.rcWork; |
| 102 } |
| 103 } |
| 104 } |
| 105 |
| 106 LONG width = rect.right - rect.left; |
| 107 LONG height = rect.bottom - rect.top; |
| 108 LONG x = (owner_rect.left + owner_rect.right - width) / 2; |
| 109 LONG y = (owner_rect.top + owner_rect.bottom - height) / 2; |
| 110 |
| 111 x = std::max(x, area_rect.left); |
| 112 x = std::min(x, area_rect.right - width); |
| 113 y = std::max(y, area_rect.top); |
| 114 y = std::min(y, area_rect.bottom - width); |
| 115 |
| 116 SetWindowPos(NULL, x, y, -1, -1, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); |
| 117 } |
| 118 |
| 114 bool VerifyConfigWindowWin::VerifyHostSecretHash() { | 119 bool VerifyConfigWindowWin::VerifyHostSecretHash() { |
| 115 const int kMaxPinLength = 256; | 120 CWindow pin_edit(GetDlgItem(IDC_PIN)); |
| 116 // TODO(simonmorris): Use ATL's string class, if it's more convenient. | 121 |
| 117 scoped_array<WCHAR> pinWSTR(new WCHAR[kMaxPinLength]); | 122 // Get the PIN length. |
| 118 HWND hwndPin = GetDlgItem(hwnd_, IDC_PIN); | 123 int pin_length = pin_edit.GetWindowTextLength(); |
| 119 CHECK(hwndPin); | 124 scoped_array<char16> pin(new char16[pin_length + 1]); |
| 120 GetWindowText(hwndPin, pinWSTR.get(), kMaxPinLength); | 125 |
| 121 std::string pin(UTF16ToUTF8(pinWSTR.get())); | 126 // Get the PIN making sure it is NULL terminated even if an error occurs. |
| 122 return VerifyHostPinHash(host_secret_hash_, host_id_, pin); | 127 int result = pin_edit.GetWindowText(pin.get(), pin_length + 1); |
| 128 pin[std::min(result, pin_length)] = 0; |
| 129 |
| 130 return VerifyHostPinHash(host_secret_hash_, host_id_, UTF16ToUTF8(pin.get())); |
| 123 } | 131 } |
| 124 | 132 |
| 125 } // namespace remoting | 133 } // namespace remoting |
| OLD | NEW |