You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Rebase against 5ccc463a4e3ba181b96a161c3c8cd4bc0cb0e607.
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
From 4c33b67050e2dc88ab8f1e08f4b2559132a50262 Mon Sep 17 00:00:00 2001
|
||||
From b4eabfd0a1eaca783c6a0fe35de8b1166412f078 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,10 +12,10 @@ 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 99aaa37..d1055e8 100644
|
||||
index 440cfaa..40c932b 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -2068,8 +2068,8 @@ static void test_file_rename_information(void)
|
||||
@@ -2111,8 +2111,8 @@ static void test_file_rename_information(void)
|
||||
res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
|
||||
ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
@ -27,18 +27,18 @@ index 99aaa37..d1055e8 100644
|
||||
|
||||
CloseHandle( handle );
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 04891e7..c0b5548 100644
|
||||
index b30ae11..07e0fc5 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -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 *dup_fd_name( struct fd *root, const char *name )
|
||||
{
|
||||
char *ret;
|
||||
+ int len;
|
||||
|
||||
if (!root) return strdup( name );
|
||||
if (!root->unix_name) return NULL;
|
||||
@@ -1727,11 +1728,18 @@ static char *dup_fd_name( struct fd *root, const char *name )
|
||||
@@ -1727,11 +1728,18 @@ char *dup_fd_name( struct fd *root, const char *name )
|
||||
/* skip . prefix */
|
||||
if (name[0] == '.' && (!name[1] || name[1] == '/')) name++;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,344 +0,0 @@
|
||||
From 33b20afef41c75ec5fb2407ec226daef12039c97 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 | 44 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/tests/file.c | 54 ++++++++++++++++++++++++-------------------------
|
||||
server/fd.c | 25 +++++++++++++++++++----
|
||||
server/protocol.def | 1 +
|
||||
4 files changed, 93 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
|
||||
index 3cef11b..be6b591 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -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))
|
||||
+ {
|
||||
+ FILE_LINK_INFORMATION *info = ptr;
|
||||
+ UNICODE_STRING name_str;
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ ANSI_STRING unix_name;
|
||||
+
|
||||
+ name_str.Buffer = info->FileName;
|
||||
+ name_str.Length = info->FileNameLength;
|
||||
+ name_str.MaximumLength = info->FileNameLength + sizeof(WCHAR);
|
||||
+
|
||||
+ attr.Length = sizeof(attr);
|
||||
+ attr.ObjectName = &name_str;
|
||||
+ attr.RootDirectory = info->RootDirectory;
|
||||
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||
+
|
||||
+ io->u.Status = nt_to_unix_file_name_attr( &attr, &unix_name, FILE_OPEN_IF );
|
||||
+ if (io->u.Status != STATUS_SUCCESS && io->u.Status != STATUS_NO_SUCH_FILE)
|
||||
+ break;
|
||||
+
|
||||
+ if (!info->ReplaceIfExists && io->u.Status == STATUS_SUCCESS)
|
||||
+ {
|
||||
+ RtlFreeAnsiString( &unix_name );
|
||||
+ io->u.Status = STATUS_OBJECT_NAME_COLLISION;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ SERVER_START_REQ( set_fd_name_info )
|
||||
+ {
|
||||
+ req->handle = wine_server_obj_handle( handle );
|
||||
+ req->rootdir = wine_server_obj_handle( attr.RootDirectory );
|
||||
+ 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 177c2c5..5b3db09 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -2113,12 +2113,12 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
- todo_wine ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %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;
|
||||
- todo_wine ok( !fileDeleted, "file should exist\n" );
|
||||
+ ok( !fileDeleted, "file should exist\n" );
|
||||
|
||||
fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
|
||||
res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
|
||||
@@ -2152,7 +2152,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %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;
|
||||
@@ -2185,7 +2185,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %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;
|
||||
@@ -2215,8 +2215,8 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
- todo_wine ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %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;
|
||||
@@ -2249,7 +2249,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
|
||||
+ ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %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;
|
||||
@@ -2283,7 +2283,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
|
||||
+ ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %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;
|
||||
@@ -2317,7 +2317,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
|
||||
+ ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %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;
|
||||
@@ -2352,7 +2352,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef , "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2399,7 +2399,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2433,8 +2433,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
- "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
+ "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2470,8 +2470,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
- "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
+ "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2505,7 +2505,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2541,7 +2541,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2578,8 +2578,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
- "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || res == STATUS_FILE_IS_A_DIRECTORY /* > Win XP */,
|
||||
+ "res expected STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2615,7 +2615,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2654,7 +2654,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expected STATUS_FILE_IS_A_DIRECTORY, got %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;
|
||||
@@ -2688,7 +2688,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "res expected STATUS_OBJECT_NAME_COLLISION, got %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;
|
||||
@@ -2721,7 +2721,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %x\n", res );
|
||||
+ ok( res == STATUS_ACCESS_DENIED, "res expected STATUS_ACCESS_DENIED, got %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;
|
||||
@@ -2754,12 +2754,12 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, fli, sizeof(FILE_LINK_INFORMATION) + fli->FileNameLength, FileLinkInformation );
|
||||
- todo_wine ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ ok( U(io).Status == STATUS_SUCCESS, "io.Status expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %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;
|
||||
- todo_wine ok( !fileDeleted, "file should exist\n" );
|
||||
+ ok( !fileDeleted, "file should exist\n" );
|
||||
|
||||
fni = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR) );
|
||||
res = pNtQueryInformationFile( handle, &io, fni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index c0b5548..94489e7 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2275,7 +2275,7 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
}
|
||||
|
||||
/* set new name for the fd */
|
||||
-static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len )
|
||||
+static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, data_size_t len, int do_link )
|
||||
{
|
||||
struct inode *inode;
|
||||
struct stat st;
|
||||
@@ -2307,6 +2307,14 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
name = combined_name;
|
||||
}
|
||||
|
||||
+ /* when creating a hard link, source must be a file */
|
||||
+ if (do_link && fd->unix_fd != -1 &&
|
||||
+ !fstat( fd->unix_fd, &st ) && S_ISDIR( st.st_mode ))
|
||||
+ {
|
||||
+ set_error( STATUS_FILE_IS_A_DIRECTORY );
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
if (!stat( name, &st ))
|
||||
{
|
||||
/* can't replace directories or special files */
|
||||
@@ -2328,15 +2336,24 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
|
||||
}
|
||||
}
|
||||
|
||||
+ /* link() expects that the target doesn't exist */
|
||||
/* rename() cannot 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;
|
||||
}
|
||||
}
|
||||
|
||||
+ if (do_link)
|
||||
+ {
|
||||
+ if (link( fd->unix_name, name ))
|
||||
+ file_set_error();
|
||||
+ free( name );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (rename( fd->unix_name, name ))
|
||||
{
|
||||
file_set_error();
|
||||
@@ -2576,7 +2593,7 @@ DECL_HANDLER(set_fd_name_info)
|
||||
|
||||
if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
|
||||
{
|
||||
- set_fd_name( fd, root_fd, get_req_data(), get_req_data_size() );
|
||||
+ set_fd_name( fd, root_fd, get_req_data(), get_req_data_size(), req->link );
|
||||
release_object( fd );
|
||||
}
|
||||
if (root_fd) release_object( root_fd );
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index d3ff4b7..c313006 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -3536,6 +3536,7 @@ enum coords_relative
|
||||
@REQ(set_fd_name_info)
|
||||
obj_handle_t handle; /* handle to a file or directory */
|
||||
obj_handle_t rootdir; /* root directory */
|
||||
+ int link; /* link instead of renaming */
|
||||
VARARG(filename,string); /* new file name */
|
||||
@END
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Fixes: [30397] Support for NtSetInformationFile class FileDispositionInformation
|
||||
# Fixes: [30399] Support for NtSetInformationFile class FileRenameInformation
|
||||
Fixes: Support for NtSetInformationFile class FileLinkInformation
|
||||
# Fixes: Support for NtSetInformationFile class FileLinkInformation
|
||||
Depends: server-File_Permissions
|
||||
|
Reference in New Issue
Block a user