[PATCH 0/2] MR9105: Revert "server: Return the NT file name in ObjectNameInformation for file objects."
This reverts commit af35741d3681f21222a85900b54d95ee422fe074. As reported on IRC by user supermario1313, and bisected by Rounin, this commit made Wine no longer follow symlinks in Z:, which the former needs for a Wine-aware sandboxing solution. I'm not a huge fan of the test, but I like leaving things untested even less. The Correct™ solution would be CreateSymbolicLink() or FSCTL_SET_REPARSE_POINT, but they're not implemented in Wine. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9105
From: Alfred Agrell <floating(a)muncher.se> This reverts commit af35741d3681f21222a85900b54d95ee422fe074. --- dlls/ntdll/unix/file.c | 28 ++++++++++++++++++++++++++++ server/change.c | 2 +- server/fd.c | 16 ---------------- server/file.c | 2 +- server/file.h | 1 - 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 958ae9a6937..6f1fc71c4db 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -7322,6 +7322,34 @@ NTSTATUS WINAPI NtQueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS info_clas case ObjectNameInformation: { OBJECT_NAME_INFORMATION *p = ptr; + char *unix_name; + WCHAR *nt_name; + + /* first try as a file object */ + + if (!(status = server_get_unix_name( handle, &unix_name ))) + { + if (!(status = unix_to_nt_file_name( unix_name, &nt_name, FILE_OPEN ))) + { + ULONG size = (wcslen(nt_name) + 1) * sizeof(WCHAR); + if (len < sizeof(*p)) status = STATUS_INFO_LENGTH_MISMATCH; + else if (len < sizeof(*p) + size) status = STATUS_BUFFER_OVERFLOW; + else + { + p->Name.Buffer = (WCHAR *)(p + 1); + p->Name.Length = size - sizeof(WCHAR); + p->Name.MaximumLength = size; + wcscpy( p->Name.Buffer, nt_name ); + } + if (used_len) *used_len = sizeof(*p) + size; + free( nt_name ); + } + free( unix_name ); + break; + } + else if (status != STATUS_OBJECT_TYPE_MISMATCH) break; + + /* not a file, treat as a generic object */ SERVER_START_REQ( get_object_name ) { diff --git a/server/change.c b/server/change.c index 5bcd0676e0d..a42ee42ffaa 100644 --- a/server/change.c +++ b/server/change.c @@ -119,7 +119,7 @@ static const struct object_ops dir_ops = default_map_access, /* map_access */ dir_get_sd, /* get_sd */ dir_set_sd, /* set_sd */ - default_fd_get_full_name, /* get_full_name */ + no_get_full_name, /* get_full_name */ no_lookup_name, /* lookup_name */ no_link_name, /* link_name */ NULL, /* unlink_name */ diff --git a/server/fd.c b/server/fd.c index c4be028845f..76f004250f1 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2202,22 +2202,6 @@ struct object *default_fd_get_sync( struct object *obj ) return sync; } -/* default get_full_name() routine for objects with an fd */ -WCHAR *default_fd_get_full_name( struct object *obj, data_size_t max, data_size_t *ret_len ) -{ - struct fd *fd = get_obj_fd( obj ); - WCHAR *ret = NULL; - - if (fd->nt_name) - { - *ret_len = fd->nt_namelen; - ret = memdup( fd->nt_name, fd->nt_namelen ); - } - release_object( fd ); - if (*ret_len > max) set_error( STATUS_BUFFER_OVERFLOW ); - return ret; -} - int default_fd_get_poll_events( struct fd *fd ) { int events = 0; diff --git a/server/file.c b/server/file.c index cc5acc2aadc..8fe0ba2230a 100644 --- a/server/file.c +++ b/server/file.c @@ -101,7 +101,7 @@ static const struct object_ops file_ops = default_map_access, /* map_access */ file_get_sd, /* get_sd */ file_set_sd, /* set_sd */ - default_fd_get_full_name, /* get_full_name */ + no_get_full_name, /* get_full_name */ file_lookup_name, /* lookup_name */ no_link_name, /* link_name */ NULL, /* unlink_name */ diff --git a/server/file.h b/server/file.h index 567194bf00a..03582434776 100644 --- a/server/file.h +++ b/server/file.h @@ -109,7 +109,6 @@ extern char *dup_fd_name( struct fd *root, const char *name ) __WINE_DEALLOC(fre extern void get_nt_name( struct fd *fd, struct unicode_str *name ); extern struct object *default_fd_get_sync( struct object *obj ); -extern WCHAR *default_fd_get_full_name( struct object *obj, data_size_t max, data_size_t *ret_len ); extern int default_fd_get_poll_events( struct fd *fd ); extern void default_poll_event( struct fd *fd, int event ); extern void fd_cancel_async( struct fd *fd, struct async *async ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9105
From: Alfred Agrell <floating(a)muncher.se> --- dlls/kernel32/tests/file.c | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c index 47b8307aeda..25ef6355e13 100644 --- a/dlls/kernel32/tests/file.c +++ b/dlls/kernel32/tests/file.c @@ -5717,6 +5717,49 @@ static void test_GetFinalPathNameByHandleW(void) CloseHandle(file); } +static void test_GetFinalPathNameByHandleW_with_symlink(void) +{ + WCHAR junction_path[MAX_PATH]; + WCHAR *userprofile_end; + DWORD attrs; + BOOL is_link; + HANDLE file; + WCHAR result_path[MAX_PATH]; + UNICODE_STRING nt_path; + + if (!pGetFinalPathNameByHandleW) + { + win_skip("GetFinalPathNameByHandleW is missing\n"); + return; + } + + GetEnvironmentVariableW(L"USERPROFILE", junction_path, sizeof(junction_path)); + userprofile_end = junction_path + wcslen(junction_path); + + wcscpy(userprofile_end, L"\\My Documents"); + attrs = GetFileAttributesW(junction_path); + is_link = (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)); + todo_wine ok(is_link, "%s should be a junction\n", wine_dbgstr_w(junction_path)); + if (!is_link) + { + /* use another directory on Wine */ + wcscpy(userprofile_end, L"\\Desktop"); + attrs = GetFileAttributesW(junction_path); + is_link = (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)); + ok(is_link, "%s should be a symlink on Wine\n", wine_dbgstr_w(junction_path)); + } + + file = CreateFileW(junction_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, 0); + pGetFinalPathNameByHandleW(file, result_path, sizeof(result_path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); + CloseHandle(file); + + pRtlDosPathNameToNtPathName_U(junction_path, &nt_path, NULL, NULL); + /* extra +4 to skip \\?\ prefix, since it's \??\ instead in nt_path */ + ok(wcscmp(result_path+4, nt_path.Buffer+4) != 0, + "expected %s and %s to be different\n", wine_dbgstr_w(result_path), wine_dbgstr_w(nt_path.Buffer)); + RtlFreeUnicodeString(&nt_path); +} + static void test_SetFileInformationByHandle(void) { FILE_ATTRIBUTE_TAG_INFO fileattrinfo = { 0 }; @@ -6937,6 +6980,7 @@ START_TEST(file) test_file_access(); test_GetFinalPathNameByHandleA(); test_GetFinalPathNameByHandleW(); + test_GetFinalPathNameByHandleW_with_symlink(); test_SetFileInformationByHandle(); test_SetFileRenameInfo(); test_GetFileAttributesExW(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9105
participants (2)
-
Alfred Agrell -
Alfred Agrell (@Alcaro)