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

Side by Side Diff: remoting/host/win/host_service.cc

Issue 10831271: [Chromoting] Adding uiAccess='true' to the remoting_me2me_host.exe's manifest as it is required to … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 8 years, 4 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/win/host_service.h" 8 #include "remoting/host/win/host_service.h"
9 9
10 #include <windows.h> 10 #include <windows.h>
11 #include <shellapi.h>
11 #include <wtsapi32.h> 12 #include <wtsapi32.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/base_switches.h"
16 #include "base/bind.h" 17 #include "base/bind.h"
17 #include "base/command_line.h" 18 #include "base/command_line.h"
18 #include "base/file_path.h" 19 #include "base/file_path.h"
19 #include "base/logging.h" 20 #include "base/logging.h"
20 #include "base/message_loop.h" 21 #include "base/message_loop.h"
21 #include "base/single_thread_task_runner.h" 22 #include "base/single_thread_task_runner.h"
22 #include "base/stringprintf.h" 23 #include "base/stringprintf.h"
23 #include "base/threading/thread.h" 24 #include "base/threading/thread.h"
24 #include "base/utf_string_conversions.h" 25 #include "base/utf_string_conversions.h"
25 #include "base/win/wrapped_window_proc.h" 26 #include "base/win/wrapped_window_proc.h"
(...skipping 20 matching lines...) Expand all
46 47
47 // Session id that does not represent any session. 48 // Session id that does not represent any session.
48 const uint32 kInvalidSessionId = 0xffffffffu; 49 const uint32 kInvalidSessionId = 0xffffffffu;
49 50
50 const char kIoThreadName[] = "I/O thread"; 51 const char kIoThreadName[] = "I/O thread";
51 52
52 // A window class for the session change notifications window. 53 // A window class for the session change notifications window.
53 const wchar_t kSessionNotificationWindowClass[] = 54 const wchar_t kSessionNotificationWindowClass[] =
54 L"Chromoting_SessionNotificationWindow"; 55 L"Chromoting_SessionNotificationWindow";
55 56
56 // Command line actions and switches: 57 // Command line switches:
57 // "run" sumply runs the service as usual.
58 const wchar_t kRunActionName[] = L"run";
59 58
60 // "--console" runs the service interactively for debugging purposes. 59 // "--console" runs the service interactively for debugging purposes.
61 const char kConsoleSwitchName[] = "console"; 60 const char kConsoleSwitchName[] = "console";
62 61
62 // "--elevate=<binary>" requests <binary> to be launched elevated presenting UAC
63 // promt if required.
64 const char kElevateSwitchName[] = "elevate";
65
63 // "--help" or "--?" prints the usage message. 66 // "--help" or "--?" prints the usage message.
64 const char kHelpSwitchName[] = "help"; 67 const char kHelpSwitchName[] = "help";
65 const char kQuestionSwitchName[] = "?"; 68 const char kQuestionSwitchName[] = "?";
66 69
67 const char kUsageMessage[] = 70 const wchar_t kUsageMessage[] =
68 "\n" 71 L"\n"
69 "Usage: %s [action] [options]\n" 72 L"Usage: %ls [options]\n"
70 "\n" 73 L"\n"
71 "Actions:\n" 74 L"Options:\n"
72 " run - Run the service (default if no action was specified).\n" 75 L" --console - Run the service interactively for debugging purposes.\n"
73 "\n" 76 L" --elevate=<...> - Run <...> elevated.\n"
74 "Options:\n" 77 L" --help, --? - Print this message.\n";
75 " --console - Run the service interactively for debugging purposes.\n" 78
76 " --help, --? - Print this message.\n"; 79 // The command line parameters that should be copied from the service's command
80 // line when launching an elevated child.
81 const char* kCopiedSwitchNames[] = {
82 "auth-config", "host-config", switches::kV, switches::kVModule };
77 83
78 // Exit codes: 84 // Exit codes:
79 const int kSuccessExitCode = 0; 85 const int kSuccessExitCode = 0;
80 const int kUsageExitCode = 1; 86 const int kUsageExitCode = 1;
81 const int kErrorExitCode = 2; 87 const int kErrorExitCode = 2;
82 88
83 void usage(const char* program_name) { 89 void usage(const FilePath& program_name) {
84 fprintf(stderr, kUsageMessage, program_name); 90 LOG(INFO) << StringPrintf(kUsageMessage,
91 UTF16ToWide(program_name.value()).c_str());
85 } 92 }
86 93
87 } // namespace 94 } // namespace
88 95
89 namespace remoting { 96 namespace remoting {
90 97
91 HostService::HostService() : 98 HostService::HostService() :
92 console_session_id_(kInvalidSessionId), 99 console_session_id_(kInvalidSessionId),
93 run_routine_(&HostService::RunAsService), 100 run_routine_(&HostService::RunAsService),
94 service_status_handle_(0), 101 service_status_handle_(0),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 } 164 }
158 } 165 }
159 166
160 HostService* HostService::GetInstance() { 167 HostService* HostService::GetInstance() {
161 return Singleton<HostService>::get(); 168 return Singleton<HostService>::get();
162 } 169 }
163 170
164 bool HostService::InitWithCommandLine(const CommandLine* command_line) { 171 bool HostService::InitWithCommandLine(const CommandLine* command_line) {
165 CommandLine::StringVector args = command_line->GetArgs(); 172 CommandLine::StringVector args = command_line->GetArgs();
166 173
167 // Choose the action to perform. 174 // Perform elevation is requested.
175 if (command_line->HasSwitch(kElevateSwitchName)) {
176 run_routine_ = &HostService::Elevate;
177 return true;
178 }
179
168 if (!args.empty()) { 180 if (!args.empty()) {
169 if (args.size() > 1) { 181 LOG(ERROR) << "No positional parameters expected.";
170 LOG(ERROR) << "Invalid command line: more than one action requested."; 182 return false;
171 return false;
172 }
173 if (args[0] != kRunActionName) {
174 LOG(ERROR) << "Invalid command line: invalid action specified: "
175 << args[0];
176 return false;
177 }
178 } 183 }
179 184
180 // Run interactively if needed. 185 // Run interactively if needed.
181 if (run_routine_ == &HostService::RunAsService && 186 if (run_routine_ == &HostService::RunAsService &&
182 command_line->HasSwitch(kConsoleSwitchName)) { 187 command_line->HasSwitch(kConsoleSwitchName)) {
183 run_routine_ = &HostService::RunInConsole; 188 run_routine_ = &HostService::RunInConsole;
184 } 189 }
185 190
186 return true; 191 return true;
187 } 192 }
(...skipping 30 matching lines...) Expand all
218 223
219 #endif // !defined(REMOTING_MULTI_PROCESS) 224 #endif // !defined(REMOTING_MULTI_PROCESS)
220 225
221 // Run the service. 226 // Run the service.
222 message_loop->Run(); 227 message_loop->Run();
223 228
224 // Release the control handler. 229 // Release the control handler.
225 stopped_event_.Signal(); 230 stopped_event_.Signal();
226 } 231 }
227 232
233 int HostService::Elevate() {
234 // Get the name of the binary to launch.
235 FilePath binary =
236 CommandLine::ForCurrentProcess()->GetSwitchValuePath(kElevateSwitchName);
237
238 // Create the child process command line by copying known switches from our
239 // command line.
240 CommandLine command_line(CommandLine::NO_PROGRAM);
241 command_line.CopySwitchesFrom(*CommandLine::ForCurrentProcess(),
242 kCopiedSwitchNames,
243 _countof(kCopiedSwitchNames));
244 CommandLine::StringType parameters = command_line.GetCommandLineString();
245
246 // Launch the child process requesting elevation.
247 SHELLEXECUTEINFO info;
248 memset(&info, 0, sizeof(info));
249 info.cbSize = sizeof(info);
250 info.lpVerb = L"runas";
251 info.lpFile = binary.value().c_str();
252 info.lpParameters = parameters.c_str();
253 info.nShow = SW_SHOWNORMAL;
254
255 if (!ShellExecuteEx(&info)) {
256 return GetLastError();
257 }
258
259 return kSuccessExitCode;
260 }
261
228 int HostService::RunAsService() { 262 int HostService::RunAsService() {
229 SERVICE_TABLE_ENTRYW dispatch_table[] = { 263 SERVICE_TABLE_ENTRYW dispatch_table[] = {
230 { const_cast<LPWSTR>(kWindowsServiceName), &HostService::ServiceMain }, 264 { const_cast<LPWSTR>(kWindowsServiceName), &HostService::ServiceMain },
231 { NULL, NULL } 265 { NULL, NULL }
232 }; 266 };
233 267
234 if (!StartServiceCtrlDispatcherW(dispatch_table)) { 268 if (!StartServiceCtrlDispatcherW(dispatch_table)) {
235 LOG_GETLASTERROR(ERROR) 269 LOG_GETLASTERROR(ERROR)
236 << "Failed to connect to the service control manager"; 270 << "Failed to connect to the service control manager";
237 return kErrorExitCode; 271 return kErrorExitCode;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 return 0; 436 return 0;
403 } 437 }
404 438
405 default: 439 default:
406 return DefWindowProc(hwnd, message, wparam, lparam); 440 return DefWindowProc(hwnd, message, wparam, lparam);
407 } 441 }
408 } 442 }
409 443
410 } // namespace remoting 444 } // namespace remoting
411 445
412 int main(int argc, char** argv) { 446 int CALLBACK WinMain(HINSTANCE /* instance */,
rvargas (doing something else) 2012/08/13 18:54:12 nit: why not just leave the variable name without
alexeypa (please no reviews) 2012/08/13 20:02:23 Done.
447 HINSTANCE /* previous_instance */,
448 LPSTR /* command_line */,
449 int /* show_command */) {
413 #ifdef OFFICIAL_BUILD 450 #ifdef OFFICIAL_BUILD
414 if (remoting::IsUsageStatsAllowed()) { 451 if (remoting::IsUsageStatsAllowed()) {
415 remoting::InitializeCrashReporting(); 452 remoting::InitializeCrashReporting();
416 } 453 }
417 #endif // OFFICIAL_BUILD 454 #endif // OFFICIAL_BUILD
418 455
419 CommandLine::Init(argc, argv); 456 // CommandLine::Init() ignores the passed |argc| and |argv| on Windows getting
457 // the command line from GetCommandLineW(), so we can safely pass NULL here.
458 CommandLine::Init(0, NULL);
420 459
421 // This object instance is required by Chrome code (for example, 460 // This object instance is required by Chrome code (for example,
422 // FilePath, LazyInstance, MessageLoop). 461 // FilePath, LazyInstance, MessageLoop).
423 base::AtExitManager exit_manager; 462 base::AtExitManager exit_manager;
424 463
425 // Write logs to the application profile directory. 464 // Write logs to the application profile directory.
426 FilePath debug_log = remoting::GetConfigDir(). 465 FilePath debug_log = remoting::GetConfigDir().
427 Append(FILE_PATH_LITERAL("debug.log")); 466 Append(FILE_PATH_LITERAL("debug.log"));
428 InitLogging(debug_log.value().c_str(), 467 InitLogging(debug_log.value().c_str(),
429 logging::LOG_ONLY_TO_FILE, 468 logging::LOG_ONLY_TO_FILE,
430 logging::DONT_LOCK_LOG_FILE, 469 logging::DONT_LOCK_LOG_FILE,
431 logging::APPEND_TO_OLD_LOG_FILE, 470 logging::APPEND_TO_OLD_LOG_FILE,
432 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); 471 logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
433 472
434 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 473 const CommandLine* command_line = CommandLine::ForCurrentProcess();
435
436 if (command_line->HasSwitch(kHelpSwitchName) || 474 if (command_line->HasSwitch(kHelpSwitchName) ||
437 command_line->HasSwitch(kQuestionSwitchName)) { 475 command_line->HasSwitch(kQuestionSwitchName)) {
438 usage(argv[0]); 476 usage(command_line->GetProgram());
439 return kSuccessExitCode; 477 return kSuccessExitCode;
440 } 478 }
441 479
442 remoting::HostService* service = remoting::HostService::GetInstance(); 480 remoting::HostService* service = remoting::HostService::GetInstance();
443 if (!service->InitWithCommandLine(command_line)) { 481 if (!service->InitWithCommandLine(command_line)) {
444 usage(argv[0]); 482 usage(command_line->GetProgram());
445 return kUsageExitCode; 483 return kUsageExitCode;
446 } 484 }
447 485
448 return service->Run(); 486 return service->Run();
449 } 487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698