| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <windows.h> | 5 #include <windows.h> |
| 6 #include <setupapi.h> // Must be included after windows.h | 6 #include <setupapi.h> // Must be included after windows.h |
| 7 #include <winspool.h> | 7 #include <winspool.h> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/file_version_info_win.h" | 12 #include "base/file_version_info_win.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/process_util.h" | 15 #include "base/process_util.h" |
| 16 #include "base/string16.h" | 16 #include "base/string16.h" |
| 17 #include "base/win/registry.h" | 17 #include "base/win/registry.h" |
| 18 #include "base/win/scoped_handle.h" | 18 #include "base/win/scoped_handle.h" |
| 19 #include "base/win/windows_version.h" |
| 19 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" | 20 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" |
| 20 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" | 21 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" |
| 21 #include "grit/virtual_driver_setup_resources.h" | 22 #include "grit/virtual_driver_setup_resources.h" |
| 22 | 23 |
| 23 #include <strsafe.h> // Must be after base headers to avoid deprecation | 24 #include <strsafe.h> // Must be after base headers to avoid deprecation |
| 24 // warnings. | 25 // warnings. |
| 25 | 26 |
| 26 namespace { | 27 namespace { |
| 27 const wchar_t kVersionKey[] = L"pv"; | 28 const wchar_t kVersionKey[] = L"pv"; |
| 28 const wchar_t kNameKey[] = L"name"; | 29 const wchar_t kNameKey[] = L"name"; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS) { | 64 key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS) { |
| 64 LOG(ERROR) << "Unable to set registry keys"; | 65 LOG(ERROR) << "Unable to set registry keys"; |
| 65 } | 66 } |
| 66 } | 67 } |
| 67 | 68 |
| 68 void DeleteOmahaKeys() { | 69 void DeleteOmahaKeys() { |
| 69 base::win::RegKey key; | 70 base::win::RegKey key; |
| 70 if (key.Open(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation, | 71 if (key.Open(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation, |
| 71 DELETE) != ERROR_SUCCESS) { | 72 DELETE) != ERROR_SUCCESS) { |
| 72 LOG(ERROR) << "Unable to open key to delete"; | 73 LOG(ERROR) << "Unable to open key to delete"; |
| 74 return; |
| 73 } | 75 } |
| 74 if (key.DeleteKey(L"") != ERROR_SUCCESS) { | 76 if (key.DeleteKey(L"") != ERROR_SUCCESS) { |
| 75 LOG(ERROR) << "Unable to delete key"; | 77 LOG(ERROR) << "Unable to delete key"; |
| 76 } | 78 } |
| 77 } | 79 } |
| 78 | 80 |
| 79 HRESULT GetNativeSystemPath(FilePath* path) { | 81 HRESULT GetNativeSystemPath(FilePath* path) { |
| 80 if (cloud_print::IsSystem64Bit()) { | 82 if (cloud_print::IsSystem64Bit()) { |
| 81 if (!PathService::Get(base::DIR_WINDOWS, path)) { | 83 if (!PathService::Get(base::DIR_WINDOWS, path)) { |
| 82 return ERROR_PATH_NOT_FOUND; | 84 return ERROR_PATH_NOT_FOUND; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 | 193 |
| 192 UINT CALLBACK CabinetCallback(PVOID data, | 194 UINT CALLBACK CabinetCallback(PVOID data, |
| 193 UINT notification, | 195 UINT notification, |
| 194 UINT_PTR param1, | 196 UINT_PTR param1, |
| 195 UINT_PTR param2 ) { | 197 UINT_PTR param2 ) { |
| 196 FilePath* temp_path = reinterpret_cast<FilePath*>(data); | 198 FilePath* temp_path = reinterpret_cast<FilePath*>(data); |
| 197 if (notification == SPFILENOTIFY_FILEINCABINET) { | 199 if (notification == SPFILENOTIFY_FILEINCABINET) { |
| 198 FILE_IN_CABINET_INFO* info = | 200 FILE_IN_CABINET_INFO* info = |
| 199 reinterpret_cast<FILE_IN_CABINET_INFO*>(param1); | 201 reinterpret_cast<FILE_IN_CABINET_INFO*>(param1); |
| 200 for (int i = 0; i < arraysize(kDependencyList); i++) { | 202 for (int i = 0; i < arraysize(kDependencyList); i++) { |
| 201 if (wcsstr(info->NameInCabinet, kDependencyList[i])) { | 203 FilePath base_name(info->NameInCabinet); |
| 204 base_name = base_name.BaseName(); |
| 205 if (FilePath::CompareEqualIgnoreCase(base_name.value().c_str(), |
| 206 kDependencyList[i])) { |
| 202 StringCchCopy(info->FullTargetName, MAX_PATH, | 207 StringCchCopy(info->FullTargetName, MAX_PATH, |
| 203 temp_path->Append(kDependencyList[i]).value().c_str()); | 208 temp_path->Append(kDependencyList[i]).value().c_str()); |
| 204 return FILEOP_DOIT; | 209 return FILEOP_DOIT; |
| 205 } | 210 } |
| 206 } | 211 } |
| 207 | 212 |
| 208 return FILEOP_SKIP; | 213 return FILEOP_SKIP; |
| 209 } | 214 } |
| 210 return NO_ERROR; | 215 return NO_ERROR; |
| 211 } | 216 } |
| 212 | 217 |
| 213 void ReadyPpdDependencies(const FilePath& install_path) { | 218 void ReadyPpdDependencies(const FilePath& install_path) { |
| 214 CORE_PRINTER_DRIVER driver; | 219 base::win::Version version = base::win::GetVersion(); |
| 215 GetCorePrinterDrivers(NULL, | 220 if (version >= base::win::VERSION_VISTA) { |
| 216 NULL, | 221 // GetCorePrinterDrivers and GetPrinterDriverPackagePath only exist on |
| 217 L"{D20EA372-DD35-4950-9ED8-A6335AFE79F0}", | 222 // Vista and later. Winspool.drv must be delayloaded so these calls don't |
| 218 1, | 223 // create problems on XP. |
| 219 &driver); | 224 DWORD size = MAX_PATH; |
| 220 DWORD size = MAX_PATH; | 225 wchar_t package_path[MAX_PATH] = {0}; |
| 221 wchar_t package_path[MAX_PATH]; | 226 CORE_PRINTER_DRIVER driver; |
| 222 GetPrinterDriverPackagePath(NULL, | 227 GetCorePrinterDrivers(NULL, |
| 223 NULL, | 228 NULL, |
| 224 NULL, | 229 L"{D20EA372-DD35-4950-9ED8-A6335AFE79F0}", |
| 225 driver.szPackageID, | 230 1, |
| 226 package_path, | 231 &driver); |
| 227 MAX_PATH, | 232 GetPrinterDriverPackagePath(NULL, |
| 228 &size); | 233 NULL, |
| 234 NULL, |
| 235 driver.szPackageID, |
| 236 package_path, |
| 237 MAX_PATH, |
| 238 &size); |
| 239 SetupIterateCabinet(package_path, |
| 240 0, |
| 241 CabinetCallback, |
| 242 const_cast<FilePath*>(&install_path)); |
| 243 } else { |
| 244 // PS driver files are in the sp3 cab. |
| 245 FilePath package_path; |
| 246 PathService::Get(base::DIR_WINDOWS, &package_path); |
| 247 package_path = package_path.Append(L"Driver Cache\\i386\\sp3.cab"); |
| 248 SetupIterateCabinet(package_path.value().c_str(), |
| 249 0, |
| 250 CabinetCallback, |
| 251 const_cast<FilePath*>(&install_path)); |
| 229 | 252 |
| 230 SetupIterateCabinet(package_path, | 253 // The XPS driver files are just sitting uncompressed in the driver cache. |
| 231 0, | 254 FilePath xps_path; |
| 232 CabinetCallback, | 255 PathService::Get(base::DIR_WINDOWS, &xps_path); |
| 233 const_cast<FilePath*>(&install_path)); | 256 xps_path = xps_path.Append(L"Driver Cache\\i386"); |
| 257 xps_path = xps_path.Append(kDriverName); |
| 258 file_util::CopyFile(xps_path, install_path.Append(kDriverName)); |
| 259 } |
| 234 } | 260 } |
| 235 | 261 |
| 236 HRESULT InstallPpd(const FilePath& install_path) { | 262 HRESULT InstallPpd(const FilePath& install_path) { |
| 237 DRIVER_INFO_6 driver_info = {0}; | 263 DRIVER_INFO_6 driver_info = {0}; |
| 238 HRESULT result = S_OK; | 264 HRESULT result = S_OK; |
| 239 | 265 |
| 240 // Set up paths for the files we depend on. | 266 // Set up paths for the files we depend on. |
| 241 FilePath ppd_path = install_path.Append(kPpdName); | 267 FilePath ppd_path = install_path.Append(kPpdName); |
| 242 FilePath xps_path = install_path.Append(kDriverName); | 268 FilePath xps_path = install_path.Append(kDriverName); |
| 243 FilePath ui_path = install_path.Append(kUiDriverName); | 269 FilePath ui_path = install_path.Append(kUiDriverName); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 key.WriteValue(L"DisplayName", | 402 key.WriteValue(L"DisplayName", |
| 377 cloud_print::LoadLocalString(IDS_DRIVER_NAME).c_str()); | 403 cloud_print::LoadLocalString(IDS_DRIVER_NAME).c_str()); |
| 378 key.WriteValue(L"NoModify", 1); | 404 key.WriteValue(L"NoModify", 1); |
| 379 key.WriteValue(L"NoRepair", 1); | 405 key.WriteValue(L"NoRepair", 1); |
| 380 } | 406 } |
| 381 | 407 |
| 382 void CleanupUninstall() { | 408 void CleanupUninstall() { |
| 383 ::RegDeleteKey(HKEY_LOCAL_MACHINE, kUninstallRegistry); | 409 ::RegDeleteKey(HKEY_LOCAL_MACHINE, kUninstallRegistry); |
| 384 } | 410 } |
| 385 | 411 |
| 412 bool IsOSSupported() { |
| 413 // We don't support XP service pack 2 or older. |
| 414 base::win::Version version = base::win::GetVersion(); |
| 415 return (version > base::win::VERSION_XP) || |
| 416 ((version == base::win::VERSION_XP) && |
| 417 (base::win::OSInfo::GetInstance()->service_pack().major >= 3)); |
| 418 } |
| 419 |
| 386 HRESULT InstallVirtualDriver(const FilePath& install_path) { | 420 HRESULT InstallVirtualDriver(const FilePath& install_path) { |
| 387 HRESULT result = S_OK; | 421 HRESULT result = S_OK; |
| 422 |
| 423 if (!IsOSSupported()) { |
| 424 LOG(ERROR) << "Requires XP SP3 or later."; |
| 425 return ERROR_OLD_WIN_VERSION; |
| 426 } |
| 427 |
| 388 if (!file_util::CreateDirectory(install_path)) { | 428 if (!file_util::CreateDirectory(install_path)) { |
| 389 LOG(ERROR) << "Can't create install directory"; | 429 LOG(ERROR) << "Can't create install directory."; |
| 390 return ERROR_ACCESS_DENIED; | 430 return ERROR_ACCESS_DENIED; |
| 391 } | 431 } |
| 392 SetupUninstall(install_path); | 432 SetupUninstall(install_path); |
| 393 result = RegisterPortMonitor(true, install_path); | 433 result = RegisterPortMonitor(true, install_path); |
| 394 if (!SUCCEEDED(result)) { | 434 if (!SUCCEEDED(result)) { |
| 395 LOG(ERROR) << "Unable to register port monitor."; | 435 LOG(ERROR) << "Unable to register port monitor."; |
| 396 return result; | 436 return result; |
| 397 } | 437 } |
| 398 result = InstallPpd(install_path); | 438 result = InstallPpd(install_path); |
| 399 if (!SUCCEEDED(result)) { | 439 if (!SUCCEEDED(result)) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 retval = InstallVirtualDriver(install_path); | 510 retval = InstallVirtualDriver(install_path); |
| 471 } | 511 } |
| 472 } | 512 } |
| 473 // Installer is silent by default as required by Omaha. | 513 // Installer is silent by default as required by Omaha. |
| 474 if (CommandLine::ForCurrentProcess()->HasSwitch("verbose")) { | 514 if (CommandLine::ForCurrentProcess()->HasSwitch("verbose")) { |
| 475 cloud_print::DisplayWindowsMessage(NULL, retval, | 515 cloud_print::DisplayWindowsMessage(NULL, retval, |
| 476 cloud_print::LoadLocalString(IDS_DRIVER_NAME)); | 516 cloud_print::LoadLocalString(IDS_DRIVER_NAME)); |
| 477 } | 517 } |
| 478 return retval; | 518 return retval; |
| 479 } | 519 } |
| OLD | NEW |