Signed-off-by: Paul Gofman pgofman@codeweavers.com --- server/mapping.c | 2 +- server/protocol.def | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/server/mapping.c b/server/mapping.c index 6990a1913d..1c189a282b 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -934,7 +934,7 @@ static void mapping_destroy( struct object *obj )
static enum server_fd_type mapping_get_fd_type( struct fd *fd ) { - return FD_TYPE_FILE; + return FD_TYPE_MAPPING; }
int get_page_size(void) diff --git a/server/protocol.def b/server/protocol.def index 06a29b153e..9f60e323b6 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1318,6 +1318,7 @@ enum server_fd_type FD_TYPE_MAILSLOT, /* mailslot */ FD_TYPE_CHAR, /* unspecified char device */ FD_TYPE_DEVICE, /* Windows device file */ + FD_TYPE_MAPPING, /* File mapping */ FD_TYPE_NB_TYPES };
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/file.c | 6 +++++- dlls/ntdll/server.c | 16 +++++++++++++--- dlls/ntdll/tests/om.c | 44 +++++++++++++++++++++++++++++++++++++++++-- server/fd.c | 12 ++++++++++++ 4 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index 9997a5e1cd..33f78b63ac 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -3266,10 +3266,11 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io PVOID buffer, ULONG length, FS_INFORMATION_CLASS info_class ) { + enum server_fd_type type; int fd, needs_close; struct stat st;
- io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL ); + io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, &type, NULL ); if (io->u.Status == STATUS_BAD_DEVICE_TYPE) { SERVER_START_REQ( get_volume_info ) @@ -3285,6 +3286,9 @@ NTSTATUS WINAPI NtQueryVolumeInformationFile( HANDLE handle, PIO_STATUS_BLOCK io } else if (io->u.Status) return io->u.Status;
+ if (type == FD_TYPE_MAPPING) + return STATUS_OBJECT_TYPE_MISMATCH; + io->u.Status = STATUS_NOT_IMPLEMENTED; io->Information = 0;
diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index 3832a80f1e..2626b4396d 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -1073,6 +1073,7 @@ int server_remove_fd_from_cache( HANDLE handle ) int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, int *needs_close, enum server_fd_type *type, unsigned int *options ) { + enum server_fd_type fd_type = FD_TYPE_NB_TYPES; sigset_t sigset; obj_handle_t fd_handle; int ret, fd = -1; @@ -1082,7 +1083,7 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, *needs_close = 0; wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA;
- ret = get_cached_fd( handle, &fd, type, &access, options ); + ret = get_cached_fd( handle, &fd, &fd_type, &access, options ); if (ret != STATUS_INVALID_HANDLE) goto done;
server_enter_uninterrupted_section( &fd_cache_section, &sigset ); @@ -1094,7 +1095,7 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, req->handle = wine_server_obj_handle( handle ); if (!(ret = wine_server_call( req ))) { - if (type) *type = reply->type; + fd_type = reply->type; if (options) *options = reply->options; access = reply->access; if ((fd = receive_fd( &fd_handle )) != -1) @@ -1116,12 +1117,21 @@ int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd, server_leave_uninterrupted_section( &fd_cache_section, &sigset );
done: + if (!ret && wanted_access && fd_type == FD_TYPE_MAPPING) + ret = STATUS_INVALID_HANDLE; + if (!ret && ((access & wanted_access) != wanted_access)) { ret = STATUS_ACCESS_DENIED; if (*needs_close) close( fd ); } - if (!ret) *unix_fd = fd; + if (!ret) + { + if (type) + *type = fd_type; + + *unix_fd = fd; + } return ret; }
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index c17b6ffa8d..b6a338596e 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -23,6 +23,7 @@ #include "winternl.h" #include "stdio.h" #include "winnt.h" +#include "winioctl.h" #include "stdlib.h"
static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR); @@ -72,6 +73,8 @@ static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, c static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG); static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES ); static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, void *, ULONG, FILE_INFORMATION_CLASS); +static NTSTATUS (WINAPI *pNtQueryVolumeInformationFile)( HANDLE handle, PIO_STATUS_BLOCK io, PVOID buffer, + ULONG length, FS_INFORMATION_CLASS info_class ); static NTSTATUS (WINAPI *pNtQuerySystemTime)( LARGE_INTEGER * ); static NTSTATUS (WINAPI *pRtlWaitOnAddress)( const void *, const void *, SIZE_T, const LARGE_INTEGER * ); static void (WINAPI *pRtlWakeAddressAll)( const void * ); @@ -1585,9 +1588,16 @@ static void test_query_object(void)
static void test_type_mismatch(void) { - HANDLE h; - NTSTATUS res; + char tmp_path[MAX_PATH], file_name[MAX_PATH + 16]; + FILE_FS_DEVICE_INFORMATION info; OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + LARGE_INTEGER size; + HANDLE h, hfile; + DWORD length; + NTSTATUS res; + DWORD type; + BOOL ret;
attr.Length = sizeof(attr); attr.RootDirectory = 0; @@ -1603,6 +1613,35 @@ static void test_type_mismatch(void) ok(res == STATUS_OBJECT_TYPE_MISMATCH, "expected 0xc0000024, got %x\n", res);
pNtClose( h ); + + GetTempPathA(MAX_PATH, tmp_path); + GetTempFileNameA(tmp_path, "foo", 0, file_name); + hfile = CreateFileA(file_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_FLAG_DELETE_ON_CLOSE, 0); + ok(hfile != INVALID_HANDLE_VALUE, "Got unexpected hfile %p.\n", hfile); + + size.QuadPart = 256; + res = pNtCreateSection(&h, SECTION_MAP_WRITE | SECTION_MAP_READ, NULL, &size, + PAGE_READWRITE, SEC_COMMIT, hfile); + ok(res == STATUS_SUCCESS , "Got unexpected res %x\n", res); + + res = pNtQueryVolumeInformationFile(h, &io, &info, sizeof(info), FileFsDeviceInformation); + ok(res == STATUS_OBJECT_TYPE_MISMATCH, "Got unexpected result %#x.\n", res); + + type = GetFileType(h); + ok(type == FILE_TYPE_UNKNOWN, "Got unexpected type %#x.\n", type); + + SetLastError(0xdeadbeef); + ret = WriteFile(h, file_name, 16, &length, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %#x.\n", + ret, GetLastError()); + + SetLastError(0xdeadbeef); + ret = ReadFile(h, file_name, 16, &length, NULL); + ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %#x.\n", + ret, GetLastError()); + pNtClose(h); + CloseHandle(hfile); }
static void test_event(void) @@ -2207,6 +2246,7 @@ START_TEST(om) pRtlWaitOnAddress = (void *)GetProcAddress(hntdll, "RtlWaitOnAddress"); pRtlWakeAddressAll = (void *)GetProcAddress(hntdll, "RtlWakeAddressAll"); pRtlWakeAddressSingle = (void *)GetProcAddress(hntdll, "RtlWakeAddressSingle"); + pNtQueryVolumeInformationFile = (void *)GetProcAddress(hntdll, "NtQueryVolumeInformationFile");
test_case_sensitive(); test_namespace_pipe(); diff --git a/server/fd.c b/server/fd.c index 39fb419f25..8e547f53dc 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2612,6 +2612,12 @@ DECL_HANDLER(read)
if (!fd) return;
+ if (fd->fd_ops->get_fd_type( fd ) == FD_TYPE_MAPPING) + { + set_error( STATUS_INVALID_HANDLE ); + return; + } + if ((async = create_request_async( fd, fd->comp_flags, &req->async ))) { reply->wait = async_handoff( async, fd->fd_ops->read( fd, async, req->pos ), NULL, 0 ); @@ -2629,6 +2635,12 @@ DECL_HANDLER(write)
if (!fd) return;
+ if (fd->fd_ops->get_fd_type( fd ) == FD_TYPE_MAPPING) + { + set_error( STATUS_INVALID_HANDLE ); + return; + } + if ((async = create_request_async( fd, fd->comp_flags, &req->async ))) { reply->wait = async_handoff( async, fd->fd_ops->write( fd, async, req->pos ), &reply->size, 0 );
Hi Paul,
On 01.05.2020 19:17, Paul Gofman wrote:
diff --git a/server/fd.c b/server/fd.c index 39fb419f25..8e547f53dc 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2612,6 +2612,12 @@ DECL_HANDLER(read)
if (!fd) return;
- if (fd->fd_ops->get_fd_type( fd ) == FD_TYPE_MAPPING)
- {
set_error( STATUS_INVALID_HANDLE );
return;
- }
This should be probably changed in no_fd_read or, if mapping is for some reason different than other objects, introducing a separated read() for mapping objects.
Thanks,
Jacek
On 5/2/20 12:43, Jacek Caban wrote:
Hi Paul,
On 01.05.2020 19:17, Paul Gofman wrote:
diff --git a/server/fd.c b/server/fd.c index 39fb419f25..8e547f53dc 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2612,6 +2612,12 @@ DECL_HANDLER(read) if (!fd) return; + if (fd->fd_ops->get_fd_type( fd ) == FD_TYPE_MAPPING) + { + set_error( STATUS_INVALID_HANDLE ); + return; + }
This should be probably changed in no_fd_read or, if mapping is for some reason different than other objects, introducing a separated read() for mapping objects.
Oh yeah, thanks. And there is actually already no_fd_read for mapping object, so I just don't need anything like that.