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

Side by Side Diff: base/test/test_file_util_win.cc

Issue 10914109: Refactoring and tests for the highly undertested file_util::CreateOrUpdateShortcutLink() method. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: always use both LongPathName and ShortPathName when verifying paths Created 8 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « base/test/test_file_util.h ('k') | base/win/win_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/test/test_file_util.h" 5 #include "base/test/test_file_util.h"
6 6
7 #include <aclapi.h> 7 #include <aclapi.h>
8 #include <shlwapi.h> 8 #include <shlwapi.h>
9 #include <windows.h> 9 #include <windows.h>
10 #include <shlobj.h>
11 #include <propkey.h>
12 #include <propvarutil.h>
10 13
11 #include <vector> 14 #include <vector>
12 15
13 #include "base/file_path.h" 16 #include "base/file_path.h"
14 #include "base/file_util.h" 17 #include "base/file_util.h"
15 #include "base/logging.h" 18 #include "base/logging.h"
16 #include "base/string_split.h" 19 #include "base/string_split.h"
20 #include "base/win/scoped_comptr.h"
17 #include "base/win/scoped_handle.h" 21 #include "base/win/scoped_handle.h"
22 #include "base/win/windows_version.h"
18 #include "base/threading/platform_thread.h" 23 #include "base/threading/platform_thread.h"
19 24
25 // propsys.lib is required for PropvariantTo*().
26 #pragma comment(lib, "propsys.lib")
27
20 namespace file_util { 28 namespace file_util {
21 29
22 static const ptrdiff_t kOneMB = 1024 * 1024; 30 static const ptrdiff_t kOneMB = 1024 * 1024;
23 31
24 namespace { 32 namespace {
25 33
26 struct PermissionInfo { 34 struct PermissionInfo {
27 PSECURITY_DESCRIPTOR security_descriptor; 35 PSECURITY_DESCRIPTOR security_descriptor;
28 ACL dacl; 36 ACL dacl;
29 }; 37 };
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // This will prevent us from evicting from the cache, but these don't 269 // This will prevent us from evicting from the cache, but these don't
262 // matter anyway. 270 // matter anyway.
263 EvictFileFromSystemCache(cur_dest_path); 271 EvictFileFromSystemCache(cur_dest_path);
264 } 272 }
265 } while (FindNextFile(fh, &fd)); 273 } while (FindNextFile(fh, &fd));
266 274
267 FindClose(fh); 275 FindClose(fh);
268 return true; 276 return true;
269 } 277 }
270 278
279 VerifyShortcutStatus VerifyShortcut(const string16& shortcut_path,
280 const ShortcutProperties& properties) {
281 base::win::ScopedComPtr<IShellLink> i_shell_link;
282 base::win::ScopedComPtr<IPersistFile> i_persist_file;
283 // |temp_path| is used when verifying paths below: this method checks that the
284 // read path matches either the ShortPathName or the LongPathName (as
285 // returned by the Windows API) equivalent of the given path property.
286 wchar_t temp_path[MAX_PATH] = {0};
287
288 wchar_t read_target[MAX_PATH] = {0};
289 wchar_t read_working_dir[MAX_PATH] = {0};
290 wchar_t read_arguments[MAX_PATH] = {0};
291 wchar_t read_description[MAX_PATH] = {0};
292 wchar_t read_icon[MAX_PATH] = {0};
293 int read_icon_index = 0;
294
295 // Initialize the shell interfaces.
296 if (FAILED(i_shell_link.CreateInstance(CLSID_ShellLink, NULL,
297 CLSCTX_INPROC_SERVER)) ||
298 FAILED(i_persist_file.QueryFrom(i_shell_link))) {
299 return VERIFY_SHORTCUT_FAILURE_UNEXPECTED;
300 }
301
302 // Load the shortcut.
303 if (FAILED(i_persist_file->Load(shortcut_path.c_str(), 0)))
304 return VERIFY_SHORTCUT_FAILURE_FILE_NOT_FOUND;
305
306 if ((properties.options & ShortcutProperties::PROPERTIES_TARGET) &&
307 (FAILED(i_shell_link->GetPath(
308 read_target, MAX_PATH, NULL, SLGP_SHORTPATH)) ||
309 ((::GetShortPathName(
robertshield 2012/09/06 19:20:01 Could you extract the path comparison into a helpe
gab 2012/09/07 04:58:05 Done.
310 properties.target.c_str(), temp_path, MAX_PATH) == 0 ||
311 string16(read_target) != string16(temp_path)) &&
312 (::GetLongPathName(
313 properties.target.c_str(), temp_path, MAX_PATH) == 0 ||
314 string16(read_target) != string16(temp_path))))) {
315 return VERIFY_SHORTCUT_FAILURE_TARGET;
316 }
317
318 if ((properties.options & ShortcutProperties::PROPERTIES_WORKING_DIR) &&
319 (FAILED(i_shell_link->GetWorkingDirectory(read_working_dir, MAX_PATH)) ||
320 string16(read_working_dir) != properties.working_dir)) {
321 return VERIFY_SHORTCUT_FAILURE_WORKING_DIR;
322 }
323
324 if ((properties.options & ShortcutProperties::PROPERTIES_ARGUMENTS) &&
325 (FAILED(i_shell_link->GetArguments(read_arguments, MAX_PATH)) ||
326 string16(read_arguments) != properties.arguments)) {
327 return VERIFY_SHORTCUT_FAILURE_ARGUMENTS;
328 }
329
330 if ((properties.options & ShortcutProperties::PROPERTIES_DESCRIPTION) &&
331 (FAILED(i_shell_link->GetDescription(read_description, MAX_PATH)) ||
332 string16(read_description) != properties.description)) {
333 return VERIFY_SHORTCUT_FAILURE_DESCRIPTION;
334 }
335
336 if ((properties.options & ShortcutProperties::PROPERTIES_ICON) &&
337 (FAILED(i_shell_link->GetIconLocation(read_icon, MAX_PATH,
338 &read_icon_index)) ||
339 read_icon_index != properties.icon_index ||
340 ((::GetShortPathName(
341 properties.icon.c_str(), temp_path, MAX_PATH) == 0 ||
342 string16(read_icon) != string16(temp_path)) &&
343 (::GetLongPathName(properties.icon.c_str(), temp_path, MAX_PATH) == 0 ||
344 string16(read_icon) != string16(temp_path))))) {
345 return VERIFY_SHORTCUT_FAILURE_ICON;
346 }
347
348 if(base::win::GetVersion() >= base::win::VERSION_WIN7) {
349 base::win::ScopedComPtr<IPropertyStore> property_store;
350 // Note that, as mentioned on MSDN at http://goo.gl/M8h9g, if a property is
351 // not set, GetValue will return S_OK and the PROPVARIANT will be set to
352 // VT_EMPTY.
353 PROPVARIANT pv_app_id, pv_dual_mode;
354 if (FAILED(property_store.QueryFrom(i_shell_link)) ||
355 property_store->GetValue(PKEY_AppUserModel_ID, &pv_app_id) != S_OK ||
356 property_store->GetValue(PKEY_AppUserModel_IsDualMode,
357 &pv_dual_mode) != S_OK) {
358 return VERIFY_SHORTCUT_FAILURE_UNEXPECTED;
359 }
360
361 // Note, as mentioned on MSDN at http://goo.gl/hZ3sO, if |pv_app_id| is a
362 // VT_EMPTY it is successfully converted to the empty string.
363 wchar_t read_app_id[MAX_PATH] = {0};
364 PropVariantToString(pv_app_id, read_app_id, MAX_PATH);
365 if((properties.options & ShortcutProperties::PROPERTIES_APP_ID) &&
366 string16(read_app_id) != properties.app_id) {
367 return VERIFY_SHORTCUT_FAILURE_APP_ID;
368 }
369
370 // Note, as mentioned on MSDN at http://goo.gl/9mBHB, if |pv_dual_mode| is a
371 // VT_EMPTY it is successfully converted to false.
372 BOOL read_dual_mode;
373 PropVariantToBoolean(pv_dual_mode, &read_dual_mode);
374 if((properties.options & ShortcutProperties::PROPERTIES_DUAL_MODE) &&
375 static_cast<bool>(read_dual_mode) != properties.dual_mode) {
376 return VERIFY_SHORTCUT_FAILURE_DUAL_MODE;
377 }
378 }
379
380 return VERIFY_SHORTCUT_SUCCESS;
381 }
382
271 // Checks if the volume supports Alternate Data Streams. This is required for 383 // Checks if the volume supports Alternate Data Streams. This is required for
272 // the Zone Identifier implementation. 384 // the Zone Identifier implementation.
273 bool VolumeSupportsADS(const FilePath& path) { 385 bool VolumeSupportsADS(const FilePath& path) {
274 wchar_t drive[MAX_PATH] = {0}; 386 wchar_t drive[MAX_PATH] = {0};
275 wcscpy_s(drive, MAX_PATH, path.value().c_str()); 387 wcscpy_s(drive, MAX_PATH, path.value().c_str());
276 388
277 if (!PathStripToRootW(drive)) 389 if (!PathStripToRootW(drive))
278 return false; 390 return false;
279 391
280 DWORD fs_flags = 0; 392 DWORD fs_flags = 0;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 DCHECK(info_ != NULL); 446 DCHECK(info_ != NULL);
335 DCHECK_NE(0u, length_); 447 DCHECK_NE(0u, length_);
336 } 448 }
337 449
338 PermissionRestorer::~PermissionRestorer() { 450 PermissionRestorer::~PermissionRestorer() {
339 if (!RestorePermissionInfo(path_, info_, length_)) 451 if (!RestorePermissionInfo(path_, info_, length_))
340 NOTREACHED(); 452 NOTREACHED();
341 } 453 }
342 454
343 } // namespace file_util 455 } // namespace file_util
OLDNEW
« no previous file with comments | « base/test/test_file_util.h ('k') | base/win/win_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698