| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/win/rdp_client_window.h" | 5 #include "remoting/host/win/rdp_client_window.h" |
| 6 | 6 |
| 7 #include <wtsdefs.h> | 7 #include <wtsdefs.h> |
| 8 | 8 |
| 9 #include <list> | 9 #include <list> |
| 10 | 10 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 base::win::ScopedComPtr<mstsc::IMsTscSecuredSettings> secured_settings; | 240 base::win::ScopedComPtr<mstsc::IMsTscSecuredSettings> secured_settings; |
| 241 base::win::ScopedComPtr<mstsc::IMsRdpClientSecuredSettings> secured_settings2; | 241 base::win::ScopedComPtr<mstsc::IMsRdpClientSecuredSettings> secured_settings2; |
| 242 base::win::ScopedBstr server_name( | 242 base::win::ScopedBstr server_name( |
| 243 base::UTF8ToUTF16(server_endpoint_.ToStringWithoutPort()).c_str()); | 243 base::UTF8ToUTF16(server_endpoint_.ToStringWithoutPort()).c_str()); |
| 244 base::win::ScopedBstr terminal_id(base::UTF8ToUTF16(terminal_id_).c_str()); | 244 base::win::ScopedBstr terminal_id(base::UTF8ToUTF16(terminal_id_).c_str()); |
| 245 | 245 |
| 246 // Create the child window that actually hosts the ActiveX control. | 246 // Create the child window that actually hosts the ActiveX control. |
| 247 RECT rect = { 0, 0, screen_size_.width(), screen_size_.height() }; | 247 RECT rect = { 0, 0, screen_size_.width(), screen_size_.height() }; |
| 248 activex_window.Create(m_hWnd, rect, nullptr, | 248 activex_window.Create(m_hWnd, rect, nullptr, |
| 249 WS_CHILD | WS_VISIBLE | WS_BORDER); | 249 WS_CHILD | WS_VISIBLE | WS_BORDER); |
| 250 if (activex_window.m_hWnd == nullptr) { | 250 if (activex_window.m_hWnd == nullptr) |
| 251 result = HRESULT_FROM_WIN32(GetLastError()); | 251 return LogOnCreateError(HRESULT_FROM_WIN32(GetLastError())); |
| 252 goto done; | |
| 253 } | |
| 254 | 252 |
| 255 // Instantiate the RDP ActiveX control. | 253 // Instantiate the RDP ActiveX control. |
| 256 result = activex_window.CreateControlEx( | 254 result = activex_window.CreateControlEx( |
| 257 OLESTR("MsTscAx.MsTscAx"), | 255 OLESTR("MsTscAx.MsTscAx"), |
| 258 nullptr, | 256 nullptr, |
| 259 nullptr, | 257 nullptr, |
| 260 control.Receive(), | 258 control.Receive(), |
| 261 __uuidof(mstsc::IMsTscAxEvents), | 259 __uuidof(mstsc::IMsTscAxEvents), |
| 262 reinterpret_cast<IUnknown*>(static_cast<RdpEventsSink*>(this))); | 260 reinterpret_cast<IUnknown*>(static_cast<RdpEventsSink*>(this))); |
| 263 if (FAILED(result)) | 261 if (FAILED(result)) |
| 264 goto done; | 262 return LogOnCreateError(result); |
| 265 | 263 |
| 266 result = control.QueryInterface(client_.Receive()); | 264 result = control.QueryInterface(client_.Receive()); |
| 267 if (FAILED(result)) | 265 if (FAILED(result)) |
| 268 goto done; | 266 return LogOnCreateError(result); |
| 269 | 267 |
| 270 // Use 32-bit color. | 268 // Use 32-bit color. |
| 271 result = client_->put_ColorDepth(32); | 269 result = client_->put_ColorDepth(32); |
| 272 if (FAILED(result)) | 270 if (FAILED(result)) |
| 273 goto done; | 271 return LogOnCreateError(result); |
| 274 | 272 |
| 275 // Set dimensions of the remote desktop. | 273 // Set dimensions of the remote desktop. |
| 276 result = client_->put_DesktopWidth(screen_size_.width()); | 274 result = client_->put_DesktopWidth(screen_size_.width()); |
| 277 if (FAILED(result)) | 275 if (FAILED(result)) |
| 278 goto done; | 276 return LogOnCreateError(result); |
| 279 result = client_->put_DesktopHeight(screen_size_.height()); | 277 result = client_->put_DesktopHeight(screen_size_.height()); |
| 280 if (FAILED(result)) | 278 if (FAILED(result)) |
| 281 goto done; | 279 return LogOnCreateError(result); |
| 282 | 280 |
| 283 // Set the server name to connect to. | 281 // Set the server name to connect to. |
| 284 result = client_->put_Server(server_name); | 282 result = client_->put_Server(server_name); |
| 285 if (FAILED(result)) | 283 if (FAILED(result)) |
| 286 goto done; | 284 return LogOnCreateError(result); |
| 287 | 285 |
| 288 // Fetch IMsRdpClientAdvancedSettings interface for the client. | 286 // Fetch IMsRdpClientAdvancedSettings interface for the client. |
| 289 result = client_->get_AdvancedSettings2(client_settings_.Receive()); | 287 result = client_->get_AdvancedSettings2(client_settings_.Receive()); |
| 290 if (FAILED(result)) | 288 if (FAILED(result)) |
| 291 goto done; | 289 return LogOnCreateError(result); |
| 292 | 290 |
| 293 // Disable background input mode. | 291 // Disable background input mode. |
| 294 result = client_settings_->put_allowBackgroundInput(0); | 292 result = client_settings_->put_allowBackgroundInput(0); |
| 295 if (FAILED(result)) | 293 if (FAILED(result)) |
| 296 goto done; | 294 return LogOnCreateError(result); |
| 297 | 295 |
| 298 // Do not use bitmap cache. | 296 // Do not use bitmap cache. |
| 299 result = client_settings_->put_BitmapPersistence(0); | 297 result = client_settings_->put_BitmapPersistence(0); |
| 300 if (SUCCEEDED(result)) | 298 if (SUCCEEDED(result)) |
| 301 result = client_settings_->put_CachePersistenceActive(0); | 299 result = client_settings_->put_CachePersistenceActive(0); |
| 302 if (FAILED(result)) | 300 if (FAILED(result)) |
| 303 goto done; | 301 return LogOnCreateError(result); |
| 304 | 302 |
| 305 // Do not use compression. | 303 // Do not use compression. |
| 306 result = client_settings_->put_Compress(0); | 304 result = client_settings_->put_Compress(0); |
| 307 if (FAILED(result)) | 305 if (FAILED(result)) |
| 308 goto done; | 306 return LogOnCreateError(result); |
| 309 | 307 |
| 310 // Enable the Ctrl+Alt+Del screen. | 308 // Enable the Ctrl+Alt+Del screen. |
| 311 result = client_settings_->put_DisableCtrlAltDel(0); | 309 result = client_settings_->put_DisableCtrlAltDel(0); |
| 312 if (FAILED(result)) | 310 if (FAILED(result)) |
| 313 goto done; | 311 return LogOnCreateError(result); |
| 314 | 312 |
| 315 // Disable printer and clipboard redirection. | 313 // Disable printer and clipboard redirection. |
| 316 result = client_settings_->put_DisableRdpdr(FALSE); | 314 result = client_settings_->put_DisableRdpdr(FALSE); |
| 317 if (FAILED(result)) | 315 if (FAILED(result)) |
| 318 goto done; | 316 return LogOnCreateError(result); |
| 319 | 317 |
| 320 // Do not display the connection bar. | 318 // Do not display the connection bar. |
| 321 result = client_settings_->put_DisplayConnectionBar(VARIANT_FALSE); | 319 result = client_settings_->put_DisplayConnectionBar(VARIANT_FALSE); |
| 322 if (FAILED(result)) | 320 if (FAILED(result)) |
| 323 goto done; | 321 return LogOnCreateError(result); |
| 324 | 322 |
| 325 // Do not grab focus on connect. | 323 // Do not grab focus on connect. |
| 326 result = client_settings_->put_GrabFocusOnConnect(VARIANT_FALSE); | 324 result = client_settings_->put_GrabFocusOnConnect(VARIANT_FALSE); |
| 327 if (FAILED(result)) | 325 if (FAILED(result)) |
| 328 goto done; | 326 return LogOnCreateError(result); |
| 329 | 327 |
| 330 // Enable enhanced graphics, font smoothing and desktop composition. | 328 // Enable enhanced graphics, font smoothing and desktop composition. |
| 331 const LONG kDesiredFlags = WTS_PERF_ENABLE_ENHANCED_GRAPHICS | | 329 const LONG kDesiredFlags = WTS_PERF_ENABLE_ENHANCED_GRAPHICS | |
| 332 WTS_PERF_ENABLE_FONT_SMOOTHING | | 330 WTS_PERF_ENABLE_FONT_SMOOTHING | |
| 333 WTS_PERF_ENABLE_DESKTOP_COMPOSITION; | 331 WTS_PERF_ENABLE_DESKTOP_COMPOSITION; |
| 334 result = client_settings_->put_PerformanceFlags(kDesiredFlags); | 332 result = client_settings_->put_PerformanceFlags(kDesiredFlags); |
| 335 if (FAILED(result)) | 333 if (FAILED(result)) |
| 336 goto done; | 334 return LogOnCreateError(result); |
| 337 | 335 |
| 338 // Set the port to connect to. | 336 // Set the port to connect to. |
| 339 result = client_settings_->put_RDPPort(server_endpoint_.port()); | 337 result = client_settings_->put_RDPPort(server_endpoint_.port()); |
| 340 if (FAILED(result)) | 338 if (FAILED(result)) |
| 341 goto done; | 339 return LogOnCreateError(result); |
| 342 | 340 |
| 343 // Disable audio in the session. | 341 // Disable audio in the session. |
| 344 // TODO(alexeypa): re-enable audio redirection when http://crbug.com/242312 is | 342 // TODO(alexeypa): re-enable audio redirection when http://crbug.com/242312 is |
| 345 // fixed. | 343 // fixed. |
| 346 result = client_->get_SecuredSettings2(secured_settings2.Receive()); | 344 result = client_->get_SecuredSettings2(secured_settings2.Receive()); |
| 347 if (SUCCEEDED(result)) { | 345 if (SUCCEEDED(result)) { |
| 348 result = secured_settings2->put_AudioRedirectionMode(kRdpAudioModeNone); | 346 result = secured_settings2->put_AudioRedirectionMode(kRdpAudioModeNone); |
| 349 if (FAILED(result)) | 347 if (FAILED(result)) |
| 350 goto done; | 348 return LogOnCreateError(result); |
| 351 } | 349 } |
| 352 | 350 |
| 353 result = client_->get_SecuredSettings(secured_settings.Receive()); | 351 result = client_->get_SecuredSettings(secured_settings.Receive()); |
| 354 if (FAILED(result)) | 352 if (FAILED(result)) |
| 355 goto done; | 353 return LogOnCreateError(result); |
| 356 | 354 |
| 357 // Set the terminal ID as the working directory for the initial program. It is | 355 // Set the terminal ID as the working directory for the initial program. It is |
| 358 // observed that |WorkDir| is used only if an initial program is also | 356 // observed that |WorkDir| is used only if an initial program is also |
| 359 // specified, but is still passed to the RDP server and can then be read back | 357 // specified, but is still passed to the RDP server and can then be read back |
| 360 // from the session parameters. This makes it possible to use |WorkDir| to | 358 // from the session parameters. This makes it possible to use |WorkDir| to |
| 361 // match the RDP connection with the session it is attached to. | 359 // match the RDP connection with the session it is attached to. |
| 362 // | 360 // |
| 363 // This code should be in sync with WtsTerminalMonitor::LookupTerminalId(). | 361 // This code should be in sync with WtsTerminalMonitor::LookupTerminalId(). |
| 364 result = secured_settings->put_WorkDir(terminal_id); | 362 result = secured_settings->put_WorkDir(terminal_id); |
| 365 if (FAILED(result)) | 363 if (FAILED(result)) |
| 366 goto done; | 364 return LogOnCreateError(result); |
| 367 | 365 |
| 368 result = client_->Connect(); | 366 result = client_->Connect(); |
| 369 if (FAILED(result)) | 367 if (FAILED(result)) |
| 370 goto done; | 368 return LogOnCreateError(result); |
| 371 | |
| 372 done: | |
| 373 if (FAILED(result)) { | |
| 374 LOG(ERROR) << "RDP: failed to initiate a connection to " | |
| 375 << server_endpoint_.ToString() << ": error=" | |
| 376 << std::hex << result << std::dec; | |
| 377 client_.Release(); | |
| 378 client_settings_.Release(); | |
| 379 return -1; | |
| 380 } | |
| 381 | 369 |
| 382 return 0; | 370 return 0; |
| 383 } | 371 } |
| 384 | 372 |
| 385 void RdpClientWindow::OnDestroy() { | 373 void RdpClientWindow::OnDestroy() { |
| 386 client_.Release(); | 374 client_.Release(); |
| 387 client_settings_.Release(); | 375 client_settings_.Release(); |
| 388 } | 376 } |
| 389 | 377 |
| 390 HRESULT RdpClientWindow::OnAuthenticationWarningDisplayed() { | 378 HRESULT RdpClientWindow::OnAuthenticationWarningDisplayed() { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 return S_OK; | 443 return S_OK; |
| 456 } | 444 } |
| 457 | 445 |
| 458 HRESULT RdpClientWindow::OnConfirmClose(VARIANT_BOOL* allow_close) { | 446 HRESULT RdpClientWindow::OnConfirmClose(VARIANT_BOOL* allow_close) { |
| 459 *allow_close = VARIANT_TRUE; | 447 *allow_close = VARIANT_TRUE; |
| 460 | 448 |
| 461 NotifyDisconnected(); | 449 NotifyDisconnected(); |
| 462 return S_OK; | 450 return S_OK; |
| 463 } | 451 } |
| 464 | 452 |
| 453 int RdpClientWindow::LogOnCreateError(HRESULT error) { |
| 454 LOG(ERROR) << "RDP: failed to initiate a connection to " |
| 455 << server_endpoint_.ToString() << ": error=" |
| 456 << std::hex << error << std::dec; |
| 457 client_.Release(); |
| 458 client_settings_.Release(); |
| 459 return -1; |
| 460 } |
| 461 |
| 465 void RdpClientWindow::NotifyConnected() { | 462 void RdpClientWindow::NotifyConnected() { |
| 466 if (event_handler_) | 463 if (event_handler_) |
| 467 event_handler_->OnConnected(); | 464 event_handler_->OnConnected(); |
| 468 } | 465 } |
| 469 | 466 |
| 470 void RdpClientWindow::NotifyDisconnected() { | 467 void RdpClientWindow::NotifyDisconnected() { |
| 471 if (event_handler_) { | 468 if (event_handler_) { |
| 472 EventHandler* event_handler = event_handler_; | 469 EventHandler* event_handler = event_handler_; |
| 473 event_handler_ = nullptr; | 470 event_handler_ = nullptr; |
| 474 event_handler->OnDisconnected(); | 471 event_handler->OnDisconnected(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 return CallNextHookEx(hook, code, wparam, lparam); | 518 return CallNextHookEx(hook, code, wparam, lparam); |
| 522 | 519 |
| 523 // Close the window once all pending window messages are processed. | 520 // Close the window once all pending window messages are processed. |
| 524 HWND window = reinterpret_cast<HWND>(wparam); | 521 HWND window = reinterpret_cast<HWND>(wparam); |
| 525 LOG(WARNING) << "RDP: closing a window: " << std::hex << window << std::dec; | 522 LOG(WARNING) << "RDP: closing a window: " << std::hex << window << std::dec; |
| 526 ::PostMessage(window, WM_CLOSE, 0, 0); | 523 ::PostMessage(window, WM_CLOSE, 0, 0); |
| 527 return 0; | 524 return 0; |
| 528 } | 525 } |
| 529 | 526 |
| 530 } // namespace remoting | 527 } // namespace remoting |
| OLD | NEW |