0

Added resources.

Virtual_driver_setup now has localization support.
All dlls and exes now have a version resource.
Common (untranslated) strings are now pulled from a common resource file.
Installer and port monitor now have separate .gyp files.
Still to do: Integrate with TC and add all languages.

BUG=
TEST=

Review URL: http://codereview.chromium.org/6930019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85825 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
abodenha@google.com
2011-05-18 22:12:41 +00:00
parent c3f3840bee
commit 973da4d5cf
13 changed files with 362 additions and 176 deletions

@ -1,106 +1,17 @@
# 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',
],
'target_defaults': {
'variables': {
'chromium_code': 1,
'version_py_path': '../../chrome/tools/build/version.py',
'version_path': 'VERSION',
},
'include_dirs': [
'../..',
],
'libraries': [
'userenv.lib',
],
'sources': [
'win/virtual_driver_helpers.h',
'win/virtual_driver_helpers.cc',
'win/virtual_driver_consts.h',
'win/virtual_driver_consts.cc',
],
},
'conditions': [
['OS=="win"', {
'targets' : [
{
'target_name': 'gcp_portmon',
'type': 'loadable_module',
'dependencies': [
'../../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',
'type': 'loadable_module',
'defines': [
'<@(nacl_win64_defines)',
],
'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': {
'msvs_target_platform': 'x64',
},
},
},
{
'target_name': 'virtual_driver_unittests',
'type': 'executable',
'msvs_guid': '97F82D29-58D8-4909-86C8-F2BBBCC4FEBF',
'dependencies': [
'../../base/base.gyp:base',
'../../base/base.gyp:test_support_base',
'../../testing/gmock.gyp:gmock',
'../../testing/gtest.gyp:gtest',
],
'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
},
},
},
],
'targets': [
{
'target_name': 'virtual_driver',
'type': 'none',
'dependencies': [
'win/install/virtual_driver_install.gyp:*',
'win/port_monitor/virtual_driver_port_monitor.gyp:*',
],
},
],
]
}
# Local Variables:

@ -0,0 +1,3 @@
include_rules = [
"+grit", # For generated headers
]

@ -8,23 +8,18 @@
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/file_version_info_win.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/process_util.h"
#include "base/string16.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"
#include "grit/virtual_driver_setup_resources.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);
}
HRESULT GetGpdPath(FilePath* path) {
if (!PathService::Get(base::DIR_EXE, path)) {
LOG(ERROR) << "Unable to get install path.";
@ -34,25 +29,17 @@ HRESULT GetGpdPath(FilePath* path) {
return S_OK;
}
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)) {
LOG(ERROR) << "Unable to get install path.";
return ERROR_PATH_NOT_FOUND;
}
*path = path->Append(GetPortMonitorDllName());
*path = path->Append(cloud_print::GetPortMonitorDllName());
return S_OK;
}
HRESULT GetPortMonitorInstallPath(FilePath* path) {
if (IsSystem64Bit()) {
if (cloud_print::IsSystem64Bit()) {
if (!PathService::Get(base::DIR_WINDOWS, path)) {
return ERROR_PATH_NOT_FOUND;
}
@ -65,7 +52,7 @@ HRESULT GetPortMonitorInstallPath(FilePath* path) {
return ERROR_PATH_NOT_FOUND;
}
}
*path = path->Append(GetPortMonitorDllName());
*path = path->Append(cloud_print::GetPortMonitorDllName());
return S_OK;
}
@ -139,33 +126,55 @@ HRESULT RegisterPortMonitor(bool install) {
return S_OK;
}
HRESULT InstallGpd() {
HRESULT result = S_OK;
FilePath source_path;
result = GetGpdPath(&source_path);
if (!SUCCEEDED(result)) {
return result;
DWORDLONG GetVersionNumber() {
DWORDLONG retval = 0;
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfoForCurrentModule());
if (version_info.get()) {
FileVersionInfoWin* version_info_win =
static_cast<FileVersionInfoWin*>(version_info.get());
VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
retval = fixed_file_info->dwFileVersionMS;
retval <<= 32;
retval |= fixed_file_info->dwFileVersionMS;
}
return retval;
}
HRESULT InstallGpd() {
DRIVER_INFO_6 driver_info = {0};
HRESULT result = S_OK;
// Set up paths for the files we depend on.
FilePath source_path;
FilePath driver_dir;
cloud_print::GetPrinterDriverDir(&driver_dir);
FilePath xps_path = driver_dir.Append(L"mxdwdrv.dll");
FilePath ui_path = driver_dir.Append(L"unidrvui.dll");
FilePath ui_help_path = driver_dir.Append(L"unidrv.hlp");
DRIVER_INFO_6 driver_info = {0};
driver_info.cVersion = 3;
result = GetGpdPath(&source_path);
if (!SUCCEEDED(result)) {
return result;
}
// None of the print API structures likes constant strings even though they
// don't modify the string. const_casting is the cleanest option.
driver_info.pName = const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str());
driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str());
driver_info.pDataFile = const_cast<LPWSTR>(source_path.value().c_str());
driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str());
// TODO(abodenha@chromium.org) Pull these strings from resources.
driver_info.pszMfgName = L"Google";
driver_info.pszProvider = driver_info.pszMfgName;
driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str());
driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str());
// Set up user visible strings.
string16 manufacturer = cloud_print::LoadLocalString(IDS_GOOGLE);
driver_info.pszMfgName = const_cast<LPWSTR>(manufacturer.c_str());
driver_info.pszProvider = const_cast<LPWSTR>(manufacturer.c_str());
driver_info.pszOEMUrl = L"http://www.google.com/cloudprint";
driver_info.dwlDriverVersion = 1;
driver_info.pDefaultDataType = L"RAW";
driver_info.dwlDriverVersion = GetVersionNumber();
string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
driver_info.pName = const_cast<LPWSTR>(driver_name.c_str());
// Set up supported print system version. Must be 3.
driver_info.cVersion = 3;
// TODO(abodenha@chromium.org) Properly handle dependencies.
// GPD files are often dependent on various Windows core drivers.
// I haven't found a reliable way to express those dependencies
@ -183,12 +192,16 @@ HRESULT InstallGpd() {
HRESULT UninstallGpd() {
int tries = 10;
string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
while (!DeletePrinterDriverEx(NULL,
NULL,
const_cast<LPWSTR>
(cloud_print::kVirtualDriverName),
const_cast<LPWSTR>(driver_name.c_str()),
DPD_DELETE_UNUSED_FILES,
0) && tries > 0) {
if (GetLastError() == ERROR_UNKNOWN_PRINTER_DRIVER) {
LOG(WARNING) << "Print driver is already uninstalled.";
return S_OK;
}
// After deleting the printer it can take a few seconds before
// the driver is free for deletion. Retry a few times before giving up.
LOG(WARNING) << "Attempt to delete printer driver failed. Retrying.";
@ -205,17 +218,17 @@ HRESULT UninstallGpd() {
HRESULT InstallPrinter(void) {
PRINTER_INFO_2 printer_info = {0};
printer_info.pPrinterName =
const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
// None of the print API structures likes constant strings even though they
// don't modify the string. const_casting is the cleanest option.
string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
printer_info.pDriverName = const_cast<LPWSTR>(driver_name.c_str());
printer_info.pPrinterName = const_cast<LPWSTR>(driver_name.c_str());
printer_info.pComment = const_cast<LPWSTR>(driver_name.c_str());
string16 port_name;
printer_info.pPortName = const_cast<LPWSTR>(cloud_print::kPortName);
printer_info.pDriverName =
const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
printer_info.pPrinterName = printer_info.pDriverName;
// TODO(abodenha@chromium.org) pComment should be localized.
printer_info.pComment = const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
printer_info.Attributes = PRINTER_ATTRIBUTE_DIRECT|PRINTER_ATTRIBUTE_LOCAL;
printer_info.pPrintProcessor = L"winprint";
printer_info.pDatatype = L"RAW";
HANDLE handle = AddPrinter(NULL, 2, reinterpret_cast<BYTE*>(&printer_info));
if (handle == NULL) {
HRESULT result = cloud_print::GetLastHResult();
@ -230,7 +243,8 @@ HRESULT UninstallPrinter(void) {
HANDLE handle = NULL;
PRINTER_DEFAULTS printer_defaults = {0};
printer_defaults.DesiredAccess = PRINTER_ALL_ACCESS;
if (!OpenPrinter(const_cast<LPWSTR>(cloud_print::kVirtualDriverName),
string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
if (!OpenPrinter(const_cast<LPWSTR>(driver_name.c_str()),
&handle,
&printer_defaults)) {
// If we can't open the printer, it was probably already removed.
@ -302,7 +316,8 @@ int WINAPI WinMain(__in HINSTANCE hInstance,
retval = InstallVirtualDriver();
}
if (!CommandLine::ForCurrentProcess()->HasSwitch("silent")) {
cloud_print::DisplayWindowsMessage(NULL, retval);
cloud_print::DisplayWindowsMessage(NULL, retval,
cloud_print::LoadLocalString(IDS_DRIVER_NAME));
}
return retval;
}

@ -0,0 +1,65 @@
# 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.
{
'target_defaults': {
'variables': {
'chromium_code': 1,
},
'include_dirs': [
'../../../..',
],
},
'targets' : [
{
'target_name': 'virtual_driver_setup',
'type': 'executable',
'msvs_guid': 'E1E25ACA-043D-4D6E-A06F-97126532843A',
'dependencies': [
'../../../../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_en-US.rc',
'<(SHARED_INTERMEDIATE_DIR)/virtual_driver_setup_resources/virtual_driver_setup_resources_es.rc',
],
'msvs_settings': {
'VCLinkerTool': {
'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS
},
},
},
{
'target_name': 'virtual_driver_setup_resources',
'type': 'none',
'msvs_guid': '13D30B4C-1B06-40DB-8ED6-D2CAD76940CB',
'variables': {
'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/virtual_driver_setup_resources',
},
'actions': [
{
'action_name': 'virtual_driver_setup_resources',
'variables': {
'grit_grd_file': 'virtual_driver_setup_resources.grd',
},
'includes': [ '../../../../build/grit_action.gypi' ],
},
],
'includes': [ '../../../../build/grit_target.gypi' ],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-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.
-->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/virtual_driver_setup_resources.h" type="rc_header">
<emit emit_type='prepend'></emit>
</output>
<output filename="virtual_driver_setup_resources_en-US.rc" type="rc_all" lang="en" language_section="lang"/>
<output filename="virtual_driver_setup_resources_es.rc" type="rc_all" lang="es" language_section="lang"/>
</outputs>
<release seq="1">
<messages>
<message name="IDS_GOOGLE"
meaning="Google" desc="The name of the company that built this.">
Google
</message>
<message name="IDS_DRIVER_NAME"
meaning="Driver Name" desc="The user visible name of the printer we create and its associated driver.">
Google Cloud Print Virtual Printer
</message>
</messages>
</release>
</grit>

@ -59,12 +59,6 @@ const wchar_t kChromePathRegValue[] = L"PathToChromeExe";
const wchar_t kChromePathRegKey[] = L"Software\\Google\\CloudPrint";
namespace {
#ifdef _WIN64
const wchar_t *kPortMonitorDllName = kPortMonitorDllName64;
#else
const wchar_t *kPortMonitorDllName = kPortMonitorDllName32;
#endif
const wchar_t kXpsMimeType[] = L"application/vnd.ms-xpsdocument";
const size_t kMaxCommandLineLen = 0x7FFF;
@ -195,7 +189,7 @@ bool GetJobTitle(HANDLE printer_handle,
// configuration.
void HandlePortUi(HWND hwnd, const string16& caption) {
if (hwnd != NULL && IsWindow(hwnd)) {
DisplayWindowsMessage(hwnd, CO_E_NOT_SUPPORTED);
DisplayWindowsMessage(hwnd, CO_E_NOT_SUPPORTED, cloud_print::kPortName);
}
}
@ -313,7 +307,7 @@ BOOL WINAPI Monitor2EnumPorts(HANDLE,
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
*needed_bytes += static_cast<DWORD>(kPortNameSize);
*needed_bytes += static_cast<DWORD>(cloud_print::kPortNameSize);
if (ports_size < *needed_bytes) {
LOG(WARNING) << *needed_bytes << " bytes are required. Only "
<< ports_size << " were allocated.";
@ -337,15 +331,20 @@ BOOL WINAPI Monitor2EnumPorts(HANDLE,
// EnumPorts to fail until the spooler is restarted.
// This is NOT mentioned in the documentation.
wchar_t* string_target =
reinterpret_cast<wchar_t*>(ports + ports_size - kPortNameSize);
reinterpret_cast<wchar_t*>(ports + ports_size -
cloud_print::kPortNameSize);
if (level == 1) {
PORT_INFO_1* port_info = reinterpret_cast<PORT_INFO_1*>(ports);
port_info->pName = string_target;
StringCbCopy(port_info->pName, kPortNameSize, kPortName);
StringCbCopy(port_info->pName,
cloud_print::kPortNameSize,
cloud_print::kPortName);
} else {
PORT_INFO_2* port_info = reinterpret_cast<PORT_INFO_2*>(ports);
port_info->pPortName = string_target;
StringCbCopy(port_info->pPortName, kPortNameSize, kPortName);
StringCbCopy(port_info->pPortName,
cloud_print::kPortNameSize,
cloud_print::kPortName);
port_info->pMonitorName = NULL;
port_info->pDescription = NULL;
port_info->fPortType = PORT_TYPE_WRITE;
@ -554,15 +553,18 @@ DWORD WINAPI Monitor2XcvDataPort(HANDLE xcv_handle,
// We don't handle AddPort or DeletePort since we don't support
// dynamic creation of ports.
if (lstrcmp(L"MonitorUI", data_name) == 0) {
DWORD dll_path_len = 0;
FilePath dll_path(GetPortMonitorDllName());
dll_path_len = static_cast<DWORD>(dll_path.value().length());
if (output_data_bytes_needed != NULL) {
*output_data_bytes_needed = sizeof(kPortMonitorDllName);
*output_data_bytes_needed = dll_path_len;
}
if (output_data_bytes < sizeof(kPortMonitorDllName)) {
if (output_data_bytes < dll_path_len) {
return ERROR_INSUFFICIENT_BUFFER;
} else {
ret_val = StringCbCopy(reinterpret_cast<wchar_t*>(output_data),
output_data_bytes,
kPortMonitorDllName);
dll_path.value().c_str());
}
} else {
return ERROR_INVALID_PARAMETER;
@ -627,8 +629,9 @@ HRESULT WINAPI DllRegisterServer(void) {
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.
monitor_info.pDLLName = const_cast<LPWSTR>(cloud_print::kPortMonitorDllName);
monitor_info.pName = const_cast<LPWSTR>(cloud_print::kPortMonitorDllName);
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;
}
@ -640,9 +643,10 @@ HRESULT WINAPI DllUnregisterServer(void) {
if (!cloud_print::CanRegister()) {
return E_ACCESSDENIED;
}
FilePath dll_path(cloud_print::GetPortMonitorDllName());
if (DeleteMonitor(NULL,
NULL,
const_cast<LPWSTR>(cloud_print::kPortMonitorDllName))) {
const_cast<LPWSTR>(dll_path.value().c_str()))) {
return S_OK;
}
return cloud_print::GetLastHResult();

@ -0,0 +1,78 @@
# 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.
{
'includes': [
'../../../../build/common.gypi',
],
'target_defaults': {
'variables': {
'chromium_code': 1,
},
'include_dirs': [
'../..',
],
'libraries': [
'userenv.lib',
],
'sources': [
'../virtual_driver_consts.h',
'../virtual_driver_consts.cc',
'../virtual_driver_helpers.h',
'../virtual_driver_helpers.cc',
'../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',
],
'msvs_guid': 'ED3D7186-C94E-4D8B-A8E7-B7260F638F46',
},
{
'target_name': 'gcp_portmon64',
'type': 'loadable_module',
'defines': [
'<@(nacl_win64_defines)',
],
'dependencies': [
'../../../../base/base.gyp:base_nacl_win64',
],
'msvs_guid': '9BB292F4-6104-495A-B415-C3E314F46D6F',
'configurations': {
'Common_Base': {
'msvs_target_platform': 'x64',
},
},
},
{
'target_name': 'virtual_driver_unittests',
'type': 'executable',
'msvs_guid': '97F82D29-58D8-4909-86C8-F2BBBCC4FEBF',
'dependencies': [
'../../../../base/base.gyp:base',
'../../../../base/base.gyp:test_support_base',
'../../../../testing/gmock.gyp:gmock',
'../../../../testing/gtest.gyp:gtest',
],
'sources': [
# Infrastructure files.
'../../../../base/test/run_all_unittests.cc',
'port_monitor_unittest.cc',
],
},
],
}
# Local Variables:
# tab-width:2
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=2 shiftwidth=2:

@ -0,0 +1,39 @@
// 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.
#ifdef APSTUDIO_INVOKED
# error Don't open this in the GUI, it'll be massacred on save.
#endif // APSTUDIO_INVOKED
1 VERSIONINFO
FILEVERSION 0,1,0,1
PRODUCTVERSION 0,1,0,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Google Inc."
VALUE "FileDescription", "GCP Virtual Driver"
VALUE "FileVersion", "0, 1, 0, 1"
VALUE "InternalName", "GCP Virtual Driver"
VALUE "ProductName", "GCP Virtual Driver"
VALUE "ProductVersion", "0, 1, 0, 1"
VALUE "LegalCopyright", "Copyright (c) 2011 The Chromium Authors. All rights reserved."
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

@ -7,15 +7,7 @@
#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";
const wchar_t kPortName[] = L"GCP:";
const size_t kPortNameSize = sizeof(kPortName);
// The driver name is user visible so it SHOULD be localized, BUT
// the name is used as a key to find both the driver and printer.
// We'll need to be careful. If the name changes for the
// driver it could create bugs.
const wchar_t kVirtualDriverName[] = L"Google Cloud Print Virtual Printer";
}

@ -7,11 +7,8 @@
#pragma once
namespace cloud_print {
extern const wchar_t kPortMonitorDllName64[];
extern const wchar_t kPortMonitorDllName32[];
extern const wchar_t kPortName[];
extern const size_t kPortNameSize;
extern const wchar_t kVirtualDriverName[];
}
#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_VIRTUAL_DRIVER_CONSTS_H_

@ -6,13 +6,17 @@
#include <windows.h>
#include <winspool.h>
#include "base/file_util.h"
#include "cloud_print/virtual_driver/win/virtual_driver_consts.h"
#include "base/logging.h"
#include "base/string16.h"
#include "base/win/windows_version.h"
namespace cloud_print {
const size_t kMaxMessageLen = 100;
void DisplayWindowsMessage(HWND hwnd, HRESULT message_id) {
void DisplayWindowsMessage(HWND hwnd,
HRESULT message_id,
const string16 &caption) {
wchar_t message_text[kMaxMessageLen + 1] = L"";
::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
@ -22,7 +26,7 @@ void DisplayWindowsMessage(HWND hwnd, HRESULT message_id) {
message_text,
kMaxMessageLen,
NULL);
::MessageBox(hwnd, message_text, kVirtualDriverName, MB_OK);
::MessageBox(hwnd, message_text, caption.c_str(), MB_OK);
}
HRESULT GetLastHResult() {
@ -30,6 +34,14 @@ HRESULT GetLastHResult() {
return HRESULT_FROM_WIN32(error_code);
}
string16 GetPortMonitorDllName() {
if (IsSystem64Bit()) {
return string16(L"gcp_portmon64.dll");
} else {
return string16(L"gcp_portmon32.dll");
}
}
HRESULT GetPrinterDriverDir(FilePath* path) {
BYTE driver_dir_buffer[MAX_PATH * sizeof(wchar_t)];
DWORD needed = 0;
@ -49,5 +61,29 @@ HRESULT GetPrinterDriverDir(FilePath* path) {
*path = path->Append(L"3");
return S_OK;
}
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);
}
string16 LoadLocalString(DWORD string_id) {
static wchar_t dummy = L'\0';
// We never expect strings longer than MAX_PATH characters.
static wchar_t buffer[MAX_PATH];
HMODULE module = NULL;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
&dummy,
&module);
int count = LoadString(module,
string_id,
buffer,
MAX_PATH);
CHECK_NE(0, count);
return string16(buffer);
}
}

@ -7,19 +7,32 @@
#pragma once
#include <windows.h>
#include "base/string16.h"
class FilePath;
namespace cloud_print {
// Returns TRUE if the current OS is 64 bit.
bool IsSystem64Bit();
// Convert an HRESULT to a localized string and display it in a message box.
void DisplayWindowsMessage(HWND hwnd, HRESULT message_id);
void DisplayWindowsMessage(HWND hwnd,
HRESULT message_id,
const string16 &caption);
// Similar to the Windows API call GetLastError but returns an HRESULT.
HRESULT GetLastHResult();
// Returns the correct port monitor DLL file name for the current machine.
string16 GetPortMonitorDllName();
// Gets the standard install path for "version 3" print drivers.
HRESULT GetPrinterDriverDir(FilePath* path);
// Retrieves a string from the string table of the module that contains the
// calling code.
string16 LoadLocalString(DWORD string_id);
}
#endif // CLOUD_PRINT_VIRTUAL_DRIVER_WIN_HELPERS_H_

@ -145,4 +145,7 @@
"chrome/browser/resources/options_resources.grd": {
"includes": [22000],
},
"cloud_print/virtual_driver/win/install/virtual_driver_setup_resources.grd": {
"messages": [22500],
},
}