|
|
@ -490,38 +490,69 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) { |
|
|
|
|
|
|
|
|
|
|
|
void fs__stat(uv_fs_t* req, const wchar_t* path) { |
|
|
|
HANDLE file; |
|
|
|
WIN32_FIND_DATAW ent; |
|
|
|
int result; |
|
|
|
unsigned short mode; |
|
|
|
|
|
|
|
fs__open(req, path, _O_RDONLY, 0); |
|
|
|
if (req->result == -1) { |
|
|
|
req->ptr = NULL; |
|
|
|
|
|
|
|
file = FindFirstFileExW(path, FindExInfoStandard, &ent, |
|
|
|
FindExSearchNameMatch, NULL, 0); |
|
|
|
|
|
|
|
if (file == INVALID_HANDLE_VALUE) { |
|
|
|
SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
result = _fstati64(req->result, &req->stat); |
|
|
|
if (result == -1) { |
|
|
|
req->ptr = NULL; |
|
|
|
} else { |
|
|
|
FindClose(file); |
|
|
|
|
|
|
|
/*
|
|
|
|
* VC CRT doesn't properly set S_IFDIR in _fstati64, |
|
|
|
* so we set it here if path is a directory. |
|
|
|
*/ |
|
|
|
if (GetFileAttributesW(path) & FILE_ATTRIBUTE_DIRECTORY) { |
|
|
|
mode = req->stat.st_mode; |
|
|
|
mode &= ~_S_IFMT; |
|
|
|
mode |= _S_IFDIR; |
|
|
|
|
|
|
|
req->stat.st_mode = mode; |
|
|
|
assert((req->stat.st_mode & _S_IFMT) == _S_IFDIR); |
|
|
|
if (ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && |
|
|
|
ent.dwReserved0 == IO_REPARSE_TAG_SYMLINK) { |
|
|
|
fs__open(req, path, _O_RDONLY, 0); |
|
|
|
if (req->result != -1) { |
|
|
|
result = _fstati64(req->result, &req->stat); |
|
|
|
_close(req->result); |
|
|
|
|
|
|
|
if (result != -1) { |
|
|
|
req->ptr = &req->stat; |
|
|
|
} |
|
|
|
|
|
|
|
SET_REQ_RESULT(req, result); |
|
|
|
} |
|
|
|
|
|
|
|
req->ptr = &req->stat; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
_close(req->result); |
|
|
|
req->stat.st_ino = 0; |
|
|
|
req->stat.st_uid = 0; |
|
|
|
req->stat.st_gid = 0; |
|
|
|
req->stat.st_mode = 0; |
|
|
|
req->stat.st_rdev = 0; |
|
|
|
req->stat.st_dev = 0; |
|
|
|
req->stat.st_nlink = 1; |
|
|
|
|
|
|
|
SET_REQ_RESULT(req, result); |
|
|
|
if (ent.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) { |
|
|
|
req->stat.st_mode |= (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6)); |
|
|
|
} else { |
|
|
|
req->stat.st_mode |= ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3) + |
|
|
|
((_S_IREAD|_S_IWRITE) >> 6)); |
|
|
|
} |
|
|
|
|
|
|
|
if (ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { |
|
|
|
req->stat.st_mode |= _S_IFDIR; |
|
|
|
} else { |
|
|
|
req->stat.st_mode |= _S_IFREG; |
|
|
|
} |
|
|
|
|
|
|
|
uv_filetime_to_time_t(&ent.ftLastWriteTime, &(req->stat.st_mtime)); |
|
|
|
uv_filetime_to_time_t(&ent.ftLastAccessTime, &(req->stat.st_atime)); |
|
|
|
uv_filetime_to_time_t(&ent.ftCreationTime, &(req->stat.st_ctime)); |
|
|
|
|
|
|
|
req->stat.st_size = ((int64_t)ent.nFileSizeHigh << 32) + |
|
|
|
(int64_t)ent.nFileSizeLow; |
|
|
|
|
|
|
|
req->ptr = &req->stat; |
|
|
|
req->result = 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1543,3 +1574,4 @@ void uv_fs_req_cleanup(uv_fs_t* req) { |
|
|
|
|
|
|
|
req->flags |= UV_FS_CLEANEDUP; |
|
|
|
} |
|
|
|
|
|
|
|