mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
ntdll-FileDispositionInformation: Cleanup of patches for File{Rename,Link}Information.
This commit is contained in:
parent
9fde9be110
commit
32c289493f
@ -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 <dmitry@baikal.ru>
|
||||
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
|
||||
|
||||
|
@ -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 <dmitry@baikal.ru>
|
||||
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
|
||||
|
||||
|
@ -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" <erich.e.hoover@gmail.com>
|
||||
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
|
||||
|
||||
|
@ -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 <qhong@codeweavers.com>
|
||||
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
|
||||
|
||||
|
@ -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 <qhong@codeweavers.com>
|
||||
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
|
||||
|
||||
|
@ -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 <zhangjianqiu_133@yeah.net>
|
||||
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();
|
@ -1,43 +0,0 @@
|
||||
From 2679e91c82514d2f2d90374a06588601498c1baa Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -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 <sebastian@fds-team.de>
|
||||
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)
|
@ -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 <sebastian@fds-team.de>
|
||||
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)
|
@ -1,15 +1,15 @@
|
||||
From 8efe01bbe1fbfdc40bbe97f8f779ded0f252cc6c Mon Sep 17 00:00:00 2001
|
||||
From: Qian Hong <qhong@codeweavers.com>
|
||||
From 526d905701f6d27f38cce701f36f6280f7c2c6cf Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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 <sebastian@fds-team.de>.
|
||||
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
|
@ -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 <sebastian@fds-team.de>
|
||||
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++;
|
||||
|
@ -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 <bt2517@126.com>
|
||||
Date: Tue, 28 Apr 2015 19:06:31 +0800
|
||||
Subject: include: Add declaration for FILE_LINK_INFORMATION.
|
@ -1,66 +0,0 @@
|
||||
From c11a0a4e007badd714f500da3899a88ab363e51a Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -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 <qhong@codeweavers.com>
|
||||
Date: Wed, 3 Jun 2015 17:41:59 +0800
|
||||
Subject: ntdll/tests: Add tests for FileLinkInformation class.
|
@ -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 <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -1,105 +0,0 @@
|
||||
From c39f1e2c924271c262aef89202bec0a4593134af Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 0df467329be9b32d8dadc93230e89629d465511f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
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
|
||||
|
@ -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 },';
|
||||
|
Loading…
Reference in New Issue
Block a user