OLD | NEW |
---|---|
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 class PathBuffer { |
13 public: | |
14 PathBuffer() : length(0) { } | |
15 | |
16 wchar_t data[MAX_PATH + 1]; | |
17 int length; | |
18 | |
19 bool Add(const wchar_t* name) { | |
20 size_t written = _snwprintf(data + length, | |
21 MAX_PATH - length, | |
22 L"%s", | |
23 name); | |
24 data[MAX_PATH] = L'\0'; | |
25 if (written == wcsnlen(name, MAX_PATH + 1)) { | |
26 length += written; | |
27 return true; | |
28 } else { | |
29 SetLastError(ERROR_BUFFER_OVERFLOW); | |
30 return false; | |
31 } | |
32 } | |
33 | |
34 void Reset(int new_length) { | |
35 length = new_length; | |
36 data[length] = L'\0'; | |
37 } | |
38 }; | |
39 | |
40 | |
41 // Forward declarations. | |
13 static bool ListRecursively(const wchar_t* dir_name, | 42 static bool ListRecursively(const wchar_t* dir_name, |
14 bool recursive, | 43 bool recursive, |
15 DirectoryListing* listing); | 44 DirectoryListing* listing); |
16 static bool DeleteRecursively(const wchar_t* dir_name); | 45 static bool DeleteRecursively(const wchar_t* dir_name); |
17 | 46 |
18 | 47 |
48 static void PostError(DirectoryListing* listing, | |
49 const wchar_t* dir_name) { | |
50 const char* utf8_path = StringUtils::WideToUtf8(dir_name); | |
51 listing->HandleError(utf8_path); | |
52 free(const_cast<char*>(utf8_path)); | |
53 } | |
54 | |
55 | |
19 static bool HandleDir(wchar_t* dir_name, | 56 static bool HandleDir(wchar_t* dir_name, |
20 wchar_t* path, | 57 PathBuffer* path, |
21 int path_length, | |
22 bool recursive, | 58 bool recursive, |
23 DirectoryListing* listing) { | 59 DirectoryListing* listing) { |
24 if (wcscmp(dir_name, L".") != 0 && | 60 if (wcscmp(dir_name, L".") == 0) return true; |
25 wcscmp(dir_name, L"..") != 0) { | 61 if (wcscmp(dir_name, L"..") == 0) return true; |
26 size_t written = _snwprintf(path + path_length, | 62 if (!path->Add(dir_name)) { |
27 MAX_PATH - path_length, | 63 PostError(listing, path->data); |
28 L"%s", | 64 return false; |
29 dir_name); | |
30 if (written != wcslen(dir_name)) { | |
31 return false; | |
32 } | |
33 char* utf8_path = StringUtils::WideToUtf8(path); | |
34 bool ok = listing->HandleDirectory(utf8_path); | |
35 free(utf8_path); | |
36 if (!ok) return ok; | |
37 if (recursive) { | |
38 return ListRecursively(path, recursive, listing); | |
39 } | |
40 } | 65 } |
41 return true; | 66 char* utf8_path = StringUtils::WideToUtf8(path->data); |
67 bool ok = listing->HandleDirectory(utf8_path); | |
68 free(utf8_path); | |
69 return ok && (!recursive || ListRecursively(path->data, recursive, listing)); | |
Bill Hesse
2013/02/13 14:41:40
Line 69 is the only change from the previously com
| |
42 } | 70 } |
43 | 71 |
44 | 72 |
45 static bool HandleFile(wchar_t* file_name, | 73 static bool HandleFile(wchar_t* file_name, |
46 wchar_t* path, | 74 PathBuffer* path, |
47 int path_length, | |
48 DirectoryListing* listing) { | 75 DirectoryListing* listing) { |
49 size_t written = _snwprintf(path + path_length, | 76 if (!path->Add(file_name)) { |
50 MAX_PATH - path_length, | 77 PostError(listing, path->data); |
51 L"%s", | |
52 file_name); | |
53 if (written != wcslen(file_name)) { | |
54 return false; | 78 return false; |
55 }; | 79 } |
56 char* utf8_path = StringUtils::WideToUtf8(path); | 80 char* utf8_path = StringUtils::WideToUtf8(path->data); |
57 bool ok = listing->HandleFile(utf8_path); | 81 bool ok = listing->HandleFile(utf8_path); |
58 free(utf8_path); | 82 free(utf8_path); |
59 return ok; | 83 return ok; |
60 } | 84 } |
61 | 85 |
62 | 86 |
63 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data, | 87 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data, |
64 wchar_t* path, | 88 PathBuffer* path, |
65 int path_length, | |
66 bool recursive, | 89 bool recursive, |
67 DirectoryListing* listing) { | 90 DirectoryListing* listing) { |
68 DWORD attributes = find_file_data->dwFileAttributes; | 91 DWORD attributes = find_file_data->dwFileAttributes; |
69 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 92 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
70 return HandleDir(find_file_data->cFileName, | 93 return HandleDir(find_file_data->cFileName, |
71 path, | 94 path, |
72 path_length, | |
73 recursive, | 95 recursive, |
74 listing); | 96 listing); |
75 } else { | 97 } else { |
76 return HandleFile(find_file_data->cFileName, path, path_length, listing); | 98 return HandleFile(find_file_data->cFileName, path, listing); |
77 } | 99 } |
78 } | 100 } |
79 | 101 |
80 | 102 |
81 // ComputeFullSearchPath must be called with a path array of size at | 103 static PathBuffer* ComputeFullSearchPath(const wchar_t* dir_name) { |
82 // least MAX_PATH. | |
83 static bool ComputeFullSearchPath(const wchar_t* dir_name, | |
84 wchar_t* path, | |
85 int* path_length) { | |
86 // GetFullPathName only works in a multi-threaded environment if | 104 // GetFullPathName only works in a multi-threaded environment if |
87 // SetCurrentDirectory is not used. We currently have no plan for | 105 // SetCurrentDirectory is not used. We currently have no plan for |
88 // exposing SetCurrentDirectory. | 106 // exposing SetCurrentDirectory. |
89 size_t written = GetFullPathNameW(dir_name, MAX_PATH, path, NULL); | 107 PathBuffer* path = new PathBuffer(); |
108 | |
109 size_t written = GetFullPathNameW(dir_name, MAX_PATH + 1, path->data, NULL); | |
90 // GetFullPathName only accepts input strings of size less than | 110 // GetFullPathName only accepts input strings of size less than |
91 // MAX_PATH and returns 0 to indicate failure for paths longer than | 111 // MAX_PATH and returns 0 to indicate failure for paths longer than |
92 // that. Therefore the path buffer is always big enough. | 112 // that. Therefore the path buffer is always big enough. |
93 if (written == 0 || written > MAX_PATH) { | 113 if (written == 0 || written > MAX_PATH) { |
94 return false; | 114 delete path; |
115 return NULL; | |
95 } | 116 } |
96 *path_length = written; | 117 path->length = written; |
97 written = _snwprintf(path + *path_length, | 118 if (path->Add(L"\\*")) { |
98 MAX_PATH - *path_length, | 119 return path; |
99 L"%s", | 120 } else { |
100 L"\\*"); | 121 delete path; |
101 if (written != 2) { | 122 return NULL; |
102 return false; | |
103 } | 123 } |
104 *path_length += written; | |
105 return true; | |
106 } | |
107 | |
108 static void PostError(DirectoryListing* listing, | |
109 const wchar_t* dir_name) { | |
110 const char* utf8_path = StringUtils::WideToUtf8(dir_name); | |
111 listing->HandleError(utf8_path); | |
112 free(const_cast<char*>(utf8_path)); | |
113 } | 124 } |
114 | 125 |
115 | 126 |
116 static bool ListRecursively(const wchar_t* dir_name, | 127 static bool ListRecursively(const wchar_t* dir_name, |
117 bool recursive, | 128 bool recursive, |
118 DirectoryListing* listing) { | 129 DirectoryListing* listing) { |
119 // Compute full path for the directory currently being listed. The | 130 // Compute full path for the directory currently being listed. The |
120 // path buffer will be used to construct the current path in the | 131 // path buffer will be used to construct the current path in the |
121 // recursive traversal. path_length does not always equal | 132 // recursive traversal. path_length does not always equal |
122 // strlen(path) but indicates the current prefix of path that is the | 133 // strlen(path) but indicates the current prefix of path that is the |
123 // path of the current directory in the traversal. | 134 // path of the current directory in the traversal. |
124 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t))); | 135 PathBuffer* path = ComputeFullSearchPath(dir_name); |
125 int path_length = 0; | 136 if (path == NULL) { |
126 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); | |
127 if (!valid) { | |
128 PostError(listing, dir_name); | 137 PostError(listing, dir_name); |
129 free(path); | 138 delete path; |
130 return false; | 139 return false; |
131 } | 140 } |
132 | 141 |
133 WIN32_FIND_DATAW find_file_data; | 142 WIN32_FIND_DATAW find_file_data; |
134 HANDLE find_handle = FindFirstFileW(path, &find_file_data); | 143 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data); |
135 | 144 |
136 // Adjust the path by removing the '*' used for the search. | 145 // Adjust the path by removing the '*' used for the search. |
137 path_length -= 1; | 146 path->Reset(path->length - 1); |
138 path[path_length] = '\0'; | |
139 | 147 |
140 if (find_handle == INVALID_HANDLE_VALUE) { | 148 if (find_handle == INVALID_HANDLE_VALUE) { |
141 PostError(listing, path); | 149 PostError(listing, path->data); |
142 free(path); | 150 delete path; |
143 return false; | 151 return false; |
144 } | 152 } |
145 | 153 |
154 int path_length = path->length; | |
146 bool success = HandleEntry(&find_file_data, | 155 bool success = HandleEntry(&find_file_data, |
147 path, | 156 path, |
148 path_length, | |
149 recursive, | 157 recursive, |
150 listing); | 158 listing); |
151 | 159 |
152 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { | 160 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { |
161 path->Reset(path_length); // HandleEntry adds the entry name to path. | |
153 success = HandleEntry(&find_file_data, | 162 success = HandleEntry(&find_file_data, |
154 path, | 163 path, |
155 path_length, | |
156 recursive, | 164 recursive, |
157 listing) && success; | 165 listing) && success; |
158 } | 166 } |
159 | 167 |
160 if (GetLastError() != ERROR_NO_MORE_FILES) { | 168 if (GetLastError() != ERROR_NO_MORE_FILES) { |
161 success = false; | 169 success = false; |
162 PostError(listing, dir_name); | 170 PostError(listing, dir_name); |
163 } | 171 } |
164 | 172 |
165 if (FindClose(find_handle) == 0) { | 173 if (FindClose(find_handle) == 0) { |
166 success = false; | 174 success = false; |
167 PostError(listing, dir_name); | 175 PostError(listing, dir_name); |
168 } | 176 } |
169 free(path); | 177 delete path; |
170 | 178 |
171 return success; | 179 return success; |
172 } | 180 } |
173 | 181 |
174 | 182 |
175 static bool DeleteFile(wchar_t* file_name, | 183 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { |
176 wchar_t* path, | 184 if (!path->Add(file_name)) return false; |
177 int path_length) { | |
178 size_t written = _snwprintf(path + path_length, | |
179 MAX_PATH - path_length, | |
180 L"%s", | |
181 file_name); | |
182 if (written != wcslen(file_name)) { | |
183 return false; | |
184 } | |
185 | 185 |
186 if (DeleteFileW(path) != 0) { | 186 if (DeleteFileW(path->data) != 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 = GetFileAttributesW(path); | 194 DWORD attributes = GetFileAttributesW(path->data); |
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 (SetFileAttributesW(path, attributes) == 0) { | 202 if (SetFileAttributesW(path->data, attributes) == 0) { |
203 return false; | 203 return false; |
204 } | 204 } |
205 | 205 |
206 return DeleteFileW(path) != 0; | 206 return DeleteFileW(path->data) != 0; |
207 } | 207 } |
208 } | 208 } |
209 | 209 |
210 return false; | 210 return false; |
211 } | 211 } |
212 | 212 |
213 | 213 |
214 static bool DeleteDir(wchar_t* dir_name, | 214 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { |
215 wchar_t* path, | 215 if (wcscmp(dir_name, L".") == 0) return true; |
216 int path_length) { | 216 if (wcscmp(dir_name, L"..") == 0) return true; |
217 if (wcscmp(dir_name, L".") != 0 && | 217 return path->Add(dir_name) && DeleteRecursively(path->data); |
218 wcscmp(dir_name, L"..") != 0) { | |
219 size_t written = _snwprintf(path + path_length, | |
220 MAX_PATH - path_length, | |
221 L"%s", | |
222 dir_name); | |
223 if (written != wcslen(dir_name)) { | |
224 return false; | |
225 } | |
226 return DeleteRecursively(path); | |
227 } | |
228 return true; | |
229 } | 218 } |
230 | 219 |
231 | 220 |
232 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, | 221 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { |
233 wchar_t* path, | |
234 int path_length) { | |
235 DWORD attributes = find_file_data->dwFileAttributes; | 222 DWORD attributes = find_file_data->dwFileAttributes; |
236 | 223 |
237 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { | 224 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { |
238 return DeleteDir(find_file_data->cFileName, path, path_length); | 225 return DeleteDir(find_file_data->cFileName, path); |
239 } else { | 226 } else { |
240 return DeleteFile(find_file_data->cFileName, path, path_length); | 227 return DeleteFile(find_file_data->cFileName, path); |
241 } | 228 } |
242 } | 229 } |
243 | 230 |
244 | 231 |
245 static bool DeleteRecursively(const wchar_t* dir_name) { | 232 static bool DeleteRecursively(const wchar_t* dir_name) { |
246 // If the directory is a junction, it's pointing to some other place in the | 233 // 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. | 234 // filesystem that we do not want to recurse into. |
248 DWORD attributes = GetFileAttributesW(dir_name); | 235 DWORD attributes = GetFileAttributesW(dir_name); |
249 if ((attributes != INVALID_FILE_ATTRIBUTES) && | 236 if ((attributes != INVALID_FILE_ATTRIBUTES) && |
250 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { | 237 (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { |
251 // Just delete the junction itself. | 238 // Just delete the junction itself. |
252 return RemoveDirectoryW(dir_name) != 0; | 239 return RemoveDirectoryW(dir_name) != 0; |
253 } | 240 } |
254 | 241 |
255 // Compute full path for the directory currently being deleted. The | 242 // Compute full path for the directory currently being deleted. The |
256 // path buffer will be used to construct the current path in the | 243 // path buffer will be used to construct the current path in the |
257 // recursive traversal. path_length does not always equal | 244 // recursive traversal. path_length does not always equal |
258 // strlen(path) but indicates the current prefix of path that is the | 245 // strlen(path) but indicates the current prefix of path that is the |
259 // path of the current directory in the traversal. | 246 // path of the current directory in the traversal. |
260 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t))); | 247 PathBuffer* path = ComputeFullSearchPath(dir_name); |
261 int path_length = 0; | 248 if (path == NULL) return false; |
262 bool valid = ComputeFullSearchPath(dir_name, path, &path_length); | 249 |
263 if (!valid) { | 250 WIN32_FIND_DATAW find_file_data; |
264 free(path); | 251 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data); |
252 | |
253 // Adjust the path by removing the '*' used for the search. | |
254 int path_length = path->length - 1; | |
255 path->Reset(path_length); | |
256 | |
257 if (find_handle == INVALID_HANDLE_VALUE) { | |
258 delete path; | |
265 return false; | 259 return false; |
266 } | 260 } |
267 | 261 |
268 WIN32_FIND_DATAW find_file_data; | 262 bool success = DeleteEntry(&find_file_data, path); |
269 HANDLE find_handle = FindFirstFileW(path, &find_file_data); | |
270 | 263 |
271 // Adjust the path by removing the '*' used for the search. | 264 while ((FindNextFileW(find_handle, &find_file_data) != 0) && success) { |
272 path_length -= 1; | 265 path->Reset(path_length); // DeleteEntry adds to the path. |
273 path[path_length] = '\0'; | 266 success = success && DeleteEntry(&find_file_data, path); |
274 | |
275 if (find_handle == INVALID_HANDLE_VALUE) { | |
276 free(path); | |
277 return false; | |
278 } | 267 } |
279 | 268 |
280 bool success = DeleteEntry(&find_file_data, path, path_length); | 269 delete path; |
281 | |
282 while ((FindNextFileW(find_handle, &find_file_data) != 0) && success) { | |
283 success = success && DeleteEntry(&find_file_data, path, path_length); | |
284 } | |
285 | |
286 free(path); | |
287 | 270 |
288 if ((GetLastError() != ERROR_NO_MORE_FILES) || | 271 if ((GetLastError() != ERROR_NO_MORE_FILES) || |
289 (FindClose(find_handle) == 0) || | 272 (FindClose(find_handle) == 0) || |
290 (RemoveDirectoryW(dir_name) == 0)) { | 273 (RemoveDirectoryW(dir_name) == 0)) { |
291 return false; | 274 return false; |
292 } | 275 } |
293 | 276 |
294 return success; | 277 return success; |
295 } | 278 } |
296 | 279 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 free(const_cast<wchar_t*>(system_name)); | 338 free(const_cast<wchar_t*>(system_name)); |
356 return (create_status != 0); | 339 return (create_status != 0); |
357 } | 340 } |
358 | 341 |
359 | 342 |
360 char* Directory::CreateTemp(const char* const_template) { | 343 char* Directory::CreateTemp(const char* const_template) { |
361 // Returns a new, unused directory name, modifying the contents of | 344 // Returns a new, unused directory name, modifying the contents of |
362 // dir_template. Creates this directory, with a default security | 345 // dir_template. Creates this directory, with a default security |
363 // descriptor inherited from its parent directory. | 346 // descriptor inherited from its parent directory. |
364 // The return value must be freed by the caller. | 347 // The return value must be freed by the caller. |
365 wchar_t* path = static_cast<wchar_t*>(malloc(MAX_PATH * sizeof(wchar_t))); | 348 PathBuffer* path = new PathBuffer(); |
366 int path_length; | |
367 if (0 == strncmp(const_template, "", 1)) { | 349 if (0 == strncmp(const_template, "", 1)) { |
368 path_length = GetTempPathW(MAX_PATH, path); | 350 path->length = GetTempPathW(MAX_PATH, path->data); |
369 if (path_length == 0) { | 351 if (path->length == 0) { |
370 free(path); | 352 delete path; |
371 return NULL; | 353 return NULL; |
372 } | 354 } |
373 } else { | 355 } else { |
374 const wchar_t* system_template = StringUtils::Utf8ToWide(const_template); | 356 const wchar_t* system_template = StringUtils::Utf8ToWide(const_template); |
375 _snwprintf(path, MAX_PATH, L"%s", system_template); | 357 path->Add(system_template); |
376 free(const_cast<wchar_t*>(system_template)); | 358 free(const_cast<wchar_t*>(system_template)); |
377 path_length = wcslen(path); | |
378 } | 359 } |
379 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. | 360 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. |
380 if (path_length > MAX_PATH - 44) { | 361 if (path->length > MAX_PATH - 44) { |
381 free(path); | 362 delete path; |
382 return NULL; | 363 return NULL; |
383 } | 364 } |
384 if ((path)[path_length - 1] == L'\\') { | 365 if ((path->data)[path->length - 1] == L'\\') { |
385 // No base name for the directory - use "tempdir". | 366 // No base name for the directory - use "tempdir". |
386 _snwprintf(path + path_length, MAX_PATH - path_length, L"tempdir"); | 367 path->Add(L"tempdir"); |
387 path_length = wcslen(path); | |
388 } | 368 } |
389 | 369 |
390 UUID uuid; | 370 UUID uuid; |
391 RPC_STATUS status = UuidCreateSequential(&uuid); | 371 RPC_STATUS status = UuidCreateSequential(&uuid); |
392 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { | 372 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { |
393 free(path); | 373 delete path; |
394 return NULL; | 374 return NULL; |
395 } | 375 } |
396 RPC_WSTR uuid_string; | 376 RPC_WSTR uuid_string; |
397 status = UuidToStringW(&uuid, &uuid_string); | 377 status = UuidToStringW(&uuid, &uuid_string); |
398 if (status != RPC_S_OK) { | 378 if (status != RPC_S_OK) { |
399 free(path); | 379 delete path; |
400 return NULL; | 380 return NULL; |
401 } | 381 } |
402 | 382 |
403 _snwprintf(path + path_length, MAX_PATH - path_length, L"-%s", uuid_string); | 383 path->Add(L"-"); |
384 // RPC_WSTR is an unsigned short*, so we cast to wchar_t*. | |
385 path->Add(reinterpret_cast<wchar_t*>(uuid_string)); | |
404 RpcStringFreeW(&uuid_string); | 386 RpcStringFreeW(&uuid_string); |
405 if (!CreateDirectoryW(path, NULL)) { | 387 if (!CreateDirectoryW(path->data, NULL)) { |
406 free(path); | 388 delete path; |
407 return NULL; | 389 return NULL; |
408 } | 390 } |
409 char* result = StringUtils::WideToUtf8(path); | 391 char* result = StringUtils::WideToUtf8(path->data); |
410 free(path); | 392 delete path; |
411 return result; | 393 return result; |
412 } | 394 } |
413 | 395 |
414 | 396 |
415 bool Directory::Delete(const char* dir_name, bool recursive) { | 397 bool Directory::Delete(const char* dir_name, bool recursive) { |
416 bool result = false; | 398 bool result = false; |
417 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name); | 399 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name); |
418 if (!recursive) { | 400 if (!recursive) { |
419 result = (RemoveDirectoryW(system_dir_name) != 0); | 401 result = (RemoveDirectoryW(system_dir_name) != 0); |
420 } else { | 402 } else { |
(...skipping 17 matching lines...) Expand all Loading... | |
438 bool success = DeleteRecursively(system_new_path); | 420 bool success = DeleteRecursively(system_new_path); |
439 if (!success) return false; | 421 if (!success) return false; |
440 } | 422 } |
441 DWORD flags = MOVEFILE_WRITE_THROUGH; | 423 DWORD flags = MOVEFILE_WRITE_THROUGH; |
442 int move_status = | 424 int move_status = |
443 MoveFileExW(system_path, system_new_path, flags); | 425 MoveFileExW(system_path, system_new_path, flags); |
444 free(const_cast<wchar_t*>(system_path)); | 426 free(const_cast<wchar_t*>(system_path)); |
445 free(const_cast<wchar_t*>(system_new_path)); | 427 free(const_cast<wchar_t*>(system_new_path)); |
446 return (move_status != 0); | 428 return (move_status != 0); |
447 } | 429 } |
OLD | NEW |