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 // This file implements the Windows service controlling Me2Me host processes | 5 // This file implements the Windows service controlling Me2Me host processes |
6 // running within user sessions. | 6 // running within user sessions. |
7 | 7 |
8 #include "remoting/host/win/host_service.h" | 8 #include "remoting/host/win/host_service.h" |
9 | 9 |
10 #include <sddl.h> | 10 #include <sddl.h> |
11 #include <windows.h> | 11 #include <windows.h> |
12 #include <wtsapi32.h> | 12 #include <wtsapi32.h> |
13 | 13 |
14 #include "base/base_paths.h" | 14 #include "base/base_paths.h" |
15 #include "base/base_switches.h" | 15 #include "base/base_switches.h" |
16 #include "base/bind.h" | 16 #include "base/bind.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
19 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
20 #include "base/run_loop.h" | 20 #include "base/run_loop.h" |
21 #include "base/single_thread_task_runner.h" | 21 #include "base/single_thread_task_runner.h" |
22 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
24 #include "base/win/scoped_com_initializer.h" | 24 #include "base/win/scoped_com_initializer.h" |
25 #include "base/win/wrapped_window_proc.h" | |
26 #include "remoting/base/auto_thread.h" | 25 #include "remoting/base/auto_thread.h" |
27 #include "remoting/base/scoped_sc_handle_win.h" | 26 #include "remoting/base/scoped_sc_handle_win.h" |
28 #include "remoting/base/stoppable.h" | 27 #include "remoting/base/stoppable.h" |
29 #include "remoting/host/branding.h" | 28 #include "remoting/host/branding.h" |
30 #include "remoting/host/host_exit_codes.h" | 29 #include "remoting/host/host_exit_codes.h" |
31 #include "remoting/host/logging.h" | 30 #include "remoting/host/logging.h" |
32 #include "remoting/host/win/security_descriptor.h" | 31 #include "remoting/host/win/security_descriptor.h" |
33 | 32 |
34 #if defined(REMOTING_MULTI_PROCESS) | 33 #if defined(REMOTING_MULTI_PROCESS) |
35 #include "remoting/host/daemon_process.h" | 34 #include "remoting/host/daemon_process.h" |
36 #endif // defined(REMOTING_MULTI_PROCESS) | 35 #endif // defined(REMOTING_MULTI_PROCESS) |
37 | 36 |
38 #include "remoting/host/win/core_resource.h" | 37 #include "remoting/host/win/core_resource.h" |
39 #include "remoting/host/win/wts_terminal_observer.h" | 38 #include "remoting/host/win/wts_terminal_observer.h" |
40 | 39 |
41 #if !defined(REMOTING_MULTI_PROCESS) | 40 #if !defined(REMOTING_MULTI_PROCESS) |
42 #include "remoting/host/win/wts_console_session_process_driver.h" | 41 #include "remoting/host/win/wts_console_session_process_driver.h" |
43 #endif // !defined(REMOTING_MULTI_PROCESS) | 42 #endif // !defined(REMOTING_MULTI_PROCESS) |
44 | 43 |
45 namespace remoting { | 44 namespace remoting { |
46 | 45 |
47 namespace { | 46 namespace { |
48 | 47 |
49 const char kIoThreadName[] = "I/O thread"; | 48 const char kIoThreadName[] = "I/O thread"; |
50 | 49 |
51 // A window class for the session change notifications window. | |
52 const wchar_t kSessionNotificationWindowClass[] = | |
53 L"Chromoting_SessionNotificationWindow"; | |
54 | |
55 // Command line switches: | 50 // Command line switches: |
56 | 51 |
57 // "--console" runs the service interactively for debugging purposes. | 52 // "--console" runs the service interactively for debugging purposes. |
58 const char kConsoleSwitchName[] = "console"; | 53 const char kConsoleSwitchName[] = "console"; |
59 | 54 |
60 // Concatenates ACE type, permissions and sid given as SDDL strings into an ACE | 55 // Concatenates ACE type, permissions and sid given as SDDL strings into an ACE |
61 // definition in SDDL form. | 56 // definition in SDDL form. |
62 #define SDDL_ACE(type, permissions, sid) \ | 57 #define SDDL_ACE(type, permissions, sid) \ |
63 L"(" type L";;" permissions L";;;" sid L")" | 58 L"(" type L";;" permissions L";;;" sid L")" |
64 | 59 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 return result; | 390 return result; |
396 | 391 |
397 // Subscribe to Ctrl-C and other console events. | 392 // Subscribe to Ctrl-C and other console events. |
398 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { | 393 if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { |
399 LOG_GETLASTERROR(ERROR) | 394 LOG_GETLASTERROR(ERROR) |
400 << "Failed to set console control handler"; | 395 << "Failed to set console control handler"; |
401 return result; | 396 return result; |
402 } | 397 } |
403 | 398 |
404 // Create a window for receiving session change notifications. | 399 // Create a window for receiving session change notifications. |
405 HWND window = NULL; | 400 win::MessageWindow window; |
406 WNDCLASSEX window_class; | 401 if (!window.Create(this)) { |
407 base::win::InitializeWindowClass( | |
408 kSessionNotificationWindowClass, | |
409 &base::win::WrappedWindowProc<SessionChangeNotificationProc>, | |
410 0, 0, 0, NULL, NULL, NULL, NULL, NULL, | |
411 &window_class); | |
412 HINSTANCE instance = window_class.hInstance; | |
413 ATOM atom = RegisterClassExW(&window_class); | |
414 if (atom == 0) { | |
415 LOG_GETLASTERROR(ERROR) | 402 LOG_GETLASTERROR(ERROR) |
416 << "Failed to register the window class '" | 403 << "Failed to create the session notification window"; |
417 << kSessionNotificationWindowClass << "'"; | |
418 goto cleanup; | |
419 } | |
420 | |
421 window = CreateWindowW(MAKEINTATOM(atom), 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, | |
422 instance, 0); | |
423 if (window == NULL) { | |
424 LOG_GETLASTERROR(ERROR) | |
425 << "Failed to creat the session notificationwindow"; | |
426 goto cleanup; | 404 goto cleanup; |
427 } | 405 } |
428 | 406 |
429 // Subscribe to session change notifications. | 407 // Subscribe to session change notifications. |
430 if (WTSRegisterSessionNotification(window, | 408 if (WTSRegisterSessionNotification(window.hwnd(), |
431 NOTIFY_FOR_ALL_SESSIONS) != FALSE) { | 409 NOTIFY_FOR_ALL_SESSIONS) != FALSE) { |
432 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>( | 410 CreateLauncher(scoped_refptr<AutoThreadTaskRunner>( |
433 new AutoThreadTaskRunner(main_task_runner_, | 411 new AutoThreadTaskRunner(main_task_runner_, |
434 run_loop.QuitClosure()))); | 412 run_loop.QuitClosure()))); |
435 | 413 |
436 // Run the service. | 414 // Run the service. |
437 run_loop.Run(); | 415 run_loop.Run(); |
438 | 416 |
439 // Release the control handler. | 417 // Release the control handler. |
440 stopped_event_.Signal(); | 418 stopped_event_.Signal(); |
441 | 419 |
442 WTSUnRegisterSessionNotification(window); | 420 WTSUnRegisterSessionNotification(window.hwnd()); |
443 result = kSuccessExitCode; | 421 result = kSuccessExitCode; |
444 } | 422 } |
445 | 423 |
446 cleanup: | 424 cleanup: |
447 if (window != NULL) { | |
448 DestroyWindow(window); | |
449 } | |
450 | |
451 if (atom != 0) { | |
452 UnregisterClass(MAKEINTATOM(atom), instance); | |
453 } | |
454 | |
455 // Unsubscribe from console events. Ignore the exit code. There is nothing | 425 // Unsubscribe from console events. Ignore the exit code. There is nothing |
456 // we can do about it now and the program is about to exit anyway. Even if | 426 // we can do about it now and the program is about to exit anyway. Even if |
457 // it crashes nothing is going to be broken because of it. | 427 // it crashes nothing is going to be broken because of it. |
458 SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); | 428 SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); |
459 | 429 |
460 return result; | 430 return result; |
461 } | 431 } |
462 | 432 |
| 433 bool HostService::HandleMessage( |
| 434 UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) { |
| 435 if (message == WM_WTSSESSION_CHANGE) { |
| 436 OnSessionChange(wparam, lparam); |
| 437 *result = 0; |
| 438 return true; |
| 439 } |
| 440 |
| 441 return false; |
| 442 } |
| 443 |
463 // static | 444 // static |
464 BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { | 445 BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { |
465 HostService* self = HostService::GetInstance(); | 446 HostService* self = HostService::GetInstance(); |
466 switch (event) { | 447 switch (event) { |
467 case CTRL_C_EVENT: | 448 case CTRL_C_EVENT: |
468 case CTRL_BREAK_EVENT: | 449 case CTRL_BREAK_EVENT: |
469 case CTRL_CLOSE_EVENT: | 450 case CTRL_CLOSE_EVENT: |
470 case CTRL_LOGOFF_EVENT: | 451 case CTRL_LOGOFF_EVENT: |
471 case CTRL_SHUTDOWN_EVENT: | 452 case CTRL_SHUTDOWN_EVENT: |
472 self->main_task_runner_->PostTask(FROM_HERE, base::Bind( | 453 self->main_task_runner_->PostTask(FROM_HERE, base::Bind( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 HostService* self = HostService::GetInstance(); | 493 HostService* self = HostService::GetInstance(); |
513 | 494 |
514 // Run the service. | 495 // Run the service. |
515 self->RunAsServiceImpl(); | 496 self->RunAsServiceImpl(); |
516 | 497 |
517 // Release the control handler and notify the main thread that it can exit | 498 // Release the control handler and notify the main thread that it can exit |
518 // now. | 499 // now. |
519 self->stopped_event_.Signal(); | 500 self->stopped_event_.Signal(); |
520 } | 501 } |
521 | 502 |
522 // static | |
523 LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd, | |
524 UINT message, | |
525 WPARAM wparam, | |
526 LPARAM lparam) { | |
527 switch (message) { | |
528 case WM_WTSSESSION_CHANGE: { | |
529 HostService* self = HostService::GetInstance(); | |
530 self->OnSessionChange(wparam, lparam); | |
531 return 0; | |
532 } | |
533 | |
534 default: | |
535 return DefWindowProc(hwnd, message, wparam, lparam); | |
536 } | |
537 } | |
538 | |
539 int DaemonProcessMain() { | 503 int DaemonProcessMain() { |
540 HostService* service = HostService::GetInstance(); | 504 HostService* service = HostService::GetInstance(); |
541 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) { | 505 if (!service->InitWithCommandLine(CommandLine::ForCurrentProcess())) { |
542 return kUsageExitCode; | 506 return kUsageExitCode; |
543 } | 507 } |
544 | 508 |
545 return service->Run(); | 509 return service->Run(); |
546 } | 510 } |
547 | 511 |
548 } // namespace remoting | 512 } // namespace remoting |
OLD | NEW |