This source file includes following definitions.
- Usage
- RunElevated
- SelectMainRoutine
- HostMain
#include "remoting/host/host_main.h"
#include <string>
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringize_macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "remoting/base/breakpad.h"
#include "remoting/base/resources.h"
#include "remoting/host/host_exit_codes.h"
#include "remoting/host/logging.h"
#include "remoting/host/setup/me2me_native_messaging_host.h"
#include "remoting/host/usage_stats_consent.h"
#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#endif
#if defined(OS_WIN)
#include <commctrl.h>
#include <shellapi.h>
#endif
namespace remoting {
int HostProcessMain();
#if defined(OS_WIN)
int DaemonProcessMain();
int DesktopProcessMain();
int ElevatedControllerMain();
int RdpDesktopSessionMain();
#endif
const char kElevateSwitchName[] = "elevate";
const char kProcessTypeSwitchName[] = "type";
const char kProcessTypeController[] = "controller";
const char kProcessTypeDaemon[] = "daemon";
const char kProcessTypeDesktop[] = "desktop";
const char kProcessTypeHost[] = "host";
const char kProcessTypeRdpDesktopSession[] = "rdp_desktop_session";
namespace {
typedef int (*MainRoutineFn)();
const char kHelpSwitchName[] = "help";
const char kQuestionSwitchName[] = "?";
const char kVersionSwitchName[] = "version";
const char kUsageMessage[] =
"Usage: %s [options]\n"
"\n"
"Options:\n"
" --audio-pipe-name=<pipe> - Sets the pipe name to capture audio on Linux.\n"
" --console - Runs the daemon interactively.\n"
" --daemon-pipe=<pipe> - Specifies the pipe to connect to the daemon.\n"
" --elevate=<binary> - Runs <binary> elevated.\n"
" --host-config=<config> - Specifies the host configuration.\n"
" --help, -? - Print this message.\n"
" --type - Specifies process type.\n"
" --version - Prints the host version and exits.\n";
void Usage(const base::FilePath& program_name) {
printf(kUsageMessage, program_name.MaybeAsASCII().c_str());
}
#if defined(OS_WIN)
int RunElevated() {
const CommandLine::SwitchMap& switches =
CommandLine::ForCurrentProcess()->GetSwitches();
CommandLine::StringVector args = CommandLine::ForCurrentProcess()->GetArgs();
CommandLine command_line(CommandLine::NO_PROGRAM);
for (CommandLine::SwitchMap::const_iterator i = switches.begin();
i != switches.end(); ++i) {
if (i->first != kElevateSwitchName)
command_line.AppendSwitchNative(i->first, i->second);
}
for (CommandLine::StringVector::const_iterator i = args.begin();
i != args.end(); ++i) {
command_line.AppendArgNative(*i);
}
base::FilePath binary =
CommandLine::ForCurrentProcess()->GetSwitchValuePath(kElevateSwitchName);
CommandLine::StringType parameters = command_line.GetCommandLineString();
SHELLEXECUTEINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.lpVerb = L"runas";
info.lpFile = binary.value().c_str();
info.lpParameters = parameters.c_str();
info.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&info)) {
DWORD exit_code = GetLastError();
LOG_GETLASTERROR(ERROR) << "Unable to launch '" << binary.value() << "'";
return exit_code;
}
return kSuccessExitCode;
}
#endif
MainRoutineFn SelectMainRoutine(const std::string& process_type) {
MainRoutineFn main_routine = NULL;
if (process_type == kProcessTypeHost) {
main_routine = &HostProcessMain;
#if defined(OS_WIN)
} else if (process_type == kProcessTypeDaemon) {
main_routine = &DaemonProcessMain;
} else if (process_type == kProcessTypeDesktop) {
main_routine = &DesktopProcessMain;
} else if (process_type == kProcessTypeController) {
main_routine = &ElevatedControllerMain;
} else if (process_type == kProcessTypeRdpDesktopSession) {
main_routine = &RdpDesktopSessionMain;
#endif
}
return main_routine;
}
}
int HostMain(int argc, char** argv) {
#if defined(OS_MACOSX)
base::mac::ScopedNSAutoreleasePool pool;
#endif
CommandLine::Init(argc, argv);
#if defined(REMOTING_ENABLE_BREAKPAD)
if (IsUsageStatsAllowed()) {
InitializeCrashReporting();
}
#endif
base::AtExitManager exit_manager;
InitHostLogging();
#if defined(OS_WIN)
INITCOMMONCONTROLSEX info;
info.dwSize = sizeof(info);
info.dwICC = ICC_STANDARD_CLASSES;
InitCommonControlsEx(&info);
#endif
const CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kHelpSwitchName) ||
command_line->HasSwitch(kQuestionSwitchName)) {
Usage(command_line->GetProgram());
return kSuccessExitCode;
}
if (command_line->HasSwitch(kVersionSwitchName)) {
printf("%s\n", STRINGIZE(VERSION));
return kSuccessExitCode;
}
#if defined(OS_WIN)
if (command_line->HasSwitch(kElevateSwitchName)) {
return RunElevated();
}
#endif
std::string process_type = kProcessTypeHost;
if (command_line->HasSwitch(kProcessTypeSwitchName)) {
process_type = command_line->GetSwitchValueASCII(kProcessTypeSwitchName);
}
MainRoutineFn main_routine = SelectMainRoutine(process_type);
if (!main_routine) {
fprintf(stderr, "Unknown process type '%s' specified.",
process_type.c_str());
Usage(command_line->GetProgram());
return kUsageExitCode;
}
base::i18n::InitializeICU();
remoting::LoadResources("");
int exit_code = main_routine();
if (exit_code == kUsageExitCode) {
Usage(command_line->GetProgram());
}
remoting::UnloadResources();
return exit_code;
}
}