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

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

Issue 16813006: Make Directory.list pull-based, making it possible to pause, resume and cancel directory listing. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review update. Created 7 years, 6 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 | « runtime/bin/directory_macos.cc ('k') | sdk/lib/io/directory_impl.dart » ('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) 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 "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_WINDOWS) 6 #if defined(TARGET_OS_WINDOWS)
7 7
8 #include "bin/directory.h" 8 #include "bin/directory.h"
9 #include "bin/file.h" 9 #include "bin/file.h"
10 #include "bin/utils.h" 10 #include "bin/utils.h"
11 11
12 #include <errno.h> // NOLINT 12 #include <errno.h> // NOLINT
13 #include <sys/stat.h> // NOLINT 13 #include <sys/stat.h> // NOLINT
14 14
15 #include "bin/log.h" 15 #include "bin/log.h"
16 16
17 #undef DeleteFile 17 #undef DeleteFile
18 18
19 namespace dart { 19 namespace dart {
20 namespace bin { 20 namespace bin {
21 21
22 class PathBuffer { 22 PathBuffer::PathBuffer() : length_(0) {
23 public: 23 data_ = new wchar_t[MAX_PATH + 1];
24 PathBuffer() : length(0) { 24 }
25 data = new wchar_t[MAX_PATH + 1]; 25
26 char* PathBuffer::AsString() const {
27 return StringUtils::WideToUtf8(AsStringW());
28 }
29
30 wchar_t* PathBuffer::AsStringW() const {
31 return reinterpret_cast<wchar_t*>(data_);
32 }
33
34 bool PathBuffer::Add(const char* name) {
35 const wchar_t* wide_name = StringUtils::Utf8ToWide(name);
36 bool success = AddW(wide_name);
37 free(const_cast<wchar_t*>(wide_name));
38 return success;
39 }
40
41 bool PathBuffer::AddW(const wchar_t* name) {
42 wchar_t* data = AsStringW();
43 int written = _snwprintf(data + length_,
44 MAX_PATH - length_,
45 L"%s",
46 name);
47 data[MAX_PATH] = L'\0';
48 if (written <= MAX_PATH - length_ &&
49 written >= 0 &&
50 static_cast<size_t>(written) == wcsnlen(name, MAX_PATH + 1)) {
51 length_ += written;
52 return true;
53 } else {
54 SetLastError(ERROR_BUFFER_OVERFLOW);
55 return false;
26 } 56 }
57 }
27 58
28 ~PathBuffer() { 59 void PathBuffer::Reset(int new_length) {
29 delete[] data; 60 length_ = new_length;
30 } 61 AsStringW()[length_] = L'\0';
31 62 }
32 wchar_t* data;
33 int length;
34
35 bool Add(const wchar_t* name) {
36 int written = _snwprintf(data + length,
37 MAX_PATH - length,
38 L"%s",
39 name);
40 data[MAX_PATH] = L'\0';
41 if (written <= MAX_PATH - length &&
42 written >= 0 &&
43 static_cast<size_t>(written) == wcsnlen(name, MAX_PATH + 1)) {
44 length += written;
45 return true;
46 } else {
47 SetLastError(ERROR_BUFFER_OVERFLOW);
48 return false;
49 }
50 }
51
52 void Reset(int new_length) {
53 length = new_length;
54 data[length] = L'\0';
55 }
56 };
57 63
58 // If link_name points to a link, IsBrokenLink will return true if link_name 64 // If link_name points to a link, IsBrokenLink will return true if link_name
59 // points to an invalid target. 65 // points to an invalid target.
60 static bool IsBrokenLink(const wchar_t* link_name) { 66 static bool IsBrokenLink(const wchar_t* link_name) {
61 HANDLE handle = CreateFileW( 67 HANDLE handle = CreateFileW(
62 link_name, 68 link_name,
63 0, 69 0,
64 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 70 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
65 NULL, 71 NULL,
66 OPEN_EXISTING, 72 OPEN_EXISTING,
(...skipping 10 matching lines...) Expand all
77 // A linked list structure holding a link target's unique file system ID. 83 // A linked list structure holding a link target's unique file system ID.
78 // Used to detect loops in the file system when listing recursively. 84 // Used to detect loops in the file system when listing recursively.
79 struct LinkList { 85 struct LinkList {
80 DWORD volume; 86 DWORD volume;
81 DWORD id_low; 87 DWORD id_low;
82 DWORD id_high; 88 DWORD id_high;
83 LinkList* next; 89 LinkList* next;
84 }; 90 };
85 91
86 // Forward declarations. 92 // Forward declarations.
87 static bool ListRecursively(PathBuffer* path,
88 bool recursive,
89 bool follow_links,
90 LinkList* seen,
91 DirectoryListing* listing);
92 static bool DeleteRecursively(PathBuffer* path); 93 static bool DeleteRecursively(PathBuffer* path);
93 94
94 95
95 static void PostError(DirectoryListing* listing, 96 static ListType HandleFindFile(DirectoryListing* listing,
96 const wchar_t* dir_name) { 97 DirectoryListingEntry* entry,
97 const char* utf8_path = StringUtils::WideToUtf8(dir_name); 98 WIN32_FIND_DATAW& find_file_data) {
98 listing->HandleError(utf8_path); 99 if (!listing->path_buffer().AddW(find_file_data.cFileName)) {
99 free(const_cast<char*>(utf8_path)); 100 return kListError;
100 }
101
102
103 static bool HandleDir(wchar_t* dir_name,
104 PathBuffer* path,
105 bool recursive,
106 bool follow_links,
107 LinkList* seen,
108 DirectoryListing* listing) {
109 if (wcscmp(dir_name, L".") == 0) return true;
110 if (wcscmp(dir_name, L"..") == 0) return true;
111 if (!path->Add(dir_name)) {
112 PostError(listing, path->data);
113 return false;
114 } 101 }
115 char* utf8_path = StringUtils::WideToUtf8(path->data); 102 DWORD attributes = find_file_data.dwFileAttributes;
116 bool ok = listing->HandleDirectory(utf8_path);
117 free(utf8_path);
118 return ok &&
119 (!recursive ||
120 ListRecursively(path, recursive, follow_links, seen, listing));
121 }
122
123
124 static bool HandleFile(wchar_t* file_name,
125 PathBuffer* path,
126 DirectoryListing* listing) {
127 if (!path->Add(file_name)) {
128 PostError(listing, path->data);
129 return false;
130 }
131 char* utf8_path = StringUtils::WideToUtf8(path->data);
132 bool ok = listing->HandleFile(utf8_path);
133 free(utf8_path);
134 return ok;
135 }
136
137
138 static bool HandleLink(wchar_t* link_name,
139 PathBuffer* path,
140 DirectoryListing* listing) {
141 if (!path->Add(link_name)) {
142 PostError(listing, path->data);
143 return false;
144 }
145 char* utf8_path = StringUtils::WideToUtf8(path->data);
146 bool ok = listing->HandleLink(utf8_path);
147 free(utf8_path);
148 return ok;
149 }
150
151
152 static bool HandleEntry(LPWIN32_FIND_DATAW find_file_data,
153 PathBuffer* path,
154 bool recursive,
155 bool follow_links,
156 LinkList* seen,
157 DirectoryListing* listing) {
158 DWORD attributes = find_file_data->dwFileAttributes;
159 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { 103 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
160 if (!follow_links) { 104 if (!listing->follow_links()) {
161 return HandleLink(find_file_data->cFileName, path, listing); 105 return kListLink;
162 } 106 }
163 int path_length = path->length;
164 if (!path->Add(find_file_data->cFileName)) return false;
165 HANDLE handle = CreateFileW( 107 HANDLE handle = CreateFileW(
166 path->data, 108 listing->path_buffer().AsStringW(),
167 0, 109 0,
168 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 110 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
169 NULL, 111 NULL,
170 OPEN_EXISTING, 112 OPEN_EXISTING,
171 FILE_FLAG_BACKUP_SEMANTICS, 113 FILE_FLAG_BACKUP_SEMANTICS,
172 NULL); 114 NULL);
173 path->Reset(path_length);
174 if (handle == INVALID_HANDLE_VALUE) { 115 if (handle == INVALID_HANDLE_VALUE) {
175 // Report as (broken) link. 116 // Report as (broken) link.
176 return HandleLink(find_file_data->cFileName, path, listing); 117 return kListLink;
177 } 118 }
178 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 119 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
179 // Check the seen link targets to see if we are in a file system loop. 120 // Check the seen link targets to see if we are in a file system loop.
180 LinkList current_link; 121 LinkList current_link;
181 BY_HANDLE_FILE_INFORMATION info; 122 BY_HANDLE_FILE_INFORMATION info;
182 // Get info 123 // Get info
183 if (!GetFileInformationByHandle(handle, &info)) { 124 if (!GetFileInformationByHandle(handle, &info)) {
184 DWORD error = GetLastError(); 125 DWORD error = GetLastError();
185 CloseHandle(handle); 126 CloseHandle(handle);
186 SetLastError(error); 127 SetLastError(error);
187 PostError(listing, path->data); 128 return kListError;
188 return false;
189 } 129 }
190 CloseHandle(handle); 130 CloseHandle(handle);
191 current_link.volume = info.dwVolumeSerialNumber; 131 current_link.volume = info.dwVolumeSerialNumber;
192 current_link.id_low = info.nFileIndexLow; 132 current_link.id_low = info.nFileIndexLow;
193 current_link.id_high = info.nFileIndexHigh; 133 current_link.id_high = info.nFileIndexHigh;
194 current_link.next = seen; 134 current_link.next = entry->link();
195 LinkList* previous = seen; 135 LinkList* previous = entry->link();
196 while (previous != NULL) { 136 while (previous != NULL) {
197 if (previous->volume == current_link.volume && 137 if (previous->volume == current_link.volume &&
198 previous->id_low == current_link.id_low && 138 previous->id_low == current_link.id_low &&
199 previous->id_high == current_link.id_high) { 139 previous->id_high == current_link.id_high) {
200 // Report the looping link as a link, rather than following it. 140 // Report the looping link as a link, rather than following it.
201 return HandleLink(find_file_data->cFileName, path, listing); 141 return kListLink;
202 } 142 }
203 previous = previous->next; 143 previous = previous->next;
204 } 144 }
205 // Recurse into the directory, adding current link to the seen links list. 145 // Recurse into the directory, adding current link to the seen links list.
206 return HandleDir(find_file_data->cFileName, 146 if (wcscmp(find_file_data.cFileName, L".") == 0 ||
207 path, 147 wcscmp(find_file_data.cFileName, L"..") == 0) {
208 recursive, 148 return entry->Next(listing);
209 follow_links, 149 }
210 &current_link, 150 entry->set_link(new LinkList(current_link));
211 listing); 151 return kListDirectory;
212 } 152 }
213 } 153 }
214 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 154 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
215 return HandleDir(find_file_data->cFileName, 155 if (wcscmp(find_file_data.cFileName, L".") == 0 ||
216 path, 156 wcscmp(find_file_data.cFileName, L"..") == 0) {
217 recursive, 157 return entry->Next(listing);
218 follow_links, 158 }
219 seen, 159 return kListDirectory;
220 listing);
221 } else { 160 } else {
222 return HandleFile(find_file_data->cFileName, path, listing); 161 return kListFile;
223 } 162 }
224 } 163 }
225 164
226 165 ListType DirectoryListingEntry::Next(DirectoryListing* listing) {
227 static bool ListRecursively(PathBuffer* path, 166 if (done_) {
228 bool recursive, 167 return kListDone;
229 bool follow_links,
230 LinkList* seen,
231 DirectoryListing* listing) {
232 if (!path->Add(L"\\*")) {
233 PostError(listing, path->data);
234 return false;
235 } 168 }
236 169
237 WIN32_FIND_DATAW find_file_data; 170 WIN32_FIND_DATAW find_file_data;
238 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data);
239 171
240 // Adjust the path by removing the '*' used for the search. 172 if (lister_ == 0) {
241 path->Reset(path->length - 1); 173 if (!listing->path_buffer().AddW(L"\\*")) {
174 done_ = true;
175 return kListError;
176 }
242 177
243 if (find_handle == INVALID_HANDLE_VALUE) { 178 path_length_ = listing->path_buffer().length() - 1;
244 PostError(listing, path->data); 179
245 return false; 180 HANDLE find_handle = FindFirstFileW(listing->path_buffer().AsStringW(),
181 &find_file_data);
182
183 if (find_handle == INVALID_HANDLE_VALUE) {
184 done_ = true;
185 return kListError;
186 }
187
188 lister_ = reinterpret_cast<intptr_t>(find_handle);
189
190 listing->path_buffer().Reset(path_length_);
191
192 return HandleFindFile(listing, this, find_file_data);
246 } 193 }
247 194
248 int path_length = path->length; 195 // Reset.
249 bool success = HandleEntry(&find_file_data, 196 listing->path_buffer().Reset(path_length_);
250 path, 197 ResetLink();
251 recursive,
252 follow_links,
253 seen,
254 listing);
255 198
256 while ((FindNextFileW(find_handle, &find_file_data) != 0)) { 199 if (FindNextFileW(reinterpret_cast<HANDLE>(lister_), &find_file_data) != 0) {
257 path->Reset(path_length); // HandleEntry adds the entry name to path. 200 return HandleFindFile(listing, this, find_file_data);
258 success = HandleEntry(&find_file_data,
259 path,
260 recursive,
261 follow_links,
262 seen,
263 listing) && success;
264 } 201 }
265 202
203 done_ = true;
204
266 if (GetLastError() != ERROR_NO_MORE_FILES) { 205 if (GetLastError() != ERROR_NO_MORE_FILES) {
267 success = false; 206 return kListError;
268 PostError(listing, path->data);
269 } 207 }
270 208
271 if (FindClose(find_handle) == 0) { 209 if (FindClose(reinterpret_cast<HANDLE>(lister_)) == 0) {
272 success = false; 210 return kListError;
273 PostError(listing, path->data);
274 } 211 }
275 212
276 return success; 213 return kListDone;
277 } 214 }
278 215
279 216
280 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) { 217 static bool DeleteFile(wchar_t* file_name, PathBuffer* path) {
281 if (!path->Add(file_name)) return false; 218 if (!path->AddW(file_name)) return false;
282 219
283 if (DeleteFileW(path->data) != 0) { 220 if (DeleteFileW(path->AsStringW()) != 0) {
284 return true; 221 return true;
285 } 222 }
286 223
287 // If we failed because the file is read-only, make it writeable and try 224 // If we failed because the file is read-only, make it writeable and try
288 // again. This mirrors Linux/Mac where a directory containing read-only files 225 // again. This mirrors Linux/Mac where a directory containing read-only files
289 // can still be recursively deleted. 226 // can still be recursively deleted.
290 if (GetLastError() == ERROR_ACCESS_DENIED) { 227 if (GetLastError() == ERROR_ACCESS_DENIED) {
291 DWORD attributes = GetFileAttributesW(path->data); 228 DWORD attributes = GetFileAttributesW(path->AsStringW());
292 if (attributes == INVALID_FILE_ATTRIBUTES) { 229 if (attributes == INVALID_FILE_ATTRIBUTES) {
293 return false; 230 return false;
294 } 231 }
295 232
296 if ((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) { 233 if ((attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY) {
297 attributes &= ~FILE_ATTRIBUTE_READONLY; 234 attributes &= ~FILE_ATTRIBUTE_READONLY;
298 235
299 if (SetFileAttributesW(path->data, attributes) == 0) { 236 if (SetFileAttributesW(path->AsStringW(), attributes) == 0) {
300 return false; 237 return false;
301 } 238 }
302 239
303 return DeleteFileW(path->data) != 0; 240 return DeleteFileW(path->AsStringW()) != 0;
304 } 241 }
305 } 242 }
306 243
307 return false; 244 return false;
308 } 245 }
309 246
310 247
311 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) { 248 static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) {
312 if (wcscmp(dir_name, L".") == 0) return true; 249 if (wcscmp(dir_name, L".") == 0) return true;
313 if (wcscmp(dir_name, L"..") == 0) return true; 250 if (wcscmp(dir_name, L"..") == 0) return true;
314 return path->Add(dir_name) && DeleteRecursively(path); 251 return path->AddW(dir_name) && DeleteRecursively(path);
315 } 252 }
316 253
317 254
318 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) { 255 static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) {
319 DWORD attributes = find_file_data->dwFileAttributes; 256 DWORD attributes = find_file_data->dwFileAttributes;
320 257
321 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 258 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
322 return DeleteDir(find_file_data->cFileName, path); 259 return DeleteDir(find_file_data->cFileName, path);
323 } else { 260 } else {
324 return DeleteFile(find_file_data->cFileName, path); 261 return DeleteFile(find_file_data->cFileName, path);
325 } 262 }
326 } 263 }
327 264
328 265
329 static bool DeleteRecursively(PathBuffer* path) { 266 static bool DeleteRecursively(PathBuffer* path) {
330 DWORD attributes = GetFileAttributesW(path->data); 267 DWORD attributes = GetFileAttributesW(path->AsStringW());
331 if ((attributes == INVALID_FILE_ATTRIBUTES)) { 268 if ((attributes == INVALID_FILE_ATTRIBUTES)) {
332 return false; 269 return false;
333 } 270 }
334 // If the directory is a junction, it's pointing to some other place in the 271 // If the directory is a junction, it's pointing to some other place in the
335 // filesystem that we do not want to recurse into. 272 // filesystem that we do not want to recurse into.
336 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { 273 if ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
337 // Just delete the junction itself. 274 // Just delete the junction itself.
338 return RemoveDirectoryW(path->data) != 0; 275 return RemoveDirectoryW(path->AsStringW()) != 0;
339 } 276 }
340 // If it's a file, remove it directly. 277 // If it's a file, remove it directly.
341 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { 278 if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
342 return DeleteFile(L"", path); 279 return DeleteFile(L"", path);
343 } 280 }
344 281
345 if (!path->Add(L"\\*")) return false; 282 if (!path->AddW(L"\\*")) return false;
346 283
347 WIN32_FIND_DATAW find_file_data; 284 WIN32_FIND_DATAW find_file_data;
348 HANDLE find_handle = FindFirstFileW(path->data, &find_file_data); 285 HANDLE find_handle = FindFirstFileW(path->AsStringW(), &find_file_data);
349 286
350 // Adjust the path by removing the '*' used for the search. 287 // Adjust the path by removing the '*' used for the search.
351 int path_length = path->length - 1; 288 int path_length = path->length() - 1;
352 path->Reset(path_length); 289 path->Reset(path_length);
353 290
354 if (find_handle == INVALID_HANDLE_VALUE) { 291 if (find_handle == INVALID_HANDLE_VALUE) {
355 return false; 292 return false;
356 } 293 }
357 294
358 bool success = DeleteEntry(&find_file_data, path); 295 bool success = DeleteEntry(&find_file_data, path);
359 296
360 while ((FindNextFileW(find_handle, &find_file_data) != 0) && success) { 297 while ((FindNextFileW(find_handle, &find_file_data) != 0) && success) {
361 path->Reset(path_length); // DeleteEntry adds to the path. 298 path->Reset(path_length); // DeleteEntry adds to the path.
362 success = success && DeleteEntry(&find_file_data, path); 299 success = success && DeleteEntry(&find_file_data, path);
363 } 300 }
364 301
365 path->Reset(path_length - 1); // Drop the "\" from the end of the path. 302 path->Reset(path_length - 1); // Drop the "\" from the end of the path.
366 if ((GetLastError() != ERROR_NO_MORE_FILES) || 303 if ((GetLastError() != ERROR_NO_MORE_FILES) ||
367 (FindClose(find_handle) == 0) || 304 (FindClose(find_handle) == 0) ||
368 (RemoveDirectoryW(path->data) == 0)) { 305 (RemoveDirectoryW(path->AsStringW()) == 0)) {
369 return false; 306 return false;
370 } 307 }
371 308
372 return success; 309 return success;
373 } 310 }
374 311
375 312
376 bool Directory::List(const char* dir_name,
377 bool recursive,
378 bool follow_links,
379 DirectoryListing* listing) {
380 const wchar_t* system_name = StringUtils::Utf8ToWide(dir_name);
381 PathBuffer path;
382 if (!path.Add(system_name)) {
383 PostError(listing, system_name);
384 return false;
385 }
386 free(const_cast<wchar_t*>(system_name));
387 return ListRecursively(&path, recursive, follow_links, NULL, listing);
388 }
389
390
391 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) { 313 static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) {
392 DWORD attributes = GetFileAttributesW(dir_name); 314 DWORD attributes = GetFileAttributesW(dir_name);
393 if (attributes == INVALID_FILE_ATTRIBUTES) { 315 if (attributes == INVALID_FILE_ATTRIBUTES) {
394 DWORD last_error = GetLastError(); 316 DWORD last_error = GetLastError();
395 if (last_error == ERROR_FILE_NOT_FOUND || 317 if (last_error == ERROR_FILE_NOT_FOUND ||
396 last_error == ERROR_PATH_NOT_FOUND) { 318 last_error == ERROR_PATH_NOT_FOUND) {
397 return Directory::DOES_NOT_EXIST; 319 return Directory::DOES_NOT_EXIST;
398 } else { 320 } else {
399 // We might not be able to get the file attributes for other 321 // We might not be able to get the file attributes for other
400 // reasons such as lack of permissions. In that case we do 322 // reasons such as lack of permissions. In that case we do
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 } 371 }
450 372
451 373
452 char* Directory::CreateTemp(const char* const_template) { 374 char* Directory::CreateTemp(const char* const_template) {
453 // Returns a new, unused directory name, modifying the contents of 375 // Returns a new, unused directory name, modifying the contents of
454 // dir_template. Creates this directory, with a default security 376 // dir_template. Creates this directory, with a default security
455 // descriptor inherited from its parent directory. 377 // descriptor inherited from its parent directory.
456 // The return value must be freed by the caller. 378 // The return value must be freed by the caller.
457 PathBuffer path; 379 PathBuffer path;
458 if (0 == strncmp(const_template, "", 1)) { 380 if (0 == strncmp(const_template, "", 1)) {
459 path.length = GetTempPathW(MAX_PATH, path.data); 381 path.Reset(GetTempPathW(MAX_PATH, path.AsStringW()));
460 if (path.length == 0) { 382 if (path.length() == 0) {
461 return NULL; 383 return NULL;
462 } 384 }
463 } else { 385 } else {
464 const wchar_t* system_template = StringUtils::Utf8ToWide(const_template); 386 const wchar_t* system_template = StringUtils::Utf8ToWide(const_template);
465 path.Add(system_template); 387 path.AddW(system_template);
466 free(const_cast<wchar_t*>(system_template)); 388 free(const_cast<wchar_t*>(system_template));
467 } 389 }
468 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44. 390 // Length of tempdir-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 44.
469 if (path.length > MAX_PATH - 44) { 391 if (path.length() > MAX_PATH - 44) {
470 return NULL; 392 return NULL;
471 } 393 }
472 if ((path.data)[path.length - 1] == L'\\') { 394 if ((path.AsStringW())[path.length() - 1] == L'\\') {
473 // No base name for the directory - use "tempdir". 395 // No base name for the directory - use "tempdir".
474 path.Add(L"tempdir"); 396 path.AddW(L"tempdir");
475 } 397 }
476 398
477 UUID uuid; 399 UUID uuid;
478 RPC_STATUS status = UuidCreateSequential(&uuid); 400 RPC_STATUS status = UuidCreateSequential(&uuid);
479 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { 401 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
480 return NULL; 402 return NULL;
481 } 403 }
482 RPC_WSTR uuid_string; 404 RPC_WSTR uuid_string;
483 status = UuidToStringW(&uuid, &uuid_string); 405 status = UuidToStringW(&uuid, &uuid_string);
484 if (status != RPC_S_OK) { 406 if (status != RPC_S_OK) {
485 return NULL; 407 return NULL;
486 } 408 }
487 409
488 path.Add(L"-"); 410 path.AddW(L"-");
489 // RPC_WSTR is an unsigned short*, so we cast to wchar_t*. 411 // RPC_WSTR is an unsigned short*, so we cast to wchar_t*.
490 path.Add(reinterpret_cast<wchar_t*>(uuid_string)); 412 path.AddW(reinterpret_cast<wchar_t*>(uuid_string));
491 RpcStringFreeW(&uuid_string); 413 RpcStringFreeW(&uuid_string);
492 if (!CreateDirectoryW(path.data, NULL)) { 414 if (!CreateDirectoryW(path.AsStringW(), NULL)) {
493 return NULL; 415 return NULL;
494 } 416 }
495 char* result = StringUtils::WideToUtf8(path.data); 417 char* result = path.AsString();
496 return result; 418 return result;
497 } 419 }
498 420
499 421
500 bool Directory::Delete(const char* dir_name, bool recursive) { 422 bool Directory::Delete(const char* dir_name, bool recursive) {
501 bool result = false; 423 bool result = false;
502 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name); 424 const wchar_t* system_dir_name = StringUtils::Utf8ToWide(dir_name);
503 if (!recursive) { 425 if (!recursive) {
504 if (File::GetType(dir_name, true) == File::kIsDirectory) { 426 if (File::GetType(dir_name, true) == File::kIsDirectory) {
505 result = (RemoveDirectoryW(system_dir_name) != 0); 427 result = (RemoveDirectoryW(system_dir_name) != 0);
506 } else { 428 } else {
507 SetLastError(ERROR_FILE_NOT_FOUND); 429 SetLastError(ERROR_FILE_NOT_FOUND);
508 } 430 }
509 } else { 431 } else {
510 PathBuffer path; 432 PathBuffer path;
511 if (path.Add(system_dir_name)) { 433 if (path.AddW(system_dir_name)) {
512 result = DeleteRecursively(&path); 434 result = DeleteRecursively(&path);
513 } 435 }
514 } 436 }
515 free(const_cast<wchar_t*>(system_dir_name)); 437 free(const_cast<wchar_t*>(system_dir_name));
516 return result; 438 return result;
517 } 439 }
518 440
519 441
520 bool Directory::Rename(const char* path, const char* new_path) { 442 bool Directory::Rename(const char* path, const char* new_path) {
521 const wchar_t* system_path = StringUtils::Utf8ToWide(path); 443 const wchar_t* system_path = StringUtils::Utf8ToWide(path);
(...skipping 13 matching lines...) Expand all
535 MoveFileExW(system_path, system_new_path, flags); 457 MoveFileExW(system_path, system_new_path, flags);
536 free(const_cast<wchar_t*>(system_path)); 458 free(const_cast<wchar_t*>(system_path));
537 free(const_cast<wchar_t*>(system_new_path)); 459 free(const_cast<wchar_t*>(system_new_path));
538 return (move_status != 0); 460 return (move_status != 0);
539 } 461 }
540 462
541 } // namespace bin 463 } // namespace bin
542 } // namespace dart 464 } // namespace dart
543 465
544 #endif // defined(TARGET_OS_WINDOWS) 466 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/directory_macos.cc ('k') | sdk/lib/io/directory_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698