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

Side by Side Diff: base/file_util_win.cc

Issue 9167004: Match whole path components in DevicePathToDriveLetterPath(). Add tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rev comments. Created 8 years, 11 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/file_util_unittest.cc ('k') | no next file » | 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) 2011 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/file_util.h" 5 #include "base/file_util.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <propvarutil.h> 8 #include <propvarutil.h>
9 #include <psapi.h> 9 #include <psapi.h>
10 #include <shellapi.h> 10 #include <shellapi.h>
11 #include <shlobj.h> 11 #include <shlobj.h>
(...skipping 16 matching lines...) Expand all
28 #include "base/win/win_util.h" 28 #include "base/win/win_util.h"
29 #include "base/win/windows_version.h" 29 #include "base/win/windows_version.h"
30 30
31 namespace file_util { 31 namespace file_util {
32 32
33 namespace { 33 namespace {
34 34
35 const DWORD kFileShareAll = 35 const DWORD kFileShareAll =
36 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; 36 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
37 37
38 // Helper for NormalizeFilePath(), defined below.
39 bool DevicePathToDriveLetterPath(const FilePath& device_path,
40 FilePath* drive_letter_path) {
41 base::ThreadRestrictions::AssertIOAllowed();
42
43 // Get the mapping of drive letters to device paths.
44 const int kDriveMappingSize = 1024;
45 wchar_t drive_mapping[kDriveMappingSize] = {'\0'};
46 if (!::GetLogicalDriveStrings(kDriveMappingSize - 1, drive_mapping)) {
47 DLOG(ERROR) << "Failed to get drive mapping.";
48 return false;
49 }
50
51 // The drive mapping is a sequence of null terminated strings.
52 // The last string is empty.
53 wchar_t* drive_map_ptr = drive_mapping;
54 wchar_t device_name[MAX_PATH];
55 wchar_t drive[] = L" :";
56
57 // For each string in the drive mapping, get the junction that links
58 // to it. If that junction is a prefix of |device_path|, then we
59 // know that |drive| is the real path prefix.
60 while (*drive_map_ptr) {
61 drive[0] = drive_map_ptr[0]; // Copy the drive letter.
62
63 if (QueryDosDevice(drive, device_name, MAX_PATH) &&
64 StartsWith(device_path.value(), device_name, true)) {
65 *drive_letter_path = FilePath(drive +
66 device_path.value().substr(wcslen(device_name)));
67 return true;
68 }
69 // Move to the next drive letter string, which starts one
70 // increment after the '\0' that terminates the current string.
71 while (*drive_map_ptr++);
72 }
73
74 // No drive matched. The path does not start with a device junction
75 // that is mounted as a drive letter. This means there is no drive
76 // letter path to the volume that holds |device_path|, so fail.
77 return false;
78 }
79
80 } // namespace 38 } // namespace
81 39
82 bool AbsolutePath(FilePath* path) { 40 bool AbsolutePath(FilePath* path) {
83 base::ThreadRestrictions::AssertIOAllowed(); 41 base::ThreadRestrictions::AssertIOAllowed();
84 wchar_t file_path_buf[MAX_PATH]; 42 wchar_t file_path_buf[MAX_PATH];
85 if (!_wfullpath(file_path_buf, path->value().c_str(), MAX_PATH)) 43 if (!_wfullpath(file_path_buf, path->value().c_str(), MAX_PATH))
86 return false; 44 return false;
87 *path = FilePath(file_path_buf); 45 *path = FilePath(file_path_buf);
88 return true; 46 return true;
89 } 47 }
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 FilePath mapped_file; 998 FilePath mapped_file;
1041 if (!NormalizeToNativeFilePath(path, &mapped_file)) 999 if (!NormalizeToNativeFilePath(path, &mapped_file))
1042 return false; 1000 return false;
1043 // NormalizeToNativeFilePath() will return a path that starts with 1001 // NormalizeToNativeFilePath() will return a path that starts with
1044 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath() 1002 // "\Device\Harddisk...". Helper DevicePathToDriveLetterPath()
1045 // will find a drive letter which maps to the path's device, so 1003 // will find a drive letter which maps to the path's device, so
1046 // that we return a path starting with a drive letter. 1004 // that we return a path starting with a drive letter.
1047 return DevicePathToDriveLetterPath(mapped_file, real_path); 1005 return DevicePathToDriveLetterPath(mapped_file, real_path);
1048 } 1006 }
1049 1007
1008 bool DevicePathToDriveLetterPath(const FilePath& nt_device_path,
1009 FilePath* out_drive_letter_path) {
1010 base::ThreadRestrictions::AssertIOAllowed();
1011
1012 // Get the mapping of drive letters to device paths.
1013 const int kDriveMappingSize = 1024;
1014 wchar_t drive_mapping[kDriveMappingSize] = {'\0'};
1015 if (!::GetLogicalDriveStrings(kDriveMappingSize - 1, drive_mapping)) {
1016 DLOG(ERROR) << "Failed to get drive mapping.";
1017 return false;
1018 }
1019
1020 // The drive mapping is a sequence of null terminated strings.
1021 // The last string is empty.
1022 wchar_t* drive_map_ptr = drive_mapping;
1023 wchar_t device_path_as_string[MAX_PATH];
1024 wchar_t drive[] = L" :";
1025
1026 // For each string in the drive mapping, get the junction that links
1027 // to it. If that junction is a prefix of |device_path|, then we
1028 // know that |drive| is the real path prefix.
1029 while (*drive_map_ptr) {
1030 drive[0] = drive_map_ptr[0]; // Copy the drive letter.
1031
1032 if (QueryDosDevice(drive, device_path_as_string, MAX_PATH)) {
1033 FilePath device_path(device_path_as_string);
1034 if (device_path == nt_device_path ||
1035 device_path.IsParent(nt_device_path)) {
1036 *out_drive_letter_path = FilePath(drive +
1037 nt_device_path.value().substr(wcslen(device_path_as_string)));
1038 return true;
1039 }
1040 }
1041 // Move to the next drive letter string, which starts one
1042 // increment after the '\0' that terminates the current string.
1043 while (*drive_map_ptr++);
1044 }
1045
1046 // No drive matched. The path does not start with a device junction
1047 // that is mounted as a drive letter. This means there is no drive
1048 // letter path to the volume that holds |device_path|, so fail.
1049 return false;
1050 }
1051
1050 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) { 1052 bool NormalizeToNativeFilePath(const FilePath& path, FilePath* nt_path) {
1051 base::ThreadRestrictions::AssertIOAllowed(); 1053 base::ThreadRestrictions::AssertIOAllowed();
1052 // In Vista, GetFinalPathNameByHandle() would give us the real path 1054 // In Vista, GetFinalPathNameByHandle() would give us the real path
1053 // from a file handle. If we ever deprecate XP, consider changing the 1055 // from a file handle. If we ever deprecate XP, consider changing the
1054 // code below to a call to GetFinalPathNameByHandle(). The method this 1056 // code below to a call to GetFinalPathNameByHandle(). The method this
1055 // function uses is explained in the following msdn article: 1057 // function uses is explained in the following msdn article:
1056 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx 1058 // http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
1057 base::win::ScopedHandle file_handle( 1059 base::win::ScopedHandle file_handle(
1058 ::CreateFile(path.value().c_str(), 1060 ::CreateFile(path.value().c_str(),
1059 GENERIC_READ, 1061 GENERIC_READ,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 uint8 unused = *(touch + offset); 1164 uint8 unused = *(touch + offset);
1163 offset += step_size; 1165 offset += step_size;
1164 } 1166 }
1165 FreeLibrary(dll_module); 1167 FreeLibrary(dll_module);
1166 } 1168 }
1167 1169
1168 return true; 1170 return true;
1169 } 1171 }
1170 1172
1171 } // namespace file_util 1173 } // namespace file_util
OLDNEW
« no previous file with comments | « base/file_util_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698