Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: remoting/host/host_service_win.cc

Issue 9476017: Chromoting service now launches the host process in the session the is currently attached to the ph… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removing scoped_ptr<ScopedHandle>. Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/host_service_win.h" 8 #include "remoting/host/host_service_win.h"
9 9
10 #include <windows.h> 10 #include <windows.h>
11 #include <wtsapi32.h> 11 #include <wtsapi32.h>
12 #include <stdio.h> 12 #include <stdio.h>
13 13
14 #include "base/at_exit.h" 14 #include "base/at_exit.h"
15 #include "base/base_paths.h" 15 #include "base/base_paths.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/file_path.h" 18 #include "base/file_util.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/message_loop.h" 20 #include "base/message_loop.h"
21 #include "base/path_service.h" 21 #include "base/path_service.h"
22 #include "base/stringprintf.h" 22 #include "base/stringprintf.h"
23 #include "base/utf_string_conversions.h" 23 #include "base/utf_string_conversions.h"
24 #include "base/win/wrapped_window_proc.h" 24 #include "base/win/wrapped_window_proc.h"
25 25
26 #include "remoting/host/host_service_resource.h" 26 #include "remoting/host/host_service_resource.h"
27 #include "remoting/base/scoped_sc_handle_win.h" 27 #include "remoting/base/scoped_sc_handle_win.h"
28 #include "remoting/host/wts_console_observer_win.h" 28 #include "remoting/host/wts_console_observer_win.h"
29 #include "remoting/host/wts_session_process_launcher_win.h" 29 #include "remoting/host/wts_session_process_launcher_win.h"
30 30
31 using base::StringPrintf; 31 using base::StringPrintf;
32 32
33 namespace { 33 namespace {
34 34
35 // Service name. 35 // Service name.
36 const char kServiceName[] = "chromoting"; 36 const char kServiceName[] = "chromoting";
37 // TODO(alexeypa): investigate and migrate this over to Chrome's i18n framework. 37 // TODO(alexeypa): investigate and migrate this over to Chrome's i18n framework.
38 const char kMuiStringFormat[] = "@%ls,-%d"; 38 const char kMuiStringFormat[] = "@%ls,-%d";
39 const char kServiceDependencies[] = ""; 39 const char kServiceDependencies[] = "";
40 40
41 const char kServiceCommandLineFormat[] = "\"%ls\" --host-binary=\"%ls\"";
42
41 const DWORD kServiceStopTimeoutMs = 30 * 1000; 43 const DWORD kServiceStopTimeoutMs = 30 * 1000;
42 44
43 // Session id that does not represent any session. 45 // Session id that does not represent any session.
44 const uint32 kInvalidSession = 0xffffffff; 46 const uint32 kInvalidSession = 0xffffffff;
45 47
46 // A window class for the session change notifications window. 48 // A window class for the session change notifications window.
47 static const char kSessionNotificationWindowClass[] = 49 static const char kSessionNotificationWindowClass[] =
48 "Chromoting_SessionNotificationWindow"; 50 "Chromoting_SessionNotificationWindow";
49 51
50 // Command line actions and switches: 52 // Command line actions and switches:
51 // "run" sumply runs the service as usual. 53 // "run" sumply runs the service as usual.
52 const char kRunActionName[] = "run"; 54 const char kRunActionName[] = "run";
53 55
54 // "install" requests the service to be installed. 56 // "install" requests the service to be installed.
55 const char kInstallActionName[] = "install"; 57 const char kInstallActionName[] = "install";
56 58
57 // "remove" uninstalls the service. 59 // "remove" uninstalls the service.
58 const char kRemoveActionName[] = "remove"; 60 const char kRemoveActionName[] = "remove";
59 61
60 // "--console" runs the service interactively for debugging purposes. 62 // "--console" runs the service interactively for debugging purposes.
61 const char kConsoleSwitchName[] = "console"; 63 const char kConsoleSwitchName[] = "console";
62 64
65 // "--host-binary" specifies the host binary to run in console session.
66 const char kHostBinarySwitchName[] = "host-binary";
67
63 // "--help" or "--?" prints the usage message. 68 // "--help" or "--?" prints the usage message.
64 const char kHelpSwitchName[] = "help"; 69 const char kHelpSwitchName[] = "help";
65 const char kQuestionSwitchName[] = "?"; 70 const char kQuestionSwitchName[] = "?";
66 71
67 const char kUsageMessage[] = 72 const char kUsageMessage[] =
68 "\n" 73 "\n"
69 "Usage: %s [action] [options]\n" 74 "Usage: %s [action] [options]\n"
70 "\n" 75 "\n"
71 "Actions:\n" 76 "Actions:\n"
72 " run - Run the service. If no action specified 'run' is assumed.\n" 77 " run - Run the service (default if no action was specified).\n"
73 " install - Install the service.\n" 78 " install - Install the service.\n"
74 " remove - Uninstall the service.\n" 79 " remove - Uninstall the service.\n"
75 "\n" 80 "\n"
76 "Options:\n" 81 "Options:\n"
77 " --console - Run the service interactively for debugging purposes.\n" 82 " --console - Run the service interactively for debugging purposes.\n"
78 " --help, --? - Print this message.\n"; 83 " --host-binary - Specifies the host binary to run in the console session.\n"
84 " --help, --? - Print this message.\n";
79 85
80 // Exit codes: 86 // Exit codes:
81 const int kSuccessExitCode = 0; 87 const int kSuccessExitCode = 0;
82 const int kUsageExitCode = 1; 88 const int kUsageExitCode = 1;
83 const int kErrorExitCode = 2; 89 const int kErrorExitCode = 2;
84 90
85 void usage(const char* program_name) { 91 void usage(const char* program_name) {
86 fprintf(stderr, kUsageMessage, program_name); 92 fprintf(stderr, kUsageMessage, program_name);
87 } 93 }
88 94
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 162 }
157 163
158 HostService* HostService::GetInstance() { 164 HostService* HostService::GetInstance() {
159 return Singleton<HostService>::get(); 165 return Singleton<HostService>::get();
160 } 166 }
161 167
162 bool HostService::InitWithCommandLine(const CommandLine* command_line) { 168 bool HostService::InitWithCommandLine(const CommandLine* command_line) {
163 CommandLine::StringVector args = command_line->GetArgs(); 169 CommandLine::StringVector args = command_line->GetArgs();
164 170
165 // Choose the action to perform. 171 // Choose the action to perform.
172 bool host_binary_required = true;
166 if (!args.empty()) { 173 if (!args.empty()) {
167 if (args.size() > 1) { 174 if (args.size() > 1) {
168 LOG(ERROR) << "Invalid command line: more than one action requested."; 175 LOG(ERROR) << "Invalid command line: more than one action requested.";
169 return false; 176 return false;
170 } 177 }
171 if (args[0] == ASCIIToUTF16(kInstallActionName)) { 178 if (args[0] == ASCIIToUTF16(kInstallActionName)) {
172 run_routine_ = &HostService::Install; 179 run_routine_ = &HostService::Install;
173 } else if (args[0] == ASCIIToUTF16(kRemoveActionName)) { 180 } else if (args[0] == ASCIIToUTF16(kRemoveActionName)) {
174 run_routine_ = &HostService::Remove; 181 run_routine_ = &HostService::Remove;
182 host_binary_required = false;
175 } else if (args[0] != ASCIIToUTF16(kRunActionName)) { 183 } else if (args[0] != ASCIIToUTF16(kRunActionName)) {
176 LOG(ERROR) << "Invalid command line: invalid action specified: " 184 LOG(ERROR) << "Invalid command line: invalid action specified: "
177 << args[0]; 185 << args[0];
178 return false; 186 return false;
179 } 187 }
180 } 188 }
181 189
190 if (host_binary_required) {
191 if (command_line->HasSwitch(kHostBinarySwitchName)) {
192 host_binary_ = command_line->GetSwitchValuePath(kHostBinarySwitchName);
193 } else {
194 LOG(ERROR) << "Invalid command line: --" << kHostBinarySwitchName
195 << " is required.";
196 return false;
197 }
198 }
199
182 // Run interactively if needed. 200 // Run interactively if needed.
183 if (run_routine_ == &HostService::RunAsService && 201 if (run_routine_ == &HostService::RunAsService &&
184 command_line->HasSwitch(kConsoleSwitchName)) { 202 command_line->HasSwitch(kConsoleSwitchName)) {
185 run_routine_ = &HostService::RunInConsole; 203 run_routine_ = &HostService::RunInConsole;
186 } 204 }
187 205
188 return true; 206 return true;
189 } 207 }
190 208
191 int HostService::Install() { 209 int HostService::Install() {
192 ScopedScHandle scmanager( 210 ScopedScHandle scmanager(
193 OpenSCManagerW(NULL, NULL, 211 OpenSCManagerW(NULL, NULL,
194 SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE)); 212 SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE));
195 if (!scmanager.IsValid()) { 213 if (!scmanager.IsValid()) {
196 LOG_GETLASTERROR(ERROR) 214 LOG_GETLASTERROR(ERROR)
197 << "Failed to connect to the service control manager"; 215 << "Failed to connect to the service control manager";
198 return kErrorExitCode; 216 return kErrorExitCode;
199 } 217 }
200 218
201 FilePath exe; 219 FilePath exe;
202 if (!PathService::Get(base::FILE_EXE, &exe)) { 220 if (!PathService::Get(base::FILE_EXE, &exe)) {
203 LOG(ERROR) << "Unable to retrieve the service binary path."; 221 LOG(ERROR) << "Unable to retrieve the service binary path.";
204 return kErrorExitCode; 222 return kErrorExitCode;
205 } 223 }
206 224
207 string16 name = StringPrintf(ASCIIToUTF16(kMuiStringFormat).c_str(), 225 string16 name = StringPrintf(ASCIIToUTF16(kMuiStringFormat).c_str(),
208 exe.value().c_str(), 226 exe.value().c_str(),
209 IDS_DISPLAY_SERVICE_NAME); 227 IDS_DISPLAY_SERVICE_NAME);
228
229 if (!file_util::AbsolutePath(&host_binary_) ||
230 !file_util::PathExists(host_binary_)) {
231 LOG(ERROR) << "Invalid host binary name: " << host_binary_.value();
232 return kErrorExitCode;
233 }
234
235 string16 command_line = StringPrintf(
236 ASCIIToUTF16(kServiceCommandLineFormat).c_str(),
237 exe.value().c_str(),
238 host_binary_.value().c_str());
210 ScopedScHandle service( 239 ScopedScHandle service(
211 CreateServiceW(scmanager, 240 CreateServiceW(scmanager,
212 service_name_.c_str(), 241 service_name_.c_str(),
213 name.c_str(), 242 name.c_str(),
214 SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG, 243 SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG,
215 SERVICE_WIN32_OWN_PROCESS, 244 SERVICE_WIN32_OWN_PROCESS,
216 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 245 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
217 exe.value().c_str(), 246 command_line.c_str(),
218 NULL, 247 NULL,
219 NULL, 248 NULL,
220 ASCIIToUTF16(kServiceDependencies).c_str(), 249 ASCIIToUTF16(kServiceDependencies).c_str(),
221 NULL, 250 NULL,
222 NULL)); 251 NULL));
223 252
224 if (service.IsValid()) { 253 if (service.IsValid()) {
225 // Set the service description if the service is freshly installed. 254 // Set the service description if the service is freshly installed.
226 string16 description = StringPrintf( 255 string16 description = StringPrintf(
227 ASCIIToUTF16(kMuiStringFormat).c_str(), 256 ASCIIToUTF16(kMuiStringFormat).c_str(),
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 344
316 printf("The service has been removed successfully.\n"); 345 printf("The service has been removed successfully.\n");
317 return kSuccessExitCode; 346 return kSuccessExitCode;
318 } 347 }
319 348
320 int HostService::Run() { 349 int HostService::Run() {
321 return (this->*run_routine_)(); 350 return (this->*run_routine_)();
322 } 351 }
323 352
324 void HostService::RunMessageLoop() { 353 void HostService::RunMessageLoop() {
325 WtsSessionProcessLauncher launcher(this); 354 WtsSessionProcessLauncher launcher(this, host_binary_);
326 355
327 // Run the service. 356 // Run the service.
328 message_loop_->Run(); 357 message_loop_->Run();
329 358
330 // Clean up the observers by emulating detaching from the console. 359 // Clean up the observers by emulating detaching from the console.
331 shutting_down_ = true; 360 shutting_down_ = true;
332 OnSessionChange(); 361 OnSessionChange();
333 362
334 // Release the control handler. 363 // Release the control handler.
335 stopped_event_.Signal(); 364 stopped_event_.Signal();
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 } 567 }
539 568
540 remoting::HostService* service = remoting::HostService::GetInstance(); 569 remoting::HostService* service = remoting::HostService::GetInstance();
541 if (!service->InitWithCommandLine(command_line)) { 570 if (!service->InitWithCommandLine(command_line)) {
542 usage(argv[0]); 571 usage(argv[0]);
543 return kUsageExitCode; 572 return kUsageExitCode;
544 } 573 }
545 574
546 return service->Run(); 575 return service->Run();
547 } 576 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698