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

Side by Side Diff: runtime/bin/directory_win.cc

Issue 11550014: Use unicode versions of all directory system calls on Windows. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 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 | « no previous file | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/directory.h" 5 #include "bin/directory.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 9
10 #include "bin/log.h" 10 #include "bin/log.h"
11 11
12 // Forward declaration. 12 // Forward declaration.
13 static bool ListRecursively(const char* dir_name, 13 static bool ListRecursively(const wchar_t* dir_name,
14 bool recursive, 14 bool recursive,
15 DirectoryListing* listing); 15 DirectoryListing* listing);
16 static bool DeleteRecursively(const char* dir_name); 16 static bool DeleteRecursively(const wchar_t* dir_name);
17 17
18 18
19 static bool HandleDir(char* dir_name, 19 static bool HandleDir(wchar_t* dir_name,
20 char* path, 20 wchar_t* path,
21 int path_length, 21 int path_length,
22 bool recursive, 22 bool recursive,
23 DirectoryListing* listing) { 23 DirectoryListing* listing) {
24 if (strcmp(dir_name, ".") != 0 && 24 if (wcscmp(dir_name, L".") != 0 &&
25 strcmp(dir_name, "..") != 0) { 25 wcscmp(dir_name, L"..") != 0) {
26 size_t written = snprintf(path + path_length, 26 size_t written = _snwprintf(path + path_length,
27 MAX_PATH - path_length, 27 MAX_PATH - path_length,
28 "%s", 28 L"%s",
29 dir_name); 29 dir_name);
30 if (written != strlen(dir_name)) { 30 if (written != wcslen(dir_name)) {
31 return false; 31 return false;
32 } 32 }
33 char* utf8_path = StringUtils::ConsoleStringToUtf8(path); 33 char* utf8_path = StringUtils::WideToUtf8(path);
34 bool ok = listing->HandleDirectory(utf8_path); 34 bool ok = listing->HandleDirectory(utf8_path);
35 free(utf8_path); 35 free(utf8_path);
36 if (!ok) return ok; 36 if (!ok) return ok;
37 if (recursive) { 37 if (recursive) {
38 return ListRecursively(path, recursive, listing); 38 return ListRecursively(path, recursive, listing);
39 } 39 }
40 } 40 }
41 return true; 41 return true;
42 } 42 }
43 43
44 44
45 static bool HandleFile(char* file_name, 45 static bool HandleFile(wchar_t* file_name,
46 char* path, 46 wchar_t* path,
47 int path_length, 47 int path_length,
48 DirectoryListing* listing) { 48 DirectoryListing* listing) {
49 size_t written = snprintf(path + path_length, 49 size_t written = _snwprintf(path + path_length,
50 MAX_PATH - path_length, 50 MAX_PATH - path_length,
51 "%s", 51 L"%s",
52 file_name); 52 file_name);
53 if (written != strlen(file_name)) { 53 if (written != wcslen(file_name)) {
54 return false; 54 return false;
55 }; 55 };
56 char* utf8_path = StringUtils::ConsoleStringToUtf8(path); 56 char* utf8_path = StringUtils::WideToUtf8(path);
57 bool ok = listing->HandleFile(utf8_path); 57 bool ok = listing->HandleFile(utf8_path);
58 free(utf8_path); 58 free(utf8_path);
59 return ok; 59 return ok;
60 } 60 }
61 61
62 62
63 static bool HandleEntry(LPWIN32_FIND_DATA find_file_data, 63 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
64 char* path, 64 wchar_t* path,
65 int path_length, 65 int path_length,
66 bool recursive, 66 bool recursive,
67 DirectoryListing* listing) { 67 DirectoryListing* listing) {
68 DWORD attributes = find_file_data->dwFileAttributes; 68 DWORD attributes = find_file_data->dwFileAttributes;
69 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 69 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
70 return HandleDir(find_file_data->cFileName, 70 return HandleDir(find_file_data->cFileName,
71 path, 71 path,
72 path_length, 72 path_length,
73 recursive, 73 recursive,
74 listing); 74 listing);
75 } else { 75 } else {
76 return HandleFile(find_file_data->cFileName, path, path_length, listing); 76 return HandleFile(find_file_data->cFileName, path, path_length, listing);
77 } 77 }
78 } 78 }
79 79
80 80
81 // ComputeFullSearchPath must be called with a path array of size at 81 // ComputeFullSearchPath must be called with a path array of size at
82 // least MAX_PATH. 82 // least MAX_PATH.
83 static bool ComputeFullSearchPath(const char* dir_name, 83 static bool ComputeFullSearchPath(const wchar_t* dir_name,
84 char* path, 84 wchar_t* path,
85 int* path_length) { 85 int* path_length) {
86 // GetFullPathName only works in a multi-threaded environment if 86 // GetFullPathName only works in a multi-threaded environment if
87 // SetCurrentDirectory is not used. We currently have no plan for 87 // SetCurrentDirectory is not used. We currently have no plan for
88 // exposing SetCurrentDirectory. 88 // exposing SetCurrentDirectory.
89 size_t written = GetFullPathName(dir_name, MAX_PATH, path, NULL); 89 size_t written = GetFullPathNameW(dir_name, MAX_PATH, path, NULL);
90 // GetFullPathName only accepts input strings of size less than 90 // GetFullPathName only accepts input strings of size less than
91 // MAX_PATH and returns 0 to indicate failure for paths longer than 91 // MAX_PATH and returns 0 to indicate failure for paths longer than
92 // that. Therefore the path buffer is always big enough. 92 // that. Therefore the path buffer is always big enough.
93 if (written == 0) { 93 if (written == 0 || written > MAX_PATH) {
94 return false; 94 return false;
95 } 95 }
96 *path_length = written; 96 *path_length = written;
97 written = snprintf(path + *path_length, 97 written = _snwprintf(path + *path_length,
98 MAX_PATH - *path_length, 98 MAX_PATH - *path_length,
99 "%s", 99 L"%s",
100 "\\*"); 100 L"\\*");
101 if (written != 2) { 101 if (written != 2) {
102 return false; 102 return false;
103 } 103 }
104 *path_length += written; 104 *path_length += written;
105 return true; 105 return true;
106 } 106 }
107 107
108 static void PostError(DirectoryListing* listing, 108 static void PostError(DirectoryListing* listing,
109 const char* dir_name) { 109 const wchar_t* dir_name) {
110 const char* utf8_path = StringUtils::ConsoleStringToUtf8(dir_name); 110 const char* utf8_path = StringUtils::WideToUtf8(dir_name);
111 listing->HandleError(utf8_path); 111 listing->HandleError(utf8_path);
112 free(const_cast<char*>(utf8_path)); 112 free(const_cast<char*>(utf8_path));
113 } 113 }
114 114
115 115
116 static bool ListRecursively(const char* dir_name, 116 static bool ListRecursively(const wchar_t* dir_name,
117 bool recursive, 117 bool recursive,
118 DirectoryListing* listing) { 118 DirectoryListing* listing) {
119 // Compute full path for the directory currently being listed. The 119 // Compute full path for the directory currently being listed. The
120 // path buffer will be used to construct the current path in the 120 // path buffer will be used to construct the current path in the
121 // recursive traversal. path_length does not always equal 121 // recursive traversal. path_length does not always equal
122 // strlen(path) but indicates the current prefix of path that is the 122 // strlen(path) but indicates the current prefix of path that is the
123 // path of the current directory in the traversal. 123 // path of the current directory in the traversal.
124 char* path = static_cast<char*>(malloc(MAX_PATH)); 124 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t)));
125 int path_length = 0; 125 int path_length = 0;
126 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); 126 bool valid = ComputeFullSearchPath(dir_name, path, &path_length);
127 if (!valid) { 127 if (!valid) {
128 PostError(listing, dir_name); 128 PostError(listing, dir_name);
129 free(path); 129 free(path);
130 return false; 130 return false;
131 } 131 }
132 132
133 WIN32_FIND_DATA find_file_data; 133 WIN32_FIND_DATAW find_file_data;
134 HANDLE find_handle = FindFirstFile(path, &find_file_data); 134 HANDLE find_handle = FindFirstFileW(path, &find_file_data);
135 135
136 // Adjust the path by removing the '*' used for the search. 136 // Adjust the path by removing the '*' used for the search.
137 path_length -= 1; 137 path_length -= 1;
138 path[path_length] = '\0'; 138 path[path_length] = '\0';
139 139
140 if (find_handle == INVALID_HANDLE_VALUE) { 140 if (find_handle == INVALID_HANDLE_VALUE) {
141 PostError(listing, path); 141 PostError(listing, path);
142 free(path); 142 free(path);
143 return false; 143 return false;
144 } 144 }
145 145
146 bool success = HandleEntry(&find_file_data, 146 bool success = HandleEntry(&find_file_data,
147 path, 147 path,
148 path_length, 148 path_length,
149 recursive, 149 recursive,
150 listing); 150 listing);
151 151
152 while ((FindNextFile(find_handle, &find_file_data) != 0)) { 152 while ((FindNextFileW(find_handle, &find_file_data) != 0)) {
153 success = HandleEntry(&find_file_data, 153 success = HandleEntry(&find_file_data,
154 path, 154 path,
155 path_length, 155 path_length,
156 recursive, 156 recursive,
157 listing) && success; 157 listing) && success;
158 } 158 }
159 159
160 if (GetLastError() != ERROR_NO_MORE_FILES) { 160 if (GetLastError() != ERROR_NO_MORE_FILES) {
161 success = false; 161 success = false;
162 PostError(listing, dir_name); 162 PostError(listing, dir_name);
163 } 163 }
164 164
165 if (FindClose(find_handle) == 0) { 165 if (FindClose(find_handle) == 0) {
166 success = false; 166 success = false;
167 PostError(listing, dir_name); 167 PostError(listing, dir_name);
168 } 168 }
169 free(path); 169 free(path);
170 170
171 return success; 171 return success;
172 } 172 }
173 173
174 174
175 static bool DeleteFile(char* file_name, 175 static bool DeleteFile(wchar_t* file_name,
176 char* path, 176 wchar_t* path,
177 int path_length) { 177 int path_length) {
178 size_t written = snprintf(path + path_length, 178 size_t written = _snwprintf(path + path_length,
179 MAX_PATH - path_length, 179 MAX_PATH - path_length,
180 "%s", 180 L"%s",
181 file_name); 181 file_name);
182 if (written != strlen(file_name)) { 182 if (written != wcslen(file_name)) {
183 return false; 183 return false;
184 } 184 }
185 185
186 if (DeleteFile(path) != 0) { 186 if (DeleteFileW(path) != 0) {
187 return true; 187 return true;
188 } 188 }
189 189
190 // If we failed because the file is read-only, make it writeable and try 190 // If we failed because the file is read-only, make it writeable and try
191 // again. This mirrors Linux/Mac where a directory containing read-only files 191 // again. This mirrors Linux/Mac where a directory containing read-only files
192 // can still be recursively deleted. 192 // can still be recursively deleted.
193 if (GetLastError() == ERROR_ACCESS_DENIED) { 193 if (GetLastError() == ERROR_ACCESS_DENIED) {
194 DWORD attributes = GetFileAttributes(path); 194 DWORD attributes = GetFileAttributesW(path);
195 if (attributes == INVALID_FILE_ATTRIBUTES) { 195 if (attributes == INVALID_FILE_ATTRIBUTES) {
196 return false; 196 return false;
197 } 197 }
198 198
199 if ((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { 199 if ((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) {
200 attributes &= ~FILE_ATTRIBUTE_READONLY; 200 attributes &= ~FILE_ATTRIBUTE_READONLY;
201 201
202 if (SetFileAttributes(path, attributes) == 0) { 202 if (SetFileAttributesW(path, attributes) == 0) {
203 return false; 203 return false;
204 } 204 }
205 205
206 return DeleteFile(path) != 0; 206 return DeleteFileW(path) != 0;
207 } 207 }
208 } 208 }
209 209
210 return false; 210 return false;
211 } 211 }
212 212
213 213
214 static bool DeleteDir(char* dir_name, 214 static bool DeleteDir(wchar_t* dir_name,
215 char* path, 215 wchar_t* path,
216 int path_length) { 216 int path_length) {
217 if (strcmp(dir_name, ".") != 0 && 217 if (wcscmp(dir_name, L".") != 0 &&
218 strcmp(dir_name, "..") != 0) { 218 wcscmp(dir_name, L"..") != 0) {
219 size_t written = snprintf(path + path_length, 219 size_t written = _snwprintf(path + path_length,
220 MAX_PATH - path_length, 220 MAX_PATH - path_length,
221 "%s", 221 L"%s",
222 dir_name); 222 dir_name);
223 if (written != strlen(dir_name)) { 223 if (written != wcslen(dir_name)) {
224 return false; 224 return false;
225 } 225 }
226 return DeleteRecursively(path); 226 return DeleteRecursively(path);
227 } 227 }
228 return true; 228 return true;
229 } 229 }
230 230
231 231
232 static bool DeleteEntry(LPWIN32_FIND_DATA find_file_data, 232 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data,
233 char* path, 233 wchar_t* path,
234 int path_length) { 234 int path_length) {
235 DWORD attributes = find_file_data->dwFileAttributes; 235 DWORD attributes = find_file_data->dwFileAttributes;
236 236
237 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 237 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
238 return DeleteDir(find_file_data->cFileName, path, path_length); 238 return DeleteDir(find_file_data->cFileName, path, path_length);
239 } else { 239 } else {
240 return DeleteFile(find_file_data->cFileName, path, path_length); 240 return DeleteFile(find_file_data->cFileName, path, path_length);
241 } 241 }
242 } 242 }
243 243
244 244
245 static bool DeleteRecursively(const char* dir_name) { 245 static bool DeleteRecursively(const wchar_t* dir_name) {
246 // If the directory is a junction, it's pointing to some other place in the 246 // If the directory is a junction, it's pointing to some other place in the
247 // filesystem that we do not want to recurse into. 247 // filesystem that we do not want to recurse into.
248 DWORD attributes = GetFileAttributes(dir_name); 248 DWORD attributes = GetFileAttributesW(dir_name);
249 if ((attributes != INVALID_FILE_ATTRIBUTES) && 249 if ((attributes != INVALID_FILE_ATTRIBUTES) &&
250 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { 250 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
251 // Just delete the junction itself. 251 // Just delete the junction itself.
252 return RemoveDirectory(dir_name) != 0; 252 return RemoveDirectoryW(dir_name) != 0;
253 } 253 }
254 254
255 // Compute full path for the directory currently being deleted. The 255 // Compute full path for the directory currently being deleted. The
256 // path buffer will be used to construct the current path in the 256 // path buffer will be used to construct the current path in the
257 // recursive traversal. path_length does not always equal 257 // recursive traversal. path_length does not always equal
258 // strlen(path) but indicates the current prefix of path that is the 258 // strlen(path) but indicates the current prefix of path that is the
259 // path of the current directory in the traversal. 259 // path of the current directory in the traversal.
260 char* path = static_cast<char*>(malloc(MAX_PATH)); 260 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t)));
261 int path_length = 0; 261 int path_length = 0;
262 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); 262 bool valid = ComputeFullSearchPath(dir_name, path, &path_length);
263 if (!valid) { 263 if (!valid) {
264 free(path); 264 free(path);
265 return false; 265 return false;
266 } 266 }
267 267
268 WIN32_FIND_DATA find_file_data; 268 WIN32_FIND_DATAW find_file_data;
269 HANDLE find_handle = FindFirstFile(path, &find_file_data); 269 HANDLE find_handle = FindFirstFileW(path, &find_file_data);
270 270
271 // Adjust the path by removing the '*' used for the search. 271 // Adjust the path by removing the '*' used for the search.
272 path_length -= 1; 272 path_length -= 1;
273 path[path_length] = '\0'; 273 path[path_length] = '\0';
274 274
275 if (find_handle == INVALID_HANDLE_VALUE) { 275 if (find_handle == INVALID_HANDLE_VALUE) {
276 free(path); 276 free(path);
277 return false; 277 return false;
278 } 278 }
279 279
280 bool success = DeleteEntry(&find_file_data, path, path_length); 280 bool success = DeleteEntry(&find_file_data, path, path_length);
281 281
282 while ((FindNextFile(find_handle, &find_file_data) != 0) && success) { 282 while ((FindNextFileW(find_handle, &find_file_data) != 0) && success) {
283 success = success && DeleteEntry(&find_file_data, path, path_length); 283 success = success && DeleteEntry(&find_file_data, path, path_length);
284 } 284 }
285 285
286 free(path); 286 free(path);
287 287
288 if ((GetLastError() != ERROR_NO_MORE_FILES) || 288 if ((GetLastError() != ERROR_NO_MORE_FILES) ||
289 (FindClose(find_handle) == 0) || 289 (FindClose(find_handle) == 0) ||
290 (RemoveDirectory(dir_name) == 0)) { 290 (RemoveDirectoryW(dir_name) == 0)) {
291 return false; 291 return false;
292 } 292 }
293 293
294 return success; 294 return success;
295 } 295 }
296 296
297 297
298 bool Directory::List(const char* dir_name, 298 bool Directory::List(const char* dir_name,
299 bool recursive, 299 bool recursive,
300 DirectoryListing* listing) { 300 DirectoryListing* listing) {
301 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); 301 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name);
302 bool completed = ListRecursively(system_name, recursive, listing); 302 bool completed = ListRecursively(system_name, recursive, listing);
303 free(const_cast<char*>(system_name)); 303 free(const_cast<wchar_t*>(system_name));
304 return completed; 304 return completed;
305 } 305 }
306 306
307 307
308 static Directory::ExistsResult ExistsHelper(const char* dir_name) { 308 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) {
309 DWORD attributes = GetFileAttributes(dir_name); 309 DWORD attributes = GetFileAttributesW(dir_name);
310 if (attributes == INVALID_FILE_ATTRIBUTES) { 310 if (attributes == INVALID_FILE_ATTRIBUTES) {
311 DWORD last_error = GetLastError(); 311 DWORD last_error = GetLastError();
312 if (last_error == ERROR_FILE_NOT_FOUND || 312 if (last_error == ERROR_FILE_NOT_FOUND ||
313 last_error == ERROR_PATH_NOT_FOUND) { 313 last_error == ERROR_PATH_NOT_FOUND) {
314 return Directory::DOES_NOT_EXIST; 314 return Directory::DOES_NOT_EXIST;
315 } else { 315 } else {
316 // We might not be able to get the file attributes for other 316 // We might not be able to get the file attributes for other
317 // reasons such as lack of permissions. In that case we do 317 // reasons such as lack of permissions. In that case we do
318 // not know if the directory exists. 318 // not know if the directory exists.
319 return Directory::UNKNOWN; 319 return Directory::UNKNOWN;
320 } 320 }
321 } 321 }
322 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; 322 bool exists = (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
323 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST; 323 return exists ? Directory::EXISTS : Directory::DOES_NOT_EXIST;
324 } 324 }
325 325
326 326
327 Directory::ExistsResult Directory::Exists(const char* dir_name) { 327 Directory::ExistsResult Directory::Exists(const char* dir_name) {
328 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); 328 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name);
329 Directory::ExistsResult result = ExistsHelper(system_name); 329 Directory::ExistsResult result = ExistsHelper(system_name);
330 free(const_cast<char*>(system_name)); 330 free(const_cast<wchar_t*>(system_name));
331 return result; 331 return result;
332 } 332 }
333 333
334 334
335 char* Directory::Current() { 335 char* Directory::Current() {
336 int length = GetCurrentDirectory(0, NULL); 336 int length = GetCurrentDirectoryW(0, NULL);
337 char* current = reinterpret_cast<char*>(malloc(length + 1)); 337 wchar_t* current = new wchar_t[length + 1];
338 GetCurrentDirectory(length + 1, current); 338 GetCurrentDirectoryW(length + 1, current);
339 char* result = StringUtils::ConsoleStringToUtf8(current); 339 char* result = StringUtils::WideToUtf8(current);
340 free(current); 340 delete[] current;
341 return result; 341 return result;
342 } 342 }
343 343
344 344
345 bool Directory::Create(const char* dir_name) { 345 bool Directory::Create(const char* dir_name) {
346 const char* system_name = StringUtils::Utf8ToConsoleString(dir_name); 346 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name);
347 // If the directory already exists and is a directory do not 347 // If the directory already exists and is a directory do not
348 // attempt to create it again and treat it as a success. 348 // attempt to create it again and treat it as a success.
349 if (ExistsHelper(system_name) == EXISTS) { 349 if (ExistsHelper(system_name) == EXISTS) {
350 free(const_cast<char*>(system_name)); 350 free(const_cast<wchar_t*>(system_name));
351 return true; 351 return true;
352 } 352 }
353 int create_status = CreateDirectory(system_name, NULL); 353 int create_status = CreateDirectoryW(system_name, NULL);
354 free(const_cast<char*>(system_name)); 354 free(const_cast<wchar_t*>(system_name));
355 return (create_status != 0); 355 return (create_status != 0);
356 } 356 }
357 357
358 358
359 char* Directory::CreateTemp(const char* const_template) { 359 char* Directory::CreateTemp(const char* const_template) {
360 // Returns a new, unused directory name, modifying the contents of 360 // Returns a new, unused directory name, modifying the contents of
361 // dir_template. Creates this directory, with a default security 361 // dir_template. Creates this directory, with a default security
362 // descriptor inherited from its parent directory. 362 // descriptor inherited from its parent directory.
363 // The return value must be freed by the caller. 363 // The return value must be freed by the caller.
364 char* path = static_cast<char*>(malloc(MAX_PATH)); 364 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t)));
365 int path_length; 365 int path_length;
366 if (0 == strncmp(const_template, "", 1)) { 366 if (0 == strncmp(const_template, "", 1)) {
367 path_length = GetTempPath(MAX_PATH, path); 367 path_length = GetTempPathW(MAX_PATH, path);
368 if (path_length == 0) { 368 if (path_length == 0) {
369 free(path); 369 free(path);
370 return NULL; 370 return NULL;
371 } 371 }
372 } else { 372 } else {
373 const char* system_template = 373 const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
374 StringUtils::Utf8ToConsoleString(const_template); 374 _snwprintf(path, MAX_PATH, L"%s", system_template);
375 snprintf(path, MAX_PATH, "%s", system_template); 375 free(const_cast<wchar_t*>(system_template));
376 free(const_cast<char*>(system_template)); 376 path_length = wcslen(path);
377 path_length = strlen(path);
378 } 377 }
379 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. 378 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44.
380 if (path_length > MAX_PATH - 44) { 379 if (path_length > MAX_PATH - 44) {
381 free(path); 380 free(path);
382 return NULL; 381 return NULL;
383 } 382 }
384 if ((path)[path_length - 1] == '\\') { 383 if ((path)[path_length - 1] == L'\\') {
385 // No base name for the directory - use "tempdir". 384 // No base name for the directory - use "tempdir".
386 snprintf(path + path_length, MAX_PATH - path_length, "tempdir"); 385 _snwprintf(path + path_length, MAX_PATH - path_length, L"tempdir");
387 path_length = strlen(path); 386 path_length = wcslen(path);
388 } 387 }
389 388
390 UUID uuid; 389 UUID uuid;
391 RPC_STATUS status = UuidCreateSequential(&uuid); 390 RPC_STATUS status = UuidCreateSequential(&uuid);
392 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { 391 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
393 free(path); 392 free(path);
394 return NULL; 393 return NULL;
395 } 394 }
396 RPC_CSTR uuid_string; 395 RPC_WSTR uuid_string;
397 status = UuidToString(&uuid, &uuid_string); 396 status = UuidToStringW(&uuid, &uuid_string);
398 if (status != RPC_S_OK) { 397 if (status != RPC_S_OK) {
399 free(path); 398 free(path);
400 return NULL; 399 return NULL;
401 } 400 }
402 401
403 snprintf(path + path_length, MAX_PATH - path_length, "-%s", uuid_string); 402 _snwprintf(path + path_length, MAX_PATH - path_length, L"-%s", uuid_string);
404 if (!CreateDirectory(path, NULL)) { 403 RpcStringFreeW(&uuid_string);
404 if (!CreateDirectoryW(path, NULL)) {
405 free(path); 405 free(path);
406 return NULL; 406 return NULL;
407 } 407 }
408 char* result = StringUtils::ConsoleStringToUtf8(path); 408 char* result = StringUtils::WideToUtf8(path);
409 free(path); 409 free(path);
410 return result; 410 return result;
411 } 411 }
412 412
413 413
414 bool Directory::Delete(const char* dir_name, bool recursive) { 414 bool Directory::Delete(const char* dir_name, bool recursive) {
415 bool result = false; 415 bool result = false;
416 const char* system_dir_name = 416 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name);
417 StringUtils::Utf8ToConsoleString(dir_name);
418 if (!recursive) { 417 if (!recursive) {
419 result = (RemoveDirectory(system_dir_name) != 0); 418 result = (RemoveDirectoryW(system_dir_name) != 0);
420 } else { 419 } else {
421 result = DeleteRecursively(system_dir_name); 420 result = DeleteRecursively(system_dir_name);
422 } 421 }
423 free(const_cast<char*>(system_dir_name)); 422 free(const_cast<wchar_t*>(system_dir_name));
424 return result; 423 return result;
425 } 424 }
426 425
427 426
428 bool Directory::Rename(const char* path, const char* new_path) { 427 bool Directory::Rename(const char* path, const char* new_path) {
429 const char* system_path = StringUtils::Utf8ToConsoleString(path); 428 const wchar_t* system_path = StringUtils::Utf8ToWide(path);
430 const char* system_new_path = 429 const wchar_t* system_new_path = StringUtils::Utf8ToWide(new_path);
431 StringUtils::Utf8ToConsoleString(new_path);
432 ExistsResult exists = ExistsHelper(system_path); 430 ExistsResult exists = ExistsHelper(system_path);
433 if (exists != EXISTS) return false; 431 if (exists != EXISTS) return false;
434 ExistsResult new_exists = ExistsHelper(system_new_path); 432 ExistsResult new_exists = ExistsHelper(system_new_path);
435 // MoveFile does not allow replacing exising directories. Therefore, 433 // MoveFile does not allow replacing exising directories. Therefore,
436 // if the new_path is currently a directory we need to delete it 434 // if the new_path is currently a directory we need to delete it
437 // first. 435 // first.
438 if (new_exists == EXISTS) { 436 if (new_exists == EXISTS) {
439 bool success = DeleteRecursively(system_new_path); 437 bool success = DeleteRecursively(system_new_path);
440 if (!success) return false; 438 if (!success) return false;
441 } 439 }
442 DWORD flags = MOVEFILE_WRITE_THROUGH; 440 DWORD flags = MOVEFILE_WRITE_THROUGH;
443 int move_status = 441 int move_status =
444 MoveFileEx(system_path, system_new_path, flags); 442 MoveFileExW(system_path, system_new_path, flags);
445 free(const_cast<char*>(system_path)); 443 free(const_cast<wchar_t*>(system_path));
446 free(const_cast<char*>(system_new_path)); 444 free(const_cast<wchar_t*>(system_new_path));
447 return (move_status != 0); 445 return (move_status != 0);
448 } 446 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698