mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against 5021e91940fe01a54e6ee91f9d9f246ce8f6dd84.
This commit is contained in:
parent
428f65dd68
commit
323b73a1f2
@ -261,9 +261,9 @@ for more details.*
|
||||
* Support for MPEG2 DXVA2 GPU video decoding through vaapi
|
||||
* Support for NVIDIA video encoder library (nvencodeapi)
|
||||
* Support for NtQuerySection ([Wine Bug #37338](https://bugs.winehq.org/show_bug.cgi?id=37338))
|
||||
* Support for NtSetInformationFile class FileDispositionInformation ([Wine Bug #30397](https://bugs.winehq.org/show_bug.cgi?id=30397))
|
||||
* ~~Support for NtSetInformationFile class FileDispositionInformation~~ ([Wine Bug #30397](https://bugs.winehq.org/show_bug.cgi?id=30397))
|
||||
* Support for NtSetInformationFile class FileLinkInformation
|
||||
* Support for NtSetInformationFile class FileRenameInformation ([Wine Bug #30399](https://bugs.winehq.org/show_bug.cgi?id=30399))
|
||||
* ~~Support for NtSetInformationFile class FileRenameInformation~~ ([Wine Bug #30399](https://bugs.winehq.org/show_bug.cgi?id=30399))
|
||||
* Support for PulseAudio backend for audio ([Wine Bug #10495](https://bugs.winehq.org/show_bug.cgi?id=10495))
|
||||
* Support for SHCreateSessionKey ([Wine Bug #35630](https://bugs.winehq.org/show_bug.cgi?id=35630))
|
||||
* Support for TransmitFile ([Wine Bug #5048](https://bugs.winehq.org/show_bug.cgi?id=5048))
|
||||
|
2
debian/changelog
vendored
2
debian/changelog
vendored
@ -32,6 +32,8 @@ wine-staging (1.7.50) UNRELEASED; urgency=low
|
||||
double \r\n (accepted upstream).
|
||||
* Removed compatibility patchset for deprecated ACL string format. The format
|
||||
was changed in version 1.7.25, released about one year ago.
|
||||
* Removed patches for FileDispositionInformation and FileRenameInformation
|
||||
(accepted upstream).
|
||||
-- Sebastian Lackner <sebastian@fds-team.de> Tue, 11 Aug 2015 06:12:14 +0200
|
||||
|
||||
wine-staging (1.7.49) unstable; urgency=low
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f6318b095ddb9969a7b2b29e2fcbad3ea02ccefb Mon Sep 17 00:00:00 2001
|
||||
From c04c1737fad3efc975d9cedcd2f12547cc482f68 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 0bdd22f..fc6fc33 100644
|
||||
index 2e630e3..740e44a 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -1455,12 +1455,13 @@ static void test_file_disposition_information(void)
|
||||
@@ -2099,12 +2099,13 @@ static void test_file_disposition_information(void)
|
||||
{
|
||||
char tmp_path[MAX_PATH], buffer[MAX_PATH + 16];
|
||||
DWORD dirpos;
|
||||
@ -27,7 +27,7 @@ index 0bdd22f..fc6fc33 100644
|
||||
|
||||
GetTempPathA( MAX_PATH, tmp_path );
|
||||
|
||||
@@ -1640,6 +1641,74 @@ static void test_file_disposition_information(void)
|
||||
@@ -2269,6 +2270,74 @@ static void test_file_disposition_information(void)
|
||||
todo_wine
|
||||
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
|
||||
RemoveDirectoryA( buffer );
|
||||
@ -103,5 +103,5 @@ index 0bdd22f..fc6fc33 100644
|
||||
|
||||
static void test_iocompletion(void)
|
||||
--
|
||||
2.4.2
|
||||
2.5.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2b11498b6880f1bf7c0675e2df234626b4f8d69e Mon Sep 17 00:00:00 2001
|
||||
From adecc0a88655710360130ba8e2c7f61d855e9d8b 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
|
||||
@ -10,10 +10,10 @@ Subject: server: Do not allow to set disposition on file which has a file
|
||||
2 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index 4bc4925..7165776 100644
|
||||
index 740e44a..99aaa37 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -1649,7 +1649,6 @@ static void test_file_disposition_information(void)
|
||||
@@ -2279,7 +2279,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 4bc4925..7165776 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;
|
||||
@@ -1683,7 +1682,6 @@ static void test_file_disposition_information(void)
|
||||
@@ -2313,7 +2312,6 @@ static void test_file_disposition_information(void)
|
||||
CloseHandle( mapping );
|
||||
fdi.DoDeleteFile = TRUE;
|
||||
res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
|
||||
@ -30,7 +30,7 @@ index 4bc4925..7165776 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 0bac57d..f93093d 100644
|
||||
index 5130b44..04891e7 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2218,6 +2218,7 @@ static struct fd *get_handle_fd_obj( struct process *process, obj_handle_t handl
|
||||
|
@ -1,136 +0,0 @@
|
||||
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.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 106 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
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)
|
||||
CloseHandle( h );
|
||||
}
|
||||
|
||||
+static void test_file_rename_information(void)
|
||||
+{
|
||||
+ static const WCHAR foo[] = {'f','o','o',0};
|
||||
+ WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16];
|
||||
+ UNICODE_STRING name_str;
|
||||
+ HANDLE handle;
|
||||
+ NTSTATUS res;
|
||||
+ IO_STATUS_BLOCK io;
|
||||
+ PFILE_RENAME_INFORMATION pfri;
|
||||
+ BOOL fileDeleted;
|
||||
+
|
||||
+ GetTempPathW( MAX_PATH, tmp_path );
|
||||
+
|
||||
+ /* newpath doesn't exist at first */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ DeleteFileW( newpath );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( fileDeleted, "File should have been deleted\n" );
|
||||
+ fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ DeleteFileW( newpath );
|
||||
+
|
||||
+ /* newpath exists in temp directory, Replace = false */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ U(io).Status = 0xdeadbeef;
|
||||
+ res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
+ todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+ fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ DeleteFileW( newpath );
|
||||
+
|
||||
+ /* newpath exists in temp directory, Replace = true */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( fileDeleted, "File should have been deleted!\n" );
|
||||
+ fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ DeleteFileW( newpath );
|
||||
+}
|
||||
+
|
||||
static void test_file_both_information(void)
|
||||
{
|
||||
IO_STATUS_BLOCK io;
|
||||
@@ -3001,6 +3106,7 @@ START_TEST(file)
|
||||
test_file_name_information();
|
||||
test_file_full_size_information();
|
||||
test_file_all_name_information();
|
||||
+ test_file_rename_information();
|
||||
test_file_disposition_information();
|
||||
test_query_volume_information_file();
|
||||
test_query_attribute_information_file();
|
||||
--
|
||||
2.4.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From d0201524cc9fcc78997ae699995bb192f37b78d1 Mon Sep 17 00:00:00 2001
|
||||
From 4c33b67050e2dc88ab8f1e08f4b2559132a50262 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,22 +12,22 @@ 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 941cc0c..8072a15 100644
|
||||
index 99aaa37..d1055e8 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -2138,8 +2138,8 @@ static void test_file_rename_information(void)
|
||||
res = pNtQueryInformationFile( handle, &io, pfni, sizeof(FILE_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR), FileNameInformation );
|
||||
@@ -2068,8 +2068,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 );
|
||||
pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
- todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
- wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
HeapFree( GetProcessHeap(), 0, pfni );
|
||||
fni->FileName[ fni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
- todo_wine ok( !lstrcmpW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
- wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
|
||||
+ ok( !lstrcmpW(fni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(fni->FileName) );
|
||||
HeapFree( GetProcessHeap(), 0, fni );
|
||||
|
||||
CloseHandle( handle );
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index d4e5321..4b0bf47 100644
|
||||
index 04891e7..c0b5548 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
|
||||
@ -62,5 +62,5 @@ index d4e5321..4b0bf47 100644
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
2.4.2
|
||||
2.5.0
|
||||
|
@ -1,665 +0,0 @@
|
||||
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.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 586 ++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 573 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
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)
|
||||
CloseHandle( h );
|
||||
}
|
||||
|
||||
+static void delete_object( WCHAR *path )
|
||||
+{
|
||||
+ BOOL ret;
|
||||
+
|
||||
+ ret = DeleteFileW( path );
|
||||
+ ok( ret || GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_ACCESS_DENIED,
|
||||
+ "DeleteFileW failed with %u\n", GetLastError() );
|
||||
+ if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
|
||||
+ {
|
||||
+ ret = RemoveDirectoryW( path );
|
||||
+ ok( ret, "RemoveDirectoryW failed with %u\n", GetLastError() );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void test_file_rename_information(void)
|
||||
{
|
||||
+ static const WCHAR foo_txt[] = {'\\','f','o','o','.','t','x','t',0};
|
||||
static const WCHAR foo[] = {'f','o','o',0};
|
||||
WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16];
|
||||
UNICODE_STRING name_str;
|
||||
- HANDLE handle;
|
||||
+ HANDLE handle, handle2;
|
||||
NTSTATUS res;
|
||||
IO_STATUS_BLOCK io;
|
||||
- PFILE_RENAME_INFORMATION pfri;
|
||||
- BOOL fileDeleted;
|
||||
+ FILE_RENAME_INFORMATION *pfri;
|
||||
+ FILE_NAME_INFORMATION *pfni;
|
||||
+ BOOL success, fileDeleted;
|
||||
|
||||
GetTempPathW( MAX_PATH, tmp_path );
|
||||
|
||||
- /* newpath doesn't exist at first */
|
||||
+ /* oldpath is a file, newpath doesn't exist */
|
||||
res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
ok( res != 0, "fail to create temp file\n" );
|
||||
handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
@@ -1470,19 +1486,308 @@ static void test_file_rename_information(void)
|
||||
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 );
|
||||
fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( fileDeleted, "File should not exist\n" );
|
||||
+ fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ 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 );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
+ todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfni );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = FALSE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ U(io).Status = 0xdeadbeef;
|
||||
+ res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
+ todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = FALSE, target file opened */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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_OBJECT_NAME_COLLISION, "res expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = TRUE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine 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" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened with FILE_SHARE_DELETE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a file, Replace = TRUE, target file opened with FILE_SHARE_DELETE | FILE_SHARE_WRITE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath doesn't exist, Replace = FALSE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ DeleteFileW( newpath );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
todo_wine ok( fileDeleted, "File should have been deleted\n" );
|
||||
fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
todo_wine ok( !fileDeleted, "File should exist\n" );
|
||||
|
||||
+ 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 );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
+ todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfni );
|
||||
+
|
||||
CloseHandle( handle );
|
||||
HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory (but child object opened), newpath doesn't exist, Replace = FALSE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ lstrcpyW( newpath, oldpath );
|
||||
+ lstrcatW( newpath, foo_txt );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
DeleteFileW( newpath );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
|
||||
- /* newpath exists in temp directory, Replace = false */
|
||||
+ 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 expected 0xdeadbeef, got %x\n", U(io).Status );
|
||||
+ todo_wine 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;
|
||||
+ ok( fileDeleted, "File should not exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a file, Replace = FALSE */
|
||||
res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
ok( res != 0, "fail to create temp file\n" );
|
||||
- handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
|
||||
res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
@@ -1500,19 +1805,59 @@ static void test_file_rename_information(void)
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
- ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
- ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
|
||||
CloseHandle( handle );
|
||||
HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a file, Replace = FALSE, target file opened */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
DeleteFileW( oldpath );
|
||||
- DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
|
||||
- /* newpath exists in temp directory, Replace = true */
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ U(io).Status = 0xdeadbeef;
|
||||
+ res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
+ todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a file, Replace = TRUE */
|
||||
res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
ok( res != 0, "fail to create temp file\n" );
|
||||
- handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
|
||||
res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
@@ -1530,14 +1875,229 @@ static void test_file_rename_information(void)
|
||||
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 );
|
||||
fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
- todo_wine ok( fileDeleted, "File should have been deleted!\n" );
|
||||
+ todo_wine ok( fileDeleted, "File should have been deleted\n" );
|
||||
fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
- ok( !fileDeleted, "File shouldn't have been deleted!\n" );
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
|
||||
CloseHandle( handle );
|
||||
HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a file, Replace = TRUE, target file opened */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a directory, Replace = FALSE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( newpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ U(io).Status = 0xdeadbeef;
|
||||
+ res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
+ todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a directory, Replace = TRUE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( newpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a directory, newpath is a directory, Replace = TRUE, target file opened */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( oldpath );
|
||||
+ success = CreateDirectoryW( oldpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( newpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ handle2 = CreateFileW( newpath, GENERIC_WRITE | DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a directory, Replace = FALSE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( newpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ U(io).Status = 0xdeadbeef;
|
||||
+ res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
+ todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath is a directory, Replace = TRUE */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( newpath );
|
||||
+ success = CreateDirectoryW( newpath, NULL );
|
||||
+ ok( success != 0, "failed to create temp directory\n" );
|
||||
+ pRtlDosPathNameToNtPathName_U( newpath, &name_str, NULL, NULL );
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + name_str.Length );
|
||||
+ pfri->Replace = TRUE;
|
||||
+ pfri->RootDir = NULL;
|
||||
+ pfri->FileNameLength = name_str.Length;
|
||||
+ memcpy( pfri->FileName, name_str.Buffer, name_str.Length );
|
||||
+ pRtlFreeUnicodeString( &name_str );
|
||||
+
|
||||
+ 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 );
|
||||
+ 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;
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
}
|
||||
|
||||
static void test_file_both_information(void)
|
||||
--
|
||||
2.4.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,76 +0,0 @@
|
||||
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
|
||||
RootDir.
|
||||
|
||||
---
|
||||
dlls/ntdll/tests/file.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
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)
|
||||
{
|
||||
static const WCHAR foo_txt[] = {'\\','f','o','o','.','t','x','t',0};
|
||||
static const WCHAR foo[] = {'f','o','o',0};
|
||||
- WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16];
|
||||
+ WCHAR tmp_path[MAX_PATH], oldpath[MAX_PATH + 16], newpath[MAX_PATH + 16], *filename, *p;
|
||||
UNICODE_STRING name_str;
|
||||
HANDLE handle, handle2;
|
||||
NTSTATUS res;
|
||||
@@ -2098,6 +2098,49 @@ static void test_file_rename_information(void)
|
||||
HeapFree( GetProcessHeap(), 0, pfri );
|
||||
delete_object( oldpath );
|
||||
delete_object( newpath );
|
||||
+
|
||||
+ /* oldpath is a file, newpath doesn't exist, test with RootDir != NULL */
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, oldpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ handle = CreateFileW( oldpath, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0 );
|
||||
+ ok( handle != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ res = GetTempFileNameW( tmp_path, foo, 0, newpath );
|
||||
+ ok( res != 0, "fail to create temp file\n" );
|
||||
+ DeleteFileW( newpath );
|
||||
+ for (filename = newpath, p = newpath; *p; p++)
|
||||
+ if (*p == '\\') filename = p + 1;
|
||||
+ handle2 = CreateFileW( tmp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
|
||||
+ ok( handle2 != INVALID_HANDLE_VALUE, "CreateFileW failed\n" );
|
||||
+
|
||||
+ pfri = HeapAlloc( GetProcessHeap(), 0, sizeof(FILE_RENAME_INFORMATION) + lstrlenW(filename) * sizeof(WCHAR) );
|
||||
+ pfri->Replace = FALSE;
|
||||
+ pfri->RootDir = handle2;
|
||||
+ pfri->FileNameLength = lstrlenW(filename) * sizeof(WCHAR);
|
||||
+ memcpy( pfri->FileName, filename, pfri->FileNameLength );
|
||||
+
|
||||
+ 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 expected STATUS_SUCCESS, got %x\n", U(io).Status );
|
||||
+ todo_wine ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ fileDeleted = GetFileAttributesW( oldpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( fileDeleted, "File should not exist\n" );
|
||||
+ fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
+ todo_wine ok( !fileDeleted, "File should exist\n" );
|
||||
+
|
||||
+ 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 );
|
||||
+ ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
+ pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
+ todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfni );
|
||||
+
|
||||
+ CloseHandle( handle );
|
||||
+ CloseHandle( handle2 );
|
||||
+ HeapFree( GetProcessHeap(), 0, pfri );
|
||||
+ delete_object( oldpath );
|
||||
+ delete_object( newpath );
|
||||
}
|
||||
|
||||
static void test_file_both_information(void)
|
||||
--
|
||||
2.4.2
|
||||
|
@ -0,0 +1,344 @@
|
||||
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,443 +0,0 @@
|
||||
From 80f50af6703521e5a8ff7a3fa9bbb67abe52a210 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 FileRenameInformation support.
|
||||
|
||||
Based on a patch by Qian Hong.
|
||||
---
|
||||
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 314c233..b865345 100644
|
||||
--- a/dlls/ntdll/file.c
|
||||
+++ b/dlls/ntdll/file.c
|
||||
@@ -2781,6 +2781,48 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
|
||||
io->u.Status = STATUS_INVALID_PARAMETER_3;
|
||||
break;
|
||||
|
||||
+ case FileRenameInformation:
|
||||
+ if (len >= sizeof(FILE_RENAME_INFORMATION))
|
||||
+ {
|
||||
+ FILE_RENAME_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->RootDir;
|
||||
+ 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->Replace && io->u.Status == STATUS_SUCCESS)
|
||||
+ {
|
||||
+ RtlFreeAnsiString( &unix_name );
|
||||
+ io->u.Status = STATUS_OBJECT_NAME_COLLISION;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ 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;
|
||||
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
|
||||
index d7be561..31a672d 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -1483,19 +1483,19 @@ 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 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;
|
||||
- todo_wine ok( fileDeleted, "File should not exist\n" );
|
||||
+ ok( fileDeleted, "File should not 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" );
|
||||
|
||||
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 );
|
||||
ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
- todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
- wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
HeapFree( GetProcessHeap(), 0, pfni );
|
||||
|
||||
CloseHandle( handle );
|
||||
@@ -1522,7 +1522,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, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -1555,7 +1555,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_OBJECT_NAME_COLLISION, "res expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "res expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -1585,10 +1585,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" );
|
||||
|
||||
@@ -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 );
|
||||
+ 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;
|
||||
@@ -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 );
|
||||
+ 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;
|
||||
@@ -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 );
|
||||
+ 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;
|
||||
@@ -1721,19 +1721,19 @@ 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 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;
|
||||
- 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;
|
||||
- todo_wine ok( !fileDeleted, "File should exist\n" );
|
||||
+ ok( !fileDeleted, "File should exist\n" );
|
||||
|
||||
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 );
|
||||
ok( res == STATUS_SUCCESS, "res expected STATUS_SUCCESS, got %x\n", res );
|
||||
pfni->FileName[ pfni->FileNameLength / sizeof(WCHAR) ] = 0;
|
||||
- todo_wine ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
- wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
+ ok( !lstrcmpW(pfni->FileName, newpath + 2), "FileName expected %s, got %s\n",
|
||||
+ wine_dbgstr_w(newpath + 2), wine_dbgstr_w(pfni->FileName) );
|
||||
HeapFree( GetProcessHeap(), 0, pfni );
|
||||
|
||||
CloseHandle( handle );
|
||||
@@ -1771,14 +1771,20 @@ static void test_file_rename_information(void)
|
||||
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 );
|
||||
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 not exist\n" );
|
||||
+ todo_wine ok( fileDeleted, "File should not exist\n" );
|
||||
|
||||
CloseHandle( handle );
|
||||
CloseHandle( handle2 );
|
||||
HeapFree( GetProcessHeap(), 0, pfri );
|
||||
delete_object( oldpath );
|
||||
+ if (res == STATUS_SUCCESS) /* remove when wine is fixed */
|
||||
+ {
|
||||
+ lstrcpyW( oldpath, newpath );
|
||||
+ lstrcatW( oldpath, foo_txt );
|
||||
+ delete_object( oldpath );
|
||||
+ }
|
||||
delete_object( newpath );
|
||||
|
||||
/* oldpath is a directory, newpath is a file, Replace = FALSE */
|
||||
@@ -1803,7 +1809,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, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -1839,7 +1845,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, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -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 );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -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 );
|
||||
+ 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;
|
||||
@@ -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 );
|
||||
+ 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;
|
||||
@@ -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 );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileRenameInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -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;
|
||||
res = pNtSetInformationFile( handle, &io, pfri, sizeof(FILE_RENAME_INFORMATION) + pfri->FileNameLength, FileRenameInformation );
|
||||
- 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;
|
||||
- todo_wine ok( fileDeleted, "File should not exist\n" );
|
||||
+ ok( fileDeleted, "File should not 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" );
|
||||
|
||||
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 f93093d..24e845c 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2266,6 +2266,80 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
fd->closed->unlink = unlink || (fd->options & FILE_DELETE_ON_CLOSE);
|
||||
}
|
||||
|
||||
+/* 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->inode || !fd->unix_name)
|
||||
+ {
|
||||
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
|
||||
+ return;
|
||||
+ }
|
||||
+ if (!(name = mem_alloc( len + 1 ))) return;
|
||||
+ 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 );
|
||||
+}
|
||||
+
|
||||
struct completion *fd_get_completion( struct fd *fd, apc_param_t *p_key )
|
||||
{
|
||||
*p_key = fd->comp_key;
|
||||
@@ -2472,3 +2546,27 @@ DECL_HANDLER(set_fd_info)
|
||||
release_object( fd );
|
||||
}
|
||||
}
|
||||
+
|
||||
+/* rename file */
|
||||
+DECL_HANDLER(rename_file)
|
||||
+{
|
||||
+ struct fd *root_fd = NULL;
|
||||
+ struct fd *fd;
|
||||
+
|
||||
+ if (req->rootdir)
|
||||
+ {
|
||||
+ struct dir *root;
|
||||
+ 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;
|
||||
+ }
|
||||
+
|
||||
+ if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
|
||||
+ {
|
||||
+ rename_fd( fd, root_fd, get_req_data(), get_req_data_size() );
|
||||
+ release_object( fd );
|
||||
+ }
|
||||
+
|
||||
+ if (root_fd) release_object( root_fd );
|
||||
+}
|
||||
diff --git a/server/protocol.def b/server/protocol.def
|
||||
index ea9eb12..3f1cef5 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -1233,6 +1233,15 @@ enum server_fd_type
|
||||
@END
|
||||
|
||||
|
||||
+
|
||||
+/* Rename a file */
|
||||
+@REQ(rename_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 */
|
||||
--
|
||||
2.5.0
|
||||
|
@ -1,30 +0,0 @@
|
||||
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.
|
||||
|
||||
---
|
||||
include/winternl.h | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index a84c6d4..d208537 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -567,6 +567,13 @@ typedef struct _FILE_RENAME_INFORMATION {
|
||||
WCHAR FileName[1];
|
||||
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
|
||||
|
||||
+typedef struct _FILE_LINK_INFORMATION {
|
||||
+ BOOLEAN ReplaceIfExists;
|
||||
+ HANDLE RootDirectory;
|
||||
+ ULONG FileNameLength;
|
||||
+ WCHAR FileName[1];
|
||||
+} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
|
||||
+
|
||||
typedef struct _FILE_NAMES_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG FileIndex;
|
||||
--
|
||||
2.4.2
|
||||
|
@ -1,381 +0,0 @@
|
||||
From 5555934a5d007286895f7ad2c7523899be9e3c9b 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 | 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 b865345..049b323 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( rename_file )
|
||||
+ {
|
||||
+ 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 5da5d0d..27ea58c 100644
|
||||
--- a/dlls/ntdll/tests/file.c
|
||||
+++ b/dlls/ntdll/tests/file.c
|
||||
@@ -2183,12 +2183,12 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->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" );
|
||||
|
||||
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 );
|
||||
@@ -2222,7 +2222,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileLinkInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -2255,7 +2255,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "res expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "res expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -2285,8 +2285,8 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
- 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;
|
||||
ok( !fileDeleted, "File should exist\n" );
|
||||
fileDeleted = GetFileAttributesW( newpath ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
|
||||
@@ -2319,7 +2319,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
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;
|
||||
@@ -2353,7 +2353,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
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;
|
||||
@@ -2387,7 +2387,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
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;
|
||||
@@ -2422,7 +2422,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->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;
|
||||
@@ -2469,7 +2469,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->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;
|
||||
@@ -2503,8 +2503,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileLinkInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
- "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
+ "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2540,8 +2540,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileLinkInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
- "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
+ "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2575,7 +2575,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2611,7 +2611,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2648,8 +2648,8 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileLinkInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
- "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION || broken(res == STATUS_FILE_IS_A_DIRECTORY) /* > Win XP */,
|
||||
+ "expect STATUS_OBJECT_NAME_COLLISION or STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2685,7 +2685,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2724,7 +2724,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "io.Status expect 0xdeadbeef, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, res is %x\n", res );
|
||||
+ ok( res == STATUS_FILE_IS_A_DIRECTORY, "res expect STATUS_FILE_IS_A_DIRECTORY, 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;
|
||||
@@ -2758,7 +2758,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
todo_wine ok( U(io).Status == 0xdeadbeef, "shouldn't be able to set FileLinkInformation, io.Status is %x\n", U(io).Status );
|
||||
- todo_wine ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, res is %x\n", res );
|
||||
+ ok( res == STATUS_OBJECT_NAME_COLLISION, "expect STATUS_OBJECT_NAME_COLLISION, 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;
|
||||
@@ -2791,7 +2791,7 @@ static void test_file_link_information(void)
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->FileNameLength, FileLinkInformation );
|
||||
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;
|
||||
@@ -2824,12 +2824,12 @@ static void test_file_link_information(void)
|
||||
|
||||
U(io).Status = 0xdeadbeef;
|
||||
res = pNtSetInformationFile( handle, &io, pfli, sizeof(FILE_LINK_INFORMATION) + pfli->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" );
|
||||
|
||||
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 757a06c..8c3c97e 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2274,8 +2274,8 @@ static void set_fd_disposition( struct fd *fd, int unlink )
|
||||
fd->closed->unlink = unlink || (fd->options & FILE_DELETE_ON_CLOSE);
|
||||
}
|
||||
|
||||
-/* 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;
|
||||
@@ -2302,8 +2302,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;
|
||||
+ }
|
||||
+
|
||||
if (stat( name, &st ))
|
||||
- goto do_rename;
|
||||
+ goto skip_checks;
|
||||
|
||||
if (!S_ISREG( st.st_mode ))
|
||||
{
|
||||
@@ -2324,25 +2332,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;
|
||||
+ }
|
||||
|
||||
failed:
|
||||
free( name );
|
||||
@@ -2555,7 +2572,7 @@ DECL_HANDLER(set_fd_info)
|
||||
}
|
||||
}
|
||||
|
||||
-/* rename file */
|
||||
+/* rename or link a file */
|
||||
DECL_HANDLER(rename_file)
|
||||
{
|
||||
struct fd *root_fd = NULL;
|
||||
@@ -2572,7 +2589,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 3f1cef5..1c868c3 100644
|
||||
--- a/server/protocol.def
|
||||
+++ b/server/protocol.def
|
||||
@@ -1234,10 +1234,11 @@ enum server_fd_type
|
||||
|
||||
|
||||
|
||||
-/* 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.5.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
Fixes: [30397] Support for NtSetInformationFile class FileDispositionInformation
|
||||
Fixes: [30399] Support for NtSetInformationFile class FileRenameInformation
|
||||
# Fixes: [30397] Support for NtSetInformationFile class FileDispositionInformation
|
||||
# Fixes: [30399] Support for NtSetInformationFile class FileRenameInformation
|
||||
Fixes: Support for NtSetInformationFile class FileLinkInformation
|
||||
Depends: server-File_Permissions
|
||||
|
@ -55,7 +55,7 @@ version()
|
||||
echo "Copyright (C) 2014-2015 the Wine Staging project authors."
|
||||
echo ""
|
||||
echo "Patchset to be applied on upstream Wine:"
|
||||
echo " commit 3b5107d06305972beaa9c5ff147ecbcd99949a75"
|
||||
echo " commit 5021e91940fe01a54e6ee91f9d9f246ce8f6dd84"
|
||||
echo ""
|
||||
}
|
||||
|
||||
@ -3149,33 +3149,19 @@ fi
|
||||
# | This patchset has the following dependencies:
|
||||
# | * server-File_Permissions
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#30397] Support for NtSetInformationFile class FileDispositionInformation
|
||||
# | * [#30399] Support for NtSetInformationFile class FileRenameInformation
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c, include/winternl.h, server/fd.c, server/protocol.def
|
||||
# | * dlls/ntdll/file.c, dlls/ntdll/tests/file.c, server/fd.c, server/protocol.def
|
||||
# |
|
||||
if test "$enable_ntdll_FileDispositionInformation" -eq 1; then
|
||||
patch_apply ntdll-FileDispositionInformation/0001-ntdll-tests-Added-tests-to-set-disposition-on-file-w.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0002-server-Do-not-allow-to-set-disposition-on-file-which.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0003-ntdll-tests-Add-tests-for-FileRenameInformation.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0004-ntdll-tests-Add-additional-tests-for-FileRenameInfor.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0005-ntdll-tests-Add-tests-for-FileRenameInformation-with.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0006-ntdll-Implement-FileRenameInformation-support.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0007-server-When-combining-root-and-name-make-sure-there-.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0008-include-Add-declaration-for-FILE_LINK_INFORMATION.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0009-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0010-server-Implement-support-for-FileLinkInformation-cla.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0003-server-When-combining-root-and-name-make-sure-there-.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0004-ntdll-tests-Add-tests-for-FileLinkInformation-class.patch
|
||||
patch_apply ntdll-FileDispositionInformation/0005-server-Implement-support-for-FileLinkInformation-cla.patch
|
||||
(
|
||||
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 '+ { "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 '+ { "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 '+ { "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 },';
|
||||
) >> "$patchlist"
|
||||
|
@ -1152,7 +1152,7 @@ diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
|
||||
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
|
||||
--- a/dlls/wined3d/utils.c
|
||||
+++ b/dlls/wined3d/utils.c
|
||||
@@ -3721,7 +3721,11 @@
|
||||
@@ -3726,7 +3726,11 @@
|
||||
float y_offset = context->render_offscreen
|
||||
? (center_offset - (2.0f * y) - h) / h
|
||||
: (center_offset - (2.0f * y) - h) / -h;
|
||||
@ -1164,7 +1164,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
|
||||
state->render_states[WINED3D_RS_ZENABLE] : WINED3D_ZB_FALSE;
|
||||
float z_scale = zenable ? 2.0f : 0.0f;
|
||||
float z_offset = zenable ? -1.0f : 0.0f;
|
||||
@@ -3844,6 +3848,7 @@
|
||||
@@ -3849,6 +3853,7 @@
|
||||
/* case WINED3D_TTFF_COUNT1: Won't ever get here. */
|
||||
case WINED3D_TTFF_COUNT2:
|
||||
mat._13 = mat._23 = mat._33 = mat._43 = 0.0f;
|
||||
@ -1172,7 +1172,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
|
||||
/* OpenGL divides the first 3 vertex coord by the 4th by default,
|
||||
* which is essentially the same as D3DTTFF_PROJECTED. Make sure that
|
||||
* the 4th coord evaluates to 1.0 to eliminate that.
|
||||
@@ -3856,6 +3861,20 @@
|
||||
@@ -3861,6 +3866,20 @@
|
||||
* A more serious problem occurs if the app passes 4 coordinates in, and the
|
||||
* 4th is != 1.0(opengl default). This would have to be fixed in draw_strided_slow
|
||||
* or a replacement shader. */
|
||||
@ -1193,7 +1193,7 @@ diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
|
||||
default:
|
||||
mat._14 = mat._24 = mat._34 = 0.0f; mat._44 = 1.0f;
|
||||
}
|
||||
@@ -4311,7 +4330,11 @@
|
||||
@@ -4316,7 +4335,11 @@
|
||||
unsigned int i;
|
||||
DWORD ttff;
|
||||
DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
|
||||
@ -9879,7 +9879,7 @@ diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
|
||||
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
|
||||
--- a/dlls/wined3d/directx.c
|
||||
+++ b/dlls/wined3d/directx.c
|
||||
@@ -5486,9 +5486,15 @@
|
||||
@@ -5493,9 +5493,15 @@
|
||||
DebugBreak();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user