diff options
-rw-r--r-- | build/all.gyp | 13 | ||||
-rw-r--r-- | cloud_print/service/win/DEPS | 3 | ||||
-rw-r--r-- | cloud_print/service/win/chrome_launcher.cc | 2 | ||||
-rw-r--r-- | cloud_print/service/win/cloud_print_service.cc | 4 | ||||
-rw-r--r-- | cloud_print/service/win/service.gyp | 66 | ||||
-rw-r--r-- | cloud_print/service/win/service_state.cc | 211 | ||||
-rw-r--r-- | cloud_print/service/win/service_state.h | 103 | ||||
-rw-r--r-- | cloud_print/service/win/service_state_unittest.cc | 89 | ||||
-rw-r--r-- | cloud_print/service/win/service_switches.cc | 16 | ||||
-rw-r--r-- | cloud_print/service/win/service_switches.h | 19 | ||||
-rw-r--r-- | cloud_print/virtual_driver/virtual_driver.gyp | 15 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/install/virtual_driver_install.gyp | 9 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/port_monitor/port_monitor.cc | 73 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/port_monitor/port_monitor.h | 4 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc | 11 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/port_monitor/virtual_driver_port_monitor.gyp | 66 |
16 files changed, 671 insertions, 33 deletions
diff --git a/build/all.gyp b/build/all.gyp index 7198959..0f8ef6a 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -107,7 +107,8 @@ 'dependencies': [ '../breakpad/breakpad.gyp:*', '../chrome_frame/chrome_frame.gyp:*', - '../cloud_print/cloud_print.gyp:*', + '../cloud_print/service/win/service.gyp:*', + '../cloud_print/virtual_driver/virtual_driver.gyp:*', '../courgette/courgette.gyp:*', '../rlz/rlz.gyp:*', '../sandbox/sandbox.gyp:*', @@ -178,7 +179,6 @@ '../chrome/chrome.gyp:safe_browsing_tests', '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:unit_tests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', @@ -308,7 +308,6 @@ '../chrome/chrome.gyp:safe_browsing_tests', '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:unit_tests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../ui/ui.gyp:gfx_unittests', @@ -336,7 +335,6 @@ '../chrome/chrome.gyp:safe_browsing_tests', '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:unit_tests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', '../ui/ui.gyp:gfx_unittests', @@ -358,7 +356,6 @@ 'type': 'none', 'dependencies': [ '../base/base.gyp:base_unittests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../crypto/crypto.gyp:crypto_unittests', 'temp_gyp/googleurl.gyp:googleurl_unittests', '../net/net.gyp:net_unittests', @@ -376,7 +373,6 @@ 'type': 'none', 'dependencies': [ '../base/base.gyp:base_unittests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../crypto/crypto.gyp:crypto_unittests', '../ipc/ipc.gyp:ipc_tests', '../media/media.gyp:media_unittests', @@ -414,7 +410,6 @@ '../chrome/chrome.gyp:safe_browsing_tests', '../chrome/chrome.gyp:sync_integration_tests', '../chrome/chrome.gyp:unit_tests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_browsertests', '../content/content.gyp:content_unittests', # mini_installer_tests depends on mini_installer. This should be @@ -460,7 +455,6 @@ 'type': 'none', 'dependencies': [ '../base/base.gyp:base_unittests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', '../ipc/ipc.gyp:ipc_tests', @@ -481,7 +475,6 @@ 'dependencies': [ '../base/base.gyp:base_unittests', '../chrome/chrome.gyp:unit_tests', - '../cloud_print/cloud_print.gyp:cloud_print_unittests', '../content/content.gyp:content_unittests', '../crypto/crypto.gyp:crypto_unittests', '../ipc/ipc.gyp:ipc_tests', @@ -526,7 +519,7 @@ '../chrome_frame/chrome_frame.gyp:npchrome_frame', '../courgette/courgette.gyp:courgette', '../courgette/courgette.gyp:courgette64', - '../cloud_print/cloud_print.gyp:cloud_print', + '../cloud_print/virtual_driver/virtual_driver.gyp:virtual_driver', '../remoting/remoting.gyp:remoting_webapp', '../third_party/adobe/flash/flash_player.gyp:flash_player', ], diff --git a/cloud_print/service/win/DEPS b/cloud_print/service/win/DEPS new file mode 100644 index 0000000..8fa9d48 --- /dev/null +++ b/cloud_print/service/win/DEPS @@ -0,0 +1,3 @@ +include_rules = [ + "+net", +] diff --git a/cloud_print/service/win/chrome_launcher.cc b/cloud_print/service/win/chrome_launcher.cc index 5921fd0..8b984f0 100644 --- a/cloud_print/service/win/chrome_launcher.cc +++ b/cloud_print/service/win/chrome_launcher.cc @@ -12,7 +12,7 @@ #include "base/win/registry.h" #include "base/win/scoped_handle.h" #include "base/win/scoped_process_information.h" -#include "cloud_print/service/service_switches.h" +#include "cloud_print/service/win/service_switches.h" namespace { diff --git a/cloud_print/service/win/cloud_print_service.cc b/cloud_print/service/win/cloud_print_service.cc index f87c2888..c0948c4 100644 --- a/cloud_print/service/win/cloud_print_service.cc +++ b/cloud_print/service/win/cloud_print_service.cc @@ -15,10 +15,10 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/win/scoped_handle.h" -#include "cloud_print/service/service_state.h" -#include "cloud_print/service/service_switches.h" #include "cloud_print/service/win/chrome_launcher.h" #include "cloud_print/service/win/resource.h" +#include "cloud_print/service/win/service_state.h" +#include "cloud_print/service/win/service_switches.h" namespace { diff --git a/cloud_print/service/win/service.gyp b/cloud_print/service/win/service.gyp new file mode 100644 index 0000000..b365e83 --- /dev/null +++ b/cloud_print/service/win/service.gyp @@ -0,0 +1,66 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'target_defaults': { + 'variables': { + 'chromium_code': 1, + }, + 'include_dirs': [ + '../../..', + ], + }, + 'targets': [ + { + 'target_name': 'cloud_print_service_lib', + 'type': 'static_library', + 'dependencies': [ + '../../../base/base.gyp:base', + '../../../build/temp_gyp/googleurl.gyp:googleurl', + '../../../net/net.gyp:net', + ], + 'sources': [ + 'chrome_launcher.cc', + 'chrome_launcher.h', + 'service_state.cc', + 'service_state.h', + 'service_switches.cc', + 'service_switches.h', + ] + }, + { + 'target_name': 'cloud_print_service', + 'type': 'executable', + 'sources': [ + 'cloud_print_service.cc', + 'cloud_print_service.h', + 'cloud_print_service.rc', + 'resource.h', + ], + 'dependencies': [ + 'cloud_print_service_lib', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '1', # Set /SUBSYSTEM:CONSOLE + 'UACExecutionLevel': '2', # /level='requireAdministrator' + }, + }, + }, + { + 'target_name': 'cloud_print_service_unittests', + 'type': 'executable', + 'sources': [ + 'service_state_unittest.cc', + ], + 'dependencies': [ + '../../../base/base.gyp:run_all_unittests', + '../../../base/base.gyp:base', + '../../../base/base.gyp:test_support_base', + '../../../testing/gmock.gyp:gmock', + '../../../testing/gtest.gyp:gtest', + 'cloud_print_service_lib', + ], + }, + ], +} diff --git a/cloud_print/service/win/service_state.cc b/cloud_print/service/win/service_state.cc new file mode 100644 index 0000000..8641000 --- /dev/null +++ b/cloud_print/service/win/service_state.cc @@ -0,0 +1,211 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cloud_print/service/win/service_state.h" + +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" +#include "base/logging.h" +#include "base/message_loop.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "net/base/escape.h" +#include "net/base/io_buffer.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_builder.h" + +namespace { + +const char kCloudPrintJsonName[] = "cloud_print"; +const char kEnabledOptionName[] = "enabled"; + +const char kEmailOptionName[] = "email"; +const char kPasswordOptionName[] = "password"; +const char kProxyIdOptionName[] = "proxy_id"; +const char kRobotEmailOptionName[] = "robot_email"; +const char kRobotTokenOptionName[] = "robot_refresh_token"; +const char kAuthTokenOptionName[] = "auth_token"; +const char kXmppAuthTokenOptionName[] = "xmpp_auth_token"; + +const char kClientLoginUrl[] = "https://www.google.com/accounts/ClientLogin"; + +const int64 kRequestTimeoutMs = 10 * 1000; + +class ServiceStateURLRequestDelegate : public net::URLRequest::Delegate { + public: + virtual void OnResponseStarted(net::URLRequest* request) { + if (request->GetResponseCode() == 200) { + Read(request); + if (request->status().is_io_pending()) + return; + } + request->Cancel(); + }; + + virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) { + Read(request); + if (!request->status().is_io_pending()) + MessageLoop::current()->Quit(); + }; + + const std::string& data() const { + return data_; + } + + private: + void Read(net::URLRequest* request) { + // Read as many bytes as are available synchronously. + const int kBufSize = 100000; + scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize)); + int num_bytes = 0; + while (request->Read(buf, kBufSize, &num_bytes)) { + data_.append(buf->data(), buf->data() + num_bytes); + } + } + std::string data_; +}; + + +void SetNotEmptyJsonString(base::DictionaryValue* dictionary, + const std::string& name, + const std::string& value) { + if (!value.empty()) + dictionary->SetString(name, value); +} + +} // namespace + +ServiceState::ServiceState() { + Reset(); +} + +ServiceState::~ServiceState() { +} + +void ServiceState::Reset() { + email_.clear(); + proxy_id_.clear(); + robot_email_.clear(); + robot_token_.clear(); + auth_token_.clear(); + xmpp_auth_token_.clear(); +} + +bool ServiceState::FromString(const std::string& json) { + Reset(); + scoped_ptr<base::Value> data(base::JSONReader::Read(json)); + if (!data.get()) + return false; + + const base::DictionaryValue* services = NULL; + if (!data->GetAsDictionary(&services)) + return false; + + base::DictionaryValue* cloud_print = NULL; + if (!services->GetDictionary(kCloudPrintJsonName, &cloud_print)) + return false; + + bool valid_file = true; + // Don't exit on fail. Collect all data for re-use by user later. + if (!cloud_print->GetBoolean(kEnabledOptionName, &valid_file)) + valid_file = false; + + cloud_print->GetString(kEmailOptionName, &email_); + cloud_print->GetString(kProxyIdOptionName, &proxy_id_); + cloud_print->GetString(kRobotEmailOptionName, &robot_email_); + cloud_print->GetString(kRobotTokenOptionName, &robot_token_); + cloud_print->GetString(kAuthTokenOptionName, &auth_token_); + cloud_print->GetString(kXmppAuthTokenOptionName, &xmpp_auth_token_); + + return valid_file && IsValid(); +} + +bool ServiceState::IsValid() const { + if (email_.empty() || proxy_id_.empty()) + return false; + bool valid_robot = !robot_email_.empty() && !robot_token_.empty(); + bool valid_auth = !auth_token_.empty() && !xmpp_auth_token_.empty(); + return valid_robot || valid_auth; +} + +std::string ServiceState::ToString() { + scoped_ptr<base::DictionaryValue> services(new DictionaryValue()); + + scoped_ptr<base::DictionaryValue> cloud_print(new DictionaryValue()); + cloud_print->SetBoolean(kEnabledOptionName, true); + + SetNotEmptyJsonString(cloud_print.get(), kEmailOptionName, email_); + SetNotEmptyJsonString(cloud_print.get(), kProxyIdOptionName, proxy_id_); + SetNotEmptyJsonString(cloud_print.get(), kRobotEmailOptionName, robot_email_); + SetNotEmptyJsonString(cloud_print.get(), kRobotTokenOptionName, robot_token_); + SetNotEmptyJsonString(cloud_print.get(), kAuthTokenOptionName, auth_token_); + SetNotEmptyJsonString(cloud_print.get(), kXmppAuthTokenOptionName, + xmpp_auth_token_); + + services->Set(kCloudPrintJsonName, cloud_print.release()); + + std::string json; + base::JSONWriter::WriteWithOptions(services.get(), + base::JSONWriter::OPTIONS_PRETTY_PRINT, + &json); + return json; +} + +std::string ServiceState::LoginToGoogle(const std::string& service, + const std::string& email, + const std::string& password) { + MessageLoop loop(MessageLoop::TYPE_IO); + + net::URLRequestContextBuilder builder; + scoped_ptr<net::URLRequestContext> context(builder.Build()); + + ServiceStateURLRequestDelegate fetcher_delegate; + GURL url(kClientLoginUrl); + + std::string post_body; + post_body += "accountType=GOOGLE"; + post_body += "&Email=" + net::EscapeUrlEncodedData(email, true); + post_body += "&Passwd=" + net::EscapeUrlEncodedData(password, true); + post_body += "&source=" + net::EscapeUrlEncodedData("CP-Service", true); + post_body += "&service=" + net::EscapeUrlEncodedData(service, true); + + net::URLRequest request(url, &fetcher_delegate); + + request.AppendBytesToUpload(post_body.c_str(), post_body.size()); + request.SetExtraRequestHeaderByName( + "Content-Type", "application/x-www-form-urlencoded", true); + request.set_context(context.get()); + request.set_method("POST"); + request.Start(); + + MessageLoop::current()->PostDelayedTask( + FROM_HERE, MessageLoop::QuitClosure(), kRequestTimeoutMs); + + MessageLoop::current()->Run(); + + const char kAuthStart[] = "Auth="; + std::vector<std::string> lines; + Tokenize(fetcher_delegate.data(), "\r\n", &lines); + for (size_t i = 0; i < lines.size(); ++i) { + std::vector<std::string> tokens; + if (StartsWithASCII(lines[i], kAuthStart, false)) + return lines[i].substr(arraysize(kAuthStart) - 1); + } + + return std::string(); +} + +bool ServiceState::Configure(const std::string& email, + const std::string& password, + const std::string& proxy_id) { + robot_token_.clear(); + robot_email_.clear(); + email_ = email; + proxy_id_ = proxy_id; + auth_token_ = LoginToGoogle("cloudprint", email_, password); + xmpp_auth_token_ = LoginToGoogle("chromiumsync", email_, password); + return IsValid(); +} + diff --git a/cloud_print/service/win/service_state.h b/cloud_print/service/win/service_state.h new file mode 100644 index 0000000..ef037bb --- /dev/null +++ b/cloud_print/service/win/service_state.h @@ -0,0 +1,103 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CLOUD_PRINT_SERVICE_SERVICE_STATE_H_ +#define CLOUD_PRINT_SERVICE_SERVICE_STATE_H_ + +#include <string> + +#include "base/file_path.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" + +class FilePath; + +// Manages Cloud Print part of Service State. +class ServiceState { + public: + ServiceState(); + virtual ~ServiceState(); + + void Reset(); + + // Initialize object from json. + bool FromString(const std::string& json); + + // Returns object state as json. + std::string ToString(); + + // Setups object using data provided by delegate. + bool Configure(const std::string& email, + const std::string& password, + const std::string& proxy_id); + + // Returns authentication token provided by Google server. + virtual std::string LoginToGoogle(const std::string& service, + const std::string& email, + const std::string& password); + + // Returns true of object state is valid. + bool IsValid() const; + + std::string email() const { + return email_; + }; + + std::string proxy_id() const { + return proxy_id_; + }; + + std::string robot_email() const { + return robot_email_; + }; + + std::string robot_token() const { + return robot_token_; + }; + + std::string auth_token() const { + return auth_token_; + }; + + std::string xmpp_auth_token() const { + return xmpp_auth_token_; + }; + + void set_email(const std::string& value) { + email_ = value; + }; + + void set_proxy_id(const std::string& value) { + proxy_id_ = value; + }; + + void set_robot_email(const std::string& value) { + robot_email_ = value; + }; + + void set_robot_token(const std::string& value) { + robot_token_ = value; + }; + + void set_auth_token(const std::string& value) { + auth_token_ = value; + }; + + void set_xmpp_auth_token(const std::string& value) { + xmpp_auth_token_ = value; + }; + + private: + std::string email_; + std::string proxy_id_; + std::string robot_email_; + std::string robot_token_; + std::string auth_token_; + std::string xmpp_auth_token_; + + DISALLOW_COPY_AND_ASSIGN(ServiceState); +}; + +#endif // CLOUD_PRINT_SERVICE_SERVICE_STATE_H_ + diff --git a/cloud_print/service/win/service_state_unittest.cc b/cloud_print/service/win/service_state_unittest.cc new file mode 100644 index 0000000..00c651e --- /dev/null +++ b/cloud_print/service/win/service_state_unittest.cc @@ -0,0 +1,89 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cloud_print/service/win/service_state.h" + +#include "base/string_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::Exactly; +using ::testing::Return; + +TEST(ServiceStateTest, Empty) { + ServiceState state; + EXPECT_FALSE(state.IsValid()); +} + +TEST(ServiceStateTest, ToString) { + ServiceState state; + EXPECT_STREQ("{\"cloud_print\": {\"enabled\": true}}", + CollapseWhitespaceASCII(state.ToString(), true).c_str()); + state.set_email("test@gmail.com"); + state.set_proxy_id("proxy"); + state.set_robot_email("robot@gmail.com"); + state.set_robot_token("abc"); + state.set_auth_token("token1"); + state.set_xmpp_auth_token("token2"); + EXPECT_TRUE(state.IsValid()); + EXPECT_STREQ("{\"cloud_print\": {\"auth_token\": \"token1\",\"email\": " + "\"test@gmail.com\",\"enabled\": true,\"proxy_id\": \"proxy\"," + "\"robot_email\": \"robot@gmail.com\",\"robot_refresh_token\": " + "\"abc\",\"xmpp_auth_token\": \"token2\"}}", + CollapseWhitespaceASCII(state.ToString(), true).c_str()); +} + +TEST(ServiceStateTest, FromString) { + ServiceState state; + // Syntax error. + EXPECT_FALSE(state.FromString("<\"cloud_print\": {\"enabled\": true}}")); + // No data. + EXPECT_FALSE(state.FromString("{\"cloud_print\": {\"enabled\": true}}")); + EXPECT_FALSE(state.FromString( + "{\"cloud_print\": {\"email\": \"test@gmail.com\"}}")); + EXPECT_STREQ("test@gmail.com", state.email().c_str()); + + // Good state. + EXPECT_TRUE(state.FromString( + "{\"cloud_print\": {\"email\": \"test2@gmail.com\",\"enabled\": true,\"" + "proxy_id\": \"proxy\",\"robot_email\": \"robot@gmail.com\",\"" + "robot_refresh_token\": \"abc\"}}")); + EXPECT_STREQ("test2@gmail.com", state.email().c_str()); + EXPECT_STREQ("proxy", state.proxy_id().c_str()); + EXPECT_STREQ("robot@gmail.com", state.robot_email().c_str()); + EXPECT_STREQ("abc", state.robot_token().c_str()); +} + +class ServiceStateMock : public ServiceState { + public: + ServiceStateMock() {} + + MOCK_METHOD3(LoginToGoogle, + std::string(const std::string& service, + const std::string& email, + const std::string& password)); + + private: + DISALLOW_COPY_AND_ASSIGN(ServiceStateMock); +}; + +TEST(ServiceStateTest, Configure) { + ServiceStateMock state; + state.set_email("test1@gmail.com"); + state.set_proxy_id("id1"); + + EXPECT_CALL(state, LoginToGoogle("cloudprint", "test2@gmail.com", "abc")) + .Times(Exactly(1)) + .WillOnce(Return("auth1")); + EXPECT_CALL(state, LoginToGoogle("chromiumsync", "test2@gmail.com", "abc")) + .Times(Exactly(1)) + .WillOnce(Return("auth2")); + + EXPECT_TRUE(state.Configure("test2@gmail.com", "abc", "id2")); + + EXPECT_STREQ("id2", state.proxy_id().c_str()); + EXPECT_STREQ("auth1", state.auth_token().c_str()); + EXPECT_STREQ("auth2", state.xmpp_auth_token().c_str()); +} diff --git a/cloud_print/service/win/service_switches.cc b/cloud_print/service/win/service_switches.cc new file mode 100644 index 0000000..296eae0 --- /dev/null +++ b/cloud_print/service/win/service_switches.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cloud_print/service/win/service_switches.h" + +const char kChromeTypeSwitch[] = "type"; +const char kConsoleSwitch[] = "console"; +const char kInstallSwitch[] = "install"; +const char kQuietSwitch[] = "quiet"; +const char kServiceSwitch[] = "service"; +const char kStartSwitch[] = "start"; +const char kStopSwitch[] = "stop"; +const char kUninstallSwitch[] = "uninstall"; +const char kUserDataDirSwitch[] = "user-data-dir"; + diff --git a/cloud_print/service/win/service_switches.h b/cloud_print/service/win/service_switches.h new file mode 100644 index 0000000..17af981 --- /dev/null +++ b/cloud_print/service/win/service_switches.h @@ -0,0 +1,19 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CLOUD_PRINT_SERVICE_SERVICE_SWITCHES_H_ +#define CLOUD_PRINT_SERVICE_SERVICE_SWITCHES_H_ + +extern const char kChromeTypeSwitch[]; +extern const char kConsoleSwitch[]; +extern const char kInstallSwitch[]; +extern const char kQuietSwitch[]; +extern const char kServiceSwitch[]; +extern const char kStartSwitch[]; +extern const char kStopSwitch[]; +extern const char kUninstallSwitch[]; +extern const char kUserDataDirSwitch[]; + +#endif // CLOUD_PRINT_SERVICE_SERVICE_SWITCHES_H_ + diff --git a/cloud_print/virtual_driver/virtual_driver.gyp b/cloud_print/virtual_driver/virtual_driver.gyp new file mode 100644 index 0000000..8368ffb --- /dev/null +++ b/cloud_print/virtual_driver/virtual_driver.gyp @@ -0,0 +1,15 @@ +# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'targets': [ + { + 'target_name': 'virtual_driver', + 'type': 'none', + 'dependencies': [ + 'win/install/virtual_driver_install.gyp:*', + 'win/port_monitor/virtual_driver_port_monitor.gyp:*', + ], + }, + ], +} diff --git a/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp b/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp index deb36e7..5318f99 100644 --- a/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp +++ b/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp @@ -8,7 +8,7 @@ 'chromium_code': 1, }, 'include_dirs': [ - '<(DEPTH)', + '../../../..', ], }, 'targets' : [ @@ -16,12 +16,15 @@ 'target_name': 'virtual_driver_setup', 'type': 'executable', 'dependencies': [ - '../virtual_driver.gyp:virtual_driver_lib', - '<(DEPTH)/base/base.gyp:base', + '../../../../base/base.gyp:base', 'virtual_driver_setup_resources', ], 'sources': [ 'setup.cc', + '../virtual_driver_consts.h', + '../virtual_driver_consts.cc', + '../virtual_driver_helpers.h', + '../virtual_driver_helpers.cc', '../virtual_driver_common_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/virtual_driver_setup_resources/virtual_driver_setup_resources_ar.rc', '<(SHARED_INTERMEDIATE_DIR)/virtual_driver_setup_resources/virtual_driver_setup_resources_bg.rc', diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc b/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc index dc46b95d..335b6a8 100644 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc +++ b/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc @@ -30,15 +30,17 @@ namespace cloud_print { -namespace { - +#ifndef UNIT_TEST +const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrome.exe"; +const wchar_t kChromePathRegValue[] = L"PathToChromeExe"; +#endif const wchar_t kIePath[] = L"Internet Explorer\\iexplore.exe"; - const char kChromeInstallUrl[] = "http://google.com/cloudprint/learn/chrome.html"; const wchar_t kChromePathRegKey[] = L"Software\\Google\\CloudPrint"; +namespace { const wchar_t kXpsMimeType[] = L"application/vnd.ms-xpsdocument"; const size_t kMaxCommandLineLen = 0x7FFF; @@ -89,6 +91,36 @@ MONITOR2 g_monitor_2 = { Monitor2Shutdown }; +// Returns true if Xps support is installed. +bool XpsIsInstalled() { + FilePath xps_path; + if (!SUCCEEDED(GetPrinterDriverDir(&xps_path))) { + return false; + } + xps_path = xps_path.Append(L"mxdwdrv.dll"); + if (!file_util::PathExists(xps_path)) { + return false; + } + return true; +} + +// Returns true if registration/unregistration can be attempted. +bool CanRegister() { + if (!XpsIsInstalled()) { + return false; + } + if (base::win::GetVersion() >= base::win::VERSION_VISTA) { + base::IntegrityLevel level = base::INTEGRITY_UNKNOWN; + if (!GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), &level)) { + return false; + } + if (level != base::HIGH_INTEGRITY) { + return false; + } + } + return true; +} + // Frees any objects referenced by port_data and sets pointers to NULL. void CleanupPortData(PortData* port_data) { delete port_data->file_path; @@ -202,8 +234,8 @@ bool LaunchPrintDialog(const string16& xps_path, // rather than the generic chrome download page. See // http://code.google.com/p/chromium/issues/detail?id=112019 void LaunchChromeDownloadPage() { - if (kIsUnittest) - return; +// Probably best to NOT launch IE from a unit test. +#ifndef UNIT_TEST HANDLE token = NULL; if (!GetUserToken(&token)) { LOG(ERROR) << "Unable to get user token."; @@ -220,6 +252,7 @@ void LaunchChromeDownloadPage() { base::LaunchOptions options; options.as_user = token_scoped; base::LaunchProcess(command_line, options, NULL); +#endif } // Returns false if the print job is being run in a context @@ -620,3 +653,33 @@ MONITORUI* WINAPI InitializePrintMonitorUI(void) { return &cloud_print::g_monitor_ui; } +HRESULT WINAPI DllRegisterServer(void) { + base::AtExitManager at_exit_manager; + if (!cloud_print::CanRegister()) { + return E_ACCESSDENIED; + } + MONITOR_INFO_2 monitor_info = {0}; + // YUCK!!! I can either copy the constant, const_cast, or define my own + // MONITOR_INFO_2 that will take const strings. + FilePath dll_path(cloud_print::GetPortMonitorDllName()); + monitor_info.pDLLName = const_cast<LPWSTR>(dll_path.value().c_str()); + monitor_info.pName = const_cast<LPWSTR>(dll_path.value().c_str()); + if (AddMonitor(NULL, 2, reinterpret_cast<BYTE*>(&monitor_info))) { + return S_OK; + } + return cloud_print::GetLastHResult(); +} + +HRESULT WINAPI DllUnregisterServer(void) { + base::AtExitManager at_exit_manager; + if (!cloud_print::CanRegister()) { + return E_ACCESSDENIED; + } + FilePath dll_path(cloud_print::GetPortMonitorDllName()); + if (DeleteMonitor(NULL, + NULL, + const_cast<LPWSTR>(dll_path.value().c_str()))) { + return S_OK; + } + return cloud_print::GetLastHResult(); +} diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor.h b/cloud_print/virtual_driver/win/port_monitor/port_monitor.h index e9e83f0..5b3c1b9 100644 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.h +++ b/cloud_print/virtual_driver/win/port_monitor/port_monitor.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -79,8 +79,8 @@ BOOL WINAPI MonitorUiConfigureOrDeletePortUI(const wchar_t*, const wchar_t* port_name); extern const wchar_t kChromeExePath[]; +extern const wchar_t kChromePathRegKey[]; extern const wchar_t kChromePathRegValue[]; -extern const bool kIsUnittest; } // namespace cloud_print diff --git a/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc b/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc index 5148276..93de765 100644 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc +++ b/cloud_print/virtual_driver/win/port_monitor/port_monitor_unittest.cc @@ -13,19 +13,10 @@ #include "testing/gtest/include/gtest/gtest.h" namespace cloud_print { - const wchar_t kChromeExePath[] = L"google\\chrome\\application\\chrometest.exe"; -const wchar_t kChromePathRegValue[] =L"PathToChromeTestExe"; -const bool kIsUnittest = true; - -namespace { - const wchar_t kAlternateChromeExePath[] = L"google\\chrome\\application\\chrometestalternate.exe"; - -const wchar_t kChromePathRegKey[] = L"Software\\Google\\CloudPrint"; - -} // namespace +const wchar_t kChromePathRegValue[] =L"PathToChromeTestExe"; class PortMonitorTest : public testing::Test { public: diff --git a/cloud_print/virtual_driver/win/port_monitor/virtual_driver_port_monitor.gyp b/cloud_print/virtual_driver/win/port_monitor/virtual_driver_port_monitor.gyp new file mode 100644 index 0000000..630b5e4 --- /dev/null +++ b/cloud_print/virtual_driver/win/port_monitor/virtual_driver_port_monitor.gyp @@ -0,0 +1,66 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'target_defaults': { + 'variables': { + 'chromium_code': 1, + }, + 'include_dirs': [ + '../..', + ], + 'libraries': [ + 'userenv.lib', + ], + 'sources': [ + '../../virtual_driver_switches.cc', + '../../virtual_driver_switches.h', + '../virtual_driver_consts.cc', + '../virtual_driver_consts.h', + '../virtual_driver_helpers.cc', + '../virtual_driver_helpers.h', + '../virtual_driver_common_resources.rc', + 'port_monitor.cc', + 'port_monitor.h', + 'port_monitor.def', + ], + }, + 'targets' : [ + { + 'target_name': 'gcp_portmon', + 'type': 'loadable_module', + 'dependencies': [ + '../../../../base/base.gyp:base', + ], + }, + { + 'target_name': 'gcp_portmon64', + 'type': 'loadable_module', + 'defines': [ + '<@(nacl_win64_defines)', + ], + 'dependencies': [ + '../../../../base/base.gyp:base_nacl_win64', + ], + 'configurations': { + 'Common_Base': { + 'msvs_target_platform': 'x64', + }, + }, + }, + { + 'target_name': 'virtual_driver_unittests', + 'type': 'executable', + 'dependencies': [ + '../../../../base/base.gyp:base', + '../../../../base/base.gyp:run_all_unittests', + '../../../../testing/gmock.gyp:gmock', + '../../../../testing/gtest.gyp:gtest', + ], + 'sources': [ + 'port_monitor_unittest.cc', + ], + }, + ], +} |