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 |