From: Joel Holdsworth joel@airwebreathe.org.uk
Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- include/winternl.h | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/include/winternl.h b/include/winternl.h index dfdb8f23ec6..95326edcf9f 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1255,6 +1255,7 @@ typedef enum _FILE_INFORMATION_CLASS { FileReplaceCompletionInformation, FileHardLinkFullIdInformation, FileIdExtdBothDirectoryInformation, + FileDispositionInformationEx, FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
@@ -1424,6 +1425,17 @@ typedef struct _FILE_DISPOSITION_INFORMATION { BOOLEAN DoDeleteFile; } FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
+typedef struct _FILE_DISPOSITION_INFORMATION_EX { + ULONG Flags; +} FILE_DISPOSITION_INFORMATION_EX, *PFILE_DISPOSITION_INFORMATION_EX; + +#define FILE_DISPOSITION_DO_NOT_DELETE 0x00000000 +#define FILE_DISPOSITION_DELETE 0x00000001 +#define FILE_DISPOSITION_POSIX_SEMANTICS 0x00000002 +#define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK 0x00000004 +#define FILE_DISPOSITION_ON_CLOSE 0x00000008 +#define FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE 0x00000010 + typedef struct _FILE_POSITION_INFORMATION { LARGE_INTEGER CurrentByteOffset; } FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
From: Joel Holdsworth joel@airwebreathe.org.uk
Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- server/fd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/server/fd.c b/server/fd.c index eaebe044f37..b8a6bea3eae 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2524,9 +2524,7 @@ static void set_fd_disposition( struct fd *fd, int unlink ) } }
- fd->closed->unlink = unlink ? 1 : 0; - if (fd->options & FILE_DELETE_ON_CLOSE) - fd->closed->unlink = -1; + fd->closed->unlink = (unlink || (fd->options & FILE_DELETE_ON_CLOSE)) ? 1 : 0; }
/* set new name for the fd */
From: Joel Holdsworth joel@airwebreathe.org.uk
Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- dlls/ntdll/unix/file.c | 29 +++++++++++++++++++++++++++-- include/wine/server_protocol.h | 14 +++++++------- server/fd.c | 9 +++++---- server/protocol.def | 4 ++-- server/request.h | 10 +++++----- server/trace.c | 8 ++++---- 6 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index eca75b2d4fb..d10c4b2bb7e 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -4743,10 +4743,35 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, { FILE_DISPOSITION_INFORMATION *info = ptr;
- SERVER_START_REQ( set_fd_disp_info ) + SERVER_START_REQ( set_fd_disp_info_ex ) { req->handle = wine_server_obj_handle( handle ); - req->unlink = info->DoDeleteFile; + req->flags = info->DoDeleteFile ? FILE_DISPOSITION_DELETE : FILE_DISPOSITION_DO_NOT_DELETE; + status = wine_server_call( req ); + } + SERVER_END_REQ; + } + else status = STATUS_INVALID_PARAMETER_3; + break; + + case FileDispositionInformationEx: + if (len >= sizeof(FILE_DISPOSITION_INFORMATION_EX)) + { + FILE_DISPOSITION_INFORMATION_EX *info = ptr; + + if (info->Flags & FILE_DISPOSITION_POSIX_SEMANTICS) + FIXME( "FILE_DISPOSITION_POSIX_SEMANTICS not supported\n" ); + if (info->Flags & FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK) + FIXME( "FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK not supported\n" ); + if (info->Flags & FILE_DISPOSITION_ON_CLOSE) + FIXME( "FILE_DISPOSITION_ON_CLOSE not supported\n" ); + if (info->Flags & FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE) + FIXME( "FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE not supported\n" ); + + SERVER_START_REQ( set_fd_disp_info_ex ) + { + req->handle = wine_server_obj_handle( handle ); + req->flags = info->Flags; status = wine_server_call( req ); } SERVER_END_REQ; diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index f61918271ff..e2a55203aef 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5171,14 +5171,14 @@ struct set_fd_completion_mode_reply
-struct set_fd_disp_info_request +struct set_fd_disp_info_ex_request { struct request_header __header; obj_handle_t handle; - int unlink; + unsigned int flags; char __pad_20[4]; }; -struct set_fd_disp_info_reply +struct set_fd_disp_info_ex_reply { struct reply_header __header; }; @@ -5764,7 +5764,7 @@ enum request REQ_set_completion_info, REQ_add_fd_completion, REQ_set_fd_completion_mode, - REQ_set_fd_disp_info, + REQ_set_fd_disp_info_ex, REQ_set_fd_name_info, REQ_set_fd_eof_info, REQ_get_window_layered_info, @@ -6049,7 +6049,7 @@ union generic_request struct set_completion_info_request set_completion_info_request; struct add_fd_completion_request add_fd_completion_request; struct set_fd_completion_mode_request set_fd_completion_mode_request; - struct set_fd_disp_info_request set_fd_disp_info_request; + struct set_fd_disp_info_ex_request set_fd_disp_info_ex_request; struct set_fd_name_info_request set_fd_name_info_request; struct set_fd_eof_info_request set_fd_eof_info_request; struct get_window_layered_info_request get_window_layered_info_request; @@ -6332,7 +6332,7 @@ union generic_reply struct set_completion_info_reply set_completion_info_reply; struct add_fd_completion_reply add_fd_completion_reply; struct set_fd_completion_mode_reply set_fd_completion_mode_reply; - struct set_fd_disp_info_reply set_fd_disp_info_reply; + struct set_fd_disp_info_ex_reply set_fd_disp_info_ex_reply; struct set_fd_name_info_reply set_fd_name_info_reply; struct set_fd_eof_info_reply set_fd_eof_info_reply; struct get_window_layered_info_reply get_window_layered_info_reply; @@ -6358,7 +6358,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 762 +#define SERVER_PROTOCOL_VERSION 763
/* ### protocol_version end ### */
diff --git a/server/fd.c b/server/fd.c index b8a6bea3eae..5208506e30f 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2463,8 +2463,9 @@ static int is_dir_empty( int fd ) }
/* set disposition for the fd */ -static void set_fd_disposition( struct fd *fd, int unlink ) +static void set_fd_disposition_ex( struct fd *fd, unsigned int flags ) { + const unsigned int unlink = flags & FILE_DISPOSITION_DELETE; struct stat st;
if (!fd->inode) @@ -2947,13 +2948,13 @@ DECL_HANDLER(set_fd_completion_mode) } }
-/* set fd disposition information */ -DECL_HANDLER(set_fd_disp_info) +/* set fd disposition extended information */ +DECL_HANDLER(set_fd_disp_info_ex) { struct fd *fd = get_handle_fd_obj( current->process, req->handle, DELETE ); if (fd) { - set_fd_disposition( fd, req->unlink ); + set_fd_disposition_ex( fd, req->flags ); release_object( fd ); } } diff --git a/server/protocol.def b/server/protocol.def index c857f72ce68..2d9866f5598 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3598,9 +3598,9 @@ struct handle_info
/* set fd disposition information */ -@REQ(set_fd_disp_info) +@REQ(set_fd_disp_info_ex) obj_handle_t handle; /* handle to a file or directory */ - int unlink; /* whether to unlink file on close */ + unsigned int flags; /* what actions should be taken when deleting a file */ @END
diff --git a/server/request.h b/server/request.h index b8d4f6a6d5e..2fd5679515a 100644 --- a/server/request.h +++ b/server/request.h @@ -375,7 +375,7 @@ DECL_HANDLER(query_completion); DECL_HANDLER(set_completion_info); DECL_HANDLER(add_fd_completion); DECL_HANDLER(set_fd_completion_mode); -DECL_HANDLER(set_fd_disp_info); +DECL_HANDLER(set_fd_disp_info_ex); DECL_HANDLER(set_fd_name_info); DECL_HANDLER(set_fd_eof_info); DECL_HANDLER(get_window_layered_info); @@ -659,7 +659,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_set_completion_info, (req_handler)req_add_fd_completion, (req_handler)req_set_fd_completion_mode, - (req_handler)req_set_fd_disp_info, + (req_handler)req_set_fd_disp_info_ex, (req_handler)req_set_fd_name_info, (req_handler)req_set_fd_eof_info, (req_handler)req_get_window_layered_info, @@ -2179,9 +2179,9 @@ C_ASSERT( sizeof(struct add_fd_completion_request) == 40 ); C_ASSERT( FIELD_OFFSET(struct set_fd_completion_mode_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_fd_completion_mode_request, flags) == 16 ); C_ASSERT( sizeof(struct set_fd_completion_mode_request) == 24 ); -C_ASSERT( FIELD_OFFSET(struct set_fd_disp_info_request, handle) == 12 ); -C_ASSERT( FIELD_OFFSET(struct set_fd_disp_info_request, unlink) == 16 ); -C_ASSERT( sizeof(struct set_fd_disp_info_request) == 24 ); +C_ASSERT( FIELD_OFFSET(struct set_fd_disp_info_ex_request, handle) == 12 ); +C_ASSERT( FIELD_OFFSET(struct set_fd_disp_info_ex_request, flags) == 16 ); +C_ASSERT( sizeof(struct set_fd_disp_info_ex_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, rootdir) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_fd_name_info_request, namelen) == 20 ); diff --git a/server/trace.c b/server/trace.c index fb006f605b5..2ed2f500103 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4317,10 +4317,10 @@ static void dump_set_fd_completion_mode_request( const struct set_fd_completion_ fprintf( stderr, ", flags=%08x", req->flags ); }
-static void dump_set_fd_disp_info_request( const struct set_fd_disp_info_request *req ) +static void dump_set_fd_disp_info_ex_request( const struct set_fd_disp_info_ex_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); - fprintf( stderr, ", unlink=%d", req->unlink ); + fprintf( stderr, ", flags=%08x", req->flags ); }
static void dump_set_fd_name_info_request( const struct set_fd_name_info_request *req ) @@ -4772,7 +4772,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_set_completion_info_request, (dump_func)dump_add_fd_completion_request, (dump_func)dump_set_fd_completion_mode_request, - (dump_func)dump_set_fd_disp_info_request, + (dump_func)dump_set_fd_disp_info_ex_request, (dump_func)dump_set_fd_name_info_request, (dump_func)dump_set_fd_eof_info_request, (dump_func)dump_get_window_layered_info_request, @@ -5334,7 +5334,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "set_completion_info", "add_fd_completion", "set_fd_completion_mode", - "set_fd_disp_info", + "set_fd_disp_info_ex", "set_fd_name_info", "set_fd_eof_info", "get_window_layered_info",
From: Joel Holdsworth joel@airwebreathe.org.uk
Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- dlls/ntdll/tests/file.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 6186afdfb63..af4a2965855 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_DISPOSITION_INFORMATION_EX fdie; FILE_STANDARD_INFORMATION fsi; BOOL fileDeleted; DWORD fdi2, size; @@ -3089,6 +3090,37 @@ static void test_file_disposition_information(void) SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); DeleteFileA( buffer );
+ /* cannot set disposition on readonly file */ + GetTempFileNameA( tmp_path, "dis", 0, buffer ); + DeleteFileA( buffer ); + handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); + ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + fdie.Flags = FILE_DISPOSITION_DELETE | FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE; + res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx ); + todo_wine + ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res ); + CloseHandle( handle ); + fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; + todo_wine + ok( fileDeleted, "File should have been deleted\n" ); + SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); + DeleteFileA( buffer ); + + /* cannot set disposition on readonly file */ + GetTempFileNameA( tmp_path, "dis", 0, buffer ); + handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0); + ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); + fdie.Flags = FILE_DISPOSITION_DELETE | FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE; + res = pNtSetInformationFile( handle, &io, &fdie, sizeof fdie, FileDispositionInformationEx ); + todo_wine + ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %lx)\n", res ); + CloseHandle( handle ); + fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; + todo_wine + ok( fileDeleted, "File should have been deleted\n" ); + SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); + DeleteFileA( buffer ); + /* can set disposition on file and then reset it */ GetTempFileNameA( tmp_path, "dis", 0, buffer ); handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
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 tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132300
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w7u_adm (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w7u_el (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w8 (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w8adm (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w864 (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w1064v1507 (32 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w7pro64 (64 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w864 (64 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== w1064v1507 (64 bit report) ===
ntdll: file.c:3101: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3105: Test failed: File should have been deleted file.c:3116: Test failed: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got c0000003) file.c:3120: Test failed: File should have been deleted
=== debian11 (32 bit report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
secur32: schannel: Timeout
wininet: http: Timeout
=== debian11 (32 bit ar:MA report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit de report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit fr report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit he:IL report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit hi:IN report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit ja:JP report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11 (32 bit zh:CN report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11b (32 bit WoW report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
=== debian11b (64 bit WoW report) ===
ntdll: file.c:3116: Test succeeded inside todo block: unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got 0) file.c:3120: Test succeeded inside todo block: File should have been deleted
This merge request was closed by Joel Holdsworth.