win: work around wine bug in uv_fs_{unlink,rmdir} (#4833)
Wine has a bug (https://bugs.winehq.org/show_bug.cgi?id=50771) where FILE_WRITE_ATTRIBUTES will cause CreateFile to fail if the file is read-only. The recommended work around is to instead use FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE, which we do as of #4318. However, we were still using FILE_WRITE_ATTRIBUTES to create the initial handle, despite this no longer being required, except for the fallback path. As a result, libuv is still broken under wine, even on master. Fix this by removing the `FILE_WRITE_ATTRIBUTES` from the initial CreateFile call and re-opening the handle in the fallback path if necessary. Note that we still have the same issue in fs_chmod and I've requested some guidance from wine on what to do about this, but this should at least fix unlink. Refs: https://github.com/JuliaLang/julia/issues/58980
This commit is contained in:
parent
7484ab251f
commit
6cf854c11b
23
src/win/fs.c
23
src/win/fs.c
@ -1112,7 +1112,7 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
|||||||
DWORD error;
|
DWORD error;
|
||||||
|
|
||||||
handle = CreateFileW(pathw,
|
handle = CreateFileW(pathw,
|
||||||
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
|
FILE_READ_ATTRIBUTES | DELETE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
@ -1187,14 +1187,33 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
|||||||
/* Remove read-only attribute */
|
/* Remove read-only attribute */
|
||||||
FILE_BASIC_INFORMATION basic = { 0 };
|
FILE_BASIC_INFORMATION basic = { 0 };
|
||||||
|
|
||||||
|
/* We opened the handle above without FILE_WRITE_ATTRIBUTES access, which
|
||||||
|
* is not required in the happy path. On windows, it would probably
|
||||||
|
* be ok to ask for them anyway, but Wine has a bug that causes such calls
|
||||||
|
* to fail (https://bugs.winehq.org/show_bug.cgi?id=50771). To work around
|
||||||
|
* this bug, we re-open the handle here */
|
||||||
|
HANDLE write_attributes_handle;
|
||||||
|
|
||||||
basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
|
basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
|
||||||
FILE_ATTRIBUTE_ARCHIVE;
|
FILE_ATTRIBUTE_ARCHIVE;
|
||||||
|
|
||||||
status = pNtSetInformationFile(handle,
|
write_attributes_handle = ReOpenFile(handle, FILE_WRITE_ATTRIBUTES,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE |
|
||||||
|
FILE_SHARE_DELETE,
|
||||||
|
FILE_FLAG_OPEN_REPARSE_POINT |
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS);
|
||||||
|
if (write_attributes_handle == INVALID_HANDLE_VALUE) {
|
||||||
|
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||||
|
CloseHandle(handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = pNtSetInformationFile(write_attributes_handle,
|
||||||
&iosb,
|
&iosb,
|
||||||
&basic,
|
&basic,
|
||||||
sizeof basic,
|
sizeof basic,
|
||||||
FileBasicInformation);
|
FileBasicInformation);
|
||||||
|
CloseHandle(write_attributes_handle);
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
|
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user