diff --git a/patches/ntdll-FileDispositionInformation/0001-server-Keep-a-pointer-to-parent-s-fd-unix_name-in-th.patch b/patches/ntdll-FileDispositionInformation/0001-server-Keep-a-pointer-to-parent-s-fd-unix_name-in-th.patch index 2988e362..54973c20 100644 --- a/patches/ntdll-FileDispositionInformation/0001-server-Keep-a-pointer-to-parent-s-fd-unix_name-in-th.patch +++ b/patches/ntdll-FileDispositionInformation/0001-server-Keep-a-pointer-to-parent-s-fd-unix_name-in-th.patch @@ -1,4 +1,4 @@ -From 48231cd898005f4c3bbb3992776d480e7eee837b Mon Sep 17 00:00:00 2001 +From 47f1bcd94dab7f58cda802dd89233ee21274c9fa Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 7 Aug 2014 18:31:33 -0600 Subject: server: Keep a pointer to parent's fd unix_name in the closed_fd @@ -9,7 +9,7 @@ Subject: server: Keep a pointer to parent's fd unix_name in the closed_fd 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/server/fd.c b/server/fd.c -index a432ec7..397e51d 100644 +index 14e98ac..7c2d717 100644 --- a/server/fd.c +++ b/server/fd.c @@ -164,7 +164,8 @@ struct closed_fd @@ -164,5 +164,5 @@ index a432ec7..397e51d 100644 set_error( STATUS_INVALID_PARAMETER ); goto error; -- -2.4.0 +2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0002-server-Add-support-for-setting-file-disposition-info.patch b/patches/ntdll-FileDispositionInformation/0002-server-Add-support-for-setting-file-disposition-info.patch index de49d8c0..38b93bf1 100644 --- a/patches/ntdll-FileDispositionInformation/0002-server-Add-support-for-setting-file-disposition-info.patch +++ b/patches/ntdll-FileDispositionInformation/0002-server-Add-support-for-setting-file-disposition-info.patch @@ -1,22 +1,22 @@ -From 723aef38c2549d8767bb185906cc3fc8d865b695 Mon Sep 17 00:00:00 2001 +From 713c458fc172d02e041ffd04542aada8f8313880 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 7 Aug 2014 20:32:19 -0600 Subject: server: Add support for setting file disposition information. --- - dlls/ntdll/file.c | 16 ++++++++++++++++ - dlls/ntdll/tests/file.c | 12 ++---------- - server/fd.c | 30 ++++++++++++++++++++++++++++++ - server/file.c | 23 +++++++++++++++++++++++ - server/file.h | 1 + - server/protocol.def | 6 ++++++ + dlls/ntdll/file.c | 16 ++++++++++++++++ + dlls/ntdll/tests/file.c | 12 ++---------- + server/fd.c | 30 ++++++++++++++++++++++++++++++ + server/file.c | 23 +++++++++++++++++++++++ + server/file.h | 1 + + server/protocol.def | 6 ++++++ 6 files changed, 78 insertions(+), 10 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index d2efcc1..5d59470 100644 +index d081750..86063b6 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -2383,6 +2383,22 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, +@@ -2765,6 +2765,22 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, else io->u.Status = STATUS_INVALID_PARAMETER_3; break; @@ -40,10 +40,10 @@ index d2efcc1..5d59470 100644 FIXME("Unsupported class (%d)\n", class); io->u.Status = STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index d70ed6b..1606f83 100644 +index 8ec367b..874aa4d 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c -@@ -1371,7 +1371,6 @@ static void test_file_disposition_information(void) +@@ -1471,7 +1471,6 @@ static void test_file_disposition_information(void) ok( res == STATUS_INVALID_INFO_CLASS || res == STATUS_NOT_IMPLEMENTED, "Unexpected NtQueryInformationFile result (expected STATUS_INVALID_INFO_CLASS, got %x)\n", res ); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -51,7 +51,7 @@ index d70ed6b..1606f83 100644 ok( res == STATUS_ACCESS_DENIED, "unexpected FileDispositionInformation result (expected STATUS_ACCESS_DENIED, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1384,11 +1383,9 @@ static void test_file_disposition_information(void) +@@ -1484,11 +1483,9 @@ static void test_file_disposition_information(void) ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -63,7 +63,7 @@ index d70ed6b..1606f83 100644 ok( fileDeleted, "File should have been deleted\n" ); DeleteFileA( buffer ); -@@ -1402,6 +1399,7 @@ static void test_file_disposition_information(void) +@@ -1502,6 +1499,7 @@ static void test_file_disposition_information(void) ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -71,7 +71,7 @@ index d70ed6b..1606f83 100644 ok( !fileDeleted, "File shouldn't have been deleted\n" ); SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); DeleteFileA( buffer ); -@@ -1412,11 +1410,9 @@ static void test_file_disposition_information(void) +@@ -1512,11 +1510,9 @@ static void test_file_disposition_information(void) ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -83,7 +83,7 @@ index d70ed6b..1606f83 100644 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1429,7 +1425,6 @@ static void test_file_disposition_information(void) +@@ -1529,7 +1525,6 @@ static void test_file_disposition_information(void) ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" ); fdi.DoDeleteFile = FALSE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -91,7 +91,7 @@ index d70ed6b..1606f83 100644 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1444,7 +1439,6 @@ static void test_file_disposition_information(void) +@@ -1544,7 +1539,6 @@ static void test_file_disposition_information(void) CloseHandle( handle ); fdi.DoDeleteFile = FALSE; res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -99,7 +99,7 @@ index d70ed6b..1606f83 100644 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); CloseHandle( handle2 ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1459,11 +1453,9 @@ static void test_file_disposition_information(void) +@@ -1559,11 +1553,9 @@ static void test_file_disposition_information(void) ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" ); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -111,7 +111,7 @@ index d70ed6b..1606f83 100644 ok( fileDeleted, "Directory should have been deleted\n" ); RemoveDirectoryA( buffer ); -@@ -1476,7 +1468,6 @@ static void test_file_disposition_information(void) +@@ -1576,7 +1568,6 @@ static void test_file_disposition_information(void) RemoveDirectoryA( buffer ); fdi.DoDeleteFile = FALSE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -119,7 +119,7 @@ index d70ed6b..1606f83 100644 ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1501,6 +1492,7 @@ static void test_file_disposition_information(void) +@@ -1601,6 +1592,7 @@ static void test_file_disposition_information(void) buffer[dirpos] = '\0'; CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -128,10 +128,10 @@ index d70ed6b..1606f83 100644 RemoveDirectoryA( buffer ); } diff --git a/server/fd.c b/server/fd.c -index b022a3c..7be3f4c 100644 +index 7c2d717..442e639 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -1921,6 +1921,36 @@ unsigned int get_fd_options( struct fd *fd ) +@@ -1942,6 +1942,36 @@ unsigned int get_fd_options( struct fd *fd ) return fd->options; } @@ -169,10 +169,10 @@ index b022a3c..7be3f4c 100644 int get_unix_fd( struct fd *fd ) { diff --git a/server/file.c b/server/file.c -index cceb8ad..0a7da00 100644 +index 792bbe0..b673bbc 100644 --- a/server/file.c +++ b/server/file.c -@@ -728,3 +728,26 @@ DECL_HANDLER(unlock_file) +@@ -741,3 +741,26 @@ DECL_HANDLER(unlock_file) release_object( file ); } } @@ -200,10 +200,10 @@ index cceb8ad..0a7da00 100644 + } +} diff --git a/server/file.h b/server/file.h -index 493d30b..d689d29 100644 +index b5e0ca7..460656f 100644 --- a/server/file.h +++ b/server/file.h -@@ -65,6 +65,7 @@ extern struct fd *get_fd_object_for_mapping( struct fd *fd, unsigned int access, +@@ -70,6 +70,7 @@ extern struct fd *get_fd_object_for_mapping( struct fd *fd, unsigned int access, extern void *get_fd_user( struct fd *fd ); extern void set_fd_user( struct fd *fd, const struct fd_ops *ops, struct object *user ); extern unsigned int get_fd_options( struct fd *fd ); @@ -212,10 +212,10 @@ index 493d30b..d689d29 100644 extern int is_same_file_fd( struct fd *fd1, struct fd *fd2 ); extern int is_fd_removable( struct fd *fd ); diff --git a/server/protocol.def b/server/protocol.def -index a8c1fb9..85505c8 100644 +index 9c4dab4..800f73c 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -1178,6 +1178,12 @@ enum server_fd_type +@@ -1200,6 +1200,12 @@ enum server_fd_type @END @@ -229,5 +229,5 @@ index a8c1fb9..85505c8 100644 @REQ(create_socket) unsigned int access; /* wanted access rights */ -- -1.7.9.5 +2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0003-server-Do-not-permit-FileDispositionInformation-to-d.patch b/patches/ntdll-FileDispositionInformation/0003-server-Do-not-permit-FileDispositionInformation-to-d.patch index 675094d2..7e7c50f4 100644 --- a/patches/ntdll-FileDispositionInformation/0003-server-Do-not-permit-FileDispositionInformation-to-d.patch +++ b/patches/ntdll-FileDispositionInformation/0003-server-Do-not-permit-FileDispositionInformation-to-d.patch @@ -1,19 +1,19 @@ -From ea378bcb8a0a6113178c2d42a3e8151b7f99dfb6 Mon Sep 17 00:00:00 2001 +From edb8a6ab85a4c07409a8b12ffd3d5955f32e2952 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 7 Aug 2014 21:14:25 -0600 Subject: server: Do not permit FileDispositionInformation to delete a file without write access. --- - dlls/ntdll/tests/file.c | 28 ++++++++++++++++++++++++++++ - server/fd.c | 7 +++++++ + dlls/ntdll/tests/file.c | 28 ++++++++++++++++++++++++++++ + server/fd.c | 7 +++++++ 2 files changed, 35 insertions(+) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 1606f83..05ce517 100644 +index 874aa4d..1e7edc3 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c -@@ -1391,6 +1391,20 @@ static void test_file_disposition_information(void) +@@ -1491,6 +1491,20 @@ static void test_file_disposition_information(void) /* cannot set disposition on readonly file */ GetTempFileNameA( tmp_path, "dis", 0, buffer ); @@ -34,7 +34,7 @@ index 1606f83..05ce517 100644 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" ); fdi.DoDeleteFile = TRUE; -@@ -1404,6 +1418,20 @@ static void test_file_disposition_information(void) +@@ -1504,6 +1518,20 @@ static void test_file_disposition_information(void) SetFileAttributesA( buffer, FILE_ATTRIBUTE_NORMAL ); DeleteFileA( buffer ); @@ -56,10 +56,10 @@ index 1606f83..05ce517 100644 GetTempFileNameA( tmp_path, "dis", 0, buffer ); handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0); diff --git a/server/fd.c b/server/fd.c -index 7be3f4c..37377d1 100644 +index 442e639..d11d98c 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -1945,6 +1945,13 @@ void set_fd_disposition( struct fd *fd, int unlink ) +@@ -1966,6 +1966,13 @@ void set_fd_disposition( struct fd *fd, int unlink ) return; } @@ -74,5 +74,5 @@ index 7be3f4c..37377d1 100644 fd->closed->unlink = 1; else if (!(fd->options & FILE_DELETE_ON_CLOSE)) -- -1.7.9.5 +2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0004-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch b/patches/ntdll-FileDispositionInformation/0004-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch index 9d8e7236..e1486433 100644 --- a/patches/ntdll-FileDispositionInformation/0004-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch +++ b/patches/ntdll-FileDispositionInformation/0004-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch @@ -1,4 +1,4 @@ -From 915da8ef1214b9378683e144ba18e3a185909dbf Mon Sep 17 00:00:00 2001 +From 6aeab9117090d0cca99eac5fa02363722022dec0 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Fri, 17 Apr 2015 00:59:02 +0800 Subject: ntdll/tests: Added tests to set disposition on file which is mapped @@ -9,10 +9,10 @@ Subject: ntdll/tests: Added tests to set disposition on file which is mapped 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 05ce517..1726546 100644 +index 1e7edc3..89f70de 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c -@@ -1355,11 +1355,12 @@ static void test_file_disposition_information(void) +@@ -1455,11 +1455,12 @@ static void test_file_disposition_information(void) { char tmp_path[MAX_PATH], buffer[MAX_PATH + 16]; DWORD dirpos; @@ -26,7 +26,7 @@ index 05ce517..1726546 100644 GetTempPathA( MAX_PATH, tmp_path ); -@@ -1523,6 +1524,74 @@ static void test_file_disposition_information(void) +@@ -1623,6 +1624,74 @@ static void test_file_disposition_information(void) todo_wine ok( !fileDeleted, "Directory shouldn't have been deleted\n" ); RemoveDirectoryA( buffer ); @@ -102,5 +102,5 @@ index 05ce517..1726546 100644 static void test_iocompletion(void) -- -2.3.5 +2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0005-server-Do-not-allow-to-set-disposition-on-file-which.patch b/patches/ntdll-FileDispositionInformation/0005-server-Do-not-allow-to-set-disposition-on-file-which.patch index a353bd04..240d892d 100644 --- a/patches/ntdll-FileDispositionInformation/0005-server-Do-not-allow-to-set-disposition-on-file-which.patch +++ b/patches/ntdll-FileDispositionInformation/0005-server-Do-not-allow-to-set-disposition-on-file-which.patch @@ -1,4 +1,4 @@ -From f32616e681bebc98e6969e142edabbd4b5cf86dd Mon Sep 17 00:00:00 2001 +From a9ec2efaf7e9e8eb0440052176e79f71b615bcc8 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Fri, 17 Apr 2015 18:39:59 +0800 Subject: server: Do not allow to set disposition on file which has a file @@ -6,14 +6,14 @@ Subject: server: Do not allow to set disposition on file which has a file --- dlls/ntdll/tests/file.c | 2 -- - server/fd.c | 15 +++++++++++++++ - 2 files changed, 15 insertions(+), 2 deletions(-) + server/fd.c | 12 ++++++++++++ + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 1726546..2784e9b 100644 +index 89f70de..b285157 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c -@@ -1533,7 +1533,6 @@ static void test_file_disposition_information(void) +@@ -1633,7 +1633,6 @@ static void test_file_disposition_information(void) ok( mapping != NULL, "failed to create file mapping\n"); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -21,7 +21,7 @@ index 1726546..2784e9b 100644 ok( res == STATUS_CANNOT_DELETE, "unexpected FileDispositionInformation result (expected STATUS_CANNOT_DELETE, got %x)\n", res ); CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1567,7 +1566,6 @@ static void test_file_disposition_information(void) +@@ -1667,7 +1666,6 @@ static void test_file_disposition_information(void) CloseHandle( mapping ); fdi.DoDeleteFile = TRUE; res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation ); @@ -30,10 +30,10 @@ index 1726546..2784e9b 100644 CloseHandle( handle ); fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; diff --git a/server/fd.c b/server/fd.c -index 036478a..90487cc 100644 +index d11d98c..553d840 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -1951,6 +1951,7 @@ unsigned int get_fd_options( struct fd *fd ) +@@ -1946,6 +1946,7 @@ unsigned int get_fd_options( struct fd *fd ) void set_fd_disposition( struct fd *fd, int unlink ) { struct stat st; @@ -41,21 +41,18 @@ index 036478a..90487cc 100644 if (fd->unix_fd == -1) { -@@ -1978,6 +1979,20 @@ void set_fd_disposition( struct fd *fd, int unlink ) +@@ -1973,6 +1974,17 @@ void set_fd_disposition( struct fd *fd, int unlink ) return; } + LIST_FOR_EACH( ptr, &fd->inode->open ) + { + struct fd *fd_ptr = LIST_ENTRY( ptr, struct fd, inode_entry ); -+ if (fd_ptr != fd) ++ if (fd_ptr != fd && fd_ptr->access & FILE_MAPPING_ACCESS) + { -+ if (fd_ptr->access & FILE_MAPPING_ACCESS) -+ { -+ /* can't unlink files which are mapped to memory */ -+ set_error( STATUS_CANNOT_DELETE ); -+ return; -+ } ++ /* can't unlink files which are mapped to memory */ ++ set_error( STATUS_CANNOT_DELETE ); ++ return; + } + } + @@ -63,5 +60,5 @@ index 036478a..90487cc 100644 fd->closed->unlink = 1; else if (!(fd->options & FILE_DELETE_ON_CLOSE)) -- -2.3.5 +2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-tests-for-FileRenameInformation.patch b/patches/ntdll-FileDispositionInformation/0006-ntdll-tests-Add-tests-for-FileRenameInformation.patch similarity index 97% rename from patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-tests-for-FileRenameInformation.patch rename to patches/ntdll-FileDispositionInformation/0006-ntdll-tests-Add-tests-for-FileRenameInformation.patch index 2e383c0a..d4d6aa94 100644 --- a/patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-tests-for-FileRenameInformation.patch +++ b/patches/ntdll-FileDispositionInformation/0006-ntdll-tests-Add-tests-for-FileRenameInformation.patch @@ -1,4 +1,4 @@ -From 946c9589b4e5b38401f8fd4922725b5c64a54da2 Mon Sep 17 00:00:00 2001 +From 3e1665a8196e64bc6f28e7ba91f7bf056fc2b2b0 Mon Sep 17 00:00:00 2001 From: Jianqiu Zhang Date: Thu, 14 May 2015 20:18:52 +0800 Subject: ntdll/tests: Add tests for FileRenameInformation. @@ -8,7 +8,7 @@ Subject: ntdll/tests: Add tests for FileRenameInformation. 1 file changed, 106 insertions(+) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 8aa6ee2..4173166 100644 +index b285157..aced150 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1435,6 +1435,111 @@ static void test_file_all_information(void) @@ -123,7 +123,7 @@ index 8aa6ee2..4173166 100644 static void test_file_both_information(void) { IO_STATUS_BLOCK io; -@@ -2923,6 +3028,7 @@ START_TEST(file) +@@ -3001,6 +3106,7 @@ START_TEST(file) test_file_name_information(); test_file_full_size_information(); test_file_all_name_information(); diff --git a/patches/ntdll-FileDispositionInformation/0006-server-Set-the-closed_fd-unix_name-shortly-before-ad.patch b/patches/ntdll-FileDispositionInformation/0006-server-Set-the-closed_fd-unix_name-shortly-before-ad.patch deleted file mode 100644 index 09b8a271..00000000 --- a/patches/ntdll-FileDispositionInformation/0006-server-Set-the-closed_fd-unix_name-shortly-before-ad.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 2679e91c82514d2f2d90374a06588601498c1baa Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 3 Jun 2015 02:46:57 +0200 -Subject: server: Set the closed_fd->unix_name shortly before adding to the - closed fd list. - ---- - server/fd.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/server/fd.c b/server/fd.c -index cc6425c..ad974bb 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -1473,6 +1473,7 @@ static void fd_destroy( struct object *obj ) - if (fd->poll_index != -1) remove_poll_user( fd, fd->poll_index ); - if (fd->inode) - { -+ fd->closed->unix_name = fd->unix_name; - inode_add_closed_fd( fd->inode, fd->closed ); - release_object( fd->inode ); - } -@@ -1667,7 +1668,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha - } - closed->unix_fd = fd->unix_fd; - closed->unlink = 0; -- closed->unix_name = fd->unix_name; -+ closed->unix_name = NULL; - fd->closed = closed; - fd->inode = (struct inode *)grab_object( orig->inode ); - list_add_head( &fd->inode->open, &fd->inode_entry ); -@@ -1838,7 +1839,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode, - - closed_fd->unix_fd = fd->unix_fd; - closed_fd->unlink = 0; -- closed_fd->unix_name = fd->unix_name; -+ closed_fd->unix_name = NULL; - - if (do_chmod) fchmod( fd->unix_fd, *mode ); - fstat( fd->unix_fd, &st ); --- -2.4.2 - diff --git a/patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch b/patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch similarity index 99% rename from patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch rename to patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch index 36b8871d..bd95d014 100644 --- a/patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch +++ b/patches/ntdll-FileDispositionInformation/0007-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch @@ -1,4 +1,4 @@ -From 4b282588eddd0aaac6889528235fa1b41a3fab76 Mon Sep 17 00:00:00 2001 +From 1de9ca4809416c9b3264bdc784cd66b3546d056c Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 2 Jun 2015 21:56:35 +0200 Subject: ntdll/tests: Add additional tests for FileRenameInformation. @@ -8,7 +8,7 @@ Subject: ntdll/tests: Add additional tests for FileRenameInformation. 1 file changed, 573 insertions(+), 13 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 4173166..70ee60a 100644 +index aced150..f20319d 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1435,20 +1435,36 @@ static void test_file_all_information(void) diff --git a/patches/ntdll-FileDispositionInformation/0009-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch b/patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch similarity index 97% rename from patches/ntdll-FileDispositionInformation/0009-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch rename to patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch index f3715320..57790b0e 100644 --- a/patches/ntdll-FileDispositionInformation/0009-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch +++ b/patches/ntdll-FileDispositionInformation/0008-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch @@ -1,4 +1,4 @@ -From 4ea4a5d47019daecf77bf03f477b4b23ede6f561 Mon Sep 17 00:00:00 2001 +From 9e4a613237ff1c43f335a1cc8525439ce45f8c3e Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 3 Jun 2015 00:50:18 +0200 Subject: ntdll/tests: Add tests for FileRenameInformation with nonzero @@ -9,7 +9,7 @@ Subject: ntdll/tests: Add tests for FileRenameInformation with nonzero 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 70ee60a..5fdf4bf 100644 +index f20319d..a0aae0a 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1453,7 +1453,7 @@ static void test_file_rename_information(void) diff --git a/patches/ntdll-FileDispositionInformation/0010-ntdll-Implement-a-hacky-version-of-FileRenameInforma.patch b/patches/ntdll-FileDispositionInformation/0009-ntdll-Implement-FileRenameInformation-support.patch similarity index 70% rename from patches/ntdll-FileDispositionInformation/0010-ntdll-Implement-a-hacky-version-of-FileRenameInforma.patch rename to patches/ntdll-FileDispositionInformation/0009-ntdll-Implement-FileRenameInformation-support.patch index 4fcd4b04..051867c5 100644 --- a/patches/ntdll-FileDispositionInformation/0010-ntdll-Implement-a-hacky-version-of-FileRenameInforma.patch +++ b/patches/ntdll-FileDispositionInformation/0009-ntdll-Implement-FileRenameInformation-support.patch @@ -1,15 +1,15 @@ -From 8efe01bbe1fbfdc40bbe97f8f779ded0f252cc6c Mon Sep 17 00:00:00 2001 -From: Qian Hong +From 526d905701f6d27f38cce701f36f6280f7c2c6cf Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner Date: Tue, 2 Jun 2015 01:56:24 +0800 -Subject: ntdll: Implement a hacky version of FileRenameInformation support. +Subject: ntdll: Implement FileRenameInformation support. -Contains various improvements by Sebastian Lackner . +Based on a patch by Qian Hong. --- - dlls/ntdll/file.c | 42 +++++++++++++++++++++++++++++ - dlls/ntdll/tests/file.c | 70 +++++++++++++++++++++++++++---------------------- - server/fd.c | 53 +++++++++++++++++++++++++++++++++++++ - server/protocol.def | 9 +++++++ - 4 files changed, 142 insertions(+), 32 deletions(-) + dlls/ntdll/file.c | 42 +++++++++++++++++++++ + dlls/ntdll/tests/file.c | 80 +++++++++++++++++++++------------------- + server/fd.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ + server/protocol.def | 9 +++++ + 4 files changed, 192 insertions(+), 37 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 86063b6..6aa46f4 100644 @@ -65,7 +65,7 @@ index 86063b6..6aa46f4 100644 FIXME("Unsupported class (%d)\n", class); io->u.Status = STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 5fdf4bf..a2d7184 100644 +index a0aae0a..941cc0c 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -1483,19 +1483,19 @@ static void test_file_rename_information(void) @@ -126,33 +126,33 @@ index 5fdf4bf..a2d7184 100644 fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); -@@ -1621,7 +1621,7 @@ static void test_file_rename_information(void) +@@ -1619,7 +1619,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); - todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- ok( !fileDeleted, "File should exist\n" ); -+ todo_wine ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); - -@@ -1655,7 +1655,7 @@ static void test_file_rename_information(void) + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +@@ -1653,7 +1653,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); - todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- ok( !fileDeleted, "File should exist\n" ); -+ todo_wine ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); - -@@ -1689,7 +1689,7 @@ static void test_file_rename_information(void) + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +@@ -1687,7 +1687,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); - todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- ok( !fileDeleted, "File should exist\n" ); -+ todo_wine ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); - + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -1721,19 +1721,19 @@ static void test_file_rename_information(void) U(io).Status = 0xdeadbeef; @@ -220,6 +220,29 @@ index 5fdf4bf..a2d7184 100644 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +@@ -1872,10 +1878,10 @@ static void test_file_rename_information(void) + + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); +- todo_wine ok( U(io).Status == STATUS_SUCCESS, "io.Status expect STATUS_SUCCESS, io.Status is %x\n", U(io).Status ); +- todo_wine ok( res == STATUS_SUCCESS, "res expect STATUS_SUCCESS, res is %x\n", res ); ++ ok( U(io).Status == STATUS_SUCCESS, "io.Status expect STATUS_SUCCESS, io.Status is %x\n", U(io).Status ); ++ ok( res == STATUS_SUCCESS, "res expect STATUS_SUCCESS, res is %x\n", res ); + fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +- todo_wine ok( fileDeleted, "File should have been deleted\n" ); ++ ok( fileDeleted, "File should have been deleted\n" ); + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; + ok( !fileDeleted, "File should exist\n" ); + +@@ -1909,7 +1915,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); + todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); + fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; + ok( !fileDeleted, "File should exist\n" ); + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -1946,7 +1952,7 @@ static void test_file_rename_information(void) U(io).Status = 0xdeadbeef; res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); @@ -229,24 +252,24 @@ index 5fdf4bf..a2d7184 100644 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -@@ -1984,7 +1990,7 @@ static void test_file_rename_information(void) +@@ -1982,7 +1988,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); - todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- ok( !fileDeleted, "File should exist\n" ); -+ todo_wine ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); - -@@ -2023,7 +2029,7 @@ static void test_file_rename_information(void) + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +@@ -2021,7 +2027,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); - todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- ok( !fileDeleted, "File should exist\n" ); -+ todo_wine ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); - + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -2055,7 +2061,7 @@ static void test_file_rename_information(void) U(io).Status = 0xdeadbeef; res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); @@ -256,6 +279,15 @@ index 5fdf4bf..a2d7184 100644 fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; ok( !fileDeleted, "File should exist\n" ); fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; +@@ -2088,7 +2094,7 @@ static void test_file_rename_information(void) + U(io).Status = 0xdeadbeef; + res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); + todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); +- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); ++ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); + fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; + ok( !fileDeleted, "File should exist\n" ); + fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; @@ -2121,12 +2127,12 @@ static void test_file_rename_information(void) U(io).Status = 0xdeadbeef; @@ -274,10 +306,91 @@ index 5fdf4bf..a2d7184 100644 pfni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); res = pNtQueryInformationFile( handle, &io, pfni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); diff --git a/server/fd.c b/server/fd.c -index ad974bb..ae61f27 100644 +index 553d840..d4e5321 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -2488,3 +2488,56 @@ DECL_HANDLER(add_fd_completion) +@@ -1991,6 +1991,80 @@ void set_fd_disposition( struct fd *fd, int unlink ) + fd->closed->unlink = 0; + } + ++/* rename a file */ ++static void rename_fd( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len ) ++{ ++ struct inode *inode; ++ struct stat st; ++ char *name; ++ ++ if (!fd->unix_name) ++ { ++ set_error( STATUS_OBJECT_TYPE_MISMATCH ); ++ return; ++ } ++ if (!(name = mem_alloc( len + 1 ))) return NULL; ++ memcpy( name, nameptr, len ); ++ name[len] = 0; ++ ++ if (root) ++ { ++ char *combined_name = dup_fd_name( root, name ); ++ if (!combined_name) ++ { ++ set_error( STATUS_NO_MEMORY ); ++ goto failed; ++ } ++ free( name ); ++ name = combined_name; ++ } ++ ++ if (stat( name, &st )) ++ goto do_rename; ++ ++ if (!S_ISREG( st.st_mode )) ++ { ++ /* can't replace directories or special files */ ++ set_error( STATUS_ACCESS_DENIED ); ++ goto failed; ++ } ++ ++ if ((inode = get_inode( st.st_dev, st.st_ino, -1 ))) ++ { ++ int is_empty = list_empty( &inode->open ); ++ release_object( inode ); ++ if (!is_empty) ++ { ++ /* can't replace an opened file */ ++ set_error( STATUS_ACCESS_DENIED ); ++ goto failed; ++ } ++ } ++ ++ /* unix rename() doesn't automatically replace files with directories */ ++ if (fd->unix_fd != -1 && !fstat( fd->unix_fd, &st ) && ++ S_ISDIR( st.st_mode ) && unlink( name )) ++ { ++ file_set_error(); ++ goto failed; ++ } ++ ++do_rename: ++ if (rename( fd->unix_name, name )) ++ { ++ file_set_error(); ++ goto failed; ++ } ++ ++ free( fd->unix_name ); ++ fd->unix_name = name; ++ fd->closed->unix_name = name; ++ return; ++ ++failed: ++ free( name ); ++} ++ + /* retrieve the unix fd for an object */ + int get_unix_fd( struct fd *fd ) + { +@@ -2484,3 +2558,27 @@ DECL_HANDLER(add_fd_completion) release_object( fd ); } } @@ -285,54 +398,25 @@ index ad974bb..ae61f27 100644 +/* rename file */ +DECL_HANDLER(rename_file) +{ ++ struct fd *root_fd = NULL; + struct fd *fd; -+ char *path; + -+ if (!(path = mem_alloc( get_req_data_size() + 1 ))) -+ return; -+ memcpy( path, get_req_data(), get_req_data_size() ); -+ path[ get_req_data_size() ] = 0; -+ -+ /* handle rootdir */ + if (req->rootdir) + { -+ char *combined_path = NULL; + struct dir *root; -+ if ((root = get_dir_obj( current->process, req->rootdir, 0 ))) -+ { -+ struct fd *root_fd; -+ if ((root_fd = get_obj_fd( (struct object *)root ))) -+ { -+ combined_path = dup_fd_name( root_fd, path ); -+ release_object( root_fd ); -+ } -+ release_object( root ); -+ } -+ -+ if (!combined_path) return; -+ free( path ); -+ path = combined_path; ++ if (!(root = get_dir_obj( current->process, req->rootdir, 0 ))) return; ++ root_fd = get_obj_fd( (struct object *)root ); ++ release_object( root ); ++ if (!root_fd) return; + } + -+ /* do the rename */ + if ((fd = get_handle_fd_obj( current->process, req->handle, 0 ))) + { -+ if (fd->unix_name) -+ { -+ if (rename( fd->unix_name, path )) -+ file_set_error(); -+ else -+ { -+ free( fd->unix_name ); -+ fd->unix_name = path; -+ path = NULL; -+ } -+ } -+ else set_error( STATUS_OBJECT_TYPE_MISMATCH ); ++ rename_fd( fd, root_fd, get_req_data(), get_req_data_size() ); + release_object( fd ); + } + -+ free( path ); ++ if (root_fd) release_object( root_fd ); +} diff --git a/server/protocol.def b/server/protocol.def index 800f73c..431d2b9 100644 diff --git a/patches/ntdll-FileDispositionInformation/0012-server-When-combining-root-and-name-make-sure-there-.patch b/patches/ntdll-FileDispositionInformation/0010-server-When-combining-root-and-name-make-sure-there-.patch similarity index 90% rename from patches/ntdll-FileDispositionInformation/0012-server-When-combining-root-and-name-make-sure-there-.patch rename to patches/ntdll-FileDispositionInformation/0010-server-When-combining-root-and-name-make-sure-there-.patch index d4eaced0..04e4b603 100644 --- a/patches/ntdll-FileDispositionInformation/0012-server-When-combining-root-and-name-make-sure-there-.patch +++ b/patches/ntdll-FileDispositionInformation/0010-server-When-combining-root-and-name-make-sure-there-.patch @@ -1,4 +1,4 @@ -From 9aadb3326ac73489928af85a43ddefd07b6fefb8 Mon Sep 17 00:00:00 2001 +From d0201524cc9fcc78997ae699995bb192f37b78d1 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 3 Jun 2015 01:37:34 +0200 Subject: server: When combining root and name, make sure there is only one @@ -12,7 +12,7 @@ Changes in v2: 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index 6710b3a..fbcee9b 100644 +index 941cc0c..8072a15 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -2138,8 +2138,8 @@ static void test_file_rename_information(void) @@ -27,10 +27,10 @@ index 6710b3a..fbcee9b 100644 CloseHandle( handle ); diff --git a/server/fd.c b/server/fd.c -index f162346..b46753e 100644 +index d4e5321..4b0bf47 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -1721,6 +1721,7 @@ void set_fd_user( struct fd *fd, const struct fd_ops *user_ops, struct object *u +@@ -1720,6 +1720,7 @@ void set_fd_user( struct fd *fd, const struct fd_ops *user_ops, struct object *u static char *dup_fd_name( struct fd *root, const char *name ) { char *ret; @@ -38,7 +38,7 @@ index f162346..b46753e 100644 if (!root) return strdup( name ); if (!root->unix_name) return NULL; -@@ -1728,11 +1729,18 @@ static char *dup_fd_name( struct fd *root, const char *name ) +@@ -1727,11 +1728,18 @@ static char *dup_fd_name( struct fd *root, const char *name ) /* skip . prefix */ if (name[0] == '.' && (!name[1] || name[1] == '/')) name++; diff --git a/patches/ntdll-FileDispositionInformation/0015-include-Add-declaration-for-FILE_LINK_INFORMATION.patch b/patches/ntdll-FileDispositionInformation/0011-include-Add-declaration-for-FILE_LINK_INFORMATION.patch similarity index 92% rename from patches/ntdll-FileDispositionInformation/0015-include-Add-declaration-for-FILE_LINK_INFORMATION.patch rename to patches/ntdll-FileDispositionInformation/0011-include-Add-declaration-for-FILE_LINK_INFORMATION.patch index 61e3bc12..a1c40a25 100644 --- a/patches/ntdll-FileDispositionInformation/0015-include-Add-declaration-for-FILE_LINK_INFORMATION.patch +++ b/patches/ntdll-FileDispositionInformation/0011-include-Add-declaration-for-FILE_LINK_INFORMATION.patch @@ -1,4 +1,4 @@ -From b4838252600fd8b4325b1a7d5753a84df40ef131 Mon Sep 17 00:00:00 2001 +From 5a4985d6c6748fef78e69367848569e69d46c13f Mon Sep 17 00:00:00 2001 From: Zhaonan Liang Date: Tue, 28 Apr 2015 19:06:31 +0800 Subject: include: Add declaration for FILE_LINK_INFORMATION. diff --git a/patches/ntdll-FileDispositionInformation/0011-server-FileRenameInformation-target-cannot-be-an-exi.patch b/patches/ntdll-FileDispositionInformation/0011-server-FileRenameInformation-target-cannot-be-an-exi.patch deleted file mode 100644 index 08b227b1..00000000 --- a/patches/ntdll-FileDispositionInformation/0011-server-FileRenameInformation-target-cannot-be-an-exi.patch +++ /dev/null @@ -1,66 +0,0 @@ -From c11a0a4e007badd714f500da3899a88ab363e51a Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 3 Jun 2015 01:26:54 +0200 -Subject: server: FileRenameInformation target cannot be an existing directory. - ---- - dlls/ntdll/tests/file.c | 10 +++++----- - server/fd.c | 5 ++++- - 2 files changed, 9 insertions(+), 6 deletions(-) - -diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index a2d7184..6710b3a 100644 ---- a/dlls/ntdll/tests/file.c -+++ b/dlls/ntdll/tests/file.c -@@ -1988,9 +1988,9 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( !fileDeleted, "File should exist\n" ); -+ ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -@@ -2027,9 +2027,9 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( !fileDeleted, "File should exist\n" ); -+ ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -@@ -2094,7 +2094,7 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -diff --git a/server/fd.c b/server/fd.c -index ae61f27..f162346 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -2526,7 +2526,10 @@ DECL_HANDLER(rename_file) - { - if (fd->unix_name) - { -- if (rename( fd->unix_name, path )) -+ struct stat st; -+ if (!stat( path, &st ) && !S_ISREG( st.st_mode )) -+ set_error( STATUS_ACCESS_DENIED ); -+ else if (rename( fd->unix_name, path )) - file_set_error(); - else - { --- -2.4.2 - diff --git a/patches/ntdll-FileDispositionInformation/0016-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch b/patches/ntdll-FileDispositionInformation/0012-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch similarity index 99% rename from patches/ntdll-FileDispositionInformation/0016-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch rename to patches/ntdll-FileDispositionInformation/0012-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch index 1851cefa..ef29e692 100644 --- a/patches/ntdll-FileDispositionInformation/0016-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch +++ b/patches/ntdll-FileDispositionInformation/0012-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch @@ -1,4 +1,4 @@ -From 3049a4cb5eaa0e35e2ce1621a4c090c1fdc13a57 Mon Sep 17 00:00:00 2001 +From e8f81b0c785cf349fcfee69b9dcdfe42ee9020d5 Mon Sep 17 00:00:00 2001 From: Qian Hong Date: Wed, 3 Jun 2015 17:41:59 +0800 Subject: ntdll/tests: Add tests for FileLinkInformation class. diff --git a/patches/ntdll-FileDispositionInformation/0017-server-Implement-support-for-FileLinkInformation-cla.patch b/patches/ntdll-FileDispositionInformation/0013-server-Implement-support-for-FileLinkInformation-cla.patch similarity index 83% rename from patches/ntdll-FileDispositionInformation/0017-server-Implement-support-for-FileLinkInformation-cla.patch rename to patches/ntdll-FileDispositionInformation/0013-server-Implement-support-for-FileLinkInformation-cla.patch index c1fbc70b..d2762663 100644 --- a/patches/ntdll-FileDispositionInformation/0017-server-Implement-support-for-FileLinkInformation-cla.patch +++ b/patches/ntdll-FileDispositionInformation/0013-server-Implement-support-for-FileLinkInformation-cla.patch @@ -1,24 +1,35 @@ -From eb0a9708ab107897cb41a20299f530a8d7bddb4c Mon Sep 17 00:00:00 2001 +From 0777c89085c995e4160750c12bdd0afd68eecafb Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 3 Jun 2015 17:04:23 +0200 Subject: server: Implement support for FileLinkInformation class in NtSetInformationFile. --- - dlls/ntdll/file.c | 42 ++++++++++++++++++++++++++ - dlls/ntdll/tests/file.c | 54 ++++++++++++++++----------------- - server/fd.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++- - server/protocol.def | 8 +++++ - 4 files changed, 155 insertions(+), 28 deletions(-) + dlls/ntdll/file.c | 44 ++++++++++++++++++++++++++++++++++++++++ + dlls/ntdll/tests/file.c | 54 ++++++++++++++++++++++++------------------------- + server/fd.c | 47 ++++++++++++++++++++++++++++-------------- + server/protocol.def | 3 ++- + 4 files changed, 105 insertions(+), 43 deletions(-) diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c -index 6aa46f4..1e27afb 100644 +index 6aa46f4..f5f2458 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c -@@ -2823,6 +2823,48 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, - else io->u.Status = STATUS_INVALID_PARAMETER_3; - break; - +@@ -2813,6 +2813,50 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io, + { + req->handle = wine_server_obj_handle( handle ); + req->rootdir = wine_server_obj_handle( attr.RootDirectory ); ++ req->link = FALSE; ++ wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); ++ io->u.Status = wine_server_call( req ); ++ } ++ SERVER_END_REQ; ++ ++ RtlFreeAnsiString( &unix_name ); ++ } ++ else io->u.Status = STATUS_INVALID_PARAMETER_3; ++ break; ++ + case FileLinkInformation: + if (len >= sizeof(FILE_LINK_INFORMATION)) + { @@ -47,23 +58,14 @@ index 6aa46f4..1e27afb 100644 + break; + } + -+ SERVER_START_REQ( link_file ) ++ SERVER_START_REQ( rename_file ) + { + req->handle = wine_server_obj_handle( handle ); + req->rootdir = wine_server_obj_handle( attr.RootDirectory ); -+ wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); -+ io->u.Status = wine_server_call( req ); -+ } -+ SERVER_END_REQ; -+ -+ RtlFreeAnsiString( &unix_name ); -+ } -+ else io->u.Status = STATUS_INVALID_PARAMETER_3; -+ break; -+ - default: - FIXME("Unsupported class (%d)\n", class); - io->u.Status = STATUS_NOT_IMPLEMENTED; ++ req->link = TRUE; + wine_server_add_data( req, unix_name.Buffer, unix_name.Length ); + io->u.Status = wine_server_call( req ); + } diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index c985a03..92613d5 100644 --- a/dlls/ntdll/tests/file.c @@ -262,118 +264,118 @@ index c985a03..92613d5 100644 pfni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) ); res = pNtQueryInformationFile( handle, &io, pfni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation ); diff --git a/server/fd.c b/server/fd.c -index 0234fc0..4729170 100644 +index 4b0bf47..db299dd 100644 --- a/server/fd.c +++ b/server/fd.c -@@ -2561,7 +2561,6 @@ DECL_HANDLER(rename_file) - goto out; - } - } -- - if (rename( fd->unix_name, path )) - file_set_error(); - else -@@ -2578,3 +2577,81 @@ out: - - free( path ); +@@ -1999,8 +1999,8 @@ void set_fd_disposition( struct fd *fd, int unlink ) + fd->closed->unlink = 0; } + +-/* rename a file */ +-static void rename_fd( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len ) ++/* rename or link a file */ ++static void rename_fd( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len, int do_link ) + { + struct inode *inode; + struct stat st; +@@ -2027,8 +2027,16 @@ static void rename_fd( struct fd *fd, struct fd *root, const char *nameptr, data + name = combined_name; + } + ++ if (do_link && fd->unix_fd != -1 && ++ !fstat( fd->unix_fd, &st ) && S_ISDIR( st.st_mode )) ++ { ++ /* when creating a hard link, source must be a file */ ++ set_error( STATUS_FILE_IS_A_DIRECTORY ); ++ goto failed; ++ } + -+/* create hardlink - FIXME: merge with rename_file */ -+DECL_HANDLER(link_file) -+{ -+ struct fd *fd; -+ char *path; -+ -+ if (!(path = mem_alloc( get_req_data_size() + 1 ))) + if (stat( name, &st )) +- goto do_rename; ++ goto skip_checks; + + if (!S_ISREG( st.st_mode )) + { +@@ -2049,25 +2057,34 @@ static void rename_fd( struct fd *fd, struct fd *root, const char *nameptr, data + } + } + ++ /* unix link() doesn't succeed when the target already exists */ + /* unix rename() doesn't automatically replace files with directories */ +- if (fd->unix_fd != -1 && !fstat( fd->unix_fd, &st ) && +- S_ISDIR( st.st_mode ) && unlink( name )) ++ if ((do_link || (fd->unix_fd != -1 && !fstat( fd->unix_fd, &st ) && ++ S_ISDIR( st.st_mode ))) && unlink( name )) + { + file_set_error(); + goto failed; + } + +-do_rename: +- if (rename( fd->unix_name, name )) ++skip_checks: ++ if (do_link) + { +- file_set_error(); +- goto failed; ++ if (link( fd->unix_name, name )) ++ file_set_error(); + } ++ else ++ { ++ if (rename( fd->unix_name, name )) ++ { ++ file_set_error(); ++ goto failed; ++ } + +- free( fd->unix_name ); +- fd->unix_name = name; +- fd->closed->unix_name = name; +- return; ++ free( fd->unix_name ); ++ fd->unix_name = name; ++ fd->closed->unix_name = name; + return; -+ memcpy( path, get_req_data(), get_req_data_size() ); -+ path[ get_req_data_size() ] = 0; -+ -+ /* handle rootdir */ -+ if (req->rootdir) -+ { -+ char *combined_path = NULL; -+ struct dir *root; -+ if ((root = get_dir_obj( current->process, req->rootdir, 0 ))) -+ { -+ struct fd *root_fd; -+ if ((root_fd = get_obj_fd( (struct object *)root ))) -+ { -+ combined_path = dup_fd_name( root_fd, path ); -+ release_object( root_fd ); -+ } -+ release_object( root ); -+ } -+ -+ if (!combined_path) return; -+ free( path ); -+ path = combined_path; + } -+ -+ /* create a hardlink */ -+ if ((fd = get_handle_fd_obj( current->process, req->handle, 0 ))) -+ { -+ if (fd->unix_name) -+ { -+ struct stat st; -+ if (fd->unix_fd != -1 && !fstat( fd->unix_fd, &st ) && S_ISDIR( st.st_mode )) -+ { -+ set_error( STATUS_FILE_IS_A_DIRECTORY ); -+ goto out; -+ } -+ if (!stat( path, &st )) -+ { -+ struct inode *inode; -+ if (!S_ISREG( st.st_mode )) -+ { -+ set_error( STATUS_ACCESS_DENIED ); -+ goto out; -+ } -+ if ((inode = get_inode( st.st_dev, st.st_ino, -1 ))) -+ { -+ int is_empty = list_empty( &inode->open ); -+ release_object( inode ); -+ if (!is_empty) -+ { -+ set_error( STATUS_ACCESS_DENIED ); -+ goto out; -+ } -+ } -+ if (unlink( path )) -+ { -+ file_set_error(); -+ goto out; -+ } -+ } -+ if (link( fd->unix_name, path )) -+ file_set_error(); -+ } -+ else set_error( STATUS_OBJECT_TYPE_MISMATCH ); -+out: -+ release_object( fd ); -+ } -+ -+ free( path ); -+} + + failed: + free( name ); +@@ -2567,7 +2584,7 @@ DECL_HANDLER(add_fd_completion) + } + } + +-/* rename file */ ++/* rename or link a file */ + DECL_HANDLER(rename_file) + { + struct fd *root_fd = NULL; +@@ -2584,7 +2601,7 @@ DECL_HANDLER(rename_file) + + if ((fd = get_handle_fd_obj( current->process, req->handle, 0 ))) + { +- rename_fd( fd, root_fd, get_req_data(), get_req_data_size() ); ++ rename_fd( fd, root_fd, get_req_data(), get_req_data_size(), req->link ); + release_object( fd ); + } + diff --git a/server/protocol.def b/server/protocol.def -index 431d2b9..1b7814b 100644 +index 431d2b9..c2c4221 100644 --- a/server/protocol.def +++ b/server/protocol.def -@@ -1215,6 +1215,14 @@ enum server_fd_type +@@ -1207,10 +1207,11 @@ enum server_fd_type @END -+/* Create a hardlink */ -+@REQ(link_file) -+ obj_handle_t handle; /* handle to the file */ -+ obj_handle_t rootdir; /* root directory */ -+ VARARG(unix_name,string); /* file name */ -+@END -+ -+ - /* Create a socket */ - @REQ(create_socket) - unsigned int access; /* wanted access rights */ +-/* Rename a file */ ++/* Rename or link a file */ + @REQ(rename_file) + obj_handle_t handle; /* handle to the file */ + obj_handle_t rootdir; /* root directory */ ++ int link; /* link instead of renaming */ + VARARG(unix_name,string); /* file name */ + @END + -- 2.4.2 diff --git a/patches/ntdll-FileDispositionInformation/0013-server-Reject-rename-when-target-has-opened-file-han.patch b/patches/ntdll-FileDispositionInformation/0013-server-Reject-rename-when-target-has-opened-file-han.patch deleted file mode 100644 index e52e5b02..00000000 --- a/patches/ntdll-FileDispositionInformation/0013-server-Reject-rename-when-target-has-opened-file-han.patch +++ /dev/null @@ -1,105 +0,0 @@ -From c39f1e2c924271c262aef89202bec0a4593134af Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 3 Jun 2015 02:03:07 +0200 -Subject: server: Reject rename when target has opened file handles. - ---- - dlls/ntdll/tests/file.c | 14 +++++++------- - server/fd.c | 25 ++++++++++++++++++++++--- - 2 files changed, 29 insertions(+), 10 deletions(-) - -diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index fbcee9b..f60b287 100644 ---- a/dlls/ntdll/tests/file.c -+++ b/dlls/ntdll/tests/file.c -@@ -1619,9 +1619,9 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( !fileDeleted, "File should exist\n" ); -+ ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -@@ -1653,9 +1653,9 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( !fileDeleted, "File should exist\n" ); -+ ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -@@ -1687,9 +1687,9 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( !fileDeleted, "File should exist\n" ); -+ ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -@@ -1915,7 +1915,7 @@ static void test_file_rename_information(void) - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); - todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); -+ ok( res == STATUS_ACCESS_DENIED, "res expect STATUS_ACCESS_DENIED, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -diff --git a/server/fd.c b/server/fd.c -index c261397..719b95f 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -2531,9 +2531,27 @@ DECL_HANDLER(rename_file) - if (fd->unix_name) - { - struct stat st; -- if (!stat( path, &st ) && !S_ISREG( st.st_mode )) -- set_error( STATUS_ACCESS_DENIED ); -- else if (rename( fd->unix_name, path )) -+ if (!stat( path, &st )) -+ { -+ struct inode *inode; -+ if (!S_ISREG( st.st_mode )) -+ { -+ set_error( STATUS_ACCESS_DENIED ); -+ goto out; -+ } -+ if ((inode = get_inode( st.st_dev, st.st_ino, -1 ))) -+ { -+ int is_empty = list_empty( &inode->open ); -+ release_object( inode ); -+ if (!is_empty) -+ { -+ set_error( STATUS_ACCESS_DENIED ); -+ goto out; -+ } -+ } -+ } -+ -+ if (rename( fd->unix_name, path )) - file_set_error(); - else - { -@@ -2543,6 +2561,7 @@ DECL_HANDLER(rename_file) - } - } - else set_error( STATUS_OBJECT_TYPE_MISMATCH ); -+out: - release_object( fd ); - } - --- -2.4.2 - diff --git a/patches/ntdll-FileDispositionInformation/0014-server-Manually-unlink-dest-when-trying-to-replace-a.patch b/patches/ntdll-FileDispositionInformation/0014-server-Manually-unlink-dest-when-trying-to-replace-a.patch deleted file mode 100644 index 54560dcc..00000000 --- a/patches/ntdll-FileDispositionInformation/0014-server-Manually-unlink-dest-when-trying-to-replace-a.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0df467329be9b32d8dadc93230e89629d465511f Mon Sep 17 00:00:00 2001 -From: Sebastian Lackner -Date: Wed, 3 Jun 2015 02:57:21 +0200 -Subject: server: Manually unlink dest when trying to replace a file with - directory. - ---- - dlls/ntdll/tests/file.c | 6 +++--- - server/fd.c | 7 +++++++ - 2 files changed, 10 insertions(+), 3 deletions(-) - -diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c -index f60b287..1f009f6 100644 ---- a/dlls/ntdll/tests/file.c -+++ b/dlls/ntdll/tests/file.c -@@ -1878,10 +1878,10 @@ static void test_file_rename_information(void) - - U(io).Status = 0xdeadbeef; - res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation ); -- todo_wine ok( U(io).Status == STATUS_SUCCESS, "io.Status expect STATUS_SUCCESS, io.Status is %x\n", U(io).Status ); -- todo_wine ok( res == STATUS_SUCCESS, "res expect STATUS_SUCCESS, res is %x\n", res ); -+ ok( U(io).Status == STATUS_SUCCESS, "io.Status expect STATUS_SUCCESS, io.Status is %x\n", U(io).Status ); -+ ok( res == STATUS_SUCCESS, "res expect STATUS_SUCCESS, res is %x\n", res ); - fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; -- todo_wine ok( fileDeleted, "File should have been deleted\n" ); -+ ok( fileDeleted, "File should have been deleted\n" ); - fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND; - ok( !fileDeleted, "File should exist\n" ); - -diff --git a/server/fd.c b/server/fd.c -index 719b95f..ae97a94 100644 ---- a/server/fd.c -+++ b/server/fd.c -@@ -2549,6 +2549,13 @@ DECL_HANDLER(rename_file) - goto out; - } - } -+ -+ if (fd->unix_fd != -1 && !fstat( fd->unix_fd, &st ) && -+ S_ISDIR( st.st_mode ) && unlink( path )) -+ { -+ file_set_error(); -+ goto out; -+ } - } - - if (rename( fd->unix_name, path )) --- -2.4.2 - diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 9d1f58e9..e6d0d376 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3030,33 +3030,25 @@ if test "$enable_ntdll_FileDispositionInformation" -eq 1; then patch_apply ntdll-FileDispositionInformation/0003-server-Do-not-permit-FileDispositionInformation-to-d.patch patch_apply ntdll-FileDispositionInformation/0004-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch patch_apply ntdll-FileDispositionInformation/0005-server-Do-not-allow-to-set-disposition-on-file-which.patch - patch_apply ntdll-FileDispositionInformation/0006-server-Set-the-closed_fd-unix_name-shortly-before-ad.patch - patch_apply ntdll-FileDispositionInformation/0007-ntdll-tests-Add-tests-for-FileRenameInformation.patch - patch_apply ntdll-FileDispositionInformation/0008-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch - patch_apply ntdll-FileDispositionInformation/0009-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch - patch_apply ntdll-FileDispositionInformation/0010-ntdll-Implement-a-hacky-version-of-FileRenameInforma.patch - patch_apply ntdll-FileDispositionInformation/0011-server-FileRenameInformation-target-cannot-be-an-exi.patch - patch_apply ntdll-FileDispositionInformation/0012-server-When-combining-root-and-name-make-sure-there-.patch - patch_apply ntdll-FileDispositionInformation/0013-server-Reject-rename-when-target-has-opened-file-han.patch - patch_apply ntdll-FileDispositionInformation/0014-server-Manually-unlink-dest-when-trying-to-replace-a.patch - patch_apply ntdll-FileDispositionInformation/0015-include-Add-declaration-for-FILE_LINK_INFORMATION.patch - patch_apply ntdll-FileDispositionInformation/0016-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch - patch_apply ntdll-FileDispositionInformation/0017-server-Implement-support-for-FileLinkInformation-cla.patch + patch_apply ntdll-FileDispositionInformation/0006-ntdll-tests-Add-tests-for-FileRenameInformation.patch + patch_apply ntdll-FileDispositionInformation/0007-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch + patch_apply ntdll-FileDispositionInformation/0008-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch + patch_apply ntdll-FileDispositionInformation/0009-ntdll-Implement-FileRenameInformation-support.patch + patch_apply ntdll-FileDispositionInformation/0010-server-When-combining-root-and-name-make-sure-there-.patch + patch_apply ntdll-FileDispositionInformation/0011-include-Add-declaration-for-FILE_LINK_INFORMATION.patch + patch_apply ntdll-FileDispositionInformation/0012-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch + patch_apply ntdll-FileDispositionInformation/0013-server-Implement-support-for-FileLinkInformation-cla.patch ( echo '+ { "Dmitry Timoshkov", "server: Keep a pointer to parent'\''s fd unix_name in the closed_fd structure.", 1 },'; echo '+ { "Dmitry Timoshkov", "server: Add support for setting file disposition information.", 1 },'; echo '+ { "Erich E. Hoover", "server: Do not permit FileDispositionInformation to delete a file without write access.", 1 },'; echo '+ { "Qian Hong", "ntdll/tests: Added tests to set disposition on file which is mapped to memory.", 1 },'; echo '+ { "Qian Hong", "server: Do not allow to set disposition on file which has a file mapping.", 1 },'; - echo '+ { "Sebastian Lackner", "server: Set the closed_fd->unix_name shortly before adding to the closed fd list.", 1 },'; echo '+ { "Jianqiu Zhang", "ntdll/tests: Add tests for FileRenameInformation.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll/tests: Add additional tests for FileRenameInformation.", 1 },'; echo '+ { "Sebastian Lackner", "ntdll/tests: Add tests for FileRenameInformation with nonzero RootDir.", 1 },'; - echo '+ { "Qian Hong", "ntdll: Implement a hacky version of FileRenameInformation support.", 1 },'; - echo '+ { "Sebastian Lackner", "server: FileRenameInformation target cannot be an existing directory.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Implement FileRenameInformation support.", 1 },'; echo '+ { "Sebastian Lackner", "server: When combining root and name, make sure there is only one slash.", 2 },'; - echo '+ { "Sebastian Lackner", "server: Reject rename when target has opened file handles.", 1 },'; - echo '+ { "Sebastian Lackner", "server: Manually unlink dest when trying to replace a file with directory.", 1 },'; echo '+ { "Zhaonan Liang", "include: Add declaration for FILE_LINK_INFORMATION.", 1 },'; echo '+ { "Qian Hong", "ntdll/tests: Add tests for FileLinkInformation class.", 1 },'; echo '+ { "Sebastian Lackner", "server: Implement support for FileLinkInformation class in NtSetInformationFile.", 1 },';