Merge 8481eb2772 into 44125af62a
This commit is contained in:
commit
25026f2bf6
73
src/win/fs.c
73
src/win/fs.c
@ -191,8 +191,6 @@ static int fs__readlink_handle(HANDLE handle,
|
||||
WCHAR* w_target;
|
||||
DWORD w_target_len;
|
||||
DWORD bytes;
|
||||
size_t i;
|
||||
size_t len;
|
||||
|
||||
if (!DeviceIoControl(handle,
|
||||
FSCTL_GET_REPARSE_POINT,
|
||||
@ -303,38 +301,6 @@ static int fs__readlink_handle(HANDLE handle,
|
||||
w_target += 4;
|
||||
w_target_len -= 4;
|
||||
|
||||
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) {
|
||||
/* String #3 in the list has the target filename. */
|
||||
if (reparse_data->AppExecLinkReparseBuffer.StringCount < 3) {
|
||||
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
w_target = reparse_data->AppExecLinkReparseBuffer.StringList;
|
||||
/* The StringList buffer contains a list of strings separated by "\0", */
|
||||
/* with "\0\0" terminating the list. Move to the 3rd string in the list: */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
len = wcslen(w_target);
|
||||
if (len == 0) {
|
||||
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
w_target += len + 1;
|
||||
}
|
||||
w_target_len = wcslen(w_target);
|
||||
if (w_target_len == 0) {
|
||||
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
/* Make sure it is an absolute path. */
|
||||
if (!(w_target_len >= 3 &&
|
||||
((w_target[0] >= L'a' && w_target[0] <= L'z') ||
|
||||
(w_target[0] >= L'A' && w_target[0] <= L'Z')) &&
|
||||
w_target[1] == L':' &&
|
||||
w_target[2] == L'\\')) {
|
||||
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Reparse tag does not indicate a symlink. */
|
||||
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
|
||||
@ -345,6 +311,33 @@ static int fs__readlink_handle(HANDLE handle,
|
||||
return uv_utf16_to_wtf8(w_target, w_target_len, target_ptr, target_len_ptr);
|
||||
}
|
||||
|
||||
/* CreateFileW wrapper. Treats reparse points which windows can't resolve as regular files */
|
||||
static HANDLE fs__create_file(WCHAR* path, DWORD desired_access, int do_lstat) {
|
||||
if (!do_lstat) {
|
||||
HANDLE handle;
|
||||
handle = CreateFileW(path,
|
||||
desired_access,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||
FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
NULL);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE
|
||||
|| GetLastError() != ERROR_CANT_ACCESS_FILE)
|
||||
return handle;
|
||||
}
|
||||
|
||||
return CreateFileW(path,
|
||||
desired_access,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static int fs__capture_path(uv_fs_t* req,
|
||||
const char* path,
|
||||
@ -2216,17 +2209,7 @@ static DWORD fs__stat_impl_from_path(WCHAR* path,
|
||||
}
|
||||
|
||||
/* If the new API does not exist, use the old API. */
|
||||
flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (do_lstat)
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
|
||||
handle = CreateFileW(path,
|
||||
FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
flags,
|
||||
NULL);
|
||||
handle = fs__create_file(path, FILE_READ_ATTRIBUTES, do_lstat);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
ret = GetLastError();
|
||||
|
||||
@ -4177,10 +4177,6 @@ typedef struct _REPARSE_DATA_BUFFER {
|
||||
struct {
|
||||
UCHAR DataBuffer[1];
|
||||
} GenericReparseBuffer;
|
||||
struct {
|
||||
ULONG StringCount;
|
||||
WCHAR StringList[1];
|
||||
} AppExecLinkReparseBuffer;
|
||||
};
|
||||
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
|
||||
|
||||
@ -4589,9 +4585,6 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||
#ifndef IO_REPARSE_TAG_LX_SYMLINK
|
||||
# define IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL)
|
||||
#endif
|
||||
#ifndef IO_REPARSE_TAG_APPEXECLINK
|
||||
# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
|
||||
#endif
|
||||
|
||||
typedef VOID (NTAPI *PIO_APC_ROUTINE)
|
||||
(PVOID ApcContext,
|
||||
|
||||
@ -2790,7 +2790,7 @@ TEST_FS_IMPL(fs_readlink_lx_symlink) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_FS_IMPL(fs_lstat_windows_store_apps) {
|
||||
TEST_FS_IMPL(fs_stat_windows_store_apps) {
|
||||
uv_loop_t* loop;
|
||||
char localappdata[MAX_PATH];
|
||||
char windowsapps_path[MAX_PATH];
|
||||
@ -2798,6 +2798,7 @@ TEST_FS_IMPL(fs_lstat_windows_store_apps) {
|
||||
size_t len;
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
uv_fs_t lstat_req;
|
||||
uv_fs_t stat_req;
|
||||
uv_dirent_t dirent;
|
||||
|
||||
@ -2835,7 +2836,16 @@ TEST_FS_IMPL(fs_lstat_windows_store_apps) {
|
||||
dirent.name) < 0) {
|
||||
continue;
|
||||
}
|
||||
ASSERT_OK(uv_fs_lstat(loop, &stat_req, file_path, NULL));
|
||||
ASSERT_OK(uv_fs_lstat(loop, &lstat_req, file_path, NULL));
|
||||
ASSERT_OK(uv_fs_stat(loop, &stat_req, file_path, NULL));
|
||||
|
||||
/* Appexeclinks should be treated as regular files,
|
||||
* so stat should return the same info as lstat
|
||||
* see https://github.com/libuv/libuv/pull/4936#issuecomment-3703811492
|
||||
* */
|
||||
ASSERT_OK(strcmp(stat_req.path, lstat_req.path));
|
||||
ASSERT_OK(memcmp(&stat_req.statbuf, &lstat_req.statbuf,
|
||||
sizeof(stat_req.statbuf)));
|
||||
}
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
|
||||
@ -392,7 +392,7 @@ TEST_FS_DECLARE (fs_symlink_dir)
|
||||
TEST_FS_DECLARE (fs_symlink_junction)
|
||||
TEST_FS_DECLARE (fs_non_symlink_reparse_point)
|
||||
TEST_FS_DECLARE (fs_readlink_lx_symlink)
|
||||
TEST_FS_DECLARE (fs_lstat_windows_store_apps)
|
||||
TEST_FS_DECLARE (fs_stat_windows_store_apps)
|
||||
TEST_FS_DECLARE (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
@ -1132,7 +1132,7 @@ TASK_LIST_START
|
||||
TEST_FS_ENTRY (fs_symlink_junction)
|
||||
TEST_FS_ENTRY (fs_non_symlink_reparse_point)
|
||||
TEST_FS_ENTRY (fs_readlink_lx_symlink)
|
||||
TEST_FS_ENTRY (fs_lstat_windows_store_apps)
|
||||
TEST_FS_ENTRY (fs_stat_windows_store_apps)
|
||||
TEST_FS_ENTRY (fs_open_flags)
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(USING_UV_SHARED)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user