[PATCH 0/3] MR10247: server, ntoskrnl.exe: Implement FsRtlGetFileSize().
Needed by Persona 5: The Phantom X (SEA/KR/CN) in order to launch the game. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10247
From: Nello De Gregoris <bluechxindv@gmail.com> Based on https://gitlab.winehq.org/wine/wine/-/commit/dcaeddd4db127ebabc4f27627e1278b.... --- server/change.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/change.c b/server/change.c index 5bcd0676e0d..e1c77218e46 100644 --- a/server/change.c +++ b/server/change.c @@ -94,6 +94,7 @@ struct dir struct inode *inode; /* inode of the associated directory */ struct process *client_process; /* client process that has a cache for this directory */ int client_entry; /* entry in client process cache */ + struct list kernel_object; /* list of kernel object pointers */ }; static struct fd *dir_get_fd( struct object *obj ); @@ -103,6 +104,7 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, static void dir_dump( struct object *obj, int verbose ); static int dir_close_handle( struct object *obj, struct process *process, obj_handle_t handle ); static void dir_destroy( struct object *obj ); +static struct list *dir_get_kernel_obj_list( struct object *obj ); static const struct object_ops dir_ops = { @@ -124,7 +126,7 @@ static const struct object_ops dir_ops = no_link_name, /* link_name */ NULL, /* unlink_name */ no_open_file, /* open_file */ - no_kernel_obj_list, /* get_kernel_obj_list */ + dir_get_kernel_obj_list, /* get_kernel_obj_list */ dir_close_handle, /* close_handle */ dir_destroy /* destroy */ }; @@ -452,6 +454,12 @@ static void dir_destroy( struct object *obj ) } } +static struct list *dir_get_kernel_obj_list( struct object *obj ) +{ + struct dir *dir = (struct dir *)obj; + return &dir->kernel_object; +} + struct dir *get_dir_obj( struct process *process, obj_handle_t handle, unsigned int access ) { return (struct dir *)get_handle_obj( process, handle, access, &dir_ops ); @@ -1143,6 +1151,7 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) return NULL; list_init( &dir->change_records ); + list_init( &dir->kernel_object ); dir->filter = 0; dir->notified = 0; dir->want_data = 0; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10247
From: Nello De Gregoris <bluechxindv@gmail.com> --- dlls/ntoskrnl.exe/ntoskrnl.c | 25 +++++++++++++++++++++++++ dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +- include/ddk/ntifs.h | 1 + 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 59fff096ca9..4d4e861cd0b 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -2460,6 +2460,31 @@ NTSTATUS WINAPI ExInitializeZone(PZONE_HEADER Zone, return STATUS_NOT_IMPLEMENTED; } +/*********************************************************************** + * FsRtlGetFileSize (NTOSKRNL.EXE.@) + */ +NTSTATUS WINAPI FsRtlGetFileSize( PFILE_OBJECT file_obj, PLARGE_INTEGER file_size ) +{ + FILE_STANDARD_INFORMATION info; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + HANDLE handle; + + TRACE( "file_obj %p, file_size %p\n", file_obj, file_size ); + + status = ObOpenObjectByPointer( file_obj, 0, NULL, 0, IoFileObjectType, KernelMode, &handle ); + if (status) return status; + + status = NtQueryInformationFile( handle, &iosb, &info, sizeof(info), FileStandardInformation ); + NtClose( handle ); + if (!status) + { + if (info.Directory) return STATUS_FILE_IS_A_DIRECTORY; + file_size->QuadPart = info.EndOfFile.QuadPart; + } + return status; +} + /*********************************************************************** * FsRtlIsNameInExpression (NTOSKRNL.EXE.@) */ diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec index 9a17b8e67f1..bfe7187fb7c 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec +++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec @@ -237,7 +237,7 @@ @ stub FsRtlFastUnlockSingle @ stub FsRtlFindInTunnelCache @ stub FsRtlFreeFileLock -@ stub FsRtlGetFileSize +@ stdcall FsRtlGetFileSize(ptr ptr) @ stub FsRtlGetNextFileLock @ stub FsRtlGetNextLargeMcbEntry @ stub FsRtlGetNextMcbEntry diff --git a/include/ddk/ntifs.h b/include/ddk/ntifs.h index 980235abdc9..965715738d7 100644 --- a/include/ddk/ntifs.h +++ b/include/ddk/ntifs.h @@ -203,6 +203,7 @@ typedef struct _REPARSE_GUID_DATA_BUFFER #define COMPRESSION_FORMAT_MASK 0x00ff #define COMPRESSION_ENGINE_MASK 0xff00 +NTSTATUS WINAPI FsRtlGetFileSize(PFILE_OBJECT, PLARGE_INTEGER); BOOLEAN WINAPI FsRtlIsNameInExpression(PUNICODE_STRING, PUNICODE_STRING, BOOLEAN, PWCH); DEVICE_OBJECT * WINAPI IoGetAttachedDevice(DEVICE_OBJECT*); PEPROCESS WINAPI IoGetRequestorProcess(IRP*); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10247
From: Nello De Gregoris <bluechxindv@gmail.com> --- dlls/ntoskrnl.exe/tests/driver.c | 66 ++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 9358cf605a4..ace8bf2f58a 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -1981,6 +1981,71 @@ static void test_object_name(void) ok(!name->Name.MaximumLength, "got maximum length %u\n", name->Name.MaximumLength); } +static void test_fsrtl_get_file_size(void) +{ + static const char data[] = "hello, world!"; + OBJECT_ATTRIBUTES attr = { sizeof(attr) }; + UNICODE_STRING pathU; + IO_STATUS_BLOCK io; + LARGE_INTEGER file_size, offset; + HANDLE file_handle, dir_handle; + FILE_OBJECT *file_obj, *dir_obj; + NTSTATUS status; + + /* test regular file */ + RtlInitUnicodeString(&pathU, L"\\??\\C:\\windows\\winetest_ntoskrnl_fsrtl.tmp"); + InitializeObjectAttributes(&attr, &pathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwCreateFile(&file_handle, DELETE | FILE_WRITE_DATA | SYNCHRONIZE, &attr, &io, NULL, + FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_CREATE, FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); + ok(!status, "ZwCreateFile failed: %#lx\n", status); + if (status) + return; + + offset.QuadPart = 0; + status = ZwWriteFile(file_handle, NULL, NULL, NULL, &io, (void *)data, sizeof(data), &offset, NULL); + ok(!status, "ZwWriteFile failed: %#lx\n", status); + + status = ObReferenceObjectByHandle(file_handle, 0, *pIoFileObjectType, KernelMode, + (void **)&file_obj, NULL); + ok(!status, "ObReferenceObjectByHandle failed: %#lx\n", status); + if (!status) + { + file_size.QuadPart = 0; + status = FsRtlGetFileSize(file_obj, &file_size); + ok(!status, "FsRtlGetFileSize failed: %#lx\n", status); + ok(file_size.QuadPart == sizeof(data), "expected %Iu, got %I64d\n", + sizeof(data), file_size.QuadPart); + ObDereferenceObject(file_obj); + } + + ZwClose(file_handle); + + /* test directory returns STATUS_FILE_IS_A_DIRECTORY */ + RtlInitUnicodeString(&pathU, L"\\??\\C:\\windows"); + InitializeObjectAttributes(&attr, &pathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); + status = ZwOpenFile(&dir_handle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &attr, &io, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); + ok(!status, "ZwOpenFile failed: %#lx\n", status); + if (status) + return; + + status = ObReferenceObjectByHandle(dir_handle, 0, *pIoFileObjectType, KernelMode, + (void **)&dir_obj, NULL); + ok(!status, "ObReferenceObjectByHandle failed: %#lx\n", status); + if (!status) + { + file_size.QuadPart = 0; + status = FsRtlGetFileSize(dir_obj, &file_size); + ok(status == STATUS_FILE_IS_A_DIRECTORY, + "expected STATUS_FILE_IS_A_DIRECTORY, got %#lx\n", status); + ObDereferenceObject(dir_obj); + } + + ZwClose(dir_handle); +} + static PIO_WORKITEM work_item; static void WINAPI main_test_task(DEVICE_OBJECT *device, void *context) @@ -2523,6 +2588,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st test_lookup_thread(); test_IoAttachDeviceToDeviceStack(); test_object_name(); + test_fsrtl_get_file_size(); #if defined(__i386__) || defined(__x86_64__) test_executable_pool(); #endif -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10247
1/3 could use tests. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10247#note_131372
participants (3)
-
Elizabeth Figura (@zfigura) -
Nello De Gregoris -
Nello De Gregoris (@bluechxin)