diff options
-rw-r--r-- | remoting/host/daemon_process.cc | 2 | ||||
-rw-r--r-- | remoting/host/daemon_process.h | 2 | ||||
-rw-r--r-- | remoting/host/daemon_process_win.cc | 54 | ||||
-rw-r--r-- | remoting/host/desktop_session_win.cc | 24 | ||||
-rw-r--r-- | remoting/host/desktop_session_win.h | 5 | ||||
-rw-r--r-- | remoting/host/win/worker_process_launcher.cc | 2 | ||||
-rw-r--r-- | remoting/host/win/worker_process_launcher_unittest.cc | 12 | ||||
-rw-r--r-- | remoting/host/worker_process_ipc_delegate.h | 2 |
8 files changed, 83 insertions, 20 deletions
diff --git a/remoting/host/daemon_process.cc b/remoting/host/daemon_process.cc index d9d05b4..f5f0a6d 100644 --- a/remoting/host/daemon_process.cc +++ b/remoting/host/daemon_process.cc @@ -126,7 +126,7 @@ bool DaemonProcess::OnMessageReceived(const IPC::Message& message) { return handled; } -void DaemonProcess::OnPermanentError() { +void DaemonProcess::OnPermanentError(int exit_code) { DCHECK(caller_task_runner()->BelongsToCurrentThread()); Stop(); } diff --git a/remoting/host/daemon_process.h b/remoting/host/daemon_process.h index 521d706..0fbf020 100644 --- a/remoting/host/daemon_process.h +++ b/remoting/host/daemon_process.h @@ -67,7 +67,7 @@ class DaemonProcess // WorkerProcessIpcDelegate implementation. virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnPermanentError() OVERRIDE; + virtual void OnPermanentError(int exit_code) OVERRIDE; // Sends an IPC message to the network process. The message will be dropped // unless the network process is connected over the IPC channel. diff --git a/remoting/host/daemon_process_win.cc b/remoting/host/daemon_process_win.cc index 5603c9a..6bf2e6e 100644 --- a/remoting/host/daemon_process_win.cc +++ b/remoting/host/daemon_process_win.cc @@ -20,6 +20,8 @@ #include "ipc/ipc_message.h" #include "ipc/ipc_message_macros.h" #include "remoting/base/auto_thread_task_runner.h" +#include "remoting/base/scoped_sc_handle_win.h" +#include "remoting/host/branding.h" #include "remoting/host/chromoting_messages.h" #include "remoting/host/desktop_session_win.h" #include "remoting/host/host_exit_codes.h" @@ -51,6 +53,7 @@ class DaemonProcessWin : public DaemonProcess { // WorkerProcessIpcDelegate implementation. virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; + virtual void OnPermanentError(int exit_code) OVERRIDE; // DaemonProcess overrides. virtual void SendToNetwork(IPC::Message* message) OVERRIDE; @@ -69,6 +72,9 @@ class DaemonProcessWin : public DaemonProcess { const tracked_objects::Location& location) OVERRIDE; virtual void LaunchNetworkProcess() OVERRIDE; + // Changes the service start type to 'manual'. + void DisableAutoStart(); + private: scoped_ptr<WorkerProcessLauncher> network_launcher_; @@ -99,6 +105,16 @@ void DaemonProcessWin::OnChannelConnected(int32 peer_pid) { DaemonProcess::OnChannelConnected(peer_pid); } +void DaemonProcessWin::OnPermanentError(int exit_code) { + // Change the service start type to 'manual' if the host has been deleted + // remotely. This way the host will not be started every time the machine + // boots until the user re-enable it again. + if (exit_code == kInvalidHostIdExitCode) + DisableAutoStart(); + + DaemonProcess::OnPermanentError(exit_code); +} + void DaemonProcessWin::SendToNetwork(IPC::Message* message) { if (network_launcher_) { network_launcher_->Send(message); @@ -186,4 +202,42 @@ scoped_ptr<DaemonProcess> DaemonProcess::Create( return daemon_process.PassAs<DaemonProcess>(); } +void DaemonProcessWin::DisableAutoStart() { + ScopedScHandle scmanager( + OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, + SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); + if (!scmanager.IsValid()) { + LOG_GETLASTERROR(INFO) + << "Failed to connect to the service control manager"; + return; + } + + DWORD desired_access = SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS; + ScopedScHandle service( + OpenService(scmanager, kWindowsServiceName, desired_access)); + if (!service.IsValid()) { + LOG_GETLASTERROR(INFO) + << "Failed to open to the '" << kWindowsServiceName << "' service"; + return; + } + + // Change the service start type to 'manual'. All |NULL| parameters below mean + // that there is no change to the corresponding service parameter. + if (!ChangeServiceConfig(service, + SERVICE_NO_CHANGE, + SERVICE_DEMAND_START, + SERVICE_NO_CHANGE, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL)) { + LOG_GETLASTERROR(INFO) + << "Failed to change the '" << kWindowsServiceName + << "'service start type to 'manual'"; + } +} + } // namespace remoting diff --git a/remoting/host/desktop_session_win.cc b/remoting/host/desktop_session_win.cc index 51ae3f5..9840207 100644 --- a/remoting/host/desktop_session_win.cc +++ b/remoting/host/desktop_session_win.cc @@ -280,7 +280,7 @@ void RdpSession::OnRdpConnected() { void RdpSession::OnRdpClosed() { DCHECK(caller_task_runner()->BelongsToCurrentThread()); - OnPermanentError(); + TerminateSession(); } void RdpSession::SetScreenResolution(const ScreenResolution& resolution) { @@ -421,7 +421,7 @@ void DesktopSessionWin::OnSessionAttachTimeout() { LOG(ERROR) << "Session attach notification didn't arrived within " << kSessionAttachTimeoutSeconds << " seconds."; - OnPermanentError(); + TerminateSession(); } void DesktopSessionWin::StartMonitoring(const std::string& terminal_id) { @@ -453,6 +453,15 @@ void DesktopSessionWin::StopMonitoring() { OnSessionDetached(); } +void DesktopSessionWin::TerminateSession() { + DCHECK(caller_task_runner_->BelongsToCurrentThread()); + + StopMonitoring(); + + // This call will delete |this| so it should be at the very end of the method. + daemon_process()->CloseDesktopSession(id()); +} + void DesktopSessionWin::OnChannelConnected(int32 peer_pid) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); @@ -490,13 +499,10 @@ bool DesktopSessionWin::OnMessageReceived(const IPC::Message& message) { return handled; } -void DesktopSessionWin::OnPermanentError() { +void DesktopSessionWin::OnPermanentError(int exit_code) { DCHECK(caller_task_runner_->BelongsToCurrentThread()); - StopMonitoring(); - - // This call will delete |this| so it should be at the very end of the method. - daemon_process()->CloseDesktopSession(id()); + TerminateSession(); } void DesktopSessionWin::OnSessionAttached(uint32 session_id) { @@ -520,7 +526,7 @@ void DesktopSessionWin::OnSessionAttached(uint32 session_id) { } if (!result) { - OnPermanentError(); + TerminateSession(); return; } @@ -540,7 +546,7 @@ void DesktopSessionWin::OnSessionAttached(uint32 session_id) { launch_elevated, WideToUTF8(kDaemonIpcSecurityDescriptor))); if (!delegate->Initialize(session_id)) { - OnPermanentError(); + TerminateSession(); return; } diff --git a/remoting/host/desktop_session_win.h b/remoting/host/desktop_session_win.h index 6baf22d..38c2e07 100644 --- a/remoting/host/desktop_session_win.h +++ b/remoting/host/desktop_session_win.h @@ -78,13 +78,16 @@ class DesktopSessionWin // Stops monitoring for session attach/detach events. void StopMonitoring(); + // Asks DaemonProcess to terminate this session. + void TerminateSession(); + // Injects a secure attention sequence into the session. virtual void InjectSas() = 0; // WorkerProcessIpcDelegate implementation. virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - virtual void OnPermanentError() OVERRIDE; + virtual void OnPermanentError(int exit_code) OVERRIDE; // WtsTerminalObserver implementation. virtual void OnSessionAttached(uint32 session_id) OVERRIDE; diff --git a/remoting/host/win/worker_process_launcher.cc b/remoting/host/win/worker_process_launcher.cc index f255935..64dfa8e 100644 --- a/remoting/host/win/worker_process_launcher.cc +++ b/remoting/host/win/worker_process_launcher.cc @@ -257,7 +257,7 @@ void WorkerProcessLauncher::StopWorker() { // misconfiguration. if (kMinPermanentErrorExitCode <= exit_code_ && exit_code_ <= kMaxPermanentErrorExitCode) { - ipc_handler_->OnPermanentError(); + ipc_handler_->OnPermanentError(exit_code_); return; } diff --git a/remoting/host/win/worker_process_launcher_unittest.cc b/remoting/host/win/worker_process_launcher_unittest.cc index 6991996..a8f3c83 100644 --- a/remoting/host/win/worker_process_launcher_unittest.cc +++ b/remoting/host/win/worker_process_launcher_unittest.cc @@ -62,7 +62,7 @@ class MockIpcDelegate : public WorkerProcessIpcDelegate { // WorkerProcessIpcDelegate interface. MOCK_METHOD1(OnChannelConnected, void(int32)); MOCK_METHOD1(OnMessageReceived, bool(const IPC::Message&)); - MOCK_METHOD0(OnPermanentError, void()); + MOCK_METHOD1(OnPermanentError, void(int)); private: DISALLOW_COPY_AND_ASSIGN(MockIpcDelegate); @@ -387,7 +387,7 @@ TEST_F(WorkerProcessLauncherTest, Start) { EXPECT_CALL(server_listener_, OnChannelConnected(_)) .Times(0); - EXPECT_CALL(server_listener_, OnPermanentError()) + EXPECT_CALL(server_listener_, OnPermanentError(_)) .Times(0); StartWorker(); @@ -407,7 +407,7 @@ TEST_F(WorkerProcessLauncherTest, StartAndConnect) { .Times(1) .WillOnce(InvokeWithoutArgs(this, &WorkerProcessLauncherTest::StopWorker)); - EXPECT_CALL(server_listener_, OnPermanentError()) + EXPECT_CALL(server_listener_, OnPermanentError(_)) .Times(0); StartWorker(); @@ -430,7 +430,7 @@ TEST_F(WorkerProcessLauncherTest, Restart) { .WillOnce(InvokeWithoutArgs(this, &WorkerProcessLauncherTest::StopWorker)); - EXPECT_CALL(server_listener_, OnPermanentError()) + EXPECT_CALL(server_listener_, OnPermanentError(_)) .Times(0); StartWorker(); @@ -453,7 +453,7 @@ TEST_F(WorkerProcessLauncherTest, DropIpcChannel) { .WillOnce(InvokeWithoutArgs( this, &WorkerProcessLauncherTest::StopWorker)); - EXPECT_CALL(server_listener_, OnPermanentError()) + EXPECT_CALL(server_listener_, OnPermanentError(_)) .Times(0); StartWorker(); @@ -473,7 +473,7 @@ TEST_F(WorkerProcessLauncherTest, PermanentError) { .WillOnce(InvokeWithoutArgs(CreateFunctor( this, &WorkerProcessLauncherTest::TerminateWorker, kMinPermanentErrorExitCode))); - EXPECT_CALL(server_listener_, OnPermanentError()) + EXPECT_CALL(server_listener_, OnPermanentError(_)) .Times(1) .WillOnce(InvokeWithoutArgs(this, &WorkerProcessLauncherTest::StopWorker)); diff --git a/remoting/host/worker_process_ipc_delegate.h b/remoting/host/worker_process_ipc_delegate.h index 0fe4771..bdacd47 100644 --- a/remoting/host/worker_process_ipc_delegate.h +++ b/remoting/host/worker_process_ipc_delegate.h @@ -27,7 +27,7 @@ class WorkerProcessIpcDelegate { virtual bool OnMessageReceived(const IPC::Message& message) = 0; // Notifies that a permanent error was encountered. - virtual void OnPermanentError() = 0; + virtual void OnPermanentError(int exit_code) = 0; }; } // namespace remoting |