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