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