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;
|
||||
|
||||
handle = CreateFileW(pathw,
|
||||
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
|
||||
FILE_READ_ATTRIBUTES | DELETE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
@ -1187,14 +1187,33 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
|
||||
/* Remove read-only attribute */
|
||||
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) |
|
||||
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,
|
||||
&basic,
|
||||
sizeof basic,
|
||||
FileBasicInformation);
|
||||
CloseHandle(write_attributes_handle);
|
||||
if (!NT_SUCCESS(status)) {
|
||||
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
|
||||
CloseHandle(handle);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user