Jacek Caban : server: Add FileModeInformation implementation.
Alexandre Julliard
julliard at winehq.org
Mon Oct 29 18:26:30 CDT 2018
Module: wine
Branch: master
Commit: 2adfa93a7f643341765d80af83ce99a9c6b23b72
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2adfa93a7f643341765d80af83ce99a9c6b23b72
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Oct 29 15:48:30 2018 +0100
server: Add FileModeInformation implementation.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45749
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/file.c | 2 +-
dlls/ntdll/tests/file.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++-
server/fd.c | 16 +++++++++
3 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 4b956d5..d3b3698 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -2244,7 +2244,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
sizeof(FILE_DISPOSITION_INFORMATION), /* FileDispositionInformation */
sizeof(FILE_POSITION_INFORMATION), /* FilePositionInformation */
sizeof(FILE_FULL_EA_INFORMATION), /* FileFullEaInformation */
- sizeof(FILE_MODE_INFORMATION), /* FileModeInformation */
+ 0, /* FileModeInformation */
sizeof(FILE_ALIGNMENT_INFORMATION), /* FileAlignmentInformation */
sizeof(FILE_ALL_INFORMATION), /* FileAllInformation */
sizeof(FILE_ALLOCATION_INFORMATION), /* FileAllocationInformation */
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index a4ae64f..076d6bf 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -85,6 +85,8 @@ static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)(HANDLE,PIO_STATUS_BLOCK,
static NTSTATUS (WINAPI *pNtQueryFullAttributesFile)(const OBJECT_ATTRIBUTES*, FILE_NETWORK_OPEN_INFORMATION*);
static NTSTATUS (WINAPI *pNtFlushBuffersFile)(HANDLE, IO_STATUS_BLOCK*);
+static WCHAR fooW[] = {'f','o','o',0};
+
static inline BOOL is_signaled( HANDLE obj )
{
return WaitForSingleObject( obj, 0 ) == WAIT_OBJECT_0;
@@ -331,7 +333,6 @@ static void open_file_test(void)
{
static const WCHAR testdirW[] = {'o','p','e','n','f','i','l','e','t','e','s','t',0};
static const char testdata[] = "Hello World";
- static WCHAR fooW[] = {'f','o','o',0};
NTSTATUS status;
HANDLE dir, root, handle, file;
WCHAR path[MAX_PATH], tmpfile[MAX_PATH];
@@ -3545,6 +3546,98 @@ static void test_file_access_information(void)
CloseHandle( h );
}
+static void test_file_mode(void)
+{
+ UNICODE_STRING file_name, pipe_dev_name, mountmgr_dev_name, mailslot_dev_name;
+ WCHAR tmp_path[MAX_PATH], dos_file_name[MAX_PATH];
+ FILE_MODE_INFORMATION mode;
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ HANDLE file;
+ unsigned i;
+ DWORD res, access;
+ NTSTATUS status;
+
+ const struct {
+ UNICODE_STRING *file_name;
+ ULONG options;
+ ULONG mode;
+ BOOL todo;
+ } option_tests[] = {
+ { &file_name, 0, 0 },
+ { &file_name, FILE_NON_DIRECTORY_FILE, 0 },
+ { &file_name, FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY, FILE_SEQUENTIAL_ONLY },
+ { &file_name, FILE_WRITE_THROUGH, FILE_WRITE_THROUGH },
+ { &file_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT },
+ { &file_name, FILE_NO_INTERMEDIATE_BUFFERING, FILE_NO_INTERMEDIATE_BUFFERING },
+ { &file_name, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, FILE_SYNCHRONOUS_IO_NONALERT },
+ { &file_name, FILE_DELETE_ON_CLOSE, 0 },
+ { &file_name, FILE_RANDOM_ACCESS | FILE_NO_COMPRESSION, 0 },
+ { &pipe_dev_name, 0, 0 },
+ { &pipe_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT, TRUE },
+ { &mailslot_dev_name, 0, 0 },
+ { &mailslot_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT, TRUE },
+ { &mountmgr_dev_name, 0, 0 },
+ { &mountmgr_dev_name, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_ALERT, TRUE }
+ };
+
+ static WCHAR pipe_devW[] = {'\\','?','?','\\','P','I','P','E','\\'};
+ static WCHAR mailslot_devW[] = {'\\','?','?','\\','M','A','I','L','S','L','O','T','\\'};
+ static WCHAR mountmgr_devW[] =
+ {'\\','?','?','\\','M','o','u','n','t','P','o','i','n','t','M','a','n','a','g','e','r'};
+
+ GetTempPathW(MAX_PATH, tmp_path);
+ res = GetTempFileNameW(tmp_path, fooW, 0, dos_file_name);
+ ok(res, "GetTempFileNameW failed: %u\n", GetLastError());
+ pRtlDosPathNameToNtPathName_U( dos_file_name, &file_name, NULL, NULL );
+
+ pipe_dev_name.Buffer = pipe_devW;
+ pipe_dev_name.Length = sizeof(pipe_devW);
+ pipe_dev_name.MaximumLength = sizeof(pipe_devW);
+
+ mailslot_dev_name.Buffer = mailslot_devW;
+ mailslot_dev_name.Length = sizeof(mailslot_devW);
+ mailslot_dev_name.MaximumLength = sizeof(mailslot_devW);
+
+ mountmgr_dev_name.Buffer = mountmgr_devW;
+ mountmgr_dev_name.Length = sizeof(mountmgr_devW);
+ mountmgr_dev_name.MaximumLength = sizeof(mountmgr_devW);
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(option_tests); i++)
+ {
+ attr.ObjectName = option_tests[i].file_name;
+ access = SYNCHRONIZE;
+
+ if (option_tests[i].file_name == &file_name)
+ {
+ file = CreateFileW(dos_file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
+ CloseHandle(file);
+ access |= GENERIC_WRITE | DELETE;
+ }
+
+ status = pNtOpenFile(&file, access, &attr, &io, 0, option_tests[i].options);
+ ok(status == STATUS_SUCCESS, "[%u] NtOpenFile failed: %x\n", i, status);
+
+ memset(&mode, 0xcc, sizeof(mode));
+ status = pNtQueryInformationFile(file, &io, &mode, sizeof(mode), FileModeInformation);
+ ok(status == STATUS_SUCCESS, "[%u] can't get FileModeInformation: %x\n", i, status);
+ todo_wine_if(option_tests[i].todo)
+ ok(mode.Mode == option_tests[i].mode, "[%u] Mode = %x, expected %x\n",
+ i, mode.Mode, option_tests[i].mode);
+
+ pNtClose(file);
+ if (option_tests[i].file_name == &file_name)
+ DeleteFileW(dos_file_name);
+ }
+}
+
static void test_query_volume_information_file(void)
{
NTSTATUS status;
@@ -4628,6 +4721,7 @@ START_TEST(file)
test_file_completion_information();
test_file_id_information();
test_file_access_information();
+ test_file_mode();
test_query_volume_information_file();
test_query_attribute_information_file();
test_ioctl();
diff --git a/server/fd.c b/server/fd.c
index 117fad8..1459ad1 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2195,6 +2195,22 @@ void default_fd_get_file_info( struct fd *fd, obj_handle_t handle, unsigned int
set_reply_data( &info, sizeof(info) );
break;
}
+ case FileModeInformation:
+ {
+ FILE_MODE_INFORMATION info;
+ if (get_reply_max_size() < sizeof(info))
+ {
+ set_error( STATUS_INFO_LENGTH_MISMATCH );
+ return;
+ }
+ info.Mode = fd->options & ( FILE_WRITE_THROUGH
+ | FILE_SEQUENTIAL_ONLY
+ | FILE_NO_INTERMEDIATE_BUFFERING
+ | FILE_SYNCHRONOUS_IO_ALERT
+ | FILE_SYNCHRONOUS_IO_NONALERT );
+ set_reply_data( &info, sizeof(info) );
+ break;
+ }
case FileIoCompletionNotificationInformation:
{
FILE_IO_COMPLETION_NOTIFICATION_INFORMATION info;
More information about the wine-cvs
mailing list