diff options
Diffstat (limited to 'cloud_print')
-rwxr-xr-x[-rw-r--r--] | cloud_print/virtual_driver/virtual_driver.gyp | 38 | ||||
-rwxr-xr-x | cloud_print/virtual_driver/win/install/setup.cc | 145 | ||||
-rw-r--r-- | cloud_print/virtual_driver/win/port_monitor/port_monitor.cc | 72 | ||||
-rwxr-xr-x | cloud_print/virtual_driver/win/virtual_driver_consts.cc | 13 | ||||
-rwxr-xr-x | cloud_print/virtual_driver/win/virtual_driver_consts.h | 15 | ||||
-rwxr-xr-x | cloud_print/virtual_driver/win/virtual_driver_helpers.cc | 31 | ||||
-rwxr-xr-x | cloud_print/virtual_driver/win/virtual_driver_helpers.h | 23 |
7 files changed, 310 insertions, 27 deletions
diff --git a/cloud_print/virtual_driver/virtual_driver.gyp b/cloud_print/virtual_driver/virtual_driver.gyp index b7435ea..dab48b9 100644..100755 --- a/cloud_print/virtual_driver/virtual_driver.gyp +++ b/cloud_print/virtual_driver/virtual_driver.gyp @@ -1,7 +1,8 @@ # 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. - +# TODO(abodenha@chromium.org) Consider splitting port monitor stuff into +# its own file. { 'includes': [ '../../build/common.gypi', @@ -19,9 +20,10 @@ 'userenv.lib', ], 'sources': [ - 'win/port_monitor/port_monitor.cc', - 'win/port_monitor/port_monitor.h', - 'win/port_monitor/port_monitor.def', + 'win/virtual_driver_helpers.h', + 'win/virtual_driver_helpers.cc', + 'win/virtual_driver_consts.h', + 'win/virtual_driver_consts.cc', ], }, 'conditions': [ @@ -34,6 +36,11 @@ '../../base/base.gyp:base', ], 'msvs_guid': 'ED3D7186-C94E-4D8B-A8E7-B7260F638F46', + 'sources': [ + 'win/port_monitor/port_monitor.cc', + 'win/port_monitor/port_monitor.h', + 'win/port_monitor/port_monitor.def', + ], }, { 'target_name': 'gcp_portmon64', @@ -44,6 +51,11 @@ 'dependencies': [ '../../base/base.gyp:base_nacl_win64', ], + 'sources': [ + 'win/port_monitor/port_monitor.cc', + 'win/port_monitor/port_monitor.h', + 'win/port_monitor/port_monitor.def', + ], 'msvs_guid': '9BB292F4-6104-495A-B415-C3E314F46D6F', 'configurations': { 'Common_Base': { @@ -64,9 +76,27 @@ 'sources': [ # Infrastructure files. '../../base/test/run_all_unittests.cc', + 'win/port_monitor/port_monitor.cc', + 'win/port_monitor/port_monitor.h', 'win/port_monitor/port_monitor_unittest.cc' ], }, + { + 'target_name': 'virtual_driver_setup', + 'type': 'executable', + 'msvs_guid': 'E1E25ACA-043D-4D6E-A06F-97126532843A', + 'dependencies': [ + '../../base/base.gyp:base', + ], + 'sources': [ + 'win/install/setup.cc', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS + }, + }, + }, ], }, ], diff --git a/cloud_print/virtual_driver/win/install/setup.cc b/cloud_print/virtual_driver/win/install/setup.cc new file mode 100755 index 0000000..820acf7 --- /dev/null +++ b/cloud_print/virtual_driver/win/install/setup.cc @@ -0,0 +1,145 @@ +// 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. + +#include <windows.h> + +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/file_util.h" +#include "base/path_service.h" +#include "base/process_util.h" +#include "base/win/scoped_handle.h" +#include "base/win/windows_version.h" +#include "cloud_print/virtual_driver/win/virtual_driver_consts.h"
+#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" +
+namespace {
+
+bool IsSystem64Bit() {
+ base::win::OSInfo::WindowsArchitecture arch =
+ base::win::OSInfo::GetInstance()->architecture();
+ return (arch == base::win::OSInfo::X64_ARCHITECTURE) ||
+ (arch == base::win::OSInfo::IA64_ARCHITECTURE);
+}
+
+const wchar_t *GetPortMonitorDllName() {
+ if (IsSystem64Bit()) {
+ return cloud_print::kPortMonitorDllName64;
+ } else {
+ return cloud_print::kPortMonitorDllName32;
+ }
+}
+
+HRESULT GetPortMonitorDllPath(FilePath* path) {
+ if (!PathService::Get(base::DIR_EXE, path)) {
+ return ERROR_PATH_NOT_FOUND;
+ }
+ *path = path->Append(GetPortMonitorDllName());
+ return S_OK;
+}
+
+HRESULT GetPortMonitorInstallPath(FilePath* path) {
+ if (IsSystem64Bit()) {
+ if (!PathService::Get(base::DIR_WINDOWS, path)) {
+ return ERROR_PATH_NOT_FOUND;
+ }
+ // Sysnative will bypass filesystem redirection and give us
+ // the location of the 64bit system32 from a 32 bit process.
+ *path = path->Append(L"sysnative");
+ } else {
+ if (!PathService::Get(base::DIR_SYSTEM, path)) {
+ return ERROR_PATH_NOT_FOUND;
+ }
+ }
+ *path = path->Append(GetPortMonitorDllName());
+ return S_OK;
+}
+
+HRESULT GetRegsvr32Path(FilePath* path) {
+ if (!PathService::Get(base::DIR_SYSTEM, path)) {
+ return ERROR_PATH_NOT_FOUND;
+ }
+ *path = path->Append(FilePath(L"regsvr32.exe"));
+ return S_OK;
+}
+
+HRESULT RegisterPortMonitor(bool install) {
+ FilePath target_path;
+ HRESULT result = S_OK;
+ result = GetPortMonitorInstallPath(&target_path);
+ if (!SUCCEEDED(result)) {
+ return result;
+ }
+ FilePath dll_path;
+ result = GetPortMonitorDllPath(&dll_path);
+ if (!SUCCEEDED(result)) {
+ return result;
+ }
+ if (install) {
+ if (!file_util::CopyFileW(dll_path, target_path)) {
+ return cloud_print::GetLastHResult();
+ }
+ }
+ FilePath regsvr32_path;
+ result = GetRegsvr32Path(®svr32_path);
+ if (!SUCCEEDED(result)) {
+ return result;
+ }
+ CommandLine command_line(regsvr32_path);
+ command_line.AppendArg("/s");
+ if (!install) {
+ command_line.AppendArg("/u");
+ }
+ command_line.AppendArgPath(dll_path);
+ HANDLE process_handle;
+ if (!base::LaunchApp(command_line.command_line_string(),
+ true,
+ false,
+ &process_handle)) {
+ return cloud_print::GetLastHResult();
+ }
+ base::win::ScopedHandle scoped_process_handle(process_handle);
+ DWORD exit_code = S_OK;
+ if (!GetExitCodeProcess(scoped_process_handle, &exit_code)) {
+ return cloud_print::GetLastHResult();
+ }
+ if (exit_code != 0) {
+ return HRESULT_FROM_WIN32(exit_code);
+ }
+ if (!install) {
+ if (!file_util::Delete(target_path, false)) {
+ return cloud_print::GetLastHResult();
+ }
+ }
+ return S_OK;
+}
+
+HRESULT InstallVirtualDriver(void) {
+ return RegisterPortMonitor(true);
+}
+
+HRESULT UninstallVirtualDriver(void) {
+ return RegisterPortMonitor(false);
+}
+ +} // namespace
+
+int WINAPI WinMain(__in HINSTANCE hInstance,
+ __in HINSTANCE hPrevInstance,
+ __in LPSTR lpCmdLine,
+ __in int nCmdShow) {
+ base::AtExitManager at_exit_manager; + CommandLine::Init(0, NULL);
+ HRESULT retval = S_OK;
+ if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) {
+ retval = UninstallVirtualDriver();
+ } else {
+ retval = InstallVirtualDriver();
+ }
+ if (!CommandLine::ForCurrentProcess()->HasSwitch("silent")) {
+ cloud_print::DisplayWindowsMessage(NULL, retval);
+ }
+ return retval;
+}
+
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 05c5272..6b4449f 100644 --- a/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc +++ b/cloud_print/virtual_driver/win/port_monitor/port_monitor.cc @@ -21,7 +21,10 @@ #include "base/string16.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" +#include "base/win/windows_version.h" #include "cloud_print/virtual_driver/win/port_monitor/spooler_win.h" +#include "cloud_print/virtual_driver/win/virtual_driver_consts.h"
+#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" namespace switches { // These constants are duplicated from chrome/common/chrome_switches.cc @@ -57,9 +60,9 @@ const wchar_t kChromePathRegKey[] = L"Software\\Google\\CloudPrint"; namespace { #ifdef _WIN64 -const wchar_t kPortMonitorDllName[] = L"gcp_portmon64.dll"; +const wchar_t *kPortMonitorDllName = kPortMonitorDllName64; #else -const wchar_t kPortMonitorDllName[] = L"gcp_portmon.dll"; +const wchar_t *kPortMonitorDllName = kPortMonitorDllName32; #endif const wchar_t kPortName[] = L"GCP:"; @@ -68,7 +71,6 @@ const wchar_t kXpsMimeType[] = L"application/vnd.ms-xpsdocument"; const size_t kMaxCommandLineLen = 0x7FFF; -const size_t kMaxMessageLen = 100; struct MonitorData { base::AtExitManager* at_exit_manager; @@ -115,16 +117,51 @@ MONITOR2 g_monitor_2 = { Monitor2Shutdown }; +// Gets the standard install path for "version 3" print drivers.
+HRESULT GetPrinterDriverPath(FilePath* path) {
+ BYTE driver_dir_buffer[MAX_PATH * sizeof(wchar_t)];
+ DWORD needed = 0;
+ if (!GetPrinterDriverDirectory(NULL,
+ NULL,
+ 1,
+ driver_dir_buffer,
+ MAX_PATH * sizeof(wchar_t),
+ &needed)) {
+ // We could try to allocate a larger buffer if needed > MAX_PATH
+ // but that really shouldn't happen.
+ return cloud_print::GetLastHResult();
+ }
+ *path = FilePath(reinterpret_cast<wchar_t*>(driver_dir_buffer));
+ *path = path->Append(L"3"); + return S_OK;
+}
+ +// Returns true if Xps support is installed. +bool XpsIsInstalled() { + FilePath xps_path; + if (!SUCCEEDED(GetPrinterDriverPath(&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() { - // TODO(abodenha@chromium.org) Add handling for XP. - // Should Verify admin rights and that XPS is installed. - base::IntegrityLevel level = base::INTEGRITY_UNKNOWN; - if (!GetProcessIntegrityLevel(base::GetCurrentProcessHandle(), &level)) { + if (!XpsIsInstalled()) { return false; } - if (level != base::HIGH_INTEGRITY) { - 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; } @@ -179,16 +216,7 @@ bool GetJobTitle(HANDLE printer_handle, // configuration. void HandlePortUi(HWND hwnd, const string16& caption) { if (hwnd != NULL && IsWindow(hwnd)) { - wchar_t message_text[kMaxMessageLen + 1] = L""; - - ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - CO_E_NOT_SUPPORTED, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - message_text, - kMaxMessageLen, - NULL); - ::MessageBox(hwnd, message_text, caption.c_str(), MB_OK); + DisplayWindowsMessage(hwnd, CO_E_NOT_SUPPORTED); } } @@ -625,8 +653,7 @@ HRESULT WINAPI DllRegisterServer(void) { if (AddMonitor(NULL, 2, reinterpret_cast<BYTE*>(&monitor_info))) { return S_OK; } - DWORD error_code = GetLastError(); - return HRESULT_FROM_WIN32(error_code); + return cloud_print::GetLastHResult();
} HRESULT WINAPI DllUnregisterServer(void) { @@ -639,6 +666,5 @@ HRESULT WINAPI DllUnregisterServer(void) { const_cast<LPWSTR>(cloud_print::kPortMonitorDllName))) { return S_OK; } - DWORD error_code = GetLastError(); - return HRESULT_FROM_WIN32(error_code); + return cloud_print::GetLastHResult();
} diff --git a/cloud_print/virtual_driver/win/virtual_driver_consts.cc b/cloud_print/virtual_driver/win/virtual_driver_consts.cc new file mode 100755 index 0000000..cd177b5 --- /dev/null +++ b/cloud_print/virtual_driver/win/virtual_driver_consts.cc @@ -0,0 +1,13 @@ +// 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. + +#include "cloud_print/virtual_driver/win/virtual_driver_consts.h" +#include <windows.h> +#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" + +namespace cloud_print { +const wchar_t kPortMonitorDllName64[] = L"gcp_portmon64.dll";
+const wchar_t kPortMonitorDllName32[] = L"gcp_portmon.dll";
+}
+
diff --git a/cloud_print/virtual_driver/win/virtual_driver_consts.h b/cloud_print/virtual_driver/win/virtual_driver_consts.h new file mode 100755 index 0000000..6cd995f --- /dev/null +++ b/cloud_print/virtual_driver/win/virtual_driver_consts.h @@ -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. + +#ifndef CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_ +#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_ +#pragma once + +namespace cloud_print { +extern const wchar_t kPortMonitorDllName64[];
+extern const wchar_t kPortMonitorDllName32[];
+} + +#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_ + diff --git a/cloud_print/virtual_driver/win/virtual_driver_helpers.cc b/cloud_print/virtual_driver/win/virtual_driver_helpers.cc new file mode 100755 index 0000000..c59211c --- /dev/null +++ b/cloud_print/virtual_driver/win/virtual_driver_helpers.cc @@ -0,0 +1,31 @@ +// 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. + +#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" +#include <windows.h> +#include "cloud_print/virtual_driver/win/virtual_driver_consts.h" + +namespace cloud_print { + +const size_t kMaxMessageLen = 100; + +void DisplayWindowsMessage(HWND hwnd, HRESULT message_id) { + wchar_t message_text[kMaxMessageLen + 1] = L""; + + ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + message_id, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + message_text, + kMaxMessageLen, + NULL); + ::MessageBox(hwnd, message_text, L"GCP", MB_OK); +} + +HRESULT GetLastHResult() { + DWORD error_code = GetLastError(); + return HRESULT_FROM_WIN32(error_code); +} +} + diff --git a/cloud_print/virtual_driver/win/virtual_driver_helpers.h b/cloud_print/virtual_driver/win/virtual_driver_helpers.h new file mode 100755 index 0000000..d8cc089 --- /dev/null +++ b/cloud_print/virtual_driver/win/virtual_driver_helpers.h @@ -0,0 +1,23 @@ +// 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. + +#ifndef CLOUD_PRINT_VIRTUAL_DRIVER_WIN_HELPERS_H_ +#define CLOUD_PRINT_VIRTUAL_DRIVER_WIN_HELPERS_H_ +#pragma once + +#include <windows.h> + +namespace cloud_print { + +// Convert an HRESULT to a localized string and display it in a message box. +void DisplayWindowsMessage(HWND hwnd, HRESULT message_id); + +// Similar to the Windows API call GetLastError but returns an HRESULT. +HRESULT GetLastHResult(); +} + +#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_HELPERS_H_ + + + |