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

Side by Side Diff: chrome/installer/util/shell_util_unittest.cc

Issue 10826188: Sharing shell_util_unittest code to verify shortcuts (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <shellapi.h> 6 #include <shellapi.h>
7 #include <shlobj.h> 7 #include <shlobj.h>
gab 2012/08/07 19:18:25 I don't think any of these include are needed anym
Halli 2012/08/07 20:52:16 shlobj.h is used for IsUserAnAdmin() Done.
8 8
9 #include <fstream> 9 #include <fstream>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/path_service.h" 13 #include "base/path_service.h"
14 #include "base/md5.h" 14 #include "base/md5.h"
15 #include "base/scoped_temp_dir.h" 15 #include "base/scoped_temp_dir.h"
16 #include "base/string16.h" 16 #include "base/string16.h"
gab 2012/08/07 19:18:25 optional: Not your fault, but while you're at it c
Halli 2012/08/07 20:52:16 Done.
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/win/scoped_comptr.h" 18 #include "base/win/scoped_comptr.h"
gab 2012/08/07 19:18:25 Remove this include.
Halli 2012/08/07 20:52:16 Done.
19 #include "base/win/windows_version.h" 19 #include "base/win/windows_version.h"
20 #include "chrome/installer/util/browser_distribution.h" 20 #include "chrome/installer/util/browser_distribution.h"
21 #include "chrome/installer/util/master_preferences.h" 21 #include "chrome/installer/util/master_preferences.h"
22 #include "chrome/installer/util/shell_util.h" 22 #include "chrome/installer/util/shell_util.h"
23 #include "chrome/installer/util/util_constants.h" 23 #include "chrome/installer/util/util_constants.h"
24 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
25 25
26 namespace { 26 namespace {
gab 2012/08/07 19:18:25 nit: Please add a blank line here (as per the Chro
Halli 2012/08/07 20:52:16 Done.
27 bool VerifyChromeShortcut(const std::wstring& exe_path,
28 const std::wstring& shortcut,
29 const std::wstring& description,
30 int icon_index) {
31 base::win::ScopedComPtr<IShellLink> i_shell_link;
32 base::win::ScopedComPtr<IPersistFile> i_persist_file;
33
34 // Get pointer to the IShellLink interface
35 bool failed = FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
36 CLSCTX_INPROC_SERVER));
37 EXPECT_FALSE(failed) << "Failed to get IShellLink";
38 if (failed)
39 return false;
40
41 // Query IShellLink for the IPersistFile interface
42 failed = FAILED(i_persist_file.QueryFrom(i_shell_link));
43 EXPECT_FALSE(failed) << "Failed to get IPersistFile";
44 if (failed)
45 return false;
46
47 failed = FAILED(i_persist_file->Load(shortcut.c_str(), 0));
48 EXPECT_FALSE(failed) << "Failed to load shortcut " << shortcut.c_str();
49 if (failed)
50 return false;
51
52 wchar_t long_path[MAX_PATH] = {0};
53 wchar_t short_path[MAX_PATH] = {0};
54 failed = ((::GetLongPathName(exe_path.c_str(), long_path, MAX_PATH) == 0) ||
55 (::GetShortPathName(exe_path.c_str(), short_path, MAX_PATH) == 0));
56 EXPECT_FALSE(failed) << "Failed to get long and short path names for "
57 << exe_path;
58 if (failed)
59 return false;
60
61 wchar_t file_path[MAX_PATH] = {0};
62 failed = ((FAILED(i_shell_link->GetPath(file_path, MAX_PATH, NULL,
63 SLGP_UNCPRIORITY))) ||
64 ((FilePath(file_path) != FilePath(long_path)) &&
65 (FilePath(file_path) != FilePath(short_path))));
66 EXPECT_FALSE(failed) << "File path " << file_path << " did not match with "
67 << exe_path;
68 if (failed)
69 return false;
70
71 wchar_t desc[MAX_PATH] = {0};
72 failed = ((FAILED(i_shell_link->GetDescription(desc, MAX_PATH))) ||
73 (std::wstring(desc) != std::wstring(description)));
74 EXPECT_FALSE(failed) << "Description " << desc << " did not match with "
75 << description;
76 if (failed)
77 return false;
78
79 wchar_t icon_path[MAX_PATH] = {0};
80 int index = 0;
81 failed = ((FAILED(i_shell_link->GetIconLocation(icon_path, MAX_PATH,
82 &index))) ||
83 ((FilePath(file_path) != FilePath(long_path)) &&
84 (FilePath(file_path) != FilePath(short_path))) ||
85 (index != icon_index));
86 EXPECT_FALSE(failed);
87 if (failed)
88 return false;
89
90 return true;
91 }
92
93 class ShellUtilTestWithDirAndDist : public testing::Test { 27 class ShellUtilTestWithDirAndDist : public testing::Test {
94 protected: 28 protected:
95 virtual void SetUp() { 29 virtual void SetUp() {
96 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 30 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
97 dist_ = BrowserDistribution::GetDistribution(); 31 dist_ = BrowserDistribution::GetDistribution();
98 ASSERT_TRUE(dist_ != NULL); 32 ASSERT_TRUE(dist_ != NULL);
99 } 33 }
100 34
101 BrowserDistribution* dist_; 35 BrowserDistribution* dist_;
102 36
103 ScopedTempDir temp_dir_; 37 ScopedTempDir temp_dir_;
104 }; 38 };
gab 2012/08/07 19:18:25 nit: Blank line here as well.
Halli 2012/08/07 20:52:16 Done.
105 }; 39 }
106 40
107 // Test that we can open archives successfully. 41 // Test that we can open archives successfully.
108 TEST_F(ShellUtilTestWithDirAndDist, UpdateChromeShortcutTest) { 42 TEST_F(ShellUtilTestWithDirAndDist, UpdateChromeShortcutTest) {
109 // Create an executable in test path by copying ourself to it. 43 // Create an executable in test path by copying ourself to it.
110 wchar_t exe_full_path_str[MAX_PATH]; 44 wchar_t exe_full_path_str[MAX_PATH];
111 EXPECT_FALSE(::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH) == 0); 45 EXPECT_FALSE(::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH) == 0);
112 FilePath exe_full_path(exe_full_path_str); 46 FilePath exe_full_path(exe_full_path_str);
113 47
114 FilePath exe_path = temp_dir_.path().AppendASCII("setup.exe"); 48 FilePath exe_path = temp_dir_.path().AppendASCII("setup.exe");
115 EXPECT_TRUE(file_util::CopyFile(exe_full_path, exe_path)); 49 EXPECT_TRUE(file_util::CopyFile(exe_full_path, exe_path));
116 50
117 FilePath shortcut_path = temp_dir_.path().AppendASCII("shortcut.lnk"); 51 FilePath shortcut_path = temp_dir_.path().AppendASCII("shortcut.lnk");
118 const std::wstring description(L"dummy description"); 52 const std::wstring description(L"dummy description");
119 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut( 53 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(
120 dist_, 54 dist_,
121 exe_path.value(), 55 exe_path.value(),
122 shortcut_path.value(), 56 shortcut_path.value(),
123 L"", 57 L"",
124 description, 58 description,
125 exe_path.value(), 59 exe_path.value(),
126 dist_->GetIconIndex(), 60 dist_->GetIconIndex(),
127 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 61 ShellUtil::SHORTCUT_CREATE_ALWAYS));
128 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 62 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
129 shortcut_path.value(), 63 shortcut_path.value(),
130 description, 0)); 64 description, 0));
131 65
132 // Now specify an icon index in master prefs and make sure it works. 66 // Now specify an icon index in master prefs and make sure it works.
133 FilePath prefs_path = temp_dir_.path().AppendASCII( 67 FilePath prefs_path = temp_dir_.path().AppendASCII(
134 installer::kDefaultMasterPrefs); 68 installer::kDefaultMasterPrefs);
135 std::ofstream file; 69 std::ofstream file;
136 file.open(prefs_path.value().c_str()); 70 file.open(prefs_path.value().c_str());
137 ASSERT_TRUE(file.is_open()); 71 ASSERT_TRUE(file.is_open());
138 file << 72 file <<
139 "{" 73 "{"
140 " \"distribution\":{" 74 " \"distribution\":{"
141 " \"chrome_shortcut_icon_index\" : 1" 75 " \"chrome_shortcut_icon_index\" : 1"
142 " }" 76 " }"
143 "}"; 77 "}";
144 file.close(); 78 file.close();
145 ASSERT_TRUE(file_util::Delete(shortcut_path, false)); 79 ASSERT_TRUE(file_util::Delete(shortcut_path, false));
146 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut( 80 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(
147 dist_, 81 dist_,
148 exe_path.value(), 82 exe_path.value(),
149 shortcut_path.value(), 83 shortcut_path.value(),
150 L"", 84 L"",
151 description, 85 description,
152 exe_path.value(), 86 exe_path.value(),
153 dist_->GetIconIndex(), 87 dist_->GetIconIndex(),
154 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 88 ShellUtil::SHORTCUT_CREATE_ALWAYS));
155 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 89 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
156 shortcut_path.value(), 90 shortcut_path.value(),
gab 2012/08/07 19:18:25 ident variable to same level as the one above it (
Halli 2012/08/07 20:52:16 Done.
157 description, 1)); 91 description, 1));
158 92
159 // Now change only description to update shortcut and make sure icon index 93 // Now change only description to update shortcut and make sure icon index
160 // doesn't change. 94 // doesn't change.
161 const std::wstring description2(L"dummy description 2"); 95 const std::wstring description2(L"dummy description 2");
162 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist_, 96 EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist_,
163 exe_path.value(), 97 exe_path.value(),
164 shortcut_path.value(), 98 shortcut_path.value(),
165 L"", 99 L"",
166 description2, 100 description2,
167 exe_path.value(), 101 exe_path.value(),
168 dist_->GetIconIndex(), 102 dist_->GetIconIndex(),
169 ShellUtil::SHORTCUT_NO_OPTIONS)); 103 ShellUtil::SHORTCUT_NO_OPTIONS));
170 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 104 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
171 shortcut_path.value(), 105 shortcut_path.value(),
172 description2, 1)); 106 description2, 1));
173 } 107 }
174 108
175 TEST_F(ShellUtilTestWithDirAndDist, CreateChromeDesktopShortcutTest) { 109 TEST_F(ShellUtilTestWithDirAndDist, CreateChromeDesktopShortcutTest) {
176 // Run this test on Vista+ only if we are running elevated. 110 // Run this test on Vista+ only if we are running elevated.
177 if (base::win::GetVersion() > base::win::VERSION_XP && !IsUserAnAdmin()) { 111 if (base::win::GetVersion() > base::win::VERSION_XP && !IsUserAnAdmin()) {
178 LOG(ERROR) << "Must be admin to run this test on Vista+"; 112 LOG(ERROR) << "Must be admin to run this test on Vista+";
179 return; 113 return;
180 } 114 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut( 155 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
222 dist_, 156 dist_,
223 exe_path.value(), 157 exe_path.value(),
224 description, 158 description,
225 L"", 159 L"",
226 L"", 160 L"",
227 exe_path.value(), 161 exe_path.value(),
228 dist_->GetIconIndex(), 162 dist_->GetIconIndex(),
229 ShellUtil::CURRENT_USER, 163 ShellUtil::CURRENT_USER,
230 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 164 ShellUtil::SHORTCUT_CREATE_ALWAYS));
231 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 165 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
232 user_shortcut_path.value(), 166 user_shortcut_path.value(),
233 description, 167 description,
234 0)); 168 0));
235 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut( 169 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
236 dist_, 170 dist_,
237 ShellUtil::CURRENT_USER, 171 ShellUtil::CURRENT_USER,
238 ShellUtil::SHORTCUT_NO_OPTIONS)); 172 ShellUtil::SHORTCUT_NO_OPTIONS));
239 173
240 // Test simple creation of a system-level shortcut. 174 // Test simple creation of a system-level shortcut.
241 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut( 175 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
242 dist_, 176 dist_,
243 exe_path.value(), 177 exe_path.value(),
244 description, 178 description,
245 L"", 179 L"",
246 L"", 180 L"",
247 exe_path.value(), 181 exe_path.value(),
248 dist_->GetIconIndex(), 182 dist_->GetIconIndex(),
249 ShellUtil::SYSTEM_LEVEL, 183 ShellUtil::SYSTEM_LEVEL,
250 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 184 ShellUtil::SHORTCUT_CREATE_ALWAYS));
251 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 185 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
252 system_shortcut_path.value(), 186 system_shortcut_path.value(),
253 description, 187 description,
254 0)); 188 0));
255 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut( 189 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
256 dist_, 190 dist_,
257 ShellUtil::SYSTEM_LEVEL, 191 ShellUtil::SYSTEM_LEVEL,
258 ShellUtil::SHORTCUT_NO_OPTIONS)); 192 ShellUtil::SHORTCUT_NO_OPTIONS));
259 193
260 // Test creation of a user-level shortcut when a system-level shortcut 194 // Test creation of a user-level shortcut when a system-level shortcut
261 // is already present (should fail). 195 // is already present (should fail).
(...skipping 10 matching lines...) Expand all
272 EXPECT_FALSE(ShellUtil::CreateChromeDesktopShortcut( 206 EXPECT_FALSE(ShellUtil::CreateChromeDesktopShortcut(
273 dist_, 207 dist_,
274 exe_path.value(), 208 exe_path.value(),
275 description, 209 description,
276 L"", 210 L"",
277 L"", 211 L"",
278 exe_path.value(), 212 exe_path.value(),
279 dist_->GetIconIndex(), 213 dist_->GetIconIndex(),
280 ShellUtil::CURRENT_USER, 214 ShellUtil::CURRENT_USER,
281 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 215 ShellUtil::SHORTCUT_CREATE_ALWAYS));
282 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 216 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
283 system_shortcut_path.value(), 217 system_shortcut_path.value(),
284 description, 218 description,
285 0)); 219 0));
286 EXPECT_FALSE(file_util::PathExists(user_shortcut_path)); 220 EXPECT_FALSE(file_util::PathExists(user_shortcut_path));
287 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut( 221 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
288 dist_, 222 dist_,
289 ShellUtil::SYSTEM_LEVEL, 223 ShellUtil::SYSTEM_LEVEL,
290 ShellUtil::SHORTCUT_NO_OPTIONS)); 224 ShellUtil::SHORTCUT_NO_OPTIONS));
291 225
292 // Test creation of a system-level shortcut when a user-level shortcut 226 // Test creation of a system-level shortcut when a user-level shortcut
(...skipping 11 matching lines...) Expand all
304 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut( 238 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
305 dist_, 239 dist_,
306 exe_path.value(), 240 exe_path.value(),
307 description, 241 description,
308 L"", 242 L"",
309 L"", 243 L"",
310 exe_path.value(), 244 exe_path.value(),
311 dist_->GetIconIndex(), 245 dist_->GetIconIndex(),
312 ShellUtil::SYSTEM_LEVEL, 246 ShellUtil::SYSTEM_LEVEL,
313 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 247 ShellUtil::SHORTCUT_CREATE_ALWAYS));
314 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 248 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
315 user_shortcut_path.value(), 249 user_shortcut_path.value(),
316 description, 250 description,
317 0)); 251 0));
318 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 252 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
319 system_shortcut_path.value(), 253 system_shortcut_path.value(),
320 description, 254 description,
321 0)); 255 0));
322 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut( 256 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
323 dist_, 257 dist_,
324 ShellUtil::CURRENT_USER, 258 ShellUtil::CURRENT_USER,
325 ShellUtil::SHORTCUT_NO_OPTIONS)); 259 ShellUtil::SHORTCUT_NO_OPTIONS));
326 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut( 260 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
327 dist_, 261 dist_,
328 ShellUtil::SYSTEM_LEVEL, 262 ShellUtil::SYSTEM_LEVEL,
329 ShellUtil::SHORTCUT_NO_OPTIONS)); 263 ShellUtil::SHORTCUT_NO_OPTIONS));
330 264
331 // Test creation of two profile-specific shortcuts (these are always 265 // Test creation of two profile-specific shortcuts (these are always
332 // user-level). 266 // user-level).
333 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut( 267 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
334 dist_, 268 dist_,
335 exe_path.value(), 269 exe_path.value(),
336 description, 270 description,
337 default_profile_user_name, 271 default_profile_user_name,
338 L"--profile-directory=\"Default\"", 272 L"--profile-directory=\"Default\"",
339 exe_path.value(), 273 exe_path.value(),
340 dist_->GetIconIndex(), 274 dist_->GetIconIndex(),
341 ShellUtil::CURRENT_USER, 275 ShellUtil::CURRENT_USER,
342 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 276 ShellUtil::SHORTCUT_CREATE_ALWAYS));
343 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 277 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
344 default_profile_shortcut_path.value(), 278 default_profile_shortcut_path.value(),
345 description, 279 description,
346 0)); 280 0));
347 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut( 281 EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
348 dist_, 282 dist_,
349 exe_path.value(), 283 exe_path.value(),
350 description, 284 description,
351 second_profile_user_name, 285 second_profile_user_name,
352 L"--profile-directory=\"Profile 1\"", 286 L"--profile-directory=\"Profile 1\"",
353 exe_path.value(), 287 exe_path.value(),
354 dist_->GetIconIndex(), 288 dist_->GetIconIndex(),
355 ShellUtil::CURRENT_USER, 289 ShellUtil::CURRENT_USER,
356 ShellUtil::SHORTCUT_CREATE_ALWAYS)); 290 ShellUtil::SHORTCUT_CREATE_ALWAYS));
357 EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(), 291 EXPECT_TRUE(ShellUtil::VerifyChromeShortcut(exe_path.value(),
358 second_profile_shortcut_path.value(), 292 second_profile_shortcut_path.value(),
359 description, 293 description,
360 0)); 294 0));
361 std::vector<string16> profile_names; 295 std::vector<string16> profile_names;
362 profile_names.push_back(default_profile_shortcut_name); 296 profile_names.push_back(default_profile_shortcut_name);
363 profile_names.push_back(second_profile_shortcut_name); 297 profile_names.push_back(second_profile_shortcut_name);
364 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( 298 EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
365 profile_names)); 299 profile_names));
366 } 300 }
367 301
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 368
435 const string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ", 369 const string16 expected[] = { L"", L"MY", L"MZXQ", L"MZXW6", L"MZXW6YQ",
436 L"MZXW6YTB", L"MZXW6YTBOI"}; 370 L"MZXW6YTB", L"MZXW6YTBOI"};
437 371
438 // Run the tests, with one more letter in the input every pass. 372 // Run the tests, with one more letter in the input every pass.
439 for (int i = 0; i < arraysize(expected); ++i) { 373 for (int i = 0; i < arraysize(expected); ++i) {
440 ASSERT_EQ(expected[i], 374 ASSERT_EQ(expected[i],
441 ShellUtil::ByteArrayToBase32(test_array, i)); 375 ShellUtil::ByteArrayToBase32(test_array, i));
442 } 376 }
443 } 377 }
OLDNEW
« chrome/installer/util/shell_util.cc ('K') | « chrome/installer/util/shell_util.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698