MD Downloads: prevent search text from overlapping with the cancel search (X)
[chromium-blink-merge.git] / remoting / host / host_main.cc
blob6e4c2b5576f4d6956d2697982eba8f17d89ee327
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // This file implements the common entry point shared by all Chromoting Host
6 // processes.
8 #include "remoting/host/host_main.h"
10 #include <string>
12 #include "base/at_exit.h"
13 #include "base/command_line.h"
14 #include "base/files/file_path.h"
15 #include "base/i18n/icu_util.h"
16 #include "base/logging.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringize_macros.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h"
21 #include "remoting/base/breakpad.h"
22 #include "remoting/host/host_exit_codes.h"
23 #include "remoting/host/logging.h"
24 #include "remoting/host/resources.h"
25 #include "remoting/host/setup/me2me_native_messaging_host.h"
26 #include "remoting/host/switches.h"
27 #include "remoting/host/usage_stats_consent.h"
29 #if defined(OS_MACOSX)
30 #include "base/mac/scoped_nsautorelease_pool.h"
31 #endif // defined(OS_MACOSX)
33 #if defined(OS_WIN)
34 #include <commctrl.h>
35 #include <shellapi.h>
36 #endif // defined(OS_WIN)
38 namespace remoting {
40 // Known entry points.
41 int HostProcessMain();
42 #if defined(OS_WIN)
43 int DaemonProcessMain();
44 int DesktopProcessMain();
45 int RdpDesktopSessionMain();
46 #endif // defined(OS_WIN)
48 namespace {
50 typedef int (*MainRoutineFn)();
52 const char kUsageMessage[] =
53 "Usage: %s [options]\n"
54 "\n"
55 "Options:\n"
56 " --audio-pipe-name=<pipe> - Sets the pipe name to capture audio on Linux.\n"
57 " --console - Runs the daemon interactively.\n"
58 " --daemon-pipe=<pipe> - Specifies the pipe to connect to the daemon.\n"
59 " --elevate=<binary> - Runs <binary> elevated.\n"
60 " --host-config=<config> - Specifies the host configuration.\n"
61 " --help, -? - Print this message.\n"
62 " --type - Specifies process type.\n"
63 " --version - Prints the host version and exits.\n"
64 " --window-id=<id> - Specifies a window to remote,"
65 " instead of the whole desktop.\n";
67 void Usage(const base::FilePath& program_name) {
68 printf(kUsageMessage, program_name.MaybeAsASCII().c_str());
71 #if defined(OS_WIN)
73 // Runs the binary specified by the command line, elevated.
74 int RunElevated() {
75 const base::CommandLine::SwitchMap& switches =
76 base::CommandLine::ForCurrentProcess()->GetSwitches();
77 base::CommandLine::StringVector args =
78 base::CommandLine::ForCurrentProcess()->GetArgs();
80 // Create the child process command line by copying switches from the current
81 // command line.
82 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
83 for (base::CommandLine::SwitchMap::const_iterator i = switches.begin();
84 i != switches.end(); ++i) {
85 if (i->first != kElevateSwitchName)
86 command_line.AppendSwitchNative(i->first, i->second);
88 for (base::CommandLine::StringVector::const_iterator i = args.begin();
89 i != args.end(); ++i) {
90 command_line.AppendArgNative(*i);
93 // Get the name of the binary to launch.
94 base::FilePath binary =
95 base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
96 kElevateSwitchName);
97 base::CommandLine::StringType parameters =
98 command_line.GetCommandLineString();
100 // Launch the child process requesting elevation.
101 SHELLEXECUTEINFO info;
102 memset(&info, 0, sizeof(info));
103 info.cbSize = sizeof(info);
104 info.lpVerb = L"runas";
105 info.lpFile = binary.value().c_str();
106 info.lpParameters = parameters.c_str();
107 info.nShow = SW_SHOWNORMAL;
109 if (!ShellExecuteEx(&info)) {
110 DWORD exit_code = GetLastError();
111 PLOG(ERROR) << "Unable to launch '" << binary.value() << "'";
112 return exit_code;
115 return kSuccessExitCode;
118 #endif // !defined(OS_WIN)
120 // Select the entry point corresponding to the process type.
121 MainRoutineFn SelectMainRoutine(const std::string& process_type) {
122 MainRoutineFn main_routine = nullptr;
124 if (process_type == kProcessTypeHost) {
125 main_routine = &HostProcessMain;
126 #if defined(OS_WIN)
127 } else if (process_type == kProcessTypeDaemon) {
128 main_routine = &DaemonProcessMain;
129 } else if (process_type == kProcessTypeDesktop) {
130 main_routine = &DesktopProcessMain;
131 } else if (process_type == kProcessTypeRdpDesktopSession) {
132 main_routine = &RdpDesktopSessionMain;
133 #endif // defined(OS_WIN)
136 return main_routine;
139 } // namespace
141 int HostMain(int argc, char** argv) {
142 #if defined(OS_MACOSX)
143 // Needed so we don't leak objects when threads are created.
144 base::mac::ScopedNSAutoreleasePool pool;
145 #endif
147 base::CommandLine::Init(argc, argv);
149 // Initialize Breakpad as early as possible. On Mac the command-line needs to
150 // be initialized first, so that the preference for crash-reporting can be
151 // looked up in the config file.
152 #if defined(REMOTING_ENABLE_BREAKPAD)
153 if (IsUsageStatsAllowed()) {
154 InitializeCrashReporting();
156 #endif // defined(REMOTING_ENABLE_BREAKPAD)
158 // This object instance is required by Chrome code (for example,
159 // LazyInstance, MessageLoop).
160 base::AtExitManager exit_manager;
162 // Enable debug logs.
163 InitHostLogging();
165 // Register and initialize common controls.
166 #if defined(OS_WIN)
167 INITCOMMONCONTROLSEX info;
168 info.dwSize = sizeof(info);
169 info.dwICC = ICC_STANDARD_CLASSES;
170 InitCommonControlsEx(&info);
171 #endif // defined(OS_WIN)
173 // Parse the command line.
174 const base::CommandLine* command_line =
175 base::CommandLine::ForCurrentProcess();
176 if (command_line->HasSwitch(kHelpSwitchName) ||
177 command_line->HasSwitch(kQuestionSwitchName)) {
178 Usage(command_line->GetProgram());
179 return kSuccessExitCode;
182 if (command_line->HasSwitch(kVersionSwitchName)) {
183 printf("%s\n", STRINGIZE(VERSION));
184 return kSuccessExitCode;
187 #if defined(OS_WIN)
188 if (command_line->HasSwitch(kElevateSwitchName)) {
189 return RunElevated();
191 #endif // defined(OS_WIN)
193 // Assume the host process by default.
194 std::string process_type = kProcessTypeHost;
195 if (command_line->HasSwitch(kProcessTypeSwitchName)) {
196 process_type = command_line->GetSwitchValueASCII(kProcessTypeSwitchName);
199 MainRoutineFn main_routine = SelectMainRoutine(process_type);
200 if (!main_routine) {
201 fprintf(stderr, "Unknown process type '%s' specified.",
202 process_type.c_str());
203 Usage(command_line->GetProgram());
204 return kUsageExitCode;
207 // Required to find the ICU data file, used by some file_util routines.
208 base::i18n::InitializeICU();
210 remoting::LoadResources("");
212 // Invoke the entry point.
213 int exit_code = main_routine();
214 if (exit_code == kUsageExitCode) {
215 Usage(command_line->GetProgram());
218 remoting::UnloadResources();
220 return exit_code;
223 } // namespace remoting
225 #if !defined(OS_WIN)
226 int main(int argc, char** argv) {
227 return remoting::HostMain(argc, argv);
229 #endif // !defined(OS_WIN)