cloud_print_service_config.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <atlbase.h>
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <atlapp.h>  // NOLINT
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/at_exit.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/callback_helpers.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/file_util.h"
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/thread.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/chrome_constants.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/common/win/cloud_print_utils.h"
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/resources.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/service/service_state.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/service/win/chrome_launcher.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/service/win/service_controller.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/service/win/service_utils.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cloud_print/service/win/setup_listener.h"
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using cloud_print::LoadLocalString;
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using cloud_print::GetErrorMessage;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SetupDialog : public base::RefCounted<SetupDialog>,
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    public ATL::CDialogImpl<SetupDialog> {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Enables accelerators.
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class MessageFilter : public base::MessageLoopForUI::MessageFilter {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   public:
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit MessageFilter(SetupDialog* dialog) : dialog_(dialog){}
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    virtual ~MessageFilter() {};
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // MessageLoopForUI::MessageFilter
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    virtual bool ProcessMessage(const MSG& msg) OVERRIDE {
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      MSG msg2 = msg;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return dialog_->IsDialogMessage(&msg2) != FALSE;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   private:
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<SetupDialog> dialog_;
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef ATL::CDialogImpl<SetupDialog> Base;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum { IDD = IDD_SETUP_DIALOG };
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BEGIN_MSG_MAP(SetupDialog)
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtrColor)
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    COMMAND_ID_HANDLER(IDC_START, OnStart)
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    COMMAND_ID_HANDLER(IDC_INSTALL, OnInstall)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    COMMAND_ID_HANDLER(IDC_LOGGING, OnLogging)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  END_MSG_MAP()
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetupDialog();
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Window Message Handlers
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnInitDialog(UINT message, WPARAM wparam, LPARAM lparam,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       BOOL& handled);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnCtrColor(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnCancel(UINT, INT nIdentifier, HWND, BOOL& handled);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnStart(UINT, INT nIdentifier, HWND, BOOL& handled);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnInstall(UINT, INT nIdentifier, HWND, BOOL& handled);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnLogging(UINT, INT nIdentifier, HWND, BOOL& handled);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LRESULT OnDestroy(UINT message, WPARAM wparam, LPARAM lparam, BOOL& handled);
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void PostUITask(const base::Closure& task);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void PostIOTask(const base::Closure& task);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // UI Calls.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Disables all controls after users actions.
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DisableControls();
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Updates state of controls after when we received service status.
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetState(ServiceController::State state, const base::string16& user,
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 bool is_logging_enabled);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show message box with error.
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ShowErrorMessageBox(const base::string16& error_message);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show use message box instructions how to deal with opened Chrome window.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AskToCloseChrome();
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 GetDlgItemText(int id) const;
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 GetUser() const;
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 GetPassword() const;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsLoggingEnabled() const;
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool IsInstalled() const {
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return state_ > ServiceController::STATE_NOT_FOUND;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // IO Calls.
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Installs service.
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void Install(const base::string16& user, const base::string16& password,
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               bool enable_logging);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Starts service.
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Start();
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Stops service.
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Stop();
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Uninstall service.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Uninstall();
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Update service state.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void UpdateState();
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Posts task to UI thread to show error using string id.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ShowError(int string_id);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Posts task to UI thread to show error using string.
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void ShowError(const base::string16& error_message);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Posts task to UI thread to show error using error code.
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ShowError(HRESULT hr);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ServiceController::State state_;
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Thread worker_;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* ui_loop_;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* io_loop_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ServiceController controller_;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SetupDialog::SetupDialog()
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : state_(ServiceController::STATE_NOT_FOUND),
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      worker_("worker") {
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui_loop_ = base::MessageLoop::current();
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(ui_loop_->IsType(base::MessageLoop::TYPE_UI));
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  worker_.StartWithOptions(
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  io_loop_ = worker_.message_loop();
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(io_loop_->IsType(base::MessageLoop::TYPE_IO));
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::PostUITask(const base::Closure& task) {
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ui_loop_->PostTask(FROM_HERE, task);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::PostIOTask(const base::Closure& task) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  io_loop_->PostTask(FROM_HERE, task);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SetupDialog::ShowErrorMessageBox(const base::string16& error_message) {
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_UI));
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MessageBox(error_message.c_str(),
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             LoadLocalString(IDS_OPERATION_FAILED_TITLE).c_str(),
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             MB_ICONERROR | MB_OK);
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::AskToCloseChrome() {
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_UI));
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MessageBox(LoadLocalString(IDS_ADD_PRINTERS_USING_CHROME).c_str(),
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             LoadLocalString(IDS_CONTINUE_IN_CHROME_TITLE).c_str(),
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             MB_OK);
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::SetState(ServiceController::State status,
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                           const base::string16& user,
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           bool is_logging_enabled) {
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_UI));
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  state_ = status;
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DWORD status_string = 0;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch(status) {
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case ServiceController::STATE_NOT_FOUND:
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_string = IDS_SERVICE_NOT_FOUND;
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case ServiceController::STATE_STOPPED:
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_string = IDS_SERVICE_STOPPED;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  case ServiceController::STATE_RUNNING:
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    status_string = IDS_SERVICE_RUNNING;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    break;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_STATUS,
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 status_string ? LoadLocalString(status_string).c_str() : L"");
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsInstalled()) {
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetDlgItemText(IDC_USER, user.c_str());
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CheckDlgButton(IDC_LOGGING,
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   is_logging_enabled ? BST_CHECKED : BST_UNCHECKED);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ATL::CWindow start_button = GetDlgItem(IDC_START);
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DWORD start_string = (status == ServiceController::STATE_STOPPED) ?
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       IDS_SERVICE_START : IDS_SERVICE_STOP;
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  start_button.SetWindowText(LoadLocalString(start_string).c_str());
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  start_button.ShowWindow(IsInstalled() ? SW_SHOW : SW_HIDE);
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  start_button.EnableWindow(TRUE);
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ATL::CWindow install_button = GetDlgItem(IDC_INSTALL);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DWORD install_string = IsInstalled() ? IDS_SERVICE_UNINSTALL :
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         IDS_SERVICE_INSTALL;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_button.SetWindowText(LoadLocalString(install_string).c_str());
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_button.ShowWindow(SW_SHOW);
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  install_button.EnableWindow(TRUE);
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!IsInstalled()) {
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetDlgItem(IDC_USER).EnableWindow(TRUE);
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetDlgItem(IDC_PASSWORD).EnableWindow(TRUE);
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetDlgItem(IDC_LOGGING).EnableWindow(TRUE);
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnInitDialog(UINT message, WPARAM wparam, LPARAM lparam,
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  BOOL& handled) {
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ATLVERIFY(CenterWindow());
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WTL::CIcon icon;
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (icon.LoadIcon(MAKEINTRESOURCE(IDI_ICON))) {
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetIcon(icon);
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetWindowText(LoadLocalString(IDS_SETUP_PROGRAM_NAME).c_str());
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_STATE_LABEL, LoadLocalString(IDS_STATE_LABEL).c_str());
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_USER_LABEL, LoadLocalString(IDS_USER_LABEL).c_str());
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_PASSWORD_LABEL,
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 LoadLocalString(IDS_PASSWORD_LABEL).c_str());
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_LOGGING, LoadLocalString(IDS_LOGGING_LABEL).c_str());
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDCANCEL, LoadLocalString(IDS_CLOSE).c_str());
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetState(ServiceController::STATE_UNKNOWN, L"", false);
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DisableControls();
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetDlgItemText(IDC_USER, GetCurrentUserName().c_str());
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostIOTask(base::Bind(&SetupDialog::UpdateState, this));
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnCtrColor(UINT message, WPARAM wparam, LPARAM lparam,
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                BOOL& handled) {
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HWND window = reinterpret_cast<HWND>(lparam);
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (GetDlgItem(IDC_LOGO).m_hWnd == window) {
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return reinterpret_cast<LRESULT>(::GetStockObject(WHITE_BRUSH));
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnStart(UINT, INT nIdentifier, HWND, BOOL& handled) {
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DisableControls();
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(IsInstalled());
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (state_ == ServiceController::STATE_RUNNING)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostIOTask(base::Bind(&SetupDialog::Stop, this));
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostIOTask(base::Bind(&SetupDialog::Start, this));
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnInstall(UINT, INT nIdentifier, HWND, BOOL& handled) {
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DisableControls();
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsInstalled()) {
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostIOTask(base::Bind(&SetupDialog::Uninstall, this));
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostIOTask(base::Bind(&SetupDialog::Install, this, GetUser(),
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          GetPassword(), IsLoggingEnabled()));
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnLogging(UINT, INT nIdentifier, HWND, BOOL& handled) {
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CheckDlgButton(IDC_LOGGING, IsLoggingEnabled()? BST_UNCHECKED : BST_CHECKED);
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnCancel(UINT, INT nIdentifier, HWND, BOOL& handled) {
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DestroyWindow();
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)LRESULT SetupDialog::OnDestroy(UINT message, WPARAM wparam, LPARAM lparam,
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               BOOL& handled) {
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostTask(FROM_HERE,
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         base::MessageLoop::QuitClosure());
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 1;
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::DisableControls() {
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetDlgItem(IDC_START).EnableWindow(FALSE);
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetDlgItem(IDC_INSTALL).EnableWindow(FALSE);
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetDlgItem(IDC_USER).EnableWindow(FALSE);
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetDlgItem(IDC_PASSWORD).EnableWindow(FALSE);
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetDlgItem(IDC_LOGGING).EnableWindow(FALSE);
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 SetupDialog::GetDlgItemText(int id) const {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ATL::CWindow& item = GetDlgItem(id);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t length = item.GetWindowTextLength();
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 result(length + 1, L'\0');
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  result.resize(item.GetWindowText(&result[0], result.size()));
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return result;
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 SetupDialog::GetUser() const {
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetDlgItemText(IDC_USER);
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 SetupDialog::GetPassword() const {
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return GetDlgItemText(IDC_PASSWORD);
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SetupDialog::IsLoggingEnabled() const{
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return IsDlgButtonChecked(IDC_LOGGING) == BST_CHECKED;
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::UpdateState() {
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller_.UpdateState();
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostUITask(base::Bind(&SetupDialog::SetState, this, controller_.state(),
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        controller_.user(), controller_.is_logging_enabled()));
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SetupDialog::ShowError(const base::string16& error_message) {
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostUITask(base::Bind(&SetupDialog::SetState,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        this,
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        ServiceController::STATE_UNKNOWN,
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        L"",
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        false));
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostUITask(base::Bind(&SetupDialog::ShowErrorMessageBox, this,
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        error_message));
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LOG(ERROR) << error_message;
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::ShowError(int string_id) {
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowError(cloud_print::LoadLocalString(string_id));
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::ShowError(HRESULT hr) {
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ShowError(GetErrorMessage(hr));
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SetupDialog::Install(const base::string16& user,
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          const base::string16& password,
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          bool enable_logging) {
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Don't forget to update state on exit.
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::ScopedClosureRunner scoped_update_status(
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&SetupDialog::UpdateState, this));
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetupListener setup(GetUser());
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = controller_.InstallCheckService(user, password,
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                               base::FilePath());
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(hr);
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  {
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Always uninstall service after requirements check.
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::ScopedClosureRunner scoped_uninstall(
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(base::IgnoreResult(&ServiceController::UninstallService),
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(&controller_)));
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    hr = controller_.StartService();
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (FAILED(hr))
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return ShowError(hr);
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!setup.WaitResponce(base::TimeDelta::FromSeconds(30)))
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return ShowError(IDS_ERROR_FAILED_START_SERVICE);
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (setup.user_data_dir().empty())
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(IDS_ERROR_NO_DATA_DIR);
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (setup.chrome_path().empty())
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(IDS_ERROR_NO_CHROME);
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!setup.is_xps_available())
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(IDS_ERROR_NO_XPS);
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath file = setup.user_data_dir();
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file = file.Append(chrome::kServiceStateFileName);
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string proxy_id;
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string contents;
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (base::ReadFileToString(file, &contents)) {
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ServiceState service_state;
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (service_state.FromString(contents))
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      proxy_id = service_state.proxy_id();
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostUITask(base::Bind(&SetupDialog::AskToCloseChrome, this));
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents = ChromeLauncher::CreateServiceStateFile(proxy_id, setup.printers());
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (contents.empty())
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(IDS_ERROR_FAILED_CREATE_CONFIG);
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t written = file_util::WriteFile(file, contents.c_str(),
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        contents.size());
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (written != contents.size()) {
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DWORD last_error = GetLastError();
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!last_error)
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return ShowError(IDS_ERROR_FAILED_CREATE_CONFIG);
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(HRESULT_FROM_WIN32(last_error));
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = controller_.InstallConnectorService(user, password, base::FilePath(),
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                           enable_logging);
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(hr);
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  hr = controller_.StartService();
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return ShowError(hr);
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::Start() {
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = controller_.StartService();
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowError(hr);
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateState();
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::Stop() {
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = controller_.StopService();
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowError(hr);
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateState();
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetupDialog::Uninstall() {
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(base::MessageLoop::current()->IsType(base::MessageLoop::TYPE_IO));
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HRESULT hr = controller_.UninstallService();
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (FAILED(hr))
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ShowError(hr);
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateState();
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class CloudPrintServiceConfigModule
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public ATL::CAtlExeModuleT<CloudPrintServiceConfigModule> {
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CloudPrintServiceConfigModule _AtlModule;
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int WINAPI WinMain(__in  HINSTANCE hInstance,
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   __in  HINSTANCE hPrevInstance,
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   __in  LPSTR lpCmdLine,
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   __in  int nCmdShow) {
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::AtExitManager at_exit;
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CommandLine::Init(0, NULL);
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoopForUI loop;
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SetupDialog> dialog(new SetupDialog());
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dialog->Create(NULL);
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  dialog->ShowWindow(SW_SHOW);
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<SetupDialog::MessageFilter> filter(
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new SetupDialog::MessageFilter(dialog));
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  loop.SetMessageFilter(filter.Pass());
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  loop.Run();
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return 0;
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
454