Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 70 participants
- 1549 messages
Re: [PATCH 2/7] ntdll/tests: Clarify some file disposition test results, remove useless tests.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=42585
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll:
file.c:458: Test failed: mismatched file size for L"WindowsUpdate.log"
Sept. 27, 2018
Re: [PATCH 1/7] ntdll/tests: Fix compilation with PSDK.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=42584
Your paranoid android.
=== w8 (32 bit Windows report) ===
ntdll:
file.c:458: Test failed: mismatched file size for L"WindowsUpdate.log"
Sept. 27, 2018
Re: [PATCH] crypt32: Add CRYPT_STRING_BINARY mode for CryptBinaryToStringW().
by Dmitry Timoshkov
Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
> +static BOOL EncodeBinaryToBinaryW(const BYTE *in_buf, DWORD in_len, DWORD flags, WCHAR *out_buf, DWORD *out_len)
> +{
> + BOOL ret = TRUE;
> +
> + if (out_buf)
> + {
> + if (*out_len < in_len)
> + {
> + SetLastError(ERROR_INSUFFICIENT_BUFFER);
> + ret = FALSE;
> + }
> + else if (in_len)
> + memcpy(out_buf, in_buf, in_len);
> + }
> + else
> +
> + *out_len = in_len;
> +
> + return ret;
> +}
Last else statement seems to be misplaced.
--
Dmitry.
Sept. 27, 2018
[PATCH 7/7] server: Fail to open a file if it has explicit delete disposition set.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/ntdll/tests/file.c | 10 ----------
server/fd.c | 11 +++++++++++
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 363fe3f6fc..82f2a6a390 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2681,16 +2681,11 @@ todo_wine
ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
/* can't open the deleted file */
handle3 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
-todo_wine
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
-if (handle3 != INVALID_HANDLE_VALUE)
- CloseHandle( handle3 );
-todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
/* can't open the deleted file (wrong sharing mode) */
handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, 0, 0);
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
-todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
@@ -2889,16 +2884,11 @@ todo_wine
ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
/* can't open the deleted directory */
handle3 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
-todo_wine
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
-todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
-if (handle3 != INVALID_HANDLE_VALUE)
- CloseHandle( handle3 );
/* can't open the deleted directory (wrong sharing mode) */
handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
-todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
CloseHandle( handle2 );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
diff --git a/server/fd.c b/server/fd.c
index 7069938e6f..ab0f94705f 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1827,6 +1827,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
{
unsigned int err;
struct inode *inode = get_inode( st.st_dev, st.st_ino, fd->unix_fd );
+ struct list *ptr;
if (!inode)
{
@@ -1841,6 +1842,16 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
list_add_head( &inode->open, &fd->inode_entry );
closed_fd = NULL;
+ LIST_FOR_EACH( ptr, &inode->open )
+ {
+ struct fd *fd_ptr = LIST_ENTRY( ptr, struct fd, inode_entry );
+ if (fd_ptr->closed->unlink == 1 /* only explicit disposition matters */)
+ {
+ set_error( STATUS_DELETE_PENDING );
+ goto error;
+ }
+ }
+
/* check directory options */
if ((options & FILE_DIRECTORY_FILE) && !S_ISDIR(st.st_mode))
{
--
2.17.1
Sept. 27, 2018
[PATCH 6/7] server: Track separately implicit and explicit file disposition.
by Dmitry Timoshkov
This simplifies next patch.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
server/fd.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/server/fd.c b/server/fd.c
index 65ff087f18..7069938e6f 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -166,7 +166,7 @@ struct closed_fd
{
struct list entry; /* entry in inode closed list */
int unix_fd; /* the unix file descriptor */
- int unlink; /* whether to unlink on close */
+ int unlink; /* whether to unlink on close: -1 - implicit FILE_DELETE_ON_CLOSE, 1 - explicit disposition */
char *unix_name; /* name to unlink on close, points to parent fd unix_name */
};
@@ -1866,7 +1866,7 @@ struct fd *open_fd( struct fd *root, const char *name, int flags, mode_t *mode,
goto error;
}
- fd->closed->unlink = (options & FILE_DELETE_ON_CLOSE) != 0;
+ fd->closed->unlink = (options & FILE_DELETE_ON_CLOSE) ? -1 : 0;
if (flags & O_TRUNC)
{
if (S_ISDIR(st.st_mode))
@@ -2254,7 +2254,9 @@ static void set_fd_disposition( struct fd *fd, int unlink )
return;
}
- fd->closed->unlink = unlink || (fd->options & FILE_DELETE_ON_CLOSE);
+ fd->closed->unlink = unlink != 0;
+ if (fd->options & FILE_DELETE_ON_CLOSE)
+ fd->closed->unlink = -1;
}
/* set new name for the fd */
--
2.17.1
Sept. 27, 2018
[PATCH 5/7] kernel32: Reimplement RemoveDirectory() by setting a delete disposition.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/kernel32/path.c | 17 ++++++++---------
dlls/ntdll/tests/file.c | 8 +++++---
2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 48a3e336ec..5318a94388 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -1656,11 +1656,10 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
{
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nt_name;
- ANSI_STRING unix_name;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
- BOOL ret = FALSE;
+ FILE_DISPOSITION_INFORMATION fdi;
TRACE( "%s\n", debugstr_w(path) );
@@ -1686,19 +1685,19 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
return FALSE;
}
- status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, FALSE );
RtlFreeUnicodeString( &nt_name );
+
+ fdi.DoDeleteFile = TRUE;
+ status = NtSetInformationFile( handle, &io, &fdi, sizeof(fdi), FileDispositionInformation);
+
+ NtClose( handle );
+
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
- NtClose( handle );
return FALSE;
}
-
- if (!(ret = (rmdir( unix_name.Buffer ) != -1))) FILE_SetDosError();
- RtlFreeAnsiString( &unix_name );
- NtClose( handle );
- return ret;
+ return TRUE;
}
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index b4223b3997..363fe3f6fc 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2857,16 +2857,18 @@ todo_wine
fileDeleted = RemoveDirectoryA( buffer );
ok( fileDeleted, "Directory should have been deleted\n" );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
-todo_wine
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
res = nt_get_file_attrs( buffer, &fdi2 );
todo_wine
ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
/* can't open the deleted directory */
handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+todo_wine
ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+if (handle2 != INVALID_HANDLE_VALUE)
+ CloseHandle( handle2 );
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( fileDeleted, "Directory should have been deleted\n" );
@@ -2889,10 +2891,10 @@ todo_wine
handle3 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
todo_wine
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
-if (handle3 != INVALID_HANDLE_VALUE)
- CloseHandle( handle3 );
todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+if (handle3 != INVALID_HANDLE_VALUE)
+ CloseHandle( handle3 );
/* can't open the deleted directory (wrong sharing mode) */
handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
--
2.17.1
Sept. 27, 2018
[PATCH 4/7] server: Allow setting delete disposition on a read-only directory.
by Dmitry Timoshkov
This makes next patch work for RemoveDirectory() call in
dlls/kernel32/tests/profile.c,test_profile_directory_readonly().
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
server/fd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/server/fd.c b/server/fd.c
index 6118f52dd5..65ff087f18 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2247,8 +2247,8 @@ static void set_fd_disposition( struct fd *fd, int unlink )
return;
}
- /* can't unlink files we don't have permission to access */
- if (unlink && !(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
+ /* can't unlink files we don't have permission to write */
+ if (unlink && !(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) && !S_ISDIR(st.st_mode))
{
set_error( STATUS_CANNOT_DELETE );
return;
--
2.17.1
Sept. 27, 2018
[PATCH 3/7] ntdll/tests: Add more file disposition tests.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/ntdll/tests/file.c | 198 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 195 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index b9b6591776..b4223b3997 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -37,6 +37,7 @@
#include "winternl.h"
#include "winuser.h"
#include "winioctl.h"
+#include "winnls.h"
#ifndef IO_COMPLETION_ALL_ACCESS
#define IO_COMPLETION_ALL_ACCESS 0x001F0003
@@ -75,6 +76,7 @@ static NTSTATUS (WINAPI *pNtQueryIoCompletion)(HANDLE, IO_COMPLETION_INFORMATION
static NTSTATUS (WINAPI *pNtRemoveIoCompletion)(HANDLE, PULONG_PTR, PULONG_PTR, PIO_STATUS_BLOCK, PLARGE_INTEGER);
static NTSTATUS (WINAPI *pNtSetIoCompletion)(HANDLE, ULONG_PTR, ULONG_PTR, NTSTATUS, SIZE_T);
static NTSTATUS (WINAPI *pNtSetInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
+static NTSTATUS (WINAPI *pNtQueryAttributesFile)(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FILE_INFORMATION_CLASS);
static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,
PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
@@ -2581,11 +2583,42 @@ static void test_file_both_information(void)
CloseHandle( h );
}
+static NTSTATUS nt_get_file_attrs(const char *name, DWORD *attrs)
+{
+ WCHAR nameW[MAX_PATH];
+ FILE_BASIC_INFORMATION info;
+ UNICODE_STRING nt_name;
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+
+ MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, MAX_PATH );
+
+ *attrs = INVALID_FILE_ATTRIBUTES;
+
+ if (!pRtlDosPathNameToNtPathName_U( nameW, &nt_name, NULL, NULL ))
+ return STATUS_UNSUCCESSFUL;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.ObjectName = &nt_name;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtQueryAttributesFile( &attr, &info );
+ pRtlFreeUnicodeString( &nt_name );
+
+ if (status == STATUS_SUCCESS)
+ *attrs = info.FileAttributes;
+
+ return status;
+}
+
static void test_file_disposition_information(void)
{
char tmp_path[MAX_PATH], buffer[MAX_PATH + 16];
DWORD dirpos;
- HANDLE handle, handle2;
+ HANDLE handle, handle2, handle3;
NTSTATUS res;
IO_STATUS_BLOCK io;
FILE_DISPOSITION_INFORMATION fdi;
@@ -2633,7 +2666,58 @@ static void test_file_disposition_information(void)
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( fileDeleted, "File should have been deleted\n" );
- DeleteFileA( buffer );
+
+ /* file exists until all handles to it get closed */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
+ ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
+ fdi.DoDeleteFile = TRUE;
+ res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
+ ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res );
+ res = nt_get_file_attrs( buffer, &fdi2 );
+todo_wine
+ ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
+ /* can't open the deleted file */
+ handle3 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
+todo_wine
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+if (handle3 != INVALID_HANDLE_VALUE)
+ CloseHandle( handle3 );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ /* can't open the deleted file (wrong sharing mode) */
+ handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
+ CloseHandle( handle2 );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "File should have been deleted\n" );
+
+ /* file exists until all handles to it get closed */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
+ /* can open the marked for delete file (proper sharing mode) */
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
+ ok( handle2 != INVALID_HANDLE_VALUE, "failed to open temp file\n" );
+ res = nt_get_file_attrs( buffer, &fdi2 );
+ ok( res == STATUS_SUCCESS, "got %#x\n", res );
+ /* can't open the marked for delete file (wrong sharing mode) */
+ handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+ ok(GetLastError() == ERROR_SHARING_VIOLATION, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
+ CloseHandle( handle2 );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "File should have been deleted\n" );
/* cannot set disposition on readonly file */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
@@ -2704,8 +2788,39 @@ static void test_file_disposition_information(void)
CloseHandle( handle2 );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( fileDeleted, "File should have been deleted\n" );
+
+ /* DeleteFile fails for wrong sharing mode */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, 0, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
+ fileDeleted = DeleteFileA( buffer );
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
+ ok(GetLastError() == ERROR_SHARING_VIOLATION, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
DeleteFileA( buffer );
+ /* DeleteFile succeeds for proper sharing mode */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, 0, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
+ fileDeleted = DeleteFileA( buffer );
+ ok( fileDeleted, "File should have been deleted\n" );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
+ res = nt_get_file_attrs( buffer, &fdi2 );
+todo_wine
+ ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
+ /* can't open the deleted file */
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
+ ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "File should have been deleted\n" );
+
/* can set disposition on a directory opened with proper access */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
DeleteFileA( buffer );
@@ -2718,7 +2833,6 @@ static void test_file_disposition_information(void)
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( fileDeleted, "Directory should have been deleted\n" );
- RemoveDirectoryA( buffer );
/* RemoveDirectory fails for wrong sharing mode */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
@@ -2734,6 +2848,83 @@ static void test_file_disposition_information(void)
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
RemoveDirectoryA( buffer );
+ /* RemoveDirectory succeeds for proper sharing mode */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ DeleteFileA( buffer );
+ ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
+ handle = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
+ fileDeleted = RemoveDirectoryA( buffer );
+ ok( fileDeleted, "Directory should have been deleted\n" );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+todo_wine
+ ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
+ res = nt_get_file_attrs( buffer, &fdi2 );
+todo_wine
+ ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
+ /* can't open the deleted directory */
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle2 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "Directory should have been deleted\n" );
+
+ /* directory exists until all handles to it get closed */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ DeleteFileA( buffer );
+ ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
+ handle = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle2 != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
+ fdi.DoDeleteFile = TRUE;
+ res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation );
+ ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res );
+ res = nt_get_file_attrs( buffer, &fdi2 );
+todo_wine
+ ok( res == STATUS_DELETE_PENDING, "got %#x\n", res );
+ /* can't open the deleted directory */
+ handle3 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+todo_wine
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+if (handle3 != INVALID_HANDLE_VALUE)
+ CloseHandle( handle3 );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ /* can't open the deleted directory (wrong sharing mode) */
+ handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+todo_wine
+ ok(GetLastError() == ERROR_ACCESS_DENIED, "got %u\n", GetLastError());
+ CloseHandle( handle2 );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "Directory should have been deleted\n" );
+
+ /* directory exists until all handles to it get closed */
+ GetTempFileNameA( tmp_path, "dis", 0, buffer );
+ DeleteFileA( buffer );
+ ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
+ handle = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE, 0);
+ ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
+ /* can open the marked for delete directory (proper sharing mode) */
+ handle2 = CreateFileA(buffer, DELETE, FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle2 != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
+ /* can't open the marked for delete file (wrong sharing mode) */
+ handle3 = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
+ ok( handle3 == INVALID_HANDLE_VALUE, "CreateFile should fail\n" );
+ ok(GetLastError() == ERROR_SHARING_VIOLATION, "got %u\n", GetLastError());
+ CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
+ CloseHandle( handle2 );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( fileDeleted, "Directory should have been deleted\n" );
+
/* cannot set disposition on a non-empty directory */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
DeleteFileA( buffer );
@@ -4287,6 +4478,7 @@ START_TEST(file)
pNtRemoveIoCompletion = (void *)GetProcAddress(hntdll, "NtRemoveIoCompletion");
pNtSetIoCompletion = (void *)GetProcAddress(hntdll, "NtSetIoCompletion");
pNtSetInformationFile = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
+ pNtQueryAttributesFile = (void *)GetProcAddress(hntdll, "NtQueryAttributesFile");
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
pNtQueryDirectoryFile = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile");
--
2.17.1
Sept. 27, 2018
[PATCH 2/7] ntdll/tests: Clarify some file disposition test results, remove useless tests.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/ntdll/tests/file.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 87c3339d31..b9b6591776 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2679,7 +2679,7 @@ static void test_file_disposition_information(void)
ok( !fileDeleted, "File shouldn't have been deleted\n" );
DeleteFileA( buffer );
- /* Delete-on-close flag doesn't change file disposition until a handle is closed */
+ /* can't reset disposition if delete-on-close flag is specified */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
@@ -2689,14 +2689,15 @@ static void test_file_disposition_information(void)
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( fileDeleted, "File should have been deleted\n" );
- DeleteFileA( buffer );
- /* Delete-on-close flag sets disposition when a handle is closed and then it could be changed back */
+ /* can't reset disposition on duplicated handle if delete-on-close flag is specified */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
handle = CreateFileA(buffer, GENERIC_WRITE | DELETE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, 0);
ok( handle != INVALID_HANDLE_VALUE, "failed to create temp file\n" );
ok( DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle2, 0, FALSE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
CloseHandle( handle );
+ fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
+ ok( !fileDeleted, "File shouldn't have been deleted\n" );
fdi.DoDeleteFile = FALSE;
res = pNtSetInformationFile( handle2, &io, &fdi, sizeof fdi, FileDispositionInformation );
ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res );
@@ -2719,16 +2720,15 @@ static void test_file_disposition_information(void)
ok( fileDeleted, "Directory should have been deleted\n" );
RemoveDirectoryA( buffer );
- /* RemoveDirectory sets directory disposition and it can be undone */
+ /* RemoveDirectory fails for wrong sharing mode */
GetTempFileNameA( tmp_path, "dis", 0, buffer );
DeleteFileA( buffer );
ok( CreateDirectoryA( buffer, NULL ), "CreateDirectory failed\n" );
handle = CreateFileA(buffer, DELETE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
ok( handle != INVALID_HANDLE_VALUE, "failed to open a directory\n" );
- RemoveDirectoryA( buffer );
- fdi.DoDeleteFile = FALSE;
- res = pNtSetInformationFile( handle, &io, &fdi, sizeof fdi, FileDispositionInformation );
- ok( res == STATUS_SUCCESS, "unexpected FileDispositionInformation result (expected STATUS_SUCCESS, got %x)\n", res );
+ fileDeleted = RemoveDirectoryA( buffer );
+ ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
+ ok(GetLastError() == ERROR_SHARING_VIOLATION, "got %u\n", GetLastError());
CloseHandle( handle );
fileDeleted = GetFileAttributesA( buffer ) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND;
ok( !fileDeleted, "Directory shouldn't have been deleted\n" );
--
2.17.1
Sept. 27, 2018
[PATCH 1/7] ntdll/tests: Fix compilation with PSDK.
by Dmitry Timoshkov
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/ntdll/tests/file.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index d9d029b7f3..87c3339d31 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1044,7 +1044,7 @@ static void test_iocp_fileio(HANDLE h)
ok( !count, "Unexpected msg count: %ld\n", count );
/* using APCs on handle with associated completion port is not allowed */
- res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
+ res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
}
@@ -1070,7 +1070,7 @@ static void test_iocp_fileio(HANDLE h)
count = get_pending_msgs(h);
ok( !count, "Unexpected msg count: %ld\n", count );
- res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
+ res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
ok(res == STATUS_PENDING, "NtReadFile returned %x\n", res);
U(iosb).Status = 0xdeadbeef;
@@ -1092,7 +1092,7 @@ static void test_iocp_fileio(HANDLE h)
ok( !count, "Unexpected msg count: %ld\n", count );
/* using APCs on handle with associated completion port is not allowed */
- res = NtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
+ res = pNtReadFile( hPipeSrv, NULL, apc, &apc_count, &iosb, recv_buf, sizeof(recv_buf), NULL, NULL );
ok(res == STATUS_INVALID_PARAMETER, "NtReadFile returned %x\n", res);
}
@@ -4197,7 +4197,7 @@ static void test_ioctl(void)
ok(status == STATUS_INVALID_HANDLE, "NtFsControlFile returned %x\n", status);
memset(&iosb, 0x55, sizeof(iosb));
- status = NtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_PIPE_PEEK, NULL, 0,
+ status = pNtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_PIPE_PEEK, NULL, 0,
&peek_buf, sizeof(peek_buf));
todo_wine
ok(status == STATUS_INVALID_DEVICE_REQUEST, "NtFsControlFile failed: %x\n", status);
--
2.17.1
Sept. 27, 2018