[PATCH v4 0/3] MR1231: Improve delete-on-close and delete disposition for files.
This series improves Wine's support for delete-on-close flag and delete disposition information on files: - adapts tests for Windows 10 - extend and fix some tests - implement some missing features in ntdll & server -- v4: ntdll: Extend file tests about delete-on-close and disposition. ntdll: Fix share mode for some delete-on-close/delete disposition tests. ntdll: Adapt file tests on delete-on-close / delete disposition to Windows 10. https://gitlab.winehq.org/wine/wine/-/merge_requests/1231
From: Eric Pouech <eric.pouech(a)gmail.com> Fix a couple of failures on Windows 10: - it seems that attributes are no longer accessible by name after shared deletion - really looks like that shared deletion is now marked at object's name hierarchy level (see error codes have changed too) So, - replace tests based on GetFileAttribute with testing presence of pending deletion flag (FileStandardInformation) - add Win10 error codes (and mark the Win7/8 ones as broken) Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com> --- dlls/ntdll/tests/file.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 98d9e6b3b0a..7b6cf704971 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -2957,6 +2957,7 @@ static void test_file_disposition_information(void) NTSTATUS res; IO_STATUS_BLOCK io; FILE_DISPOSITION_INFORMATION fdi; + FILE_STANDARD_INFORMATION fsi; BOOL fileDeleted; DWORD fdi2, size; void *view; @@ -3141,18 +3142,23 @@ static void test_file_disposition_information(void) GetTempFileNameA( tmp_path, "dis", 0, buffer ); handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0); ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); fileDeleted = DeleteFileA( buffer ); ok( fileDeleted, "File should have been deleted\n" ); - fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File shouldn't have been deleted\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + todo_wine + ok(fsi.DeletePending, "Handle should be marked for deletion\n"); res = nt_get_file_attrs( buffer, &fdi2 ); todo_wine - ok( res == STATUS_DELETE_PENDING, "got %#lx\n", res ); + ok( res == STATUS_OBJECT_NAME_NOT_FOUND || broken(res == STATUS_DELETE_PENDING), "got %#lx\n", res ); /* can't open the deleted file */ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" ); todo_wine - ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError()); + ok( GetLastError() == ERROR_FILE_NOT_FOUND || broken(GetLastError() == ERROR_ACCESS_DENIED), "got %lu\n", GetLastError()); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( fileDeleted, "File should have been deleted\n" ); @@ -3190,19 +3196,24 @@ static void test_file_disposition_information(void) ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" ); handle = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); fileDeleted = RemoveDirectoryA( buffer ); ok( fileDeleted, "Directory should have been deleted\n" ); - fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "Directory shouldn't have been deleted\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + todo_wine + ok(fsi.DeletePending, "Handle should be marked for deletion\n"); res = nt_get_file_attrs( buffer, &fdi2 ); todo_wine - ok( res == STATUS_DELETE_PENDING, "got %#lx\n", res ); + ok( res == STATUS_OBJECT_NAME_NOT_FOUND || broken(res == STATUS_DELETE_PENDING), "got %#lx\n", res ); /* can't open the deleted directory */ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); todo_wine ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" ); todo_wine - ok(GetLastError() == ERROR_ACCESS_DENIED, "got %lu\n", GetLastError()); + ok(GetLastError() == ERROR_FILE_NOT_FOUND || broken(GetLastError() == ERROR_ACCESS_DENIED), "got %lu\n", GetLastError()); if (handle2 != INVALID_HANDLE_VALUE) CloseHandle( handle2 ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1231
From: Eric Pouech <eric.pouech(a)gmail.com> Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com> --- dlls/ntdll/tests/file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 7b6cf704971..2ec61f72aa9 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3155,10 +3155,13 @@ static void test_file_disposition_information(void) todo_wine ok( res == STATUS_OBJECT_NAME_NOT_FOUND || broken(res == STATUS_DELETE_PENDING), "got %#lx\n", res ); /* can't open the deleted file */ - handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0); + handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + todo_wine ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" ); todo_wine ok( GetLastError() == ERROR_FILE_NOT_FOUND || broken(GetLastError() == ERROR_ACCESS_DENIED), "got %lu\n", GetLastError()); + if (handle2 != INVALID_HANDLE_VALUE) + CloseHandle( handle2); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( fileDeleted, "File should have been deleted\n" ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1231
From: Eric Pouech <eric.pouech(a)gmail.com> Signed-off-by: Eric Pouech <eric.pouech(a)gmail.com> --- dlls/ntdll/tests/file.c | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 2ec61f72aa9..6186afdfb63 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -3000,6 +3000,10 @@ static void test_file_disposition_information(void) fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + todo_wine + ok(fsi.DeletePending, "Handle should be marked for deletion\n"); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( fileDeleted, "File should have been deleted\n" ); @@ -3408,6 +3412,68 @@ static void test_file_disposition_information(void) res = DeleteFileA( buffer ); ok( !res, "expected failure\n" ); ok( GetLastError() == ERROR_FILE_NOT_FOUND, "got error %lu\n", GetLastError() ); + + /* pending delete flag is shared across handles */ + GetTempFileNameA( tmp_path, "dis", 0, buffer ); + handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0); + ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok( handle2 != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + fdi.DoDeleteFile = TRUE; + res = NtSetInformationFile(handle, &io, &fdi, sizeof(fdi), FileDispositionInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + todo_wine + ok(fsi.DeletePending, "Handle should be marked for deletion\n"); + fdi.DoDeleteFile = FALSE; + res = NtSetInformationFile(handle2, &io, &fdi, sizeof(fdi), FileDispositionInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + CloseHandle(handle); + CloseHandle(handle2); + res = GetFileAttributesA( buffer ); + todo_wine + ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" ); + + /* pending delete flag is shared across handles (even after closing) */ + GetTempFileNameA( tmp_path, "dis", 0, buffer ); + handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0); + ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok( handle2 != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + fdi.DoDeleteFile = TRUE; + res = NtSetInformationFile(handle, &io, &fdi, sizeof(fdi), FileDispositionInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + res = NtQueryInformationFile(handle2, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + todo_wine + ok(fsi.DeletePending, "Handle should be marked for deletion\n"); + fdi.DoDeleteFile = FALSE; + res = NtSetInformationFile(handle2, &io, &fdi, sizeof(fdi), FileDispositionInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + CloseHandle(handle2); + res = NtQueryInformationFile(handle, &io, &fsi, sizeof(fsi), FileStandardInformation); + ok(res == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", res); + ok(!fsi.DeletePending, "Handle shouldn't be marked for deletion\n"); + CloseHandle(handle); + res = GetFileAttributesA( buffer ); + todo_wine + ok( res != INVALID_FILE_ATTRIBUTES, "expected file to exist\n" ); } static void test_file_name_information(void) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/1231
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126305 Your paranoid android. === w10pro64_ja (testbot log) === WineRunTask.pl:error: The previous 1 run(s) terminated abnormally
v4: only keep the tests patches - removed the ntdll&server bits (as no feedback so far) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/1231#note_16182
participants (3)
-
Eric Pouech -
eric pouech (@epo) -
Marvin