Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: cloud_print/virtual_driver/win/install/setup.cc

Issue 8770019: Cleanup for the virtual driver setup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More cleanup Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <winspool.h> 7 #include <winspool.h>
7 8
8 #include "base/at_exit.h" 9 #include "base/at_exit.h"
9 #include "base/command_line.h" 10 #include "base/command_line.h"
10 #include "base/file_util.h" 11 #include "base/file_util.h"
11 #include "base/file_version_info_win.h" 12 #include "base/file_version_info_win.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/path_service.h" 14 #include "base/path_service.h"
14 #include "base/process_util.h" 15 #include "base/process_util.h"
15 #include "base/string16.h" 16 #include "base/string16.h"
16 #include "base/win/registry.h" 17 #include "base/win/registry.h"
17 #include "base/win/scoped_handle.h" 18 #include "base/win/scoped_handle.h"
18 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" 19 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h"
19 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" 20 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h"
20 #include "grit/virtual_driver_setup_resources.h" 21 #include "grit/virtual_driver_setup_resources.h"
21 22
23 #include <strsafe.h> // Must be after base headers to avoid deprecation
24 // warnings.
25
22 namespace { 26 namespace {
23 const wchar_t kVersionKey[] = L"pv"; 27 const wchar_t kVersionKey[] = L"pv";
24 const wchar_t kNameKey[] = L"name"; 28 const wchar_t kNameKey[] = L"name";
25 const wchar_t kLangKey[] = L"lang";
26 const wchar_t kNameValue[] = L"GCP Virtual Driver"; 29 const wchar_t kNameValue[] = L"GCP Virtual Driver";
27 const wchar_t kLangValue[] = L"rn"; 30 const wchar_t kPpdName[] = L"GCP-DRIVER.PPD";
31 const wchar_t kDriverName[] = L"MXDWDRV.DLL";
32 const wchar_t kUiDriverName[] = L"PS5UI.DLL";
33 const wchar_t kHelpName[] = L"PSCRIPT.HLP";
34 const wchar_t* kDependencyList[] = {kDriverName, kUiDriverName, kHelpName};
35 const wchar_t kUninstallRegistry[] =
36 L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
37 L"{74AA24E0-AC50-4B28-BA46-9CF05467C9B7}";
38 const wchar_t kInstallerName[] = L"virtual_driver_setup.exe";
28 39
29 void SetRegistryKeys() { 40 void SetOmahaKeys() {
30 base::win::RegKey key; 41 base::win::RegKey key;
31 if (key.Create(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation, 42 if (key.Create(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation,
32 KEY_SET_VALUE) != ERROR_SUCCESS) { 43 KEY_SET_VALUE) != ERROR_SUCCESS) {
33 LOG(ERROR) << "Unable to open key"; 44 LOG(ERROR) << "Unable to open key";
34 } 45 }
35 46
36 // Get the version from the resource file. 47 // Get the version from the resource file.
37 std::wstring version_string; 48 std::wstring version_string;
38 scoped_ptr<FileVersionInfo> version_info( 49 scoped_ptr<FileVersionInfo> version_info(
39 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 50 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
40 51
41 if (version_info.get()) { 52 if (version_info.get()) {
42 FileVersionInfoWin* version_info_win = 53 FileVersionInfoWin* version_info_win =
43 static_cast<FileVersionInfoWin*>(version_info.get()); 54 static_cast<FileVersionInfoWin*>(version_info.get());
44 version_string = version_info_win->product_version(); 55 version_string = version_info_win->product_version();
45 } else { 56 } else {
46 LOG(ERROR) << "Unable to get version string"; 57 LOG(ERROR) << "Unable to get version string";
47 // Use a random version string so that Omaha has something to go by. 58 // Use a random version string so that Omaha has something to go by.
48 version_string = L"0.0.0.99"; 59 version_string = L"0.0.0.99";
49 } 60 }
50 61
51 if (key.WriteValue(kVersionKey, version_string.c_str()) != ERROR_SUCCESS || 62 if (key.WriteValue(kVersionKey, version_string.c_str()) != ERROR_SUCCESS ||
52 key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS || 63 key.WriteValue(kNameKey, kNameValue) != ERROR_SUCCESS) {
53 key.WriteValue(kLangKey, kLangValue) != ERROR_SUCCESS) {
54 LOG(ERROR) << "Unable to set registry keys"; 64 LOG(ERROR) << "Unable to set registry keys";
55 } 65 }
56 } 66 }
57 67
58 void DeleteRegistryKeys() { 68 void DeleteOmahaKeys() {
59 base::win::RegKey key; 69 base::win::RegKey key;
60 if (key.Open(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation, 70 if (key.Open(HKEY_LOCAL_MACHINE, cloud_print::kKeyLocation,
61 DELETE) != ERROR_SUCCESS) { 71 DELETE) != ERROR_SUCCESS) {
62 LOG(ERROR) << "Unable to open key to delete"; 72 LOG(ERROR) << "Unable to open key to delete";
63 } 73 }
64 if (key.DeleteKey(L"") != ERROR_SUCCESS) { 74 if (key.DeleteKey(L"") != ERROR_SUCCESS) {
65 LOG(ERROR) << "Unable to delete key"; 75 LOG(ERROR) << "Unable to delete key";
66 } 76 }
67 } 77 }
68 78
69 HRESULT GetPpdPath(FilePath* path) { 79 HRESULT GetNativeSystemPath(FilePath* path) {
70 if (!PathService::Get(base::DIR_EXE, path)) {
71 LOG(ERROR) << "Unable to get install path.";
72 return ERROR_PATH_NOT_FOUND;
73 }
74 *path = path->Append(L"GCP-driver.ppd");
75 return S_OK;
76 }
77
78 HRESULT GetPortMonitorDllPath(FilePath* path) {
79 if (!PathService::Get(base::DIR_EXE, path)) {
80 LOG(ERROR) << "Unable to get install path.";
81 return ERROR_PATH_NOT_FOUND;
82 }
83 *path = path->Append(cloud_print::GetPortMonitorDllName());
84 return S_OK;
85 }
86
87 HRESULT GetPortMonitorInstallPath(FilePath* path) {
88 if (cloud_print::IsSystem64Bit()) { 80 if (cloud_print::IsSystem64Bit()) {
89 if (!PathService::Get(base::DIR_WINDOWS, path)) { 81 if (!PathService::Get(base::DIR_WINDOWS, path)) {
90 return ERROR_PATH_NOT_FOUND; 82 return ERROR_PATH_NOT_FOUND;
91 } 83 }
92 // Sysnative will bypass filesystem redirection and give us 84 // Sysnative will bypass filesystem redirection and give us
93 // the location of the 64bit system32 from a 32 bit process. 85 // the location of the 64bit system32 from a 32 bit process.
94 *path = path->Append(L"sysnative"); 86 *path = path->Append(L"sysnative");
95 } else { 87 } else {
96 if (!PathService::Get(base::DIR_SYSTEM, path)) { 88 if (!PathService::Get(base::DIR_SYSTEM, path)) {
97 LOG(ERROR) << "Unable to get system path."; 89 LOG(ERROR) << "Unable to get system path.";
98 return ERROR_PATH_NOT_FOUND; 90 return ERROR_PATH_NOT_FOUND;
99 } 91 }
100 } 92 }
101 *path = path->Append(cloud_print::GetPortMonitorDllName());
102 return S_OK; 93 return S_OK;
103 } 94 }
104 95
105 HRESULT GetRegsvr32Path(FilePath* path) { 96 HRESULT GetPortMonitorTargetPath(FilePath* path) {
106 if (!PathService::Get(base::DIR_SYSTEM, path)) { 97 HRESULT result = GetNativeSystemPath(path);
107 LOG(ERROR) << "Unable to get system path."; 98 if (SUCCEEDED(result))
108 return ERROR_PATH_NOT_FOUND; 99 *path = path->Append(cloud_print::GetPortMonitorDllName());
109 } 100 return result;
110 *path = path->Append(FilePath(L"regsvr32.exe"));
111 return S_OK;
112 } 101 }
113 102
114 HRESULT RegisterPortMonitor(bool install) { 103 HRESULT GetRegsvr32Path(FilePath* path) {
104 HRESULT result = GetNativeSystemPath(path);
105 if (SUCCEEDED(result))
106 *path = path->Append(FilePath(L"regsvr32.exe"));
107 return result;
108 }
109
110 HRESULT RegisterPortMonitor(bool install, const FilePath& install_path) {
115 FilePath target_path; 111 FilePath target_path;
116 HRESULT result = S_OK; 112 HRESULT result = S_OK;
117 result = GetPortMonitorInstallPath(&target_path); 113 result = GetPortMonitorTargetPath(&target_path);
118 if (!SUCCEEDED(result)) { 114 if (!SUCCEEDED(result)) {
119 LOG(ERROR) << "Unable to get port monitor target path."; 115 LOG(ERROR) << "Unable to get port monitor target path.";
120 return result; 116 return result;
121 } 117 }
122 FilePath source_path; 118 string16 source;
123 result = GetPortMonitorDllPath(&source_path); 119 source = cloud_print::GetPortMonitorDllName();
124 if (!SUCCEEDED(result)) {
125 LOG(ERROR) << "Unable to get dll source path.";
126 return result;
127 }
128 if (install) { 120 if (install) {
121 FilePath source_path = install_path.Append(source);
129 if (!file_util::CopyFileW(source_path, target_path)) { 122 if (!file_util::CopyFileW(source_path, target_path)) {
130 LOG(ERROR) << "Unable copy port monitor dll from " << 123 LOG(ERROR) << "Unable copy port monitor dll from " <<
131 source_path.value() << " to " << target_path.value(); 124 source_path.value() << " to " << target_path.value();
132 return ERROR_ACCESS_DENIED; 125 return ERROR_ACCESS_DENIED;
133 } 126 }
134 } 127 }
135 FilePath regsvr32_path; 128 FilePath regsvr32_path;
136 result = GetRegsvr32Path(&regsvr32_path); 129 result = GetRegsvr32Path(&regsvr32_path);
137 if (!SUCCEEDED(result)) { 130 if (!SUCCEEDED(result)) {
138 LOG(ERROR) << "Can't find regsvr32.exe."; 131 LOG(ERROR) << "Can't find regsvr32.exe.";
139 return result; 132 return result;
140 } 133 }
141 134
142 CommandLine command_line(regsvr32_path); 135 CommandLine command_line(regsvr32_path);
143 command_line.AppendArg("/s"); 136 command_line.AppendArg("/s");
144 if (!install) { 137 if (!install) {
145 command_line.AppendArg("/u"); 138 command_line.AppendArg("/u");
146 } 139 }
147 command_line.AppendArgPath(source_path); 140
141 FilePath final_path;
142 if (!PathService::Get(base::DIR_SYSTEM, &final_path)) {
143 LOG(ERROR) << "Unable to get system path.";
144 return ERROR_PATH_NOT_FOUND;
145 }
146 final_path = final_path.Append(cloud_print::GetPortMonitorDllName());
147 command_line.AppendArgPath(final_path);
148 148
149 base::LaunchOptions options; 149 base::LaunchOptions options;
150 HANDLE process_handle; 150 HANDLE process_handle;
151 options.wait = true; 151 options.wait = true;
152 if (!base::LaunchProcess(command_line, options, &process_handle)) { 152 if (!base::LaunchProcess(command_line, options, &process_handle)) {
153 LOG(ERROR) << "Unable to launch regsvr32.exe."; 153 LOG(ERROR) << "Unable to launch regsvr32.exe.";
154 return ERROR_NOT_SUPPORTED; 154 return ERROR_NOT_SUPPORTED;
155 } 155 }
156 base::win::ScopedHandle scoped_process_handle(process_handle); 156 base::win::ScopedHandle scoped_process_handle(process_handle);
157 157
(...skipping 24 matching lines...) Expand all
182 FileVersionInfoWin* version_info_win = 182 FileVersionInfoWin* version_info_win =
183 static_cast<FileVersionInfoWin*>(version_info.get()); 183 static_cast<FileVersionInfoWin*>(version_info.get());
184 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info(); 184 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
185 retval = fixed_file_info->dwFileVersionMS; 185 retval = fixed_file_info->dwFileVersionMS;
186 retval <<= 32; 186 retval <<= 32;
187 retval |= fixed_file_info->dwFileVersionMS; 187 retval |= fixed_file_info->dwFileVersionMS;
188 } 188 }
189 return retval; 189 return retval;
190 } 190 }
191 191
192 HRESULT InstallPpd() { 192 UINT CALLBACK CabinetCallback(PVOID data,
193 UINT notification,
194 UINT_PTR param1,
195 UINT_PTR param2 ) {
196 FilePath* temp_path = reinterpret_cast<FilePath*>(data);
197 if (notification == SPFILENOTIFY_FILEINCABINET) {
198 FILE_IN_CABINET_INFO* info =
199 reinterpret_cast<FILE_IN_CABINET_INFO*>(param1);
200 for (int i = 0; i < arraysize(kDependencyList); i++) {
201 if (wcsstr(info->NameInCabinet, kDependencyList[i])) {
202 StringCchCopy(info->FullTargetName, MAX_PATH,
203 temp_path->Append(kDependencyList[i]).value().c_str());
204 return FILEOP_DOIT;
205 }
206 }
207
208 return FILEOP_SKIP;
209 }
210 return NO_ERROR;
211 }
212
213 void ReadyPpdDependencies(const FilePath& install_path) {
214 CORE_PRINTER_DRIVER driver;
215 GetCorePrinterDrivers(NULL,
216 NULL,
217 L"{D20EA372-DD35-4950-9ED8-A6335AFE79F0}",
218 1,
219 &driver);
220 DWORD size = MAX_PATH;
221 wchar_t package_path[MAX_PATH];
222 GetPrinterDriverPackagePath(NULL,
223 NULL,
224 NULL,
225 driver.szPackageID,
226 package_path,
227 MAX_PATH,
228 &size);
229
230 SetupIterateCabinet(package_path,
231 0,
232 CabinetCallback,
233 const_cast<FilePath*>(&install_path));
234 }
235
236 HRESULT InstallPpd(const FilePath& install_path) {
193 DRIVER_INFO_6 driver_info = {0}; 237 DRIVER_INFO_6 driver_info = {0};
194 HRESULT result = S_OK; 238 HRESULT result = S_OK;
195 239
196 // Set up paths for the files we depend on. 240 // Set up paths for the files we depend on.
197 FilePath source_path; 241 FilePath ppd_path = install_path.Append(kPpdName);
198 FilePath driver_dir; 242 FilePath xps_path = install_path.Append(kDriverName);
199 cloud_print::GetPrinterDriverDir(&driver_dir); 243 FilePath ui_path = install_path.Append(kUiDriverName);
200 FilePath xps_path = driver_dir.Append(L"mxdwdrv.dll"); 244 FilePath ui_help_path = install_path.Append(kHelpName);
201 FilePath ui_path = driver_dir.Append(L"ps5ui.dll"); 245 ReadyPpdDependencies(install_path);
202 FilePath ui_help_path = driver_dir.Append(L"unidrv.hlp");
203 result = GetPpdPath(&source_path);
204 if (!SUCCEEDED(result)) {
205 return result;
206 }
207 // None of the print API structures likes constant strings even though they 246 // None of the print API structures likes constant strings even though they
208 // don't modify the string. const_casting is the cleanest option. 247 // don't modify the string. const_casting is the cleanest option.
209 driver_info.pDataFile = const_cast<LPWSTR>(source_path.value().c_str()); 248 driver_info.pDataFile = const_cast<LPWSTR>(ppd_path.value().c_str());
210 driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str()); 249 driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str());
211 driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str()); 250 driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str());
212 driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str()); 251 driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str());
213 252
214 // Set up user visible strings. 253 // Set up user visible strings.
215 string16 manufacturer = cloud_print::LoadLocalString(IDS_GOOGLE); 254 string16 manufacturer = cloud_print::LoadLocalString(IDS_GOOGLE);
216 driver_info.pszMfgName = const_cast<LPWSTR>(manufacturer.c_str()); 255 driver_info.pszMfgName = const_cast<LPWSTR>(manufacturer.c_str());
217 driver_info.pszProvider = const_cast<LPWSTR>(manufacturer.c_str()); 256 driver_info.pszProvider = const_cast<LPWSTR>(manufacturer.c_str());
218 driver_info.pszOEMUrl = L"http://www.google.com/cloudprint"; 257 driver_info.pszOEMUrl = L"http://www.google.com/cloudprint";
219 driver_info.dwlDriverVersion = GetVersionNumber(); 258 driver_info.dwlDriverVersion = GetVersionNumber();
220 string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME); 259 string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
221 driver_info.pName = const_cast<LPWSTR>(driver_name.c_str()); 260 driver_info.pName = const_cast<LPWSTR>(driver_name.c_str());
222 261
223 // Set up supported print system version. Must be 3. 262 // Set up supported print system version. Must be 3.
224 driver_info.cVersion = 3; 263 driver_info.cVersion = 3;
225 264
226 // TODO(abodenha@chromium.org) Properly handle dependencies.
227 // GPD files are often dependent on various Windows core drivers.
228 // I haven't found a reliable way to express those dependencies
229 // other than using an INF for installation.
230 if (!AddPrinterDriverEx(NULL, 265 if (!AddPrinterDriverEx(NULL,
231 6, 266 6,
232 reinterpret_cast<BYTE*>(&driver_info), 267 reinterpret_cast<BYTE*>(&driver_info),
233 APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY)) { 268 APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY)) {
234 result = cloud_print::GetLastHResult(); 269 result = cloud_print::GetLastHResult();
235 LOG(ERROR) << "Unable to add printer driver"; 270 LOG(ERROR) << "Unable to add printer driver";
236 return result;
237 } 271 }
238 return S_OK; 272 return result;
239 } 273 }
240 274
241 HRESULT UninstallPpd() { 275 HRESULT UninstallPpd() {
242 int tries = 10; 276 int tries = 10;
243 string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME); 277 string16 driver_name = cloud_print::LoadLocalString(IDS_DRIVER_NAME);
244 while (!DeletePrinterDriverEx(NULL, 278 while (!DeletePrinterDriverEx(NULL,
245 NULL, 279 NULL,
246 const_cast<LPWSTR>(driver_name.c_str()), 280 const_cast<LPWSTR>(driver_name.c_str()),
247 DPD_DELETE_UNUSED_FILES, 281 DPD_DELETE_UNUSED_FILES,
248 0) && tries > 0) { 282 0) && tries > 0) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 if (!DeletePrinter(handle)) { 336 if (!DeletePrinter(handle)) {
303 HRESULT result = cloud_print::GetLastHResult(); 337 HRESULT result = cloud_print::GetLastHResult();
304 LOG(ERROR) << "Unable to delete printer"; 338 LOG(ERROR) << "Unable to delete printer";
305 ClosePrinter(handle); 339 ClosePrinter(handle);
306 return result; 340 return result;
307 } 341 }
308 ClosePrinter(handle); 342 ClosePrinter(handle);
309 return S_OK; 343 return S_OK;
310 } 344 }
311 345
312 HRESULT InstallVirtualDriver(void) { 346 void SetupUninstall(const FilePath& install_path) {
347 // Now write the Windows Uninstall entries
348 // Minimal error checking here since the install can contiunue
349 // if this fails.
350 base::win::RegKey key;
351 if (key.Create(HKEY_LOCAL_MACHINE, kUninstallRegistry,
352 KEY_SET_VALUE) != ERROR_SUCCESS) {
353 LOG(ERROR) << "Unable to open key";
354 return;
355 }
356 CommandLine uninstall_command(install_path.Append(kInstallerName));
357 uninstall_command.AppendArg("--uninstall");
358 key.WriteValue(L"UninstallString",
359 uninstall_command.GetCommandLineString().c_str());
360 key.WriteValue(L"InstallLocation", install_path.value().c_str());
361
362
363 // Get the version resource.
364 scoped_ptr<FileVersionInfo> version_info(
365 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
366
367 if (version_info.get()) {
368 FileVersionInfoWin* version_info_win =
369 static_cast<FileVersionInfoWin*>(version_info.get());
370 key.WriteValue(L"DisplayVersion",
371 version_info_win->file_version().c_str());
372 key.WriteValue(L"Publisher", version_info_win->company_name().c_str());
373 } else {
374 LOG(ERROR) << "Unable to get version string";
375 }
376 key.WriteValue(L"DisplayName",
377 cloud_print::LoadLocalString(IDS_DRIVER_NAME).c_str());
378 key.WriteValue(L"NoModify", 1);
379 key.WriteValue(L"NoRepair", 1);
380 }
381
382 void CleanupUninstall() {
383 ::RegDeleteKey(HKEY_LOCAL_MACHINE, kUninstallRegistry);
384 }
385
386 HRESULT InstallVirtualDriver(const FilePath& install_path) {
313 HRESULT result = S_OK; 387 HRESULT result = S_OK;
314 result = RegisterPortMonitor(true); 388 if (!file_util::CreateDirectory(install_path)) {
389 LOG(ERROR) << "Can't create install directory";
390 return ERROR_ACCESS_DENIED;
391 }
392 SetupUninstall(install_path);
393 result = RegisterPortMonitor(true, install_path);
315 if (!SUCCEEDED(result)) { 394 if (!SUCCEEDED(result)) {
316 LOG(ERROR) << "Unable to register port monitor."; 395 LOG(ERROR) << "Unable to register port monitor.";
317 return result; 396 return result;
318 } 397 }
319 result = InstallPpd(); 398 result = InstallPpd(install_path);
320 if (!SUCCEEDED(result)) { 399 if (!SUCCEEDED(result)) {
321 LOG(ERROR) << "Unable to install Ppd."; 400 LOG(ERROR) << "Unable to install Ppd.";
322 return result; 401 return result;
323 } 402 }
324 result = InstallPrinter(); 403 result = InstallPrinter();
325 if (!SUCCEEDED(result)) { 404 if (!SUCCEEDED(result)) {
326 LOG(ERROR) << "Unable to install printer."; 405 LOG(ERROR) << "Unable to install printer.";
327 return result; 406 return result;
328 } 407 }
329 SetRegistryKeys(); 408 SetOmahaKeys();
330 return S_OK; 409 return S_OK;
331 } 410 }
332 411
333 HRESULT UninstallVirtualDriver(void) { 412 HRESULT UninstallVirtualDriver(const FilePath& install_path) {
334 HRESULT result = S_OK; 413 HRESULT result = S_OK;
335 result = UninstallPrinter(); 414 result = UninstallPrinter();
336 if (!SUCCEEDED(result)) { 415 if (!SUCCEEDED(result)) {
337 LOG(ERROR) << "Unable to uninstall Ppd."; 416 LOG(ERROR) << "Unable to uninstall Ppd.";
338 return result; 417 return result;
339 } 418 }
340 result = UninstallPpd(); 419 result = UninstallPpd();
341 if (!SUCCEEDED(result)) { 420 if (!SUCCEEDED(result)) {
342 LOG(ERROR) << "Unable to remove Ppd."; 421 LOG(ERROR) << "Unable to remove Ppd.";
343 return result; 422 return result;
344 } 423 }
345 result = RegisterPortMonitor(false); 424 result = RegisterPortMonitor(false, install_path);
346 if (!SUCCEEDED(result)) { 425 if (!SUCCEEDED(result)) {
347 LOG(ERROR) << "Unable to remove port monitor."; 426 LOG(ERROR) << "Unable to remove port monitor.";
348 return result; 427 return result;
349 } 428 }
350 DeleteRegistryKeys(); 429 DeleteOmahaKeys();
430 file_util::Delete(install_path, true);
431 CleanupUninstall();
351 return S_OK; 432 return S_OK;
352 } 433 }
353 434
435 HRESULT LaunchChildForUninstall() {
436 FilePath installer_source;
437 if (PathService::Get(base::FILE_EXE, &installer_source)) {
438 FilePath temp_path;
439 if (file_util::CreateTemporaryFile(&temp_path)) {
440 file_util::Move(installer_source, temp_path);
441 file_util::DeleteAfterReboot(temp_path);
442 CommandLine command_line(temp_path);
443 command_line.AppendArg("--douninstall");
444 base::LaunchOptions options;
445 if (!base::LaunchProcess(command_line, options, NULL)) {
446 LOG(ERROR) << "Unable to launch child uninstall.";
447 return ERROR_NOT_SUPPORTED;
448 }
449 }
450 }
451 return S_OK;
452 }
354 } // namespace 453 } // namespace
355 454
356 int WINAPI WinMain(__in HINSTANCE hInstance, 455 int WINAPI WinMain(__in HINSTANCE hInstance,
357 __in HINSTANCE hPrevInstance, 456 __in HINSTANCE hPrevInstance,
358 __in LPSTR lpCmdLine, 457 __in LPSTR lpCmdLine,
359 __in int nCmdShow) { 458 __in int nCmdShow) {
360 base::AtExitManager at_exit_manager; 459 base::AtExitManager at_exit_manager;
361 CommandLine::Init(0, NULL); 460 CommandLine::Init(0, NULL);
362 HRESULT retval = S_OK; 461
363 if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) { 462 FilePath install_path;
364 retval = UninstallVirtualDriver(); 463 HRESULT retval = PathService::Get(base::DIR_EXE, &install_path);
365 } else { 464 if (SUCCEEDED(retval)) {
366 retval = InstallVirtualDriver(); 465 if (CommandLine::ForCurrentProcess()->HasSwitch("douninstall")) {
466 retval = UninstallVirtualDriver(install_path);
467 } else if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) {
468 retval = LaunchChildForUninstall();
469 } else {
470 retval = InstallVirtualDriver(install_path);
471 }
367 } 472 }
368 // Installer is silent by default as required by Omaha. 473 // Installer is silent by default as required by Omaha.
369 if (CommandLine::ForCurrentProcess()->HasSwitch("verbose")) { 474 if (CommandLine::ForCurrentProcess()->HasSwitch("verbose")) {
370 cloud_print::DisplayWindowsMessage(NULL, retval, 475 cloud_print::DisplayWindowsMessage(NULL, retval,
371 cloud_print::LoadLocalString(IDS_DRIVER_NAME)); 476 cloud_print::LoadLocalString(IDS_DRIVER_NAME));
372 } 477 }
373 return retval; 478 return retval;
374 } 479 }
OLDNEW
« no previous file with comments | « cloud_print/virtual_driver/GCP-driver.ppd ('k') | cloud_print/virtual_driver/win/install/virtual_driver_install.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698