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

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

Issue 12691002: dart:io | Add Link class, as sibling to File and Directory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add fixes for Windows. Created 7 years, 9 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
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/file.h" 8 #include "bin/file.h"
9 9
10 #include <fcntl.h> // NOLINT 10 #include <fcntl.h> // NOLINT
11 #include <io.h> // NOLINT 11 #include <io.h> // NOLINT
12 #include <stdio.h> // NOLINT 12 #include <stdio.h> // NOLINT
13 #include <string.h> // NOLINT 13 #include <string.h> // NOLINT
14 #include <sys/stat.h> // NOLINT 14 #include <sys/stat.h> // NOLINT
15 #include <WinIoCtl.h> // NOLINT
15 16
16 #include "bin/builtin.h" 17 #include "bin/builtin.h"
17 #include "bin/log.h" 18 #include "bin/log.h"
18 19
19 class FileHandle { 20 class FileHandle {
20 public: 21 public:
21 explicit FileHandle(int fd) : fd_(fd) { } 22 explicit FileHandle(int fd) : fd_(fd) { }
22 ~FileHandle() { } 23 ~FileHandle() { }
23 int fd() const { return fd_; } 24 int fd() const { return fd_; }
24 void set_fd(int fd) { fd_ = fd; } 25 void set_fd(int fd) { fd_ = fd; }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 148 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
148 int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666); 149 int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666);
149 free(const_cast<wchar_t*>(system_name)); 150 free(const_cast<wchar_t*>(system_name));
150 if (fd < 0) { 151 if (fd < 0) {
151 return false; 152 return false;
152 } 153 }
153 return (close(fd) == 0); 154 return (close(fd) == 0);
154 } 155 }
155 156
156 157
158 // This structure is needed for creating and reading Junctions.
159 typedef struct _REPARSE_DATA_BUFFER {
160 ULONG ReparseTag;
161 USHORT ReparseDataLength;
162 USHORT Reserved;
163
164 union {
165 struct {
166 USHORT SubstituteNameOffset;
167 USHORT SubstituteNameLength;
168 USHORT PrintNameOffset;
169 USHORT PrintNameLength;
170 WCHAR PathBuffer[1];
171 } SymbolicLinkReparseBuffer;
172
173 struct {
174 USHORT SubstituteNameOffset;
175 USHORT SubstituteNameLength;
176 USHORT PrintNameOffset;
177 USHORT PrintNameLength;
178 WCHAR PathBuffer[1];
179 } MountPointReparseBuffer;
180
181 struct {
182 UCHAR DataBuffer[1];
183 } GenericReparseBuffer;
184 };
185 } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
186
187
188 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT;
189 static const int kMountPointHeaderSize = 4 * sizeof USHORT;
190
191
192 bool File::CreateLink(const char* utf8_name, const char* utf8_target) {
193 const wchar_t* name = StringUtils::Utf8ToWide(utf8_name);
194 int create_status = CreateDirectoryW(name, NULL);
195 // If the directory already existed, treat it as a success.
196 if (create_status == 0 &&
197 (GetLastError() != ERROR_ALREADY_EXISTS ||
198 (GetFileAttributesW(name) & FILE_ATTRIBUTE_DIRECTORY) != 0)) {
199 free(const_cast<wchar_t*>(name));
200 return false;
201 }
202
203 HANDLE dir_handle = CreateFileW(
204 name,
205 GENERIC_READ | GENERIC_WRITE,
206 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
207 NULL,
208 OPEN_EXISTING,
209 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
210 NULL);
211 free(const_cast<wchar_t*>(name));
212 if (dir_handle == INVALID_HANDLE_VALUE) {
213 return false;
214 }
215
216 const wchar_t* target = StringUtils::Utf8ToWide(utf8_target);
217 int target_len = wcslen(target);
218 if (target_len > MAX_PATH - 1) {
219 free(const_cast<wchar_t*>(target));
220 return false;
221 }
222
223 int reparse_data_buffer_size =
224 sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
225 REPARSE_DATA_BUFFER* reparse_data_buffer =
226 static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));
227 reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
228 wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, target);
229 wcscpy(
230 reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1,
231 target);
232 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
233 reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength =
234 target_len * sizeof WCHAR;
235 reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset =
236 (target_len + 1) * sizeof WCHAR;
237 reparse_data_buffer->MountPointReparseBuffer.PrintNameLength =
238 target_len * sizeof WCHAR;
239 reparse_data_buffer->ReparseDataLength =
240 (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize;
241 DWORD dummy_received_bytes;
242 int result = DeviceIoControl(
243 dir_handle,
244 FSCTL_SET_REPARSE_POINT,
245 reparse_data_buffer,
246 reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize,
247 NULL,
248 0,
249 &dummy_received_bytes,
250 NULL);
251 if (CloseHandle(dir_handle) == 0) return false;
252 free(const_cast<wchar_t*>(target));
253 free(reparse_data_buffer);
254 return (result != 0);
255 }
256
257
157 bool File::Delete(const char* name) { 258 bool File::Delete(const char* name) {
158 const wchar_t* system_name = StringUtils::Utf8ToWide(name); 259 const wchar_t* system_name = StringUtils::Utf8ToWide(name);
159 int status = _wremove(system_name); 260 int status = _wremove(system_name);
160 free(const_cast<wchar_t*>(system_name)); 261 free(const_cast<wchar_t*>(system_name));
161 if (status == -1) { 262 if (status == -1) {
162 return false; 263 return false;
163 } 264 }
164 return true; 265 return true;
165 } 266 }
166 267
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return File::kDoesNotExist; 390 return File::kDoesNotExist;
290 } 391 }
291 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { 392 } else if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
292 return File::kIsDirectory; 393 return File::kIsDirectory;
293 } else { 394 } else {
294 return File::kIsFile; 395 return File::kIsFile;
295 } 396 }
296 } 397 }
297 398
298 #endif // defined(TARGET_OS_WINDOWS) 399 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698