summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remoting/host/daemon_process.cc2
-rw-r--r--remoting/host/daemon_process.h2
-rw-r--r--remoting/host/daemon_process_win.cc54
-rw-r--r--remoting/host/desktop_session_win.cc24
-rw-r--r--remoting/host/desktop_session_win.h5
-rw-r--r--remoting/host/win/worker_process_launcher.cc2
-rw-r--r--remoting/host/win/worker_process_launcher_unittest.cc12
-rw-r--r--remoting/host/worker_process_ipc_delegate.h2
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