[PATCH 0/2] MR10651: Revert "kernelbase: Replace FileAllInformation with FileStatInformation in GetFileInformationByHandle()."
This reverts commit 1b0d8428dfc13b0fa5ea7d576dfef7aaf8a8c927. Some applications hook NtQueryInformationFile(FileAllInformation) and expect it to be called by GetFileInformationByHandle(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59644 -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651
From: Jinoh Kang <jinoh.kang.kr@gmail.com> --- dlls/ntdll/unix/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index d413bbbc0ab..9050ebc5500 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -2154,6 +2154,9 @@ static NTSTATUS server_get_name_info( HANDLE handle, FILE_NAME_INFORMATION *info const WCHAR *ptr = name->Name.Buffer; const WCHAR *end = ptr + name->Name.Length / sizeof(WCHAR); + /* The caller has verified that the handle has an associated fd */ + if (ptr == end) WARN( "handle %p is an anonymous file", handle ); + /* Skip the volume mount point. */ while (ptr != end && *ptr == '\\') ++ptr; while (ptr != end && *ptr != '\\') ++ptr; @@ -2162,7 +2165,6 @@ static NTSTATUS server_get_name_info( HANDLE handle, FILE_NAME_INFORMATION *info info->FileNameLength = (end - ptr) * sizeof(WCHAR); if (*name_len < info->FileNameLength) status = STATUS_BUFFER_OVERFLOW; - else if (!info->FileNameLength) status = STATUS_INVALID_INFO_CLASS; else *name_len = info->FileNameLength; if (info->FileNameLength) memcpy( info->FileName, ptr, *name_len ); free( name ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10651
From: Jinoh Kang <jinoh.kang.kr@gmail.com> This reverts commit 1b0d8428dfc13b0fa5ea7d576dfef7aaf8a8c927. Some applications hook NtQueryInformationFile(FileAllInformation) and expect it to be called by GetFileInformationByHandle(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59644 --- dlls/kernelbase/file.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 83977a2c40b..456113f6001 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -3106,26 +3106,27 @@ BOOL WINAPI DECLSPEC_HOTPATCH FlushFileBuffers( HANDLE file ) BOOL WINAPI DECLSPEC_HOTPATCH GetFileInformationByHandle( HANDLE file, BY_HANDLE_FILE_INFORMATION *info ) { FILE_FS_VOLUME_INFORMATION volume_info; - FILE_STAT_INFORMATION stat_info; + FILE_ALL_INFORMATION all_info; IO_STATUS_BLOCK io; NTSTATUS status; - status = NtQueryInformationFile( file, &io, &stat_info, sizeof(stat_info), FileStatInformation ); + status = NtQueryInformationFile( file, &io, &all_info, sizeof(all_info), FileAllInformation ); + if (status == STATUS_BUFFER_OVERFLOW) status = STATUS_SUCCESS; if (!set_ntstatus( status )) return FALSE; - info->dwFileAttributes = stat_info.FileAttributes; - info->ftCreationTime.dwHighDateTime = stat_info.CreationTime.u.HighPart; - info->ftCreationTime.dwLowDateTime = stat_info.CreationTime.u.LowPart; - info->ftLastAccessTime.dwHighDateTime = stat_info.LastAccessTime.u.HighPart; - info->ftLastAccessTime.dwLowDateTime = stat_info.LastAccessTime.u.LowPart; - info->ftLastWriteTime.dwHighDateTime = stat_info.LastWriteTime.u.HighPart; - info->ftLastWriteTime.dwLowDateTime = stat_info.LastWriteTime.u.LowPart; + info->dwFileAttributes = all_info.BasicInformation.FileAttributes; + info->ftCreationTime.dwHighDateTime = all_info.BasicInformation.CreationTime.u.HighPart; + info->ftCreationTime.dwLowDateTime = all_info.BasicInformation.CreationTime.u.LowPart; + info->ftLastAccessTime.dwHighDateTime = all_info.BasicInformation.LastAccessTime.u.HighPart; + info->ftLastAccessTime.dwLowDateTime = all_info.BasicInformation.LastAccessTime.u.LowPart; + info->ftLastWriteTime.dwHighDateTime = all_info.BasicInformation.LastWriteTime.u.HighPart; + info->ftLastWriteTime.dwLowDateTime = all_info.BasicInformation.LastWriteTime.u.LowPart; info->dwVolumeSerialNumber = 0; - info->nFileSizeHigh = stat_info.EndOfFile.u.HighPart; - info->nFileSizeLow = stat_info.EndOfFile.u.LowPart; - info->nNumberOfLinks = stat_info.NumberOfLinks; - info->nFileIndexHigh = stat_info.FileId.u.HighPart; - info->nFileIndexLow = stat_info.FileId.u.LowPart; + info->nFileSizeHigh = all_info.StandardInformation.EndOfFile.u.HighPart; + info->nFileSizeLow = all_info.StandardInformation.EndOfFile.u.LowPart; + info->nNumberOfLinks = all_info.StandardInformation.NumberOfLinks; + info->nFileIndexHigh = all_info.InternalInformation.IndexNumber.u.HighPart; + info->nFileIndexLow = all_info.InternalInformation.IndexNumber.u.LowPart; status = NtQueryVolumeInformationFile( file, &io, &volume_info, sizeof(volume_info), FileFsVolumeInformation ); if (status == STATUS_SUCCESS || status == STATUS_BUFFER_OVERFLOW) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10651
Instead of reverting, perhaps it's better to go with my original approach of returning proper info for "unix-side" files? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136104
On Tue Apr 14 17:29:16 2026 +0000, Gabriel Ivăncescu wrote:
Instead of reverting, perhaps it's better to go with my original approach of returning proper info for "unix-side" files? It's not just a simple revert; 66ef1bde48e6662801ff351c13499a815c8ca09e prevents FileAllInformation from failing even for anonymous Unix files.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136124
On Tue Apr 14 17:29:16 2026 +0000, Jinoh Kang wrote:
It's not just a simple revert; 66ef1bde48e6662801ff351c13499a815c8ca09e prevents FileAllInformation from failing even for anonymous Unix files. I see, this will return empty name for such files, right? Which is probably valid but will do more testing tomorrow. Even if it's decided to return actual file path later (in case of redirection for instance), it's probably preferrable as a first step, not least because even retrieving the name from unix fd can fail.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136143
FWIW I accidentally found that the same issue is with Tetrageddon Games (helped by these patches), that is packed in a single .exe file probably with the same tool concerned in the Wine bug. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136218
I see, this will return empty name for such files, right?
Indeed -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136220
On Tue Apr 14 22:20:57 2026 +0000, Jinoh Kang wrote:
I see, this will return empty name for such files, right? Indeed Looks good to me, if we need to expand on it to return proper filenames at some point, that will have to be done separately, anyway.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651#note_136300
This merge request was approved by Gabriel Ivăncescu. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10651
participants (4)
-
Gabriel Ivăncescu (@insn) -
Jinoh Kang -
Jinoh Kang (@iamahuman) -
Paul Gofman (@gofman)