summaryrefslogtreecommitdiffstats
path: root/cloud_print/service/win/cloud_print_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cloud_print/service/win/cloud_print_service.cc')
-rw-r--r--cloud_print/service/win/cloud_print_service.cc277
1 files changed, 148 insertions, 129 deletions
diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc
index bbdde7e..10456dd 100644
--- a/cloud_print/service/win/cloud_print_service.cc
+++ b/cloud_print/service/win/cloud_print_service.cc
@@ -9,6 +9,7 @@
#include <iostream>
#include "base/at_exit.h"
+#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/guid.h"
@@ -35,8 +36,8 @@ void InvalidUsage() {
base::FilePath service_path;
CHECK(PathService::Get(base::FILE_EXE, &service_path));
- std::cout << "Usage: ";
- std::cout << service_path.BaseName().value();
+ std::cout << cloud_print::LoadLocalString(IDS_COMMAND_LINE_HELP_TITLE);
+ std::cout << " " << service_path.BaseName().value();
std::cout << " [";
std::cout << "[";
std::cout << "[";
@@ -48,68 +49,77 @@ void InvalidUsage() {
std::cout << " | -" << kStartSwitch;
std::cout << " | -" << kStopSwitch;
std::cout << " ]\n";
- std::cout << "Manages cloud print windows service.\n\n";
+ std::cout << cloud_print::LoadLocalString(IDS_COMMAND_LINE_DESCRIPTION);
+ std::cout << "\n\n";
- static const struct {
+ struct {
const char* name;
- const char* description;
- } kSwitchHelp[] = {
- { kInstallSwitch, "Installs cloud print as service." },
- { switches::kUserDataDir,
- "User data directory with \"Service State\" file." },
- { kUninstallSwitch, "Uninstalls service." },
- { kStartSwitch, "Starts service. May be combined with installation." },
- { kStopSwitch, "Stops service." },
- };
+ int description;
+ } kSwitchHelp[] = {{
+ kInstallSwitch, IDS_SWITCH_HELP_INSTALL
+ }, {
+ switches::kUserDataDir, IDS_SWITCH_HELP_DATA_DIR
+ }, {
+ kUninstallSwitch, IDS_SWITCH_HELP_UNINSTALL
+ }, {
+ kStartSwitch, IDS_SWITCH_HELP_START
+ }, {
+ kStopSwitch, IDS_SWITCH_HELP_STOP
+ }};
for (size_t i = 0; i < arraysize(kSwitchHelp); ++i) {
std::cout << std::setiosflags(std::ios::left);
std::cout << " -" << std::setw(16) << kSwitchHelp[i].name;
- std::cout << kSwitchHelp[i].description << "\n";
+ std::cout << cloud_print::LoadLocalString(kSwitchHelp[i].description);
+ std::cout << "\n";
}
std::cout << "\n";
}
-std::string GetOption(const std::string& name, const std::string& default,
- bool secure) {
- std::cout << name;
- if (!default.empty()) {
- std::cout << ", press [ENTER] to keep '";
- std::cout << default;
- std::cout << "'";
- }
- std::cout << ": ";
- std::string tmp;
-
+string16 GetOption(int string_id, const string16& default,
+ bool secure) {
+ string16 prompt_format = cloud_print::LoadLocalString(string_id) ;
+ std::vector<string16> substitutions(1, default);
+ std::cout << ReplaceStringPlaceholders(prompt_format, substitutions, NULL);
+ string16 tmp;
if (secure) {
DWORD saved_mode = 0;
// Don't close.
HANDLE stdin_handle = ::GetStdHandle(STD_INPUT_HANDLE);
::GetConsoleMode(stdin_handle, &saved_mode);
::SetConsoleMode(stdin_handle, saved_mode & ~ENABLE_ECHO_INPUT);
- std::getline(std::cin, tmp);
+ std::getline(std::wcin, tmp);
::SetConsoleMode(stdin_handle, saved_mode);
std::cout << "\n";
} else {
- std::getline(std::cin, tmp);
+ std::getline(std::wcin, tmp);
}
if (tmp.empty())
return default;
return tmp;
}
-bool AskUser(const std::string& request) {
- for (;;) {
- std::cout << request << " [Y/n]:";
- std::string input;
- std::getline(std::cin, input);
- StringToLowerASCII(&input);
- if (input.empty() || input == "y") {
- return true;
- } else if (input == "n") {
- return false;
- }
+HRESULT ReportError(HRESULT hr, int string_id) {
+ LOG(ERROR) << cloud_print::GetErrorMessage(hr);
+ std::cerr << cloud_print::LoadLocalString(string_id);
+ std::cerr << "\n";
+ return hr;
+}
+
+string16 StateAsString(ServiceController::State state) {
+ DWORD string_id = 0;
+ switch(state) {
+ case ServiceController::STATE_NOT_FOUND:
+ string_id = IDS_SERVICE_NOT_FOUND;
+ break;
+ case ServiceController::STATE_STOPPED:
+ string_id = IDS_SERVICE_STOPPED;
+ break;
+ case ServiceController::STATE_RUNNING:
+ string_id = IDS_SERVICE_RUNNING;
+ break;
}
+ return string_id ? cloud_print::LoadLocalString(string_id) : string16();
}
} // namespace
@@ -141,11 +151,18 @@ class CloudPrintServiceModule
CHECK(pnRetCode);
CommandLine command_line(CommandLine::NO_PROGRAM);
command_line.ParseFromString(lpCmdLine);
+
+ LOG(INFO) << command_line.GetCommandLineString();
+
bool is_service = false;
*pnRetCode = ParseCommandLine(command_line, &is_service);
if (FAILED(*pnRetCode)) {
- LOG(ERROR) << "Operation failed. 0x" << std::setw(8) <<
- std::setbase(16) << *pnRetCode;
+ ReportError(*pnRetCode, IDS_OPERATION_FAILED_TITLE);
+ }
+ if (!is_service) {
+ controller_->UpdateState();
+ std::cout << cloud_print::LoadLocalString(IDS_STATE_LABEL);
+ std::cout << " " << StateAsString(controller_->state());
}
return is_service;
}
@@ -185,6 +202,7 @@ class CloudPrintServiceModule
command_line.GetSwitchValuePath(switches::kUserDataDir);
if (!user_data_dir_switch_.empty())
user_data_dir_switch_ = base::MakeAbsoluteFilePath(user_data_dir_switch_);
+
if (command_line.HasSwitch(kStopSwitch))
return controller_->StopService();
@@ -196,12 +214,15 @@ class CloudPrintServiceModule
string16 run_as_password;
base::FilePath user_data_dir;
std::vector<std::string> printers;
- SelectWindowsAccount(&run_as_user, &run_as_password, &user_data_dir,
- &printers);
+ HRESULT hr = SelectWindowsAccount(&run_as_user, &run_as_password,
+ &user_data_dir, &printers);
+ if (FAILED(hr))
+ return hr;
+
DCHECK(user_data_dir_switch_.empty() ||
user_data_dir_switch_ == user_data_dir);
- HRESULT hr = SetupServiceState(user_data_dir, printers);
+ hr = SetupServiceState(user_data_dir, printers);
if (FAILED(hr))
return hr;
@@ -237,112 +258,99 @@ class CloudPrintServiceModule
return S_FALSE;
}
- void SelectWindowsAccount(string16* run_as_user, string16* run_as_password,
- base::FilePath* user_data_dir,
- std::vector<std::string>* printers) {
+ HRESULT SelectWindowsAccount(string16* run_as_user, string16* run_as_password,
+ base::FilePath* user_data_dir,
+ std::vector<std::string>* printers) {
*run_as_user = GetCurrentUserName();
- for (;;) {
- std::cout << "\nPlease provide Windows account to run service.\n";
- *run_as_user = ASCIIToWide(GetOption("Account as DOMAIN\\USERNAME",
- WideToASCII(*run_as_user), false));
- *run_as_user = ReplaceLocalHostInName(*run_as_user);
- *run_as_password = ASCIIToWide(GetOption("Password", "", true));
-
- SetupListener setup(*run_as_user);
- if (FAILED(controller_->InstallCheckService(*run_as_user,
+ std::cout << cloud_print::LoadLocalString(IDS_WINDOWS_USER_PROMPT1) << "\n";
+ *run_as_user = GetOption(IDS_WINDOWS_USER_PROMPT2, *run_as_user, false);
+ *run_as_user = ReplaceLocalHostInName(*run_as_user);
+ *run_as_password = GetOption(IDS_WINDOWS_PASSWORD_PROMPT, L"", true);
+ SetupListener setup(*run_as_user);
+ HRESULT hr = controller_->InstallCheckService(*run_as_user,
*run_as_password,
- user_data_dir_switch_))) {
- LOG(ERROR) << "Failed to install service as " << *run_as_user << ".";
- continue;
- }
+ user_data_dir_switch_);
+ if (FAILED(hr)) {
+ return ReportError(hr, IDS_ERROR_FAILED_INSTALL_SERVICE);
+ }
- bool service_started = SUCCEEDED(controller_->StartService());
+ {
+ // Always uninstall service after requirements check.
+ base::ScopedClosureRunner scoped_uninstall(
+ base::Bind(base::IgnoreResult(&ServiceController::UninstallService),
+ base::Unretained(controller_.get())));
- if (service_started &&
- !setup.WaitResponce(base::TimeDelta::FromSeconds(30))) {
- LOG(ERROR) << "Failed to check environment for user " << *run_as_user
- << ".";
+ hr = controller_->StartService();
+ if (FAILED(hr)) {
+ return ReportError(hr, IDS_ERROR_FAILED_START_SERVICE);
}
- controller_->UninstallService();
- if (!service_started) {
- LOG(ERROR) << "Failed to start service as " << *run_as_user << ".";
- continue;
- }
- if (setup.user_data_dir().empty()) {
- LOG(ERROR) << "Service can't write data directory.";
- continue;
- }
- if (setup.chrome_path().empty()) {
- LOG(ERROR) << "Chrome is not available for " << *run_as_user << ".";
- continue;
- }
- if (!setup.is_xps_available()) {
- LOG(ERROR) << "XPS pack is not installed.";
- continue;
+ if (!setup.WaitResponce(base::TimeDelta::FromSeconds(30))) {
+ return ReportError(E_FAIL, IDS_ERROR_FAILED_START_SERVICE);
}
+ }
- std::cout << "\nService requirements check result: \n";
- std::cout << "Username: " << setup.user_name()<< "\n";
- std::cout << "Chrome: " << setup.chrome_path().value()<< "\n";
- std::cout << "UserDataDir: " << setup.user_data_dir().value()<< "\n";
- std::cout << "Printers:\n ";
- std::ostream_iterator<std::string> cout_it(std::cout, "\n ");
- std::copy(setup.printers().begin(), setup.printers().end(), cout_it);
- std::cout << "\n";
-
- if (AskUser("Do you want to use " + WideToASCII(*run_as_user) + "?")) {
- *user_data_dir = setup.user_data_dir();
- *printers = setup.printers();
- return;
- }
+ if (setup.user_data_dir().empty()) {
+ return ReportError(E_FAIL, IDS_ERROR_NO_DATA_DIR);
+ }
+
+ if (setup.chrome_path().empty()) {
+ return ReportError(E_FAIL, IDS_ERROR_NO_CHROME);
+ }
+
+ if (!setup.is_xps_available()) {
+ return ReportError(E_FAIL, IDS_ERROR_NO_XPS);
}
+
+ std::cout << "\n";
+ std::cout << cloud_print::LoadLocalString(IDS_SERVICE_ENV_CHECK);
+ std::cout << "\n";
+ std::cout << cloud_print::LoadLocalString(IDS_SERVICE_ENV_USER);
+ std::cout << "\n " << setup.user_name() << "\n";
+ std::cout << cloud_print::LoadLocalString(IDS_SERVICE_ENV_CHROME);
+ std::cout << "\n " << setup.chrome_path().value() << "\n";
+ std::cout << cloud_print::LoadLocalString(IDS_SERVICE_ENV_DATADIR);
+ std::cout << "\n " << setup.user_data_dir().value() << "\n";
+ std::cout << cloud_print::LoadLocalString(IDS_SERVICE_ENV_PRINTERS);
+ std::cout << "\n ";
+ std::ostream_iterator<std::string> cout_it(std::cout, "\n ");
+ std::copy(setup.printers().begin(), setup.printers().end(), cout_it);
+ std::cout << "\n";
+
+ *user_data_dir = setup.user_data_dir();
+ *printers = setup.printers();
+ return S_OK;
}
HRESULT SetupServiceState(const base::FilePath& user_data_dir,
const std::vector<std::string>& printers) {
base::FilePath file = user_data_dir.Append(chrome::kServiceStateFileName);
- for (size_t try_count = 0;; ++try_count) {
- std::string contents;
- ServiceState service_state;
+ std::string contents;
+ ServiceState service_state;
- bool is_valid = file_util::ReadFileToString(file, &contents) &&
- service_state.FromString(contents);
- std::string proxy_id = service_state.proxy_id();
+ bool is_valid = file_util::ReadFileToString(file, &contents) &&
+ service_state.FromString(contents);
+ std::string proxy_id = service_state.proxy_id();
- std::cout << "\nFile '" << file.value() << "' content:\n";
- std::cout << contents << "\n";
+ LOG(INFO) << file.value() << ": " << contents;
- if (!is_valid && try_count) {
- LOG(ERROR) << "Invalid or missing file: " << file.value();
- }
+ string16 message =
+ cloud_print::LoadLocalString(IDS_ADD_PRINTERS_USING_CHROME);
+ std::cout << "\n" << message.c_str() << "\n" ;
+ std::string new_contents =
+ ChromeLauncher::CreateServiceStateFile(proxy_id, printers);
- if (is_valid) {
- if (AskUser("Do you want to use '" + WideToASCII(file.value()) + "'")) {
- return S_OK;
- } else {
- is_valid = false;
- }
- }
-
- string16 message =
- cloud_print::LoadLocalString(IDS_ADD_PRINTERS_USING_CHROME);
- std::cout << "\n" << message.c_str() << "\n" ;
- std::string new_contents =
- ChromeLauncher::CreateServiceStateFile(proxy_id, printers);
+ if (new_contents.empty()) {
+ return ReportError(E_FAIL, IDS_ERROR_FAILED_CREATE_CONFIG);
+ }
- if (new_contents.empty()) {
- LOG(ERROR) << "Failed create Service State file.";
- return E_FAIL;
- }
- if (new_contents != contents) {
- size_t written = file_util::WriteFile(file, new_contents.c_str(),
- new_contents.size());
- if (written != new_contents.size()) {
- LOG(ERROR) << "Failed to write file " << file.value() << ".";
- return cloud_print::GetLastHResult();
- }
+ if (new_contents != contents) {
+ size_t written = file_util::WriteFile(file, new_contents.c_str(),
+ new_contents.size());
+ if (written != new_contents.size()) {
+ return ReportError(cloud_print::GetLastHResult(),
+ IDS_ERROR_FAILED_CREATE_CONFIG);
}
}
@@ -392,6 +400,17 @@ BOOL CloudPrintServiceModule::ConsoleCtrlHandler(DWORD type) {
int main(int argc, char** argv) {
CommandLine::Init(argc, argv);
base::AtExitManager at_exit;
+
+ logging::InitLogging(NULL,
+ logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
+ logging::LOCK_LOG_FILE,
+ logging::APPEND_TO_OLD_LOG_FILE,
+ logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
+
+ logging::SetMinLogLevel(
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableLogging) ?
+ logging::LOG_INFO : logging::LOG_FATAL);
+
return _AtlModule.WinMain(0);
}