summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
Diffstat (limited to 'cloud_print')
-rwxr-xr-x[-rw-r--r--]cloud_print/virtual_driver/virtual_driver.gyp38
-rwxr-xr-xcloud_print/virtual_driver/win/install/setup.cc145
-rw-r--r--cloud_print/virtual_driver/win/port_monitor/port_monitor.cc72
-rwxr-xr-xcloud_print/virtual_driver/win/virtual_driver_consts.cc13
-rwxr-xr-xcloud_print/virtual_driver/win/virtual_driver_consts.h15
-rwxr-xr-xcloud_print/virtual_driver/win/virtual_driver_helpers.cc31
-rwxr-xr-xcloud_print/virtual_driver/win/virtual_driver_helpers.h23
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(&regsvr32_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_
+
+
+