summaryrefslogtreecommitdiffstats
path: root/cloud_print/virtual_driver/win
diff options
context:
space:
mode:
authorabodenha@chromium.org <abodenha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-10 00:12:56 +0000
committerabodenha@chromium.org <abodenha@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-10 00:12:56 +0000
commit4072805a4252409a786d8b8a2e0b35e7c374ff0c (patch)
treefdb655d0364e5bda044361e401655fd6a1d9db14 /cloud_print/virtual_driver/win
parent544df7c7697ec1e7d2005b953ed5983114268ad5 (diff)
downloadchromium_src-4072805a4252409a786d8b8a2e0b35e7c374ff0c.zip
chromium_src-4072805a4252409a786d8b8a2e0b35e7c374ff0c.tar.gz
chromium_src-4072805a4252409a786d8b8a2e0b35e7c374ff0c.tar.bz2
Remove extranious fonts from the ppd file
Properly handle dependencies for installing the ppd Register for uninstall BUG=106094 TEST=Copy port monitor dlls, virtual_driver_setup.exe, and gcp-driver.ppd into a single folder and launch the setup as admin. The driver should be installed. Run it again with --uninstall (or choose the cloud print driver in add/remove programs) and the driver should be uninstalled and the containing folder removed. Review URL: http://codereview.chromium.org/8770019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113889 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print/virtual_driver/win')
-rw-r--r--cloud_print/virtual_driver/win/install/setup.cc247
-rw-r--r--cloud_print/virtual_driver/win/install/virtual_driver_install.gyp3
-rw-r--r--cloud_print/virtual_driver/win/virtual_driver_common_resources.rc4
3 files changed, 181 insertions, 73 deletions
diff --git a/cloud_print/virtual_driver/win/install/setup.cc b/cloud_print/virtual_driver/win/install/setup.cc
index 1b83cbb..d64ea9a 100644
--- a/cloud_print/virtual_driver/win/install/setup.cc
+++ b/cloud_print/virtual_driver/win/install/setup.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <windows.h>
+#include <setupapi.h> // Must be included after windows.h
#include <winspool.h>
#include "base/at_exit.h"
@@ -19,14 +20,24 @@
#include "cloud_print/virtual_driver/win/virtual_driver_helpers.h"
#include "grit/virtual_driver_setup_resources.h"
+#include <strsafe.h> // Must be after base headers to avoid deprecation
+ // warnings.
+
namespace {
const wchar_t kVersionKey[] = L"pv";
const wchar_t kNameKey[] = L"name";
-const wchar_t kLangKey[] = L"lang";
const wchar_t kNameValue[] = L"GCP Virtual Driver";
-const wchar_t kLangValue[] = L"rn";
+const wchar_t kPpdName[] = L"GCP-DRIVER.PPD";
+const wchar_t kDriverName[] = L"MXDWDRV.DLL";
+const wchar_t kUiDriverName[] = L"PS5UI.DLL";
+const wchar_t kHelpName[] = L"PSCRIPT.HLP";
+const wchar_t* kDependencyList[] = {kDriverName, kUiDriverName, kHelpName};
+const wchar_t kUninstallRegistry[] =
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
+ L"{74AA24E0-AC50-4B28-BA46-9CF05467C9B7}";
+const wchar_t kInstallerName[] = L"virtual_driver_setup.exe";
-void SetRegistryKeys() {
+void SetOmahaKeys() {
base::win::RegKey key;
if (key.Create(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation,
KEY_SET_VALUE) != ERROR_SUCCESS) {
@@ -49,13 +60,12 @@ void SetRegistryKeys() {
}
if (key.WriteValue(kVersionKey, version_string.c_str()) != ERROR_SUCCESS ||
- key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS ||
- key.WriteValue(kLangKey, kLangValue) != ERROR_SUCCESS) {
+ key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS) {
LOG(ERROR) << "Unable to set registry keys";
}
}
-void DeleteRegistryKeys() {
+void DeleteOmahaKeys() {
base::win::RegKey key;
if (key.Open(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation,
DELETE) != ERROR_SUCCESS) {
@@ -66,25 +76,7 @@ void DeleteRegistryKeys() {
}
}
-HRESULT GetPpdPath(FilePath* path) {
- if (!PathService::Get(base::DIR_EXE, path)) {
- LOG(ERROR) << "Unable to get install path.";
- return ERROR_PATH_NOT_FOUND;
- }
- *path = path->Append(L"GCP-driver.ppd");
- return S_OK;
-}
-
-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(cloud_print::GetPortMonitorDllName());
- return S_OK;
-}
-
-HRESULT GetPortMonitorInstallPath(FilePath* path) {
+HRESULT GetNativeSystemPath(FilePath* path) {
if (cloud_print::IsSystem64Bit()) {
if (!PathService::Get(base::DIR_WINDOWS, path)) {
return ERROR_PATH_NOT_FOUND;
@@ -98,34 +90,35 @@ HRESULT GetPortMonitorInstallPath(FilePath* path) {
return ERROR_PATH_NOT_FOUND;
}
}
- *path = path->Append(cloud_print::GetPortMonitorDllName());
return S_OK;
}
+HRESULT GetPortMonitorTargetPath(FilePath* path) {
+ HRESULT result = GetNativeSystemPath(path);
+ if (SUCCEEDED(result))
+ *path = path->Append(cloud_print::GetPortMonitorDllName());
+ return result;
+}
+
HRESULT GetRegsvr32Path(FilePath* path) {
- if (!PathService::Get(base::DIR_SYSTEM, path)) {
- LOG(ERROR) << "Unable to get system path.";
- return ERROR_PATH_NOT_FOUND;
- }
- *path = path->Append(FilePath(L"regsvr32.exe"));
- return S_OK;
+ HRESULT result = GetNativeSystemPath(path);
+ if (SUCCEEDED(result))
+ *path = path->Append(FilePath(L"regsvr32.exe"));
+ return result;
}
-HRESULT RegisterPortMonitor(bool install) {
+HRESULT RegisterPortMonitor(bool install, const FilePath& install_path) {
FilePath target_path;
HRESULT result = S_OK;
- result = GetPortMonitorInstallPath(&target_path);
+ result = GetPortMonitorTargetPath(&target_path);
if (!SUCCEEDED(result)) {
LOG(ERROR) << "Unable to get port monitor target path.";
return result;
}
- FilePath source_path;
- result = GetPortMonitorDllPath(&source_path);
- if (!SUCCEEDED(result)) {
- LOG(ERROR) << "Unable to get dll source path.";
- return result;
- }
+ string16 source;
+ source = cloud_print::GetPortMonitorDllName();
if (install) {
+ FilePath source_path = install_path.Append(source);
if (!file_util::CopyFileW(source_path, target_path)) {
LOG(ERROR) << "Unable copy port monitor dll from " <<
source_path.value() << " to " << target_path.value();
@@ -144,7 +137,14 @@ HRESULT RegisterPortMonitor(bool install) {
if (!install) {
command_line.AppendArg("/u");
}
- command_line.AppendArgPath(source_path);
+
+ FilePath final_path;
+ if (!PathService::Get(base::DIR_SYSTEM, &final_path)) {
+ LOG(ERROR) << "Unable to get system path.";
+ return ERROR_PATH_NOT_FOUND;
+ }
+ final_path = final_path.Append(cloud_print::GetPortMonitorDllName());
+ command_line.AppendArgPath(final_path);
base::LaunchOptions options;
HANDLE process_handle;
@@ -189,24 +189,63 @@ DWORDLONG GetVersionNumber() {
return retval;
}
-HRESULT InstallPpd() {
+UINT CALLBACK CabinetCallback(PVOID data,
+ UINT notification,
+ UINT_PTR param1,
+ UINT_PTR param2 ) {
+ FilePath* temp_path = reinterpret_cast<FilePath*>(data);
+ if (notification == SPFILENOTIFY_FILEINCABINET) {
+ FILE_IN_CABINET_INFO* info =
+ reinterpret_cast<FILE_IN_CABINET_INFO*>(param1);
+ for (int i = 0; i < arraysize(kDependencyList); i++) {
+ if (wcsstr(info->NameInCabinet, kDependencyList[i])) {
+ StringCchCopy(info->FullTargetName, MAX_PATH,
+ temp_path->Append(kDependencyList[i]).value().c_str());
+ return FILEOP_DOIT;
+ }
+ }
+
+ return FILEOP_SKIP;
+ }
+ return NO_ERROR;
+}
+
+void ReadyPpdDependencies(const FilePath& install_path) {
+ CORE_PRINTER_DRIVER driver;
+ GetCorePrinterDrivers(NULL,
+ NULL,
+ L"{D20EA372-DD35-4950-9ED8-A6335AFE79F0}",
+ 1,
+ &driver);
+ DWORD size = MAX_PATH;
+ wchar_t package_path[MAX_PATH];
+ GetPrinterDriverPackagePath(NULL,
+ NULL,
+ NULL,
+ driver.szPackageID,
+ package_path,
+ MAX_PATH,
+ &size);
+
+ SetupIterateCabinet(package_path,
+ 0,
+ CabinetCallback,
+ const_cast<FilePath*>(&install_path));
+}
+
+HRESULT InstallPpd(const FilePath& install_path) {
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"ps5ui.dll");
- FilePath ui_help_path = driver_dir.Append(L"unidrv.hlp");
- result = GetPpdPath(&source_path);
- if (!SUCCEEDED(result)) {
- return result;
- }
+ FilePath ppd_path = install_path.Append(kPpdName);
+ FilePath xps_path = install_path.Append(kDriverName);
+ FilePath ui_path = install_path.Append(kUiDriverName);
+ FilePath ui_help_path = install_path.Append(kHelpName);
+ ReadyPpdDependencies(install_path);
// 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.pDataFile = const_cast<LPWSTR>(source_path.value().c_str());
+ driver_info.pDataFile = const_cast<LPWSTR>(ppd_path.value().c_str());
driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str());
driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str());
driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str());
@@ -223,19 +262,14 @@ HRESULT InstallPpd() {
// 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
- // other than using an INF for installation.
if (!AddPrinterDriverEx(NULL,
6,
reinterpret_cast<BYTE*>(&driver_info),
APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY)) {
result = cloud_print::GetLastHResult();
LOG(ERROR) << "Unable to add printer driver";
- return result;
}
- return S_OK;
+ return result;
}
HRESULT UninstallPpd() {
@@ -309,14 +343,59 @@ HRESULT UninstallPrinter(void) {
return S_OK;
}
-HRESULT InstallVirtualDriver(void) {
+void SetupUninstall(const FilePath& install_path) {
+ // Now write the Windows Uninstall entries
+ // Minimal error checking here since the install can contiunue
+ // if this fails.
+ base::win::RegKey key;
+ if (key.Create(HKEY_LOCAL_MACHINE, kUninstallRegistry,
+ KEY_SET_VALUE) != ERROR_SUCCESS) {
+ LOG(ERROR) << "Unable to open key";
+ return;
+ }
+ CommandLine uninstall_command(install_path.Append(kInstallerName));
+ uninstall_command.AppendArg("--uninstall");
+ key.WriteValue(L"UninstallString",
+ uninstall_command.GetCommandLineString().c_str());
+ key.WriteValue(L"InstallLocation", install_path.value().c_str());
+
+
+ // Get the version resource.
+ scoped_ptr<FileVersionInfo> version_info(
+ FileVersionInfo::CreateFileVersionInfoForCurrentModule());
+
+ if (version_info.get()) {
+ FileVersionInfoWin* version_info_win =
+ static_cast<FileVersionInfoWin*>(version_info.get());
+ key.WriteValue(L"DisplayVersion",
+ version_info_win->file_version().c_str());
+ key.WriteValue(L"Publisher", version_info_win->company_name().c_str());
+ } else {
+ LOG(ERROR) << "Unable to get version string";
+ }
+ key.WriteValue(L"DisplayName",
+ cloud_print::LoadLocalString(IDS_DRIVER_NAME).c_str());
+ key.WriteValue(L"NoModify", 1);
+ key.WriteValue(L"NoRepair", 1);
+}
+
+void CleanupUninstall() {
+ ::RegDeleteKey(HKEY_LOCAL_MACHINE, kUninstallRegistry);
+}
+
+HRESULT InstallVirtualDriver(const FilePath& install_path) {
HRESULT result = S_OK;
- result = RegisterPortMonitor(true);
+ if (!file_util::CreateDirectory(install_path)) {
+ LOG(ERROR) << "Can't create install directory";
+ return ERROR_ACCESS_DENIED;
+ }
+ SetupUninstall(install_path);
+ result = RegisterPortMonitor(true, install_path);
if (!SUCCEEDED(result)) {
LOG(ERROR) << "Unable to register port monitor.";
return result;
}
- result = InstallPpd();
+ result = InstallPpd(install_path);
if (!SUCCEEDED(result)) {
LOG(ERROR) << "Unable to install Ppd.";
return result;
@@ -326,11 +405,11 @@ HRESULT InstallVirtualDriver(void) {
LOG(ERROR) << "Unable to install printer.";
return result;
}
- SetRegistryKeys();
+ SetOmahaKeys();
return S_OK;
}
-HRESULT UninstallVirtualDriver(void) {
+HRESULT UninstallVirtualDriver(const FilePath& install_path) {
HRESULT result = S_OK;
result = UninstallPrinter();
if (!SUCCEEDED(result)) {
@@ -342,15 +421,35 @@ HRESULT UninstallVirtualDriver(void) {
LOG(ERROR) << "Unable to remove Ppd.";
return result;
}
- result = RegisterPortMonitor(false);
+ result = RegisterPortMonitor(false, install_path);
if (!SUCCEEDED(result)) {
LOG(ERROR) << "Unable to remove port monitor.";
return result;
}
- DeleteRegistryKeys();
+ DeleteOmahaKeys();
+ file_util::Delete(install_path, true);
+ CleanupUninstall();
return S_OK;
}
+HRESULT LaunchChildForUninstall() {
+ FilePath installer_source;
+ if (PathService::Get(base::FILE_EXE, &installer_source)) {
+ FilePath temp_path;
+ if (file_util::CreateTemporaryFile(&temp_path)) {
+ file_util::Move(installer_source, temp_path);
+ file_util::DeleteAfterReboot(temp_path);
+ CommandLine command_line(temp_path);
+ command_line.AppendArg("--douninstall");
+ base::LaunchOptions options;
+ if (!base::LaunchProcess(command_line, options, NULL)) {
+ LOG(ERROR) << "Unable to launch child uninstall.";
+ return ERROR_NOT_SUPPORTED;
+ }
+ }
+ }
+ return S_OK;
+}
} // namespace
int WINAPI WinMain(__in HINSTANCE hInstance,
@@ -359,11 +458,17 @@ int WINAPI WinMain(__in HINSTANCE hInstance,
__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();
+
+ FilePath install_path;
+ HRESULT retval = PathService::Get(base::DIR_EXE, &install_path);
+ if (SUCCEEDED(retval)) {
+ if (CommandLine::ForCurrentProcess()->HasSwitch("douninstall")) {
+ retval = UninstallVirtualDriver(install_path);
+ } else if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) {
+ retval = LaunchChildForUninstall();
+ } else {
+ retval = InstallVirtualDriver(install_path);
+ }
}
// Installer is silent by default as required by Omaha.
if (CommandLine::ForCurrentProcess()->HasSwitch("verbose")) {
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 37ca71c..696a4c6 100644
--- a/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp
+++ b/cloud_print/virtual_driver/win/install/virtual_driver_install.gyp
@@ -32,6 +32,9 @@
'msvs_settings': {
'VCLinkerTool': {
'SubSystem': '2', # Set /SUBSYSTEM:WINDOWS
+ 'AdditionalDependencies': [
+ 'setupapi.lib',
+ ],
},
},
},
diff --git a/cloud_print/virtual_driver/win/virtual_driver_common_resources.rc b/cloud_print/virtual_driver/win/virtual_driver_common_resources.rc
index d90c230..1c03825 100644
--- a/cloud_print/virtual_driver/win/virtual_driver_common_resources.rc
+++ b/cloud_print/virtual_driver/win/virtual_driver_common_resources.rc
@@ -25,10 +25,10 @@ BEGIN
BEGIN
VALUE "CompanyName", "Google Inc."
VALUE "FileDescription", "GCP Virtual Driver"
- VALUE "FileVersion", "0, 1, 0, 1"
+ VALUE "FileVersion", "0.1.0.1"
VALUE "InternalName", "GCP Virtual Driver"
VALUE "ProductName", "GCP Virtual Driver"
- VALUE "ProductVersion", "0, 1, 0, 1"
+ VALUE "ProductVersion", "0.1.0.1"
VALUE "LegalCopyright", "Copyright (c) 2011 The Chromium Authors. All rights reserved."
END
END