summaryrefslogtreecommitdiffstats
path: root/cloud_print
diff options
context:
space:
mode:
authorabodenha@google.com <abodenha@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-26 21:32:36 +0000
committerabodenha@google.com <abodenha@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-26 21:32:36 +0000
commitf145ca463ecf500d505ae32cf96e9bb0433f86ff (patch)
tree03df17360733000b928e79bc90d683ddbb4bc967 /cloud_print
parenta1d7ade311655229a712a6eb9a3e1e72411d416a (diff)
downloadchromium_src-f145ca463ecf500d505ae32cf96e9bb0433f86ff.zip
chromium_src-f145ca463ecf500d505ae32cf96e9bb0433f86ff.tar.gz
chromium_src-f145ca463ecf500d505ae32cf96e9bb0433f86ff.tar.bz2
Create initial installer for virtual print driver.
Caveats: Only installs and registers the port monitor dll for now (Installation of the actual printer/driver is not done) Requires port monitor dlls to be in the same folder as the setup program during install. Versioning is not done. Code signing and packaging are not done Installation of the actual printer/driver is not done Sophos on hive whines and tries to quarantine the installer (I suspect that signing the code will fix this) BUG= TEST=Copy installer and port monitor dlls to the same folder. Run the installer as admin. Success message should display. Open the printers dialog and open properties for any printer. GCP: should be listed under ports. Make sure no printer is using the GCP: port. Run the installer again as admin and pass --uninstall on the command line. Success message should display. The GCP: port should no longer be available. The port monitor dll should no longer exist in c:\windows\system32 This should work on XP, Vista, and Windows 7 both 32 and 64 bit. Review URL: http://codereview.chromium.org/6895026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83075 0039d316-1c4b-4281-b951-d872f2087c98
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_
+
+
+