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

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

Issue 6930019: Added resources. (Closed)
Patch Set: Respond to feedback Created 9 years, 7 months 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
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 <winspool.h> 6 #include <winspool.h>
7 7
8 #include "base/at_exit.h" 8 #include "base/at_exit.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/file_version_info_win.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/path_service.h" 13 #include "base/path_service.h"
13 #include "base/process_util.h" 14 #include "base/process_util.h"
15 #include "base/string16.h"
14 #include "base/win/scoped_handle.h" 16 #include "base/win/scoped_handle.h"
15 #include "base/win/windows_version.h"
16 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h" 17 #include "cloud_print/virtual_driver/win/virtual_driver_consts.h"
17 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h" 18 #include "cloud_print/virtual_driver/win/virtual_driver_helpers.h"
19 #include "grit/virtual_driver_setup_resources.h"
18 20
19 namespace { 21 namespace {
20 22
21 bool IsSystem64Bit() {
22 base::win::OSInfo::WindowsArchitecture arch =
23 base::win::OSInfo::GetInstance()->architecture();
24 return (arch == base::win::OSInfo::X64_ARCHITECTURE) ||
25 (arch == base::win::OSInfo::IA64_ARCHITECTURE);
26 }
27
28 HRESULT GetGpdPath(FilePath* path) { 23 HRESULT GetGpdPath(FilePath* path) {
29 if (!PathService::Get(base::DIR_EXE, path)) { 24 if (!PathService::Get(base::DIR_EXE, path)) {
30 LOG(ERROR) << "Unable to get install path."; 25 LOG(ERROR) << "Unable to get install path.";
31 return ERROR_PATH_NOT_FOUND; 26 return ERROR_PATH_NOT_FOUND;
32 } 27 }
33 *path = path->Append(L"gcp.gpd"); 28 *path = path->Append(L"gcp.gpd");
34 return S_OK; 29 return S_OK;
35 } 30 }
36 31
37 const wchar_t *GetPortMonitorDllName() {
38 if (IsSystem64Bit()) {
39 return cloud_print::kPortMonitorDllName64;
40 } else {
41 return cloud_print::kPortMonitorDllName32;
42 }
43 }
44
45 HRESULT GetPortMonitorDllPath(FilePath* path) { 32 HRESULT GetPortMonitorDllPath(FilePath* path) {
46 if (!PathService::Get(base::DIR_EXE, path)) { 33 if (!PathService::Get(base::DIR_EXE, path)) {
47 LOG(ERROR) << "Unable to get install path."; 34 LOG(ERROR) << "Unable to get install path.";
48 return ERROR_PATH_NOT_FOUND; 35 return ERROR_PATH_NOT_FOUND;
49 } 36 }
50 *path = path->Append(GetPortMonitorDllName()); 37 FilePath dll_name;
38 cloud_print::GetPortMonitorDllName(&dll_name);
39 *path = path->Append(dll_name);
51 return S_OK; 40 return S_OK;
52 } 41 }
53 42
54 HRESULT GetPortMonitorInstallPath(FilePath* path) { 43 HRESULT GetPortMonitorInstallPath(FilePath* path) {
55 if (IsSystem64Bit()) { 44 if (cloud_print::IsSystem64Bit()) {
56 if (!PathService::Get(base::DIR_WINDOWS, path)) { 45 if (!PathService::Get(base::DIR_WINDOWS, path)) {
57 return ERROR_PATH_NOT_FOUND; 46 return ERROR_PATH_NOT_FOUND;
58 } 47 }
59 // Sysnative will bypass filesystem redirection and give us 48 // Sysnative will bypass filesystem redirection and give us
60 // the location of the 64bit system32 from a 32 bit process. 49 // the location of the 64bit system32 from a 32 bit process.
61 *path = path->Append(L"sysnative"); 50 *path = path->Append(L"sysnative");
62 } else { 51 } else {
63 if (!PathService::Get(base::DIR_SYSTEM, path)) { 52 if (!PathService::Get(base::DIR_SYSTEM, path)) {
64 LOG(ERROR) << "Unable to get system path."; 53 LOG(ERROR) << "Unable to get system path.";
65 return ERROR_PATH_NOT_FOUND; 54 return ERROR_PATH_NOT_FOUND;
66 } 55 }
67 } 56 }
68 *path = path->Append(GetPortMonitorDllName()); 57 FilePath dll_name;
58 cloud_print::GetPortMonitorDllName(&dll_name);
59 *path = path->Append(dll_name);
69 return S_OK; 60 return S_OK;
70 } 61 }
71 62
72 HRESULT GetRegsvr32Path(FilePath* path) { 63 HRESULT GetRegsvr32Path(FilePath* path) {
73 if (!PathService::Get(base::DIR_SYSTEM, path)) { 64 if (!PathService::Get(base::DIR_SYSTEM, path)) {
74 LOG(ERROR) << "Unable to get system path."; 65 LOG(ERROR) << "Unable to get system path.";
75 return ERROR_PATH_NOT_FOUND; 66 return ERROR_PATH_NOT_FOUND;
76 } 67 }
77 *path = path->Append(FilePath(L"regsvr32.exe")); 68 *path = path->Append(FilePath(L"regsvr32.exe"));
78 return S_OK; 69 return S_OK;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 } 123 }
133 if (!install) { 124 if (!install) {
134 if (!file_util::Delete(target_path, false)) { 125 if (!file_util::Delete(target_path, false)) {
135 LOG(ERROR) << "Unable to delete " << target_path.value(); 126 LOG(ERROR) << "Unable to delete " << target_path.value();
136 return ERROR_ACCESS_DENIED; 127 return ERROR_ACCESS_DENIED;
137 } 128 }
138 } 129 }
139 return S_OK; 130 return S_OK;
140 } 131 }
141 132
133 DWORDLONG GetVersionNumber() {
134 DWORDLONG retval = 0;
135 scoped_ptr<FileVersionInfo> version_info(
136 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
137 if (version_info.get()) {
138 FileVersionInfoWin* version_info_win =
139 static_cast<FileVersionInfoWin*>(version_info.get());
140 VS_FIXEDFILEINFO* fixed_file_info = version_info_win->fixed_file_info();
141 retval = fixed_file_info->dwFileVersionMS;
142 retval <<= 32;
143 retval |= fixed_file_info->dwFileVersionMS;
144 }
145 return retval;
146 }
147
142 HRESULT InstallGpd() { 148 HRESULT InstallGpd() {
149 DRIVER_INFO_6 driver_info = {0};
143 HRESULT result = S_OK; 150 HRESULT result = S_OK;
151
152 // Set up paths for the files we depend on.
144 FilePath source_path; 153 FilePath source_path;
145 result = GetGpdPath(&source_path);
146 if (!SUCCEEDED(result)) {
147 return result;
148 }
149 FilePath driver_dir; 154 FilePath driver_dir;
150 cloud_print::GetPrinterDriverDir(&driver_dir); 155 cloud_print::GetPrinterDriverDir(&driver_dir);
151 FilePath xps_path = driver_dir.Append(L"mxdwdrv.dll"); 156 FilePath xps_path = driver_dir.Append(L"mxdwdrv.dll");
152 FilePath ui_path = driver_dir.Append(L"unidrvui.dll"); 157 FilePath ui_path = driver_dir.Append(L"unidrvui.dll");
153 FilePath ui_help_path = driver_dir.Append(L"unidrv.hlp"); 158 FilePath ui_help_path = driver_dir.Append(L"unidrv.hlp");
154 DRIVER_INFO_6 driver_info = {0}; 159 result = GetGpdPath(&source_path);
155 driver_info.cVersion = 3; 160 if (!SUCCEEDED(result)) {
161 return result;
162 }
156 // None of the print API structures likes constant strings even though they 163 // None of the print API structures likes constant strings even though they
157 // don't modify the string. const_casting is the cleanest option. 164 // don't modify the string. const_casting is the cleanest option.
158 driver_info.pName = const_cast<LPWSTR>(cloud_print::kVirtualDriverName); 165 driver_info.pDataFile = const_cast<LPWSTR>(source_path.value().c_str());
166 driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str());
159 driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str()); 167 driver_info.pDriverPath = const_cast<LPWSTR>(xps_path.value().c_str());
160 driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str()); 168 driver_info.pConfigFile = const_cast<LPWSTR>(ui_path.value().c_str());
161 driver_info.pDataFile = const_cast<LPWSTR>(source_path.value().c_str()); 169
162 driver_info.pHelpFile = const_cast<LPWSTR>(ui_help_path.value().c_str()); 170 // Set up user visible strings.
163 // TODO(abodenha@chromium.org) Pull these strings from resources. 171 string16 manufacturer;
164 driver_info.pszMfgName = L"Google"; 172 cloud_print::LoadLocalString(IDS_GOOGLE, &manufacturer);
165 driver_info.pszProvider = driver_info.pszMfgName; 173 driver_info.pszMfgName = const_cast<LPWSTR>(manufacturer.c_str());
174 driver_info.pszProvider = const_cast<LPWSTR>(manufacturer.c_str());
166 driver_info.pszOEMUrl = L"http://www.google.com/cloudprint"; 175 driver_info.pszOEMUrl = L"http://www.google.com/cloudprint";
167 driver_info.dwlDriverVersion = 1; 176 driver_info.dwlDriverVersion = GetVersionNumber();
168 driver_info.pDefaultDataType = L"RAW"; 177 string16 driver_name;
178 cloud_print::LoadLocalString(IDS_DRIVER_NAME, &driver_name);
179 driver_info.pName = const_cast<LPWSTR>(driver_name.c_str());
180
181 // Set up supported print system version. Must be 3.
182 driver_info.cVersion = 3;
183
169 // TODO(abodenha@chromium.org) Properly handle dependencies. 184 // TODO(abodenha@chromium.org) Properly handle dependencies.
170 // GPD files are often dependent on various Windows core drivers. 185 // GPD files are often dependent on various Windows core drivers.
171 // I haven't found a reliable way to express those dependencies 186 // I haven't found a reliable way to express those dependencies
172 // other than using an INF for installation. 187 // other than using an INF for installation.
173 if (!AddPrinterDriverEx(NULL, 188 if (!AddPrinterDriverEx(NULL,
174 6, 189 6,
175 reinterpret_cast<BYTE*>(&driver_info), 190 reinterpret_cast<BYTE*>(&driver_info),
176 APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY)) { 191 APD_COPY_NEW_FILES|APD_COPY_FROM_DIRECTORY)) {
177 result = cloud_print::GetLastHResult(); 192 result = cloud_print::GetLastHResult();
178 LOG(ERROR) << "Unable to add printer driver"; 193 LOG(ERROR) << "Unable to add printer driver";
179 return result; 194 return result;
180 } 195 }
181 return S_OK; 196 return S_OK;
182 } 197 }
183 198
184 HRESULT UninstallGpd() { 199 HRESULT UninstallGpd() {
185 int tries = 10; 200 int tries = 10;
201 string16 driver_name;
202 cloud_print::LoadLocalString(IDS_DRIVER_NAME, &driver_name);
186 while (!DeletePrinterDriverEx(NULL, 203 while (!DeletePrinterDriverEx(NULL,
187 NULL, 204 NULL,
188 const_cast<LPWSTR> 205 const_cast<LPWSTR>(driver_name.c_str()),
189 (cloud_print::kVirtualDriverName),
190 DPD_DELETE_UNUSED_FILES, 206 DPD_DELETE_UNUSED_FILES,
191 0) && tries > 0) { 207 0) && tries > 0) {
208 if (GetLastError() == ERROR_UNKNOWN_PRINTER_DRIVER) {
209 LOG(WARNING) << "Print driver is already uninstalled.";
210 return S_OK;
211 }
192 // After deleting the printer it can take a few seconds before 212 // After deleting the printer it can take a few seconds before
193 // the driver is free for deletion. Retry a few times before giving up. 213 // the driver is free for deletion. Retry a few times before giving up.
194 LOG(WARNING) << "Attempt to delete printer driver failed. Retrying."; 214 LOG(WARNING) << "Attempt to delete printer driver failed. Retrying.";
195 tries--; 215 tries--;
196 Sleep(2000); 216 Sleep(2000);
197 } 217 }
198 if (tries <= 0) { 218 if (tries <= 0) {
199 HRESULT result = cloud_print::GetLastHResult(); 219 HRESULT result = S_OK;
200 LOG(ERROR) << "Unable to delete printer driver."; 220 LOG(ERROR) << "Unable to delete printer driver.";
201 return result; 221 return result;
202 } 222 }
203 return S_OK; 223 return S_OK;
204 } 224 }
205 225
206 HRESULT InstallPrinter(void) { 226 HRESULT InstallPrinter(void) {
207 PRINTER_INFO_2 printer_info = {0}; 227 PRINTER_INFO_2 printer_info = {0};
208 printer_info.pPrinterName = 228
209 const_cast<LPWSTR>(cloud_print::kVirtualDriverName); 229 // None of the print API structures likes constant strings even though they
230 // don't modify the string. const_casting is the cleanest option.
231 string16 driver_name;
232 cloud_print::LoadLocalString(IDS_DRIVER_NAME, &driver_name);
233 printer_info.pDriverName = const_cast<LPWSTR>(driver_name.c_str());
234 printer_info.pPrinterName = const_cast<LPWSTR>(driver_name.c_str());
235 printer_info.pComment = const_cast<LPWSTR>(driver_name.c_str());
236 string16 port_name;
210 printer_info.pPortName = const_cast<LPWSTR>(cloud_print::kPortName); 237 printer_info.pPortName = const_cast<LPWSTR>(cloud_print::kPortName);
211 printer_info.pDriverName =
212 const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
213 printer_info.pPrinterName = printer_info.pDriverName;
214 // TODO(abodenha@chromium.org) pComment should be localized.
215 printer_info.pComment = const_cast<LPWSTR>(cloud_print::kVirtualDriverName);
216 printer_info.Attributes = PRINTER_ATTRIBUTE_DIRECT|PRINTER_ATTRIBUTE_LOCAL; 238 printer_info.Attributes = PRINTER_ATTRIBUTE_DIRECT|PRINTER_ATTRIBUTE_LOCAL;
217 printer_info.pPrintProcessor = L"winprint"; 239 printer_info.pPrintProcessor = L"winprint";
218 printer_info.pDatatype = L"RAW";
219 HANDLE handle = AddPrinter(NULL, 2, reinterpret_cast<BYTE*>(&printer_info)); 240 HANDLE handle = AddPrinter(NULL, 2, reinterpret_cast<BYTE*>(&printer_info));
220 if (handle == NULL) { 241 if (handle == NULL) {
221 HRESULT result = cloud_print::GetLastHResult(); 242 HRESULT result = cloud_print::GetLastHResult();
222 LOG(ERROR) << "Unable to add printer"; 243 LOG(ERROR) << "Unable to add printer";
223 return result; 244 return result;
224 } 245 }
225 ClosePrinter(handle); 246 ClosePrinter(handle);
226 return S_OK; 247 return S_OK;
227 } 248 }
228 249
229 HRESULT UninstallPrinter(void) { 250 HRESULT UninstallPrinter(void) {
230 HANDLE handle = NULL; 251 HANDLE handle = NULL;
231 PRINTER_DEFAULTS printer_defaults = {0}; 252 PRINTER_DEFAULTS printer_defaults = {0};
232 printer_defaults.DesiredAccess = PRINTER_ALL_ACCESS; 253 printer_defaults.DesiredAccess = PRINTER_ALL_ACCESS;
233 if (!OpenPrinter(const_cast<LPWSTR>(cloud_print::kVirtualDriverName), 254 string16 driver_name;
255 cloud_print::LoadLocalString(IDS_DRIVER_NAME, &driver_name);
256 if (!OpenPrinter(const_cast<LPWSTR>(driver_name.c_str()),
234 &handle, 257 &handle,
235 &printer_defaults)) { 258 &printer_defaults)) {
236 // If we can't open the printer, it was probably already removed. 259 // If we can't open the printer, it was probably already removed.
237 LOG(WARNING) << "Unable to open printer"; 260 LOG(WARNING) << "Unable to open printer";
238 return S_OK; 261 return S_OK;
239 } 262 }
240 if (!DeletePrinter(handle)) { 263 if (!DeletePrinter(handle)) {
241 HRESULT result = cloud_print::GetLastHResult(); 264 HRESULT result = cloud_print::GetLastHResult();
242 LOG(ERROR) << "Unable to delete printer"; 265 LOG(ERROR) << "Unable to delete printer";
243 ClosePrinter(handle); 266 ClosePrinter(handle);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 __in int nCmdShow) { 318 __in int nCmdShow) {
296 base::AtExitManager at_exit_manager; 319 base::AtExitManager at_exit_manager;
297 CommandLine::Init(0, NULL); 320 CommandLine::Init(0, NULL);
298 HRESULT retval = S_OK; 321 HRESULT retval = S_OK;
299 if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) { 322 if (CommandLine::ForCurrentProcess()->HasSwitch("uninstall")) {
300 retval = UninstallVirtualDriver(); 323 retval = UninstallVirtualDriver();
301 } else { 324 } else {
302 retval = InstallVirtualDriver(); 325 retval = InstallVirtualDriver();
303 } 326 }
304 if (!CommandLine::ForCurrentProcess()->HasSwitch("silent")) { 327 if (!CommandLine::ForCurrentProcess()->HasSwitch("silent")) {
305 cloud_print::DisplayWindowsMessage(NULL, retval); 328 string16 driver_name;
329 cloud_print::LoadLocalString(IDS_DRIVER_NAME, &driver_name);
330 cloud_print::DisplayWindowsMessage(NULL, retval, driver_name);
306 } 331 }
307 return retval; 332 return retval;
308 } 333 }
309 334
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698