OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |