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

Side by Side Diff: sandbox/win/src/win_utils.cc

Issue 109843003: Replace wstring with string16 in sandbox (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 | « sandbox/win/src/win_utils.h ('k') | sandbox/win/src/win_utils_unittest.cc » ('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) 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 "sandbox/win/src/win_utils.h" 5 #include "sandbox/win/src/win_utils.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "sandbox/win/src/internal_types.h" 10 #include "sandbox/win/src/internal_types.h"
(...skipping 15 matching lines...) Expand all
26 { L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE}, 26 { L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE},
27 { L"HKEY_USERS", HKEY_USERS}, 27 { L"HKEY_USERS", HKEY_USERS},
28 { L"HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA}, 28 { L"HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA},
29 { L"HKEY_PERFORMANCE_TEXT", HKEY_PERFORMANCE_TEXT}, 29 { L"HKEY_PERFORMANCE_TEXT", HKEY_PERFORMANCE_TEXT},
30 { L"HKEY_PERFORMANCE_NLSTEXT", HKEY_PERFORMANCE_NLSTEXT}, 30 { L"HKEY_PERFORMANCE_NLSTEXT", HKEY_PERFORMANCE_NLSTEXT},
31 { L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG}, 31 { L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG},
32 { L"HKEY_DYN_DATA", HKEY_DYN_DATA} 32 { L"HKEY_DYN_DATA", HKEY_DYN_DATA}
33 }; 33 };
34 34
35 // Returns true if the provided path points to a pipe. 35 // Returns true if the provided path points to a pipe.
36 bool IsPipe(const std::wstring& path) { 36 bool IsPipe(const base::string16& path) {
37 size_t start = 0; 37 size_t start = 0;
38 if (0 == path.compare(0, sandbox::kNTPrefixLen, sandbox::kNTPrefix)) 38 if (0 == path.compare(0, sandbox::kNTPrefixLen, sandbox::kNTPrefix))
39 start = sandbox::kNTPrefixLen; 39 start = sandbox::kNTPrefixLen;
40 40
41 const wchar_t kPipe[] = L"pipe\\"; 41 const wchar_t kPipe[] = L"pipe\\";
42 return (0 == path.compare(start, arraysize(kPipe) - 1, kPipe)); 42 return (0 == path.compare(start, arraysize(kPipe) - 1, kPipe));
43 } 43 }
44 44
45 } // namespace 45 } // namespace
46 46
47 namespace sandbox { 47 namespace sandbox {
48 48
49 HKEY GetReservedKeyFromName(const std::wstring& name) { 49 HKEY GetReservedKeyFromName(const base::string16& name) {
50 for (size_t i = 0; i < arraysize(kKnownKey); ++i) { 50 for (size_t i = 0; i < arraysize(kKnownKey); ++i) {
51 if (name == kKnownKey[i].name) 51 if (name == kKnownKey[i].name)
52 return kKnownKey[i].key; 52 return kKnownKey[i].key;
53 } 53 }
54 54
55 return NULL; 55 return NULL;
56 } 56 }
57 57
58 bool ResolveRegistryName(std::wstring name, std::wstring* resolved_name) { 58 bool ResolveRegistryName(base::string16 name, base::string16* resolved_name) {
59 for (size_t i = 0; i < arraysize(kKnownKey); ++i) { 59 for (size_t i = 0; i < arraysize(kKnownKey); ++i) {
60 if (name.find(kKnownKey[i].name) == 0) { 60 if (name.find(kKnownKey[i].name) == 0) {
61 HKEY key; 61 HKEY key;
62 DWORD disposition; 62 DWORD disposition;
63 if (ERROR_SUCCESS != ::RegCreateKeyEx(kKnownKey[i].key, L"", 0, NULL, 0, 63 if (ERROR_SUCCESS != ::RegCreateKeyEx(kKnownKey[i].key, L"", 0, NULL, 0,
64 MAXIMUM_ALLOWED, NULL, &key, 64 MAXIMUM_ALLOWED, NULL, &key,
65 &disposition)) 65 &disposition))
66 return false; 66 return false;
67 67
68 bool result = GetPathFromHandle(key, resolved_name); 68 bool result = GetPathFromHandle(key, resolved_name);
69 ::RegCloseKey(key); 69 ::RegCloseKey(key);
70 70
71 if (!result) 71 if (!result)
72 return false; 72 return false;
73 73
74 *resolved_name += name.substr(wcslen(kKnownKey[i].name)); 74 *resolved_name += name.substr(wcslen(kKnownKey[i].name));
75 return true; 75 return true;
76 } 76 }
77 } 77 }
78 78
79 return false; 79 return false;
80 } 80 }
81 81
82 DWORD IsReparsePoint(const std::wstring& full_path, bool* result) { 82 DWORD IsReparsePoint(const base::string16& full_path, bool* result) {
83 std::wstring path = full_path; 83 base::string16 path = full_path;
84 84
85 // Remove the nt prefix. 85 // Remove the nt prefix.
86 if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) 86 if (0 == path.compare(0, kNTPrefixLen, kNTPrefix))
87 path = path.substr(kNTPrefixLen); 87 path = path.substr(kNTPrefixLen);
88 88
89 // Check if it's a pipe. We can't query the attributes of a pipe. 89 // Check if it's a pipe. We can't query the attributes of a pipe.
90 if (IsPipe(path)) { 90 if (IsPipe(path)) {
91 *result = FALSE; 91 *result = FALSE;
92 return ERROR_SUCCESS; 92 return ERROR_SUCCESS;
93 } 93 }
94 94
95 std::wstring::size_type last_pos = std::wstring::npos; 95 base::string16::size_type last_pos = base::string16::npos;
96 96
97 do { 97 do {
98 path = path.substr(0, last_pos); 98 path = path.substr(0, last_pos);
99 99
100 DWORD attributes = ::GetFileAttributes(path.c_str()); 100 DWORD attributes = ::GetFileAttributes(path.c_str());
101 if (INVALID_FILE_ATTRIBUTES == attributes) { 101 if (INVALID_FILE_ATTRIBUTES == attributes) {
102 DWORD error = ::GetLastError(); 102 DWORD error = ::GetLastError();
103 if (error != ERROR_FILE_NOT_FOUND && 103 if (error != ERROR_FILE_NOT_FOUND &&
104 error != ERROR_PATH_NOT_FOUND && 104 error != ERROR_PATH_NOT_FOUND &&
105 error != ERROR_INVALID_NAME) { 105 error != ERROR_INVALID_NAME) {
106 // Unexpected error. 106 // Unexpected error.
107 NOTREACHED_NT(); 107 NOTREACHED_NT();
108 return error; 108 return error;
109 } 109 }
110 } else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) { 110 } else if (FILE_ATTRIBUTE_REPARSE_POINT & attributes) {
111 // This is a reparse point. 111 // This is a reparse point.
112 *result = true; 112 *result = true;
113 return ERROR_SUCCESS; 113 return ERROR_SUCCESS;
114 } 114 }
115 115
116 last_pos = path.rfind(L'\\'); 116 last_pos = path.rfind(L'\\');
117 } while (last_pos != std::wstring::npos); 117 } while (last_pos != base::string16::npos);
118 118
119 *result = false; 119 *result = false;
120 return ERROR_SUCCESS; 120 return ERROR_SUCCESS;
121 } 121 }
122 122
123 // We get a |full_path| of the form \??\c:\some\foo\bar, and the name that 123 // We get a |full_path| of the form \??\c:\some\foo\bar, and the name that
124 // we'll get from |handle| will be \device\harddiskvolume1\some\foo\bar. 124 // we'll get from |handle| will be \device\harddiskvolume1\some\foo\bar.
125 bool SameObject(HANDLE handle, const wchar_t* full_path) { 125 bool SameObject(HANDLE handle, const wchar_t* full_path) {
126 std::wstring path(full_path); 126 base::string16 path(full_path);
127 DCHECK_NT(!path.empty()); 127 DCHECK_NT(!path.empty());
128 128
129 // Check if it's a pipe. 129 // Check if it's a pipe.
130 if (IsPipe(path)) 130 if (IsPipe(path))
131 return true; 131 return true;
132 132
133 std::wstring actual_path; 133 base::string16 actual_path;
134 if (!GetPathFromHandle(handle, &actual_path)) 134 if (!GetPathFromHandle(handle, &actual_path))
135 return false; 135 return false;
136 136
137 // This may end with a backslash. 137 // This may end with a backslash.
138 const wchar_t kBackslash = '\\'; 138 const wchar_t kBackslash = '\\';
139 if (path[path.length() - 1] == kBackslash) 139 if (path[path.length() - 1] == kBackslash)
140 path = path.substr(0, path.length() - 1); 140 path = path.substr(0, path.length() - 1);
141 141
142 // Perfect match (case-insesitive check). 142 // Perfect match (case-insesitive check).
143 if (0 == _wcsicmp(actual_path.c_str(), path.c_str())) 143 if (0 == _wcsicmp(actual_path.c_str(), path.c_str()))
144 return true; 144 return true;
145 145
146 // Look for the drive letter. 146 // Look for the drive letter.
147 size_t colon_pos = path.find(L':'); 147 size_t colon_pos = path.find(L':');
148 if (colon_pos == 0 || colon_pos == std::wstring::npos) 148 if (colon_pos == 0 || colon_pos == base::string16::npos)
149 return false; 149 return false;
150 150
151 // Only one character for the drive. 151 // Only one character for the drive.
152 if (colon_pos > 1 && path[colon_pos - 2] != kBackslash) 152 if (colon_pos > 1 && path[colon_pos - 2] != kBackslash)
153 return false; 153 return false;
154 154
155 // We only need 3 chars, but let's alloc a buffer for four. 155 // We only need 3 chars, but let's alloc a buffer for four.
156 wchar_t drive[4] = {0}; 156 wchar_t drive[4] = {0};
157 wchar_t vol_name[MAX_PATH]; 157 wchar_t vol_name[MAX_PATH];
158 memcpy(drive, &path[colon_pos - 1], 2 * sizeof(*drive)); 158 memcpy(drive, &path[colon_pos - 1], 2 * sizeof(*drive));
(...skipping 14 matching lines...) Expand all
173 if (0 != _wcsnicmp(actual_path.c_str(), vol_name, vol_length)) 173 if (0 != _wcsnicmp(actual_path.c_str(), vol_name, vol_length))
174 return false; 174 return false;
175 175
176 // Check the path after the drive letter. 176 // Check the path after the drive letter.
177 if (0 != _wcsicmp(&actual_path[vol_length], &path[colon_pos + 1])) 177 if (0 != _wcsicmp(&actual_path[vol_length], &path[colon_pos + 1]))
178 return false; 178 return false;
179 179
180 return true; 180 return true;
181 } 181 }
182 182
183 bool ConvertToLongPath(const std::wstring& short_path, 183 bool ConvertToLongPath(const base::string16& short_path,
184 std::wstring* long_path) { 184 base::string16* long_path) {
185 // Check if the path is a NT path. 185 // Check if the path is a NT path.
186 bool is_nt_path = false; 186 bool is_nt_path = false;
187 std::wstring path = short_path; 187 base::string16 path = short_path;
188 if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) { 188 if (0 == path.compare(0, kNTPrefixLen, kNTPrefix)) {
189 path = path.substr(kNTPrefixLen); 189 path = path.substr(kNTPrefixLen);
190 is_nt_path = true; 190 is_nt_path = true;
191 } 191 }
192 192
193 DWORD size = MAX_PATH; 193 DWORD size = MAX_PATH;
194 scoped_ptr<wchar_t[]> long_path_buf(new wchar_t[size]); 194 scoped_ptr<wchar_t[]> long_path_buf(new wchar_t[size]);
195 195
196 DWORD return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), 196 DWORD return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(),
197 size); 197 size);
198 while (return_value >= size) { 198 while (return_value >= size) {
199 size *= 2; 199 size *= 2;
200 long_path_buf.reset(new wchar_t[size]); 200 long_path_buf.reset(new wchar_t[size]);
201 return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), size); 201 return_value = ::GetLongPathName(path.c_str(), long_path_buf.get(), size);
202 } 202 }
203 203
204 DWORD last_error = ::GetLastError(); 204 DWORD last_error = ::GetLastError();
205 if (0 == return_value && (ERROR_FILE_NOT_FOUND == last_error || 205 if (0 == return_value && (ERROR_FILE_NOT_FOUND == last_error ||
206 ERROR_PATH_NOT_FOUND == last_error || 206 ERROR_PATH_NOT_FOUND == last_error ||
207 ERROR_INVALID_NAME == last_error)) { 207 ERROR_INVALID_NAME == last_error)) {
208 // The file does not exist, but maybe a sub path needs to be expanded. 208 // The file does not exist, but maybe a sub path needs to be expanded.
209 std::wstring::size_type last_slash = path.rfind(L'\\'); 209 base::string16::size_type last_slash = path.rfind(L'\\');
210 if (std::wstring::npos == last_slash) 210 if (base::string16::npos == last_slash)
211 return false; 211 return false;
212 212
213 std::wstring begin = path.substr(0, last_slash); 213 base::string16 begin = path.substr(0, last_slash);
214 std::wstring end = path.substr(last_slash); 214 base::string16 end = path.substr(last_slash);
215 if (!ConvertToLongPath(begin, &begin)) 215 if (!ConvertToLongPath(begin, &begin))
216 return false; 216 return false;
217 217
218 // Ok, it worked. Let's reset the return value. 218 // Ok, it worked. Let's reset the return value.
219 path = begin + end; 219 path = begin + end;
220 return_value = 1; 220 return_value = 1;
221 } else if (0 != return_value) { 221 } else if (0 != return_value) {
222 path = long_path_buf.get(); 222 path = long_path_buf.get();
223 } 223 }
224 224
225 if (return_value != 0) { 225 if (return_value != 0) {
226 if (is_nt_path) { 226 if (is_nt_path) {
227 *long_path = kNTPrefix; 227 *long_path = kNTPrefix;
228 *long_path += path; 228 *long_path += path;
229 } else { 229 } else {
230 *long_path = path; 230 *long_path = path;
231 } 231 }
232 232
233 return true; 233 return true;
234 } 234 }
235 235
236 return false; 236 return false;
237 } 237 }
238 238
239 bool GetPathFromHandle(HANDLE handle, std::wstring* path) { 239 bool GetPathFromHandle(HANDLE handle, base::string16* path) {
240 NtQueryObjectFunction NtQueryObject = NULL; 240 NtQueryObjectFunction NtQueryObject = NULL;
241 ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject); 241 ResolveNTFunctionPtr("NtQueryObject", &NtQueryObject);
242 242
243 OBJECT_NAME_INFORMATION initial_buffer; 243 OBJECT_NAME_INFORMATION initial_buffer;
244 OBJECT_NAME_INFORMATION* name = &initial_buffer; 244 OBJECT_NAME_INFORMATION* name = &initial_buffer;
245 ULONG size = sizeof(initial_buffer); 245 ULONG size = sizeof(initial_buffer);
246 // Query the name information a first time to get the size of the name. 246 // Query the name information a first time to get the size of the name.
247 NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size, 247 NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size,
248 &size); 248 &size);
249 249
250 scoped_ptr<OBJECT_NAME_INFORMATION> name_ptr; 250 scoped_ptr<OBJECT_NAME_INFORMATION> name_ptr;
251 if (size) { 251 if (size) {
252 name = reinterpret_cast<OBJECT_NAME_INFORMATION*>(new BYTE[size]); 252 name = reinterpret_cast<OBJECT_NAME_INFORMATION*>(new BYTE[size]);
253 name_ptr.reset(name); 253 name_ptr.reset(name);
254 254
255 // Query the name information a second time to get the name of the 255 // Query the name information a second time to get the name of the
256 // object referenced by the handle. 256 // object referenced by the handle.
257 status = NtQueryObject(handle, ObjectNameInformation, name, size, &size); 257 status = NtQueryObject(handle, ObjectNameInformation, name, size, &size);
258 } 258 }
259 259
260 if (STATUS_SUCCESS != status) 260 if (STATUS_SUCCESS != status)
261 return false; 261 return false;
262 262
263 path->assign(name->ObjectName.Buffer, name->ObjectName.Length / 263 path->assign(name->ObjectName.Buffer, name->ObjectName.Length /
264 sizeof(name->ObjectName.Buffer[0])); 264 sizeof(name->ObjectName.Buffer[0]));
265 return true; 265 return true;
266 } 266 }
267 267
268 bool GetNtPathFromWin32Path(const std::wstring& path, std::wstring* nt_path) { 268 bool GetNtPathFromWin32Path(const base::string16& path,
269 base::string16* nt_path) {
269 HANDLE file = ::CreateFileW(path.c_str(), 0, 270 HANDLE file = ::CreateFileW(path.c_str(), 0,
270 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, 271 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
271 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 272 OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
272 if (file == INVALID_HANDLE_VALUE) 273 if (file == INVALID_HANDLE_VALUE)
273 return false; 274 return false;
274 bool rv = GetPathFromHandle(file, nt_path); 275 bool rv = GetPathFromHandle(file, nt_path);
275 ::CloseHandle(file); 276 ::CloseHandle(file);
276 return rv; 277 return rv;
277 } 278 }
278 279
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 315
315 for (int tries = 1; !(*function_ptr) && tries < max_tries; ++tries) { 316 for (int tries = 1; !(*function_ptr) && tries < max_tries; ++tries) {
316 if (tries >= sleep_threshold) 317 if (tries >= sleep_threshold)
317 ::Sleep(1); 318 ::Sleep(1);
318 ntdll = ::GetModuleHandle(sandbox::kNtdllName); 319 ntdll = ::GetModuleHandle(sandbox::kNtdllName);
319 *function_ptr = ::GetProcAddress(ntdll, name); 320 *function_ptr = ::GetProcAddress(ntdll, name);
320 } 321 }
321 322
322 CHECK_NT(*function_ptr); 323 CHECK_NT(*function_ptr);
323 } 324 }
OLDNEW
« no previous file with comments | « sandbox/win/src/win_utils.h ('k') | sandbox/win/src/win_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698